Forward SMS notifications received by PushPlus to Telegram through a Cloudflare Worker. The service provides deduplication, content filters, optional intercept rules, and a short-lived protected inbox for another authorized automation.
Direct deployment:
SMS forwarder → PushPlus → Cloudflare Worker → Telegram
Optional relay deployment:
SMS forwarder → PushPlus → Cloudflare Pages relay → Worker → Telegram
Use the relay only when PushPlus cannot reach the Worker endpoint. It validates a relay token and forwards the request without storing the body.
Recommended resilient ingress:
SMS forwarder ──primary──→ signed direct Worker webhook ──→ Telegram
└─on final failure─→ PushPlus → relay → Worker ──┘
SmsForwarder 3.2.0 or newer can run the direct webhook first and use PushPlus only after the primary channel finally fails. Both paths reuse the same filters, workflow-scoped intercepts, Telegram delivery, and content-fingerprint dedupe.
- Receives PushPlus custom webhooks and callback notifications.
- Receives HMAC-signed, timestamped direct SmsForwarder webhooks.
- Uses Cloudflare KV to deduplicate messages before Telegram delivery.
- Deduplicates equivalent direct and PushPlus copies by SMS content fingerprint.
- Filters by title or body keyword.
- Removes recognized device metadata from Telegram messages.
- Applies configurable intercept rules before notification.
- Can place selected messages in a token-protected inbox with a six-hour TTL.
- Can recover a bounded set of recent messages missed by realtime delivery.
- Can delete bounded sets of old PushPlus records on a Cloudflare Cron trigger.
- Includes manual GitHub Actions workflows for deployment and backfill.
- Quietly monitors the Worker, relay, PushPlus production webhook, and Telegram destination hourly.
- Node.js 20 or newer for local development
- A Cloudflare account with Workers and KV
- A PushPlus account that can send a custom webhook
- A Telegram bot and destination chat
- Wrangler for manual deployment
npm ci
cp wrangler.example.toml wrangler.toml
npx wrangler kv namespace create FORWARDED_KVReplace replace-with-your-kv-namespace-id in wrangler.toml with the returned
namespace ID. Keep the real wrangler.toml out of Git.
npx wrangler secret put CALLBACK_TOKEN
npx wrangler secret put TELEGRAM_BOT_TOKEN
npx wrangler secret put TELEGRAM_CHAT_ID
npx wrangler secret put STATE_SECRET
npx wrangler secret put SMSFORWARDER_WEBHOOK_SECRETGenerate long random values for callback and state secrets:
openssl rand -hex 32Optional features require additional secrets:
npx wrangler secret put INBOX_TOKEN
npx wrangler secret put PUSHPLUS_TOKEN
npx wrangler secret put PUSHPLUS_SECRET_KEYnpm test
npm run lint
npx wrangler deployHealth endpoint:
https://your-worker.example.com/health
Direct custom-webhook endpoint:
https://your-worker.example.com/pushplus/webhook/YOUR_CALLBACK_TOKEN
Hardware SIM gateway endpoint (standard POST JSON):
https://your-worker.example.com/device/webhook/YOUR_HARDWARE_WEBHOOK_TOKEN
Keep the existing PushPlus channel enabled and put this direct channel first; see Configuration.
Signed SmsForwarder endpoint:
https://your-worker.example.com/smsforwarder/webhook
Configure the SmsForwarder channel with JSON fields for sourceId, sender,
sentAt, content, timestamp, and sign; see
Configuration. The channel
secret must match SMSFORWARDER_WEBHOOK_SECRET.
Prefer a Cloudflare custom domain when PushPlus cannot reach a workers.dev
address.
cd pages-relay
npx wrangler pages project create your-pages-project \
--production-branch main
npx wrangler pages secret put RELAY_TOKEN \
--project-name your-pages-project
npx wrangler pages secret put WORKER_ORIGIN \
--project-name your-pages-project
npx wrangler pages deploy dist \
--project-name your-pages-project --branch mainSet WORKER_ORIGIN to your deployed Worker origin, without a trailing path.
This is required for forks: the bundled relay has a maintainer deployment as
its fallback upstream and must not be used unchanged for another deployment.
Relay webhook endpoint:
https://your-pages-project.pages.dev/pushplus/webhook/YOUR_RELAY_TOKEN
RELAY_TOKEN may use the same random value as CALLBACK_TOKEN.
Use a plain-text custom webhook body:
标题:{title}
链接:{url}
{content}
Keep {url} when scheduled PushPlus record cleanup is enabled; the Worker uses
its short code to correlate handled records.
The repository includes a configuration helper:
PUSHPLUS_TOKEN='replace-me' \
PUSHPLUS_SECRET_KEY='replace-me' \
PUSHPLUS_WEBHOOK_URL='https://your-endpoint/pushplus/webhook/YOUR_TOKEN' \
npm run configure:pushplusThe helper can change the PushPlus user's default delivery channel. Set
PUSHPLUS_SET_USER_DEFAULT=false when the sender selects channels explicitly
and the existing default must remain unchanged.
Messages pass through these stages:
- authenticate the webhook or callback token;
- load the message body when a callback supplies only a short code;
- reject an already handled message using KV state;
- apply intercept rules;
- apply title and body filters;
- normalize SMS metadata and send the result to Telegram;
- store a deduplication marker with a bounded TTL.
Optional best-effort scheduled recovery uses the same filters, intercept
rules, and KV state. Its unhandled mode can recover a matching PushPlus
history record whenever the Worker has no local handled marker, even if
PushPlus reports that its channel delivery succeeded. PushPlus may omit
messages that never reached its service, so recovery is not a substitute for
connectivity from the SIM gateway. It is disabled until an operator sets an
activation timestamp and enables it explicitly. See
Configuration.
The protected inbox is available only when INBOX_TOKEN is configured:
GET /messages?since=...&sender=10001
Authorization: Bearer <INBOX_TOKEN>Only rules configured to store a match write SMS bodies to that inbox. Stored items expire automatically after six hours.
This service processes personal SMS content and may forward verification codes.
Use a private Telegram chat, strong independent tokens, and a dedicated
Cloudflare deployment. Never commit Worker secrets, PushPlus credentials,
Telegram credentials, chat IDs, SMS bodies, or a real wrangler.toml.
Follow SECURITY.md for vulnerability reports.
PushPlusSmsToTelegram is available under the MIT License.