Skip to content

feat(sms-bridge): support Twilio Messaging Service delivery - #44

Merged
xnoto merged 4 commits into
mainfrom
feat/sms-bridge-messaging-service
Sep 5, 2026
Merged

feat(sms-bridge): support Twilio Messaging Service delivery#44
xnoto merged 4 commits into
mainfrom
feat/sms-bridge-messaging-service

Conversation

@xnoto

@xnoto xnoto commented Sep 5, 2026

Copy link
Copy Markdown
Contributor

Summary

Add optional TWILIO_MESSAGING_SERVICE_SID support to the SMS bridge worker. When configured, replies use Twilio messages.create with to, body, and messaging_service_sid—never from_. When unset, the existing direct sender path remains unchanged for rollback compatibility.

Fixes #

None — owner-approved A2P delivery remediation.

Type of change

  • Bug fix
  • Feature / enhancement
  • Documentation
  • Infrastructure (OpenTofu root or module)
  • GitOps desired state (manifests, kustomize, charts, SOPS/KSOPS secrets)
  • Container image
  • CI / reusable workflow
  • Refactor / cleanup
  • Breaking change

Validation

  • Required pull-request checks pass — images CI run 33983044024 passed build & push, checks, and detect at the PR head.
  • Generated or centrally distributed files were regenerated by their owning automation, not hand-edited — none apply.

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-bridge publishes an immutable SHA tag only after an explicitly approved merge and successful main build/push.

Consumers: companion charts and tfroot-twilio PRs 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

  • Contains no plaintext secrets, decrypted SOPS values, state files, kubeconfigs, tokens, or private endpoints
  • No local OpenTofu init/plan/apply/destroy/import/state operations were run or claimed — plans come from pull-request checks
  • Breaking or irreversible effects are described above with rollback notes

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.

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.
@xnoto
xnoto requested a review from a team as a code owner September 5, 2026 18:06
@github-actions

github-actions Bot commented Sep 5, 2026

Copy link
Copy Markdown

Image CI passed

Pre-commit validation passed. View the workflow run.

@xnoto
xnoto merged commit 9ae1ead into main Sep 5, 2026
4 checks passed
@xnoto
xnoto deleted the feat/sms-bridge-messaging-service branch September 5, 2026 19:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant