Channels
Telnyx Openclaw Sms Channel
OpenClaw channel plugin: SMS/MMS via Telnyx Messaging API
Install
npm install
npm
Configuration Example
{
"channels": {
"telnyx-sms": {
"apiKey": "KEY...",
"allowFrom": ["+15551234567"],
"exposure": {
"publicUrl": "https://agent.example.com/telnyx-sms/webhook"
}
}
}
}
README
# Telnyx SMS/MMS Channel for OpenClaw
Official Telnyx SMS plugin for OpenClaw. Give any OpenClaw agent a real Telnyx phone number so people can text the agent directly over SMS/MMS.
This package is the Telnyx-owned channel plugin for OpenClaw. It is designed around a one-key Telnyx setup path: paste a Telnyx API key, let the plugin discover the phone number, messaging profile, and webhook public key, then let it configure the messaging profile webhook safely.
## Why this plugin
- Official Telnyx-maintained OpenClaw SMS/MMS channel.
- One-key setup path using a Telnyx API v2 key.
- Auto-discovers the Telnyx phone number, messaging profile, and Ed25519 public key when possible.
- Automatically registers the OpenClaw webhook route.
- Can PATCH the Telnyx messaging profile webhook URL for you.
- Refuses to overwrite an existing third-party webhook unless explicitly allowed.
- Self-probes the public webhook URL to confirm it reaches this OpenClaw gateway.
- Runs a watchdog to detect tunnel or Telnyx profile webhook drift.
- Supports inbound SMS/MMS, outbound SMS/MMS, allowlisted access, and multi-account setups.
## Telnyx-native setup
This plugin is built for the official Telnyx path:
- Start with a single Telnyx API v2 key.
- Discover the Telnyx number, messaging profile, and webhook public key automatically when possible.
- Configure the Telnyx Messaging Profile webhook URL from OpenClaw.
- Protect existing webhook URLs by default.
- Confirm the public webhook URL reaches this OpenClaw gateway before using it.
- Watch for tunnel or webhook drift after setup.
## Features
- Inbound SMS through Telnyx Messaging webhooks.
- Inbound MMS payload parsing and delivery to OpenClaw.
- Outbound SMS replies through `POST /v2/messages`.
- Outbound MMS with `media_urls`.
- Ed25519 webhook signature verification using Telnyx webhook headers.
- OpenClaw direct-message threading by phone number.
- Optional pairing via SMS verification code.
- `allowlist` or `open` DM security mode.
- Outbound allowlist enforcement so an allowlisted bot cannot accidentally send to unknown numbers.
- Multi-account config for multiple Telnyx numbers/profiles from one OpenClaw instance.
- Automatic public key discovery from `GET /v2/public_key`.
- Automatic number/profile discovery from Telnyx phone-number APIs.
- Optional messaging profile creation and orphan-number attachment with explicit opt-in.
- Automatic webhook configuration with safe overwrite protection.
- Public URL self-probe and periodic webhook watchdog.
- In-memory status/event log for recent inbound, outbound, blocked, and error events.
- MMS media URL safety checks to prevent SSRF-style fetch risks.
## Prerequisites
- OpenClaw `2026.4.21` or later.
- A Telnyx account.
- A Telnyx API v2 key.
- A Telnyx phone number with SMS/MMS capability.
- A publicly reachable webhook URL for inbound SMS/MMS.
- For US A2P messaging, approved 10DLC brand/campaign setup in Telnyx.
## Install
From ClawHub:
```sh
clawhub package install telnyx-openclaw-sms-channel
```
From source while developing:
```sh
git clone https://github.com/team-telnyx/telnyx-openclaw-sms-channel.git
cd telnyx-openclaw-sms-channel
npm install
npm run build
```
## Quick start
### 1. Create a Telnyx API key
In the Telnyx Mission Control Portal:
1. Go to API Keys.
2. Create or copy an API v2 key.
3. Keep it private. It should start with `KEY...`.
### 2. Make sure you have an SMS-capable Telnyx number
The plugin can discover your number automatically, but the account still needs at least one SMS/MMS-capable number.
If the number is already attached to a Messaging Profile, the plugin can reuse that profile. If the number is not attached to a profile, set `autoCreateProfile: true` only when you want the plugin to create a profile and attach the orphan number for you.
### 3. Configure OpenClaw
Minimal config:
```json
{
"channels": {
"telnyx-sms": {
"apiKey": "KEY...",
"allowFrom": ["+15551234567"],
"exposure": {
"publicUrl": "https://agent.example.com/telnyx-sms/webhook"
}
}
}
}
```
With only `apiKey`, the plugin attempts to discover:
- `defaultFromNumber`
- `messagingProfileId`
- `publicKey`
The `publicKey` is the Telnyx account-wide Ed25519 webhook public key from `GET /v2/public_key`.
### 4. Start OpenClaw
When the gateway starts, the plugin:
1. Registers the local webhook route, default `/telnyx-sms/webhook`.
2. Discovers missing Telnyx defaults when possible.
3. Resolves the public webhook URL.
4. Self-probes the public URL.
5. Configures the Telnyx Messaging Profile webhook URL if safe.
6. Starts a watchdog for route/profile drift.
7. Acknowledges validated webhooks quickly with `200 OK` so Telnyx does not retry unnecessarily.
### 5. Text the Telnyx number
If `dmSecurity` is `allowlist`, the sender must be in `allowFrom`.
If `dmSecurity` is `open`, anyone who knows the number can message the agent.
## Configuration reference
Full single-account example:
```json
{
"channels": {
"telnyx-sms": {
"apiKey": "KEY...",
"defaultFromNumber": "+15551234567",
"messagingProfileId": "40000000-0000-0000-0000-000000000000",
"publicKey": "base64-ed25519-public-key",
"dmSecurity": "allowlist",
"allowFrom": ["+15557654321"],
"webhookPath": "/telnyx-sms/webhook",
"exposure": {
"publicUrl": "https://agent.example.com/telnyx-sms/webhook"
},
"overwriteExistingWebhook": false,
"profileName": "OpenClaw Agent",
"autoCreateProfile": false
}
}
}
```
### `apiKey`
Telnyx API v2 key. Required.
### `defaultFromNumber`
E.164 Telnyx number used for outbound SMS/MMS. Optional when discovery can find a number.
### `messagingProfileId`
Telnyx Messaging Profile ID. Optional when discovery can find the profile attached to `defaultFromNumber`.
### `publicKey`
Base64 Ed25519 public key used to verify Telnyx webhooks. Optional when discovery can fetch it from `GET /v2/public_key`.
### `dmSecurity`
Inbound/outbound DM security policy.
Allowed values:
- `allowlist`, default. Only numbers in `allowFrom` can message the bot. Outbound sends are also restricted to `allowFrom`.
- `open`. Any phone number can message the bot.
### `allowFrom`
Phone numbers allowed to message the bot when `dmSecurity` is `allowlist`.
```json
"allowFrom": ["+15551234567", "+15557654321"]
```
### `webhookPath`
Local OpenClaw route for Telnyx webhooks.
Default:
```json
"/telnyx-sms/webhook"
```
### `exposure.publicUrl`
Stable public URL that Telnyx should call.
```json
{
"exposure": {
"publicUrl": "https://agent.example.com/telnyx-sms/webhook"
}
}
```
### `exposure.tunnel`
Development tunnel option when supported by the local machine.
```json
{
"exposure": {
"tunnel": { "provider": "cloudflared" }
}
}
```
or:
```json
{
"exposure": {
"tunnel": { "provider": "ngrok" }
}
}
```
### `overwriteExistingWebhook`
Default: `false`.
When false, the plugin refuses to overwrite a Telnyx Messaging Profile webhook URL that points somewhere else. This protects existing Zapier, production, or customer integrations.
Set to `true` only when you intentionally want this OpenClaw gateway to own the profile webhook.
### `profileName`
Name to use when auto-creating a Messaging Profile.
Default is derived from OpenClaw agent or instance metadata.
### `autoCreateProfile`
Default: `false`.
When true, the plugin may create a Messaging Profile and attach an orphan Telnyx number if no profile exists. This is explicit opt-in because profile/number changes are visible in the Telnyx dashboard and may affect billing or routing.
## Multi-account setup
Use `accounts` when one OpenClaw instance should serve multiple Telnyx numbers/profiles.
```json
{
"channels": {
"telnyx-sms": {
"apiKey": "KEY-default",
"allowFrom": ["+15550000001"],
"accounts": {
"support": {
"apiKey": "KEY-support",
"defaultFromNumber": "+15551230000",
"messagingProfileId": "support-profile-id",
"allowFrom": ["+15557654321"]
},
"sales": {
"apiKey": "KEY-sales",
"defaultFromNumber": "+15551230001",
"messagingProfileId": "sales-profile-id",
"dmSecurity": "open"
}
}
}
}
}
```
## Architecture
The plugin has four main parts:
1. **OpenClaw channel plugin**
- Registers the `telnyx-sms` channel with OpenClaw.
- Handles outbound delivery for SMS/MMS.
- Exposes channel capabilities, setup flow, pairing, and account resolution.
2. **Telnyx Messaging API client**
- Sends SMS/MMS through `POST https://api.telnyx.com/v2/messages`.
- Uses the configured or discovered Telnyx phone number as `from`.
- Includes `messaging_profile_id` when available.
- Adds `media_urls` for MMS delivery.
3. **Inbound webhook handler**
- Registers an HTTP route in the OpenClaw gateway.
- Default route: `/telnyx-sms/webhook`.
- Reads the raw request body.
- Verifies Telnyx Ed25519 webhook signatures.
- Parses inbound SMS/MMS payloads.
- Dispatches messages into OpenClaw as direct conversations.
4. **Setup and watchdog layer**
- Discovers phone number, messaging profile, and webhook public key from Telnyx.
- Resolves the public webhook URL.
- Optionally configures the Telnyx Messaging Profile webhook URL.
- Self-probes the public URL to confirm traffic reaches this gateway.
- Re-checks routing/profile state periodically and logs drift.
5. **Diagnostics and media-safety layer**
- Keeps a bounded in-memory event log of recent SMS activity.
- Records inbound receives, outbound sends, blocked media, and dispatch errors.
- Validates inbound MMS media URLs before allowing them into the message pipeline.
- Rejects localhost, private IPs, metadata-service IPs, non-HTTPS URLs, and non-Telnyx media hosts.
```text
User phone
│ SMS/MMS
▼
Telnyx Messaging
... (truncated)
channels
Comments
Sign in to leave a comment