|
| 1 | +package botplan |
| 2 | + |
| 3 | +// TextMarkup identifies how a platform expresses rich-text styling, so a Rich |
| 4 | +// renderer knows which dialect to emit. |
| 5 | +type TextMarkup int |
| 6 | + |
| 7 | +const ( |
| 8 | + // MarkupPlain: no styling; spans render as their text. (No platform in the |
| 9 | + // pilot set is plain-only, but a renderer may downgrade to it.) |
| 10 | + MarkupPlain TextMarkup = iota |
| 11 | + // MarkupHTML: an HTML subset with a parse-mode opt-in and anchor-text links. |
| 12 | + // Telegram (capability-map telegram/text-formatting: htmlTags include |
| 13 | + // b/i/code/a, hyperlinks=true). |
| 14 | + MarkupHTML |
| 15 | + // MarkupMarkers: always-on inline markers, no parse-mode, no anchor-text |
| 16 | + // links. WhatsApp (capability-map whatsapp/text-formatting: markers map, |
| 17 | + // noParseModeParameter, noAnchorTextLinks). |
| 18 | + MarkupMarkers |
| 19 | +) |
| 20 | + |
| 21 | +// Descriptor is the static per-platform capability fact-sheet a renderer |
| 22 | +// consults. It is the F5 half of the seam: every field mirrors a record in |
| 23 | +// can-i-use/capability-map.json (cited in the field's doc comment) so the |
| 24 | +// descriptor a renderer ships can be CI-checked against the platform facts. |
| 25 | +// |
| 26 | +// It carries only the facts the two pilot renderers genuinely consult when |
| 27 | +// shaping a MessagePlan — not the whole capability map. Dynamic facts (is the |
| 28 | +// window open right now, is this template approved) are NOT here; they live on |
| 29 | +// RenderTarget and in the template catalog, because they vary per send. |
| 30 | +type Descriptor struct { |
| 31 | + // MaxPromptButtons is the largest number of choices that render as inline/ |
| 32 | + // reply buttons before the renderer must degrade to a list or pages. |
| 33 | + // Telegram: no fixed small cap (inline grid) — set high. WhatsApp: |
| 34 | + // capability-map whatsapp/reply-buttons constraints.maxButtons = 3. |
| 35 | + MaxPromptButtons int |
| 36 | + |
| 37 | + // MaxListRows is the largest number of choices that render as a single |
| 38 | + // selectable list before paging is required. Telegram has no list message |
| 39 | + // (buttons only) — 0 means "not applicable". WhatsApp: capability-map |
| 40 | + // whatsapp/list-messages constraints.maxRowsAcrossAllSections = 10. |
| 41 | + MaxListRows int |
| 42 | + |
| 43 | + // MaxButtonLabelChars is the button/row label ceiling; longer labels are |
| 44 | + // truncated. Telegram: no documented hard limit — 0 means "unbounded". |
| 45 | + // WhatsApp: capability-map whatsapp/reply-buttons buttonLabelMaxChars = 20. |
| 46 | + MaxButtonLabelChars int |
| 47 | + |
| 48 | + // SupportsEdit reports whether the platform can update a message in place |
| 49 | + // (LivePanel). Telegram: capability-map telegram/edit-message native = true. |
| 50 | + // WhatsApp: capability-map whatsapp/edit-message absent = false → append. |
| 51 | + SupportsEdit bool |
| 52 | + |
| 53 | + // SupportsDelete reports whether the platform can retract a message. |
| 54 | + // Telegram: capability-map telegram/delete-message native = true. WhatsApp: |
| 55 | + // capability-map whatsapp/delete-message absent = false. |
| 56 | + SupportsDelete bool |
| 57 | + |
| 58 | + // SupportsCallbackAck reports whether a tap can be acknowledged (toast / |
| 59 | + // spinner-stop). Telegram: capability-map telegram/callback-query |
| 60 | + // semanticsRequiresAck = true. WhatsApp: capability-map whatsapp/callback-ack |
| 61 | + // absent = false — there is nothing to ack. |
| 62 | + SupportsCallbackAck bool |
| 63 | + |
| 64 | + // WindowGated reports whether proactive sends are gated by a service window |
| 65 | + // that may force a template. Telegram: false (capability-map |
| 66 | + // telegram/proactive-messaging native, no window). WhatsApp: true |
| 67 | + // (capability-map whatsapp/customer-service-window partial, 24h). |
| 68 | + WindowGated bool |
| 69 | + |
| 70 | + // SupportsInlineURLButton reports whether a fully dynamic URL button can ride |
| 71 | + // a normal (non-template) message. Telegram: capability-map |
| 72 | + // telegram/inline-keyboard (URL buttons) = true. WhatsApp: capability-map |
| 73 | + // whatsapp/cta-url-button native = true, but only in-window — the renderer |
| 74 | + // combines this flag with RenderTarget.WindowOpen. |
| 75 | + SupportsInlineURLButton bool |
| 76 | + |
| 77 | + // SupportsButtonGrid reports whether buttons arrange in a multi-column grid |
| 78 | + // (so ActionPrompt.LayoutRows is meaningful). Telegram: capability-map |
| 79 | + // telegram/inline-keyboard constraints.layout = "grid" = true. WhatsApp: |
| 80 | + // capability-map whatsapp/reply-buttons grid = false. |
| 81 | + SupportsButtonGrid bool |
| 82 | + |
| 83 | + // SupportsMedia reports whether the platform can send an image. Telegram: |
| 84 | + // capability-map telegram/send-photo native = true. WhatsApp: capability-map |
| 85 | + // whatsapp/send-image native = true (though the client may not yet implement |
| 86 | + // it — a platform fact, not a client fact). |
| 87 | + SupportsMedia bool |
| 88 | + |
| 89 | + // TextMarkup is the styling dialect the Rich renderer must emit. See |
| 90 | + // TextMarkup. Telegram: MarkupHTML. WhatsApp: MarkupMarkers. |
| 91 | + TextMarkup TextMarkup |
| 92 | + |
| 93 | + // SupportsAnchorTextLinks reports whether a link span can render as anchor |
| 94 | + // text over a hidden URL. Telegram: capability-map telegram/text-formatting |
| 95 | + // hyperlinks = true. WhatsApp: capability-map whatsapp/text-formatting |
| 96 | + // noAnchorTextLinks → false, so links render as "anchor: url". |
| 97 | + SupportsAnchorTextLinks bool |
| 98 | +} |
0 commit comments