feat(twilio): add sms, mms, and voice helpers#558
Merged
Merged
Conversation
Contributor
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
19 tasks
patrick-chinchill
pushed a commit
to Chinchill-AI/chat-sdk-python
that referenced
this pull request
Jun 13, 2026
Completes the Twilio Programmable Messaging adapter (10th platform),
porting packages/adapter-twilio from upstream chat@4.30.0. Builds on the
PR-1 scaffolding (types, format converter, cards).
Source:
- adapter.py -- TwilioAdapter + create_twilio_adapter: webhook routing,
SMS/MMS send, REST/webhook message parsing, thread-ID encode/decode
(twilio:{sender}:{recipient}), attachment rehydration, not-implemented
surfaces (edit/reactions), accumulate-and-post streaming.
- api.py -- hand-rolled Messages/Calls/Media REST helpers over an
injectable transport (no official twilio SDK, mirroring upstream);
non-2xx responses mapped to the typed shared.errors hierarchy.
- webhook.py -- X-Twilio-Signature HMAC-SHA1 verification (sorted/
deduplicated base string, GET vs POST signing) compared with
hmac.compare_digest; custom webhook_verifier precedence; body parsing
(text / status / unsupported).
- voice.py -- standalone call + transcription webhook parsing and TwiML
response builders (Say / Gather speech), XML-escaped.
- utils.py / thread.py -- request/param plumbing, encodeURIComponent
parity, sender-field split, thread-ID helpers.
- __init__.py / pyproject.toml -- public exports + the [twilio] extra
(aiohttp); imports stay lazy so the package loads without aiohttp.
Tests (122 total across the package): test_twilio_api.py (28),
test_twilio_webhook.py (23), test_twilio_voice.py (14), and a new
test_twilio_adapter.py (33) porting upstream src/index.test.ts (thread
IDs, webhook routing, media rehydration, SMS/MMS/media-only/messaging-
service sends, REST parsing, fetch_messages merge/sort/limit, streaming).
Real assertions, AsyncMock for async transports, env isolation.
Python-specific divergence (documented in docs/UPSTREAM_SYNC.md and
CHANGELOG.md): the media-download path validates the rehydrated URL
(https + Twilio-owned host) before forwarding HTTP Basic credentials,
where upstream fetchTwilioMedia GETs blindly -- folded into the existing
rehydrate_attachment URL allowlist non-parity row, with a regression test.
Validation: ruff check + format clean; pyrefly 0 errors; audit_test_quality
0 hard failures; full suite 4572 passed / 6 skipped.
https://claude.ai/code/session_013zwTcMek5rNqBTQvs2oF64
patrick-chinchill
added a commit
to Chinchill-AI/chat-sdk-python
that referenced
this pull request
Jun 18, 2026
) * feat(twilio): scaffolding — types, format converter (vercel/chat#558, PR 1 of 2) PR 1 of 2 for the Twilio adapter port (upstream 25ebc3b, chat@4.30.0). Non-adapter scaffolding only; the adapter (webhook verification, Messages API, voice helpers, send/stream) lands in PR 2. Mirrors how the Messenger port was split (#118 / #124). Adds under src/chat_sdk/adapters/twilio/: - types.py: TwilioAdapterConfig (all-optional, mirroring upstream; TWILIO_MESSAGING_SERVICE_SID / TWILIO_PHONE_NUMBER env fallbacks with `??` semantics at construction time, TWILIO_ACCOUNT_SID / TWILIO_AUTH_TOKEN resolved lazily at API-call time), TwilioThreadId, TwilioCredential/TwilioCredentials, TwilioHttpRequest/TwilioHttpResponse (the Python analog of upstream's injectable `fetch`), form-param aliases, TwilioWebhookUrl + TwilioWebhookVerifier (SECURITY surface, Slack-verifier-style contract), webhook payload dataclasses (text/status/unsupported + media), webhook error classes, and the TwilioMessageResource / TwilioCallResource wire TypedDicts (functional syntax — `from` is a Python keyword; Twilio's wire keys are already snake_case). - format_converter.py: TWILIO_MESSAGE_LIMIT (1600), truncate_twilio_text (TypeError on non-positive/non-int limits incl. bools), twilio_text_or_placeholder, and TwilioFormatConverter (markdown passes through as literal text; tables rewritten to ASCII code blocks). Mirrors upstream markdown.ts + format/index.ts. - cards.py: card_to_twilio_text — shared fallback text with `*` markers stripped. Mirrors upstream cards.ts. - __init__.py: exports types/format/cards only (PR 2 adds the adapter). Tests (28): tests/test_twilio_format.py (format/index.test.ts + markdown.test.ts ports + config env-fallback `??` regressions), tests/test_twilio_cards.py (cards.test.ts port), and tests/test_twilio_boundaries.py (Python analog of upstream's four boundary.test.ts files: no top-level aiohttp, no official `twilio` SDK, helper modules never import the adapter — auto-extends to the PR 2 modules). Validation: ruff check + format, audit_test_quality, pyrefly (0 errors), fidelity --strict vs chat@4.29.0, full suite 4474 passed / 6 skipped. Refs vercel/chat#558. https://claude.ai/code/session_013zwTcMek5rNqBTQvs2oF64 * feat(twilio): adapter, api, voice, webhook (vercel/chat#558, PR 2 of 2) Completes the Twilio Programmable Messaging adapter (10th platform), porting packages/adapter-twilio from upstream chat@4.30.0. Builds on the PR-1 scaffolding (types, format converter, cards). Source: - adapter.py -- TwilioAdapter + create_twilio_adapter: webhook routing, SMS/MMS send, REST/webhook message parsing, thread-ID encode/decode (twilio:{sender}:{recipient}), attachment rehydration, not-implemented surfaces (edit/reactions), accumulate-and-post streaming. - api.py -- hand-rolled Messages/Calls/Media REST helpers over an injectable transport (no official twilio SDK, mirroring upstream); non-2xx responses mapped to the typed shared.errors hierarchy. - webhook.py -- X-Twilio-Signature HMAC-SHA1 verification (sorted/ deduplicated base string, GET vs POST signing) compared with hmac.compare_digest; custom webhook_verifier precedence; body parsing (text / status / unsupported). - voice.py -- standalone call + transcription webhook parsing and TwiML response builders (Say / Gather speech), XML-escaped. - utils.py / thread.py -- request/param plumbing, encodeURIComponent parity, sender-field split, thread-ID helpers. - __init__.py / pyproject.toml -- public exports + the [twilio] extra (aiohttp); imports stay lazy so the package loads without aiohttp. Tests (122 total across the package): test_twilio_api.py (28), test_twilio_webhook.py (23), test_twilio_voice.py (14), and a new test_twilio_adapter.py (33) porting upstream src/index.test.ts (thread IDs, webhook routing, media rehydration, SMS/MMS/media-only/messaging- service sends, REST parsing, fetch_messages merge/sort/limit, streaming). Real assertions, AsyncMock for async transports, env isolation. Python-specific divergence (documented in docs/UPSTREAM_SYNC.md and CHANGELOG.md): the media-download path validates the rehydrated URL (https + Twilio-owned host) before forwarding HTTP Basic credentials, where upstream fetchTwilioMedia GETs blindly -- folded into the existing rehydrate_attachment URL allowlist non-parity row, with a regression test. Validation: ruff check + format clean; pyrefly 0 errors; audit_test_quality 0 hard failures; full suite 4572 passed / 6 skipped. https://claude.ai/code/session_013zwTcMek5rNqBTQvs2oF64 --------- Co-authored-by: Claude <noreply@anthropic.com>
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
adds a first-class Twilio adapter for SMS and MMS bots, plus low-level voice helpers for custom Twilio voice routes
this includes webhook parsing and signature verification, outbound Messages API helpers, phone-number and Messaging Service sending, inbound MMS attachments with authenticated
fetchData, plain text card fallback rendering, markdown conversion, and runtime-lightapi,webhook,voice, andformatsubpathsthe adapter intentionally avoids the
twilionpm runtime dependency so apps can use the low-level helpers without pulling in the full SDK