From d2eab84b954bba094f00fe694597c92be1ee7e02 Mon Sep 17 00:00:00 2001 From: Jessica Matsuoka Date: Fri, 6 Mar 2026 00:36:19 +0100 Subject: [PATCH 1/2] chore: remove webhook validation from Getting started --- .../send_handle_incoming_sms/.env.example | 3 --- .../send_handle_incoming_sms/README.md | 9 +-------- .../send_handle_incoming_sms/controller.py | 16 ++-------------- .../send_handle_incoming_sms/server.py | 3 +-- sinch/domains/conversation/conversation.py | 2 +- 5 files changed, 5 insertions(+), 28 deletions(-) diff --git a/examples/getting-started/conversation/send_handle_incoming_sms/.env.example b/examples/getting-started/conversation/send_handle_incoming_sms/.env.example index 9716be1d..dd1509f2 100644 --- a/examples/getting-started/conversation/send_handle_incoming_sms/.env.example +++ b/examples/getting-started/conversation/send_handle_incoming_sms/.env.example @@ -9,8 +9,5 @@ SINCH_KEY_SECRET= CONVERSATION_APP_ID= SINCH_CONVERSATION_REGION= -# Webhook secret (set when configuring the callback in Sinch dashboard) -CONVERSATION_WEBHOOKS_SECRET= - # Server SERVER_PORT=3001 diff --git a/examples/getting-started/conversation/send_handle_incoming_sms/README.md b/examples/getting-started/conversation/send_handle_incoming_sms/README.md index ee2fda88..93aac62b 100644 --- a/examples/getting-started/conversation/send_handle_incoming_sms/README.md +++ b/examples/getting-started/conversation/send_handle_incoming_sms/README.md @@ -35,12 +35,6 @@ see that the MO was received and processed. SINCH_CONVERSATION_REGION= ``` - - Webhook secret (the value you set when configuring the callback URL for this app). - See [Conversation API callbacks](https://developers.sinch.com/docs/conversation/callbacks): - ``` - CONVERSATION_WEBHOOKS_SECRET=your_webhook_secret - ``` - - Server port (optional; default 3001): ``` SERVER_PORT=3001 @@ -92,8 +86,7 @@ Forwarding https://abc123.ngrok-free.app -> http://localhost:3001 Use the **HTTPS** URL when configuring the callback: `https:///ConversationEvent` -Configure this callback URL (and the webhook secret) in the Sinch dashboard for your Conversation API app. -The webhook secret must match `CONVERSATION_WEBHOOKS_SECRET` in your `.env`. +Configure this callback URL in the Sinch dashboard for your Conversation API app. ### Sending an SMS to your Sinch number diff --git a/examples/getting-started/conversation/send_handle_incoming_sms/controller.py b/examples/getting-started/conversation/send_handle_incoming_sms/controller.py index bc1d7178..98d7c4aa 100644 --- a/examples/getting-started/conversation/send_handle_incoming_sms/controller.py +++ b/examples/getting-started/conversation/send_handle_incoming_sms/controller.py @@ -3,9 +3,8 @@ class ConversationController: - def __init__(self, sinch_client, webhooks_secret, app_id): + def __init__(self, sinch_client, app_id): self.sinch_client = sinch_client - self.webhooks_secret = webhooks_secret self.app_id = app_id self.logger = self.sinch_client.configuration.logger @@ -13,18 +12,7 @@ def conversation_event(self): headers = dict(request.headers) raw_body = getattr(request, "raw_body", None) or b"" - webhooks_service = self.sinch_client.conversation.webhooks(self.webhooks_secret) - - # Set to True to enforce signature validation (recommended in production) - ensure_valid_signature = False - if ensure_valid_signature: - valid = webhooks_service.validate_authentication_header( - headers=headers, - json_payload=raw_body, - ) - if not valid: - return Response(status=401) - + webhooks_service = self.sinch_client.conversation.webhooks() event = webhooks_service.parse_event(raw_body, headers) handle_conversation_event( event=event, diff --git a/examples/getting-started/conversation/send_handle_incoming_sms/server.py b/examples/getting-started/conversation/send_handle_incoming_sms/server.py index 6582205a..ae399f43 100644 --- a/examples/getting-started/conversation/send_handle_incoming_sms/server.py +++ b/examples/getting-started/conversation/send_handle_incoming_sms/server.py @@ -22,7 +22,6 @@ def load_config(): config = load_config() port = int(config.get("SERVER_PORT") or "3001") app_id = config.get("CONVERSATION_APP_ID") or "" -webhooks_secret = config.get("CONVERSATION_WEBHOOKS_SECRET") or "" conversation_region = (config.get("SINCH_CONVERSATION_REGION") or "").strip() if not conversation_region: raise ValueError( @@ -40,7 +39,7 @@ def load_config(): sinch_client.configuration.logger.setLevel(logging.INFO) conversation_controller = ConversationController( - sinch_client, webhooks_secret, app_id + sinch_client, app_id ) diff --git a/sinch/domains/conversation/conversation.py b/sinch/domains/conversation/conversation.py index b85cff21..f9f06685 100644 --- a/sinch/domains/conversation/conversation.py +++ b/sinch/domains/conversation/conversation.py @@ -14,7 +14,7 @@ def __init__(self, sinch): self._sinch = sinch self.messages = Messages(self._sinch) - def webhooks(self, callback_secret: str) -> ConversationWebhooks: + def webhooks(self, callback_secret: str = "") -> ConversationWebhooks: """ Create a Conversation API webhooks handler with the given webhook secret. From 575f032d428422dc3f3232ba0f459c8f336bf808 Mon Sep 17 00:00:00 2001 From: Jessica Matsuoka Date: Fri, 6 Mar 2026 17:05:58 +0100 Subject: [PATCH 2/2] remove app id --- .../conversation/send_handle_incoming_sms/.env.example | 1 - .../conversation/send_handle_incoming_sms/README.md | 3 +-- .../conversation/send_handle_incoming_sms/controller.py | 4 +--- .../conversation/send_handle_incoming_sms/server.py | 6 +----- .../send_handle_incoming_sms/server_business_logic.py | 9 +++++---- 5 files changed, 8 insertions(+), 15 deletions(-) diff --git a/examples/getting-started/conversation/send_handle_incoming_sms/.env.example b/examples/getting-started/conversation/send_handle_incoming_sms/.env.example index dd1509f2..af1dc362 100644 --- a/examples/getting-started/conversation/send_handle_incoming_sms/.env.example +++ b/examples/getting-started/conversation/send_handle_incoming_sms/.env.example @@ -6,7 +6,6 @@ SINCH_KEY_SECRET= # Conversation API: existing app (already created and configured for SMS). # SINCH_CONVERSATION_REGION is required. # Set it to the same region as the one your app was created in (e.g. eu). -CONVERSATION_APP_ID= SINCH_CONVERSATION_REGION= # Server diff --git a/examples/getting-started/conversation/send_handle_incoming_sms/README.md b/examples/getting-started/conversation/send_handle_incoming_sms/README.md index 93aac62b..b9a5e5e4 100644 --- a/examples/getting-started/conversation/send_handle_incoming_sms/README.md +++ b/examples/getting-started/conversation/send_handle_incoming_sms/README.md @@ -29,9 +29,8 @@ see that the MO was received and processed. SINCH_KEY_SECRET=your_key_secret ``` - - Conversation API app (existing app, already configured for SMS). Set `SINCH_CONVERSATION_REGION` to the same region as the one your app was created in (e.g. `eu`): + - Conversation API: set `SINCH_CONVERSATION_REGION` to the same region as the one your app was created in (e.g. `eu`). ``` - CONVERSATION_APP_ID=your_conversation_app_id SINCH_CONVERSATION_REGION= ``` diff --git a/examples/getting-started/conversation/send_handle_incoming_sms/controller.py b/examples/getting-started/conversation/send_handle_incoming_sms/controller.py index 98d7c4aa..e5816460 100644 --- a/examples/getting-started/conversation/send_handle_incoming_sms/controller.py +++ b/examples/getting-started/conversation/send_handle_incoming_sms/controller.py @@ -3,9 +3,8 @@ class ConversationController: - def __init__(self, sinch_client, app_id): + def __init__(self, sinch_client): self.sinch_client = sinch_client - self.app_id = app_id self.logger = self.sinch_client.configuration.logger def conversation_event(self): @@ -18,7 +17,6 @@ def conversation_event(self): event=event, logger=self.logger, sinch_client=self.sinch_client, - app_id=self.app_id, ) return Response(status=200) diff --git a/examples/getting-started/conversation/send_handle_incoming_sms/server.py b/examples/getting-started/conversation/send_handle_incoming_sms/server.py index ae399f43..f5805228 100644 --- a/examples/getting-started/conversation/send_handle_incoming_sms/server.py +++ b/examples/getting-started/conversation/send_handle_incoming_sms/server.py @@ -21,7 +21,6 @@ def load_config(): config = load_config() port = int(config.get("SERVER_PORT") or "3001") -app_id = config.get("CONVERSATION_APP_ID") or "" conversation_region = (config.get("SINCH_CONVERSATION_REGION") or "").strip() if not conversation_region: raise ValueError( @@ -38,9 +37,7 @@ def load_config(): logging.basicConfig() sinch_client.configuration.logger.setLevel(logging.INFO) -conversation_controller = ConversationController( - sinch_client, app_id -) +conversation_controller = ConversationController(sinch_client) @app.before_request @@ -56,6 +53,5 @@ def before_request(): if __name__ == "__main__": print("Getting Started: MO SMS → MT reply (Conversation API, DISPATCH, channel identity)") - print(f"App ID: {app_id or '(set CONVERSATION_APP_ID in .env)'}") print(f"Listening on port {port}. Expose with: ngrok http {port}") app.run(port=port) diff --git a/examples/getting-started/conversation/send_handle_incoming_sms/server_business_logic.py b/examples/getting-started/conversation/send_handle_incoming_sms/server_business_logic.py index 506f9f73..28107874 100644 --- a/examples/getting-started/conversation/send_handle_incoming_sms/server_business_logic.py +++ b/examples/getting-started/conversation/send_handle_incoming_sms/server_business_logic.py @@ -6,11 +6,11 @@ from sinch.domains.conversation.models.v1.webhooks import MessageInboundEvent -def handle_conversation_event(event, logger, sinch_client, app_id): +def handle_conversation_event(event, logger, sinch_client): """Webhook entry: handle only MESSAGE_INBOUND; delegate to inbound handler.""" if not isinstance(event, MessageInboundEvent): return - _handle_message_inbound(event, logger, sinch_client, app_id) + _handle_message_inbound(event, logger, sinch_client) def _get_mo_text(event: MessageInboundEvent) -> str: @@ -22,7 +22,7 @@ def _get_mo_text(event: MessageInboundEvent) -> str: return "(no text content)" -def _handle_message_inbound(event: MessageInboundEvent, logger, sinch_client, app_id): +def _handle_message_inbound(event: MessageInboundEvent, logger, sinch_client): """Parse MO, then send MT echo to the same number via Conversation API.""" msg = event.message channel_identity = msg.channel_identity @@ -34,8 +34,9 @@ def _handle_message_inbound(event: MessageInboundEvent, logger, sinch_client, ap mo_text = _get_mo_text(event) logger.info("MO SMS from %s: %s", identity, mo_text) + app_id = event.app_id if not app_id: - logger.warning("CONVERSATION_APP_ID not set; skipping MT reply.") + logger.warning("Event has no app_id; skipping MT reply.") return reply_text = f"Your message said: {mo_text}"