You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Spike (time-boxed investigation, no shipping code) — blocks the WhatsApp adapter implementation in #438.
Context
The WhatsApp Cloud API rejects free-form text outside a 24-hour customer-service window opened by a user-initiated inbound message, and requires a pre-approved message template (type: "template" with name, language, components) for proactive/business-initiated sends. The WhatsApp adapter in #438 is outbound-only with no inbound in v1, so there is effectively no open window for scheduled/proactive delivery → SendResponse must send a template message.
This has no analog in the Telegram/Slack adapters (which send free text unconditionally and chunk/upload long content via markdown.SplitMessage). We need the template + long-content strategy settled before writing whatsapp.go, because it dictates the config schema, the SendResponse payload builder, and the tests.
Goal
Produce a written decision (comment or short design note on this issue) that answers the questions below concretely enough that #438 can be implemented without further design debate.
Questions to answer
Template selection.
Fixed default template (name + language) in whatsapp-config.yaml, or per-schedule override (extend ScheduleConfig)? Recommend one for v1.
What's the components/parameter shape? Most likely: one body template with a single {{1}} parameter carrying the agent's response summary. Confirm against a real approved-template example.
Language policy: single configured language.code (e.g. en_US), or derive it? v1 default.
Long-content handling (the agent's response can be long markdown; WhatsApp body parameters have length limits — the Telegram/Slack SplitMessage/file-upload path does not apply).
Truncate the summary into the body parameter (and rely on a2a.Message.Summary when present, as Telegram/Slack already prefer)?
Or send a media/document message (upload → type: document) for long reports?
Or split across multiple template sends? (Likely undesirable — each is billable and rate-limited.)
Decide the v1 behavior + a hard character cap.
Parameter safety. WhatsApp rejects template body parameters containing newlines, tabs, or >4 consecutive spaces. Define the sanitization step (collapse whitespace, strip newlines) the SendResponse builder must apply, and where it lives (in markdown.ToWhatsApp or the send path).
Freeform fallback (scope check). Is allow_freeform (send type: text when a window is known open) worth any v1 investment, given there's no inbound to open a window? Recommend include/defer. If deferred, note it's a v2 concern tied to the inbound-webhook question in [Feature]: WhatsApp channel adapter (outbound-only, like Telegram/Slack) #438.
Config schema. Given the above, specify the exact whatsapp-config.yamlsettings: keys the adapter reads in Init (e.g. phone_number_id, access_token_env, api_version, template_name, template_language, max_body_chars), so [Feature]: WhatsApp channel adapter (outbound-only, like Telegram/Slack) #438's config template and Init validation are locked.
Provider constraints to record. Pin the Meta Graph API version, note the template approval lead time (templates must be pre-approved in Meta Business Manager — a human/ops dependency, not code), and the per-number send rate limits that bound scheduled-delivery throughput.
Deliverable
A decision note on this issue covering (1)–(6), plus a sample type: template request body (the exact JSON SendResponse will POST to graph.facebook.com/<ver>/<phoneID>/messages) that the #438 implementation and its tests can be built against.
Spike (time-boxed investigation, no shipping code) — blocks the WhatsApp adapter implementation in #438.
Context
The WhatsApp Cloud API rejects free-form text outside a 24-hour customer-service window opened by a user-initiated inbound message, and requires a pre-approved message template (
type: "template"withname,language,components) for proactive/business-initiated sends. The WhatsApp adapter in #438 is outbound-only with no inbound in v1, so there is effectively no open window for scheduled/proactive delivery →SendResponsemust send a template message.This has no analog in the Telegram/Slack adapters (which send free text unconditionally and chunk/upload long content via
markdown.SplitMessage). We need the template + long-content strategy settled before writingwhatsapp.go, because it dictates the config schema, theSendResponsepayload builder, and the tests.Goal
Produce a written decision (comment or short design note on this issue) that answers the questions below concretely enough that #438 can be implemented without further design debate.
Questions to answer
Template selection.
whatsapp-config.yaml, or per-schedule override (extendScheduleConfig)? Recommend one for v1.components/parameter shape? Most likely: one body template with a single{{1}}parameter carrying the agent's response summary. Confirm against a real approved-template example.language.code(e.g.en_US), or derive it? v1 default.Long-content handling (the agent's response can be long markdown; WhatsApp body parameters have length limits — the Telegram/Slack
SplitMessage/file-upload path does not apply).a2a.Message.Summarywhen present, as Telegram/Slack already prefer)?type: document) for long reports?Parameter safety. WhatsApp rejects template body parameters containing newlines, tabs, or >4 consecutive spaces. Define the sanitization step (collapse whitespace, strip newlines) the
SendResponsebuilder must apply, and where it lives (inmarkdown.ToWhatsAppor the send path).Freeform fallback (scope check). Is
allow_freeform(sendtype: textwhen a window is known open) worth any v1 investment, given there's no inbound to open a window? Recommend include/defer. If deferred, note it's a v2 concern tied to the inbound-webhook question in [Feature]: WhatsApp channel adapter (outbound-only, like Telegram/Slack) #438.Config schema. Given the above, specify the exact
whatsapp-config.yamlsettings:keys the adapter reads inInit(e.g.phone_number_id,access_token_env,api_version,template_name,template_language,max_body_chars), so [Feature]: WhatsApp channel adapter (outbound-only, like Telegram/Slack) #438's config template andInitvalidation are locked.Provider constraints to record. Pin the Meta Graph API version, note the template approval lead time (templates must be pre-approved in Meta Business Manager — a human/ops dependency, not code), and the per-number send rate limits that bound scheduled-delivery throughput.
Deliverable
A decision note on this issue covering (1)–(6), plus a sample
type: templaterequest body (the exact JSONSendResponsewill POST tograph.facebook.com/<ver>/<phoneID>/messages) that the #438 implementation and its tests can be built against.Out of scope
Parent
Part of #438 (WhatsApp channel adapter, outbound-only). Resolves open questions #1 and #2 there.