feat(sms-bridge): support Twilio Messaging Service delivery - #44
Merged
Conversation
Finish the partial Messaging Service support on this branch. The worker honors an optional TWILIO_MESSAGING_SERVICE_SID: when non-empty, each reply is submitted through twilio.messages.create with only `to`, `body`, and `messaging_service_sid` and never `from_`; when empty or unset, the exact prior direct `from_` send from the channel destination number is preserved. The Settings field moves to the end of the frozen dataclass with a "" default so existing keyword-based Settings test construction keeps working; from_env still strips the value and worker_ready still treats the setting as optional. An unrelated error-string tweak bundled into the partial commit is reverted. Inbound routing, session and job state transitions, single-attempt no-retry semantics, delivery-unknown handling, and bounded no-detail telemetry are unchanged. Tests pin the service-mode and fallback call arguments, recipient and sms_body preservation, and the delivery-exception path (delivery-unknown plus twilio-send-failed, with no provider or payload detail in telemetry). The bridge README documents the non-secret optional worker setting, the per-deployment fallback, and the separate A2P/manual Twilio-console association boundary.
Cover the completed TWILIO_MESSAGING_SERVICE_SID delivery paths: the service-mode request uses exactly to, body, and messaging_service_sid with no from_ and preserves the recipient and sms_body-normalized reply; the unset path keeps the exact direct from_ channel-number call and relies on the trailing Settings default so existing keyword-based construction (unchanged setUp) still works; and a Twilio send exception persists delivery-unknown with twilio-send-failed while telemetry carries no provider, payload, or identifier detail.
Drop a stray walrus binding accidentally introduced while transcribing
the failure table; the tuple must stay the original plain
(OSError("socket detail"), "os") entry.
Image CI passedPre-commit validation passed. View the workflow run. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Add optional
TWILIO_MESSAGING_SERVICE_SIDsupport to the SMS bridge worker. When configured, replies use Twiliomessages.createwithto,body, andmessaging_service_sid—neverfrom_. When unset, the existing direct sender path remains unchanged for rollback compatibility.Fixes #
None — owner-approved A2P delivery remediation.
Type of change
Validation
imagesCI run 33983044024 passed build & push, checks, and detect at the PR head.Coverage validates exact Messaging Service and direct-sender call arguments, recipient/body preservation, and bounded delivery-exception handling. No local tests, container build, or live Twilio call were run or claimed.
Impact and rollout
Producer:
images/opencode-sms-bridgepublishes an immutable SHA tag only after an explicitly approved merge and successfulmainbuild/push.Consumers: companion
chartsandtfroot-twilioPRs prepare non-secret ConfigMap wiring and the Messaging Service sender pool. A final GitOps selection PR remains blocked until Terraform has applied the service and yielded its real SID. The A2P Brand/Campaign association remains a separate manual Twilio operator gate.Delivery stages: this PR authors and validates source only. Merge, image publication, chart publication, OpenTofu apply, provider campaign association, GitOps selection, Argo reconciliation, health, and an approved-sender test are distinct gates.
Rollback: leave the SID unset in the consumer to retain direct
from_delivery; select the prior immutable image through GitOps if source rollback is required.Safety and secrets
AI-assisted change: an OpenCode agent materially produced this change. Reviewers should verify mutually exclusive
messaging_service_sid/from_arguments, fallback behavior, and the bounded no-detail delivery failure path.