如何通过Telegram Webhook实现Shelly继电器的触发控制?
如何通过Telegram Webhook实现Shelly继电器的请求体参数触发?
问题背景
要实现收到Telegram消息时触发Shelly继电器开启,已知Shelly的控制要求参数通过POST请求体传递,正确的调用方式是:
curl -X POST https://shelly-54-eu.shelly.cloud/device/relay/control -d "channel=0&turn=on&id=<Shelly_id>&auth_key=<Shelly_auth_key>"
尝试直接将Telegram Webhook指向Shelly API时遇到两个问题:
- 方式一:用
--data-urlencode设置Webhook URL,返回401 Unauthorized(因为Shelly不接受URL参数,要求参数在请求体) - 方式二:用
-d设置URL,出现URL被截断(&被curl解析为多个参数分隔符),仍返回401
核心原因
Telegram Webhook发送的请求是固定格式的JSON payload(包含聊天消息等Update数据),无法直接匹配Shelly要求的application/x-www-form-urlencoded表单请求体格式,且Shelly拒绝接收URL中携带的参数,因此必须通过一个中间转发服务做格式转换。
解决方案:搭建中间转发服务
你需要一个简单的后端服务(或无服务器云函数),负责接收Telegram的Webhook请求,然后按照Shelly的要求构造并发送POST请求。
示例:Python Flask 转发服务
from flask import Flask, request import requests app = Flask(__name__) # 替换为你的Shelly信息和Telegram Bot Token SHELLY_API_URL = "https://shelly-54-eu.shelly.cloud/device/relay/control" SHELLY_PARAMS = { "channel": "0", "turn": "on", "id": "<你的Shelly_id>", "auth_key": "<你的Shelly_auth_key>" } TELEGRAM_BOT_TOKEN = "<你的Telegram Bot Token>" @app.route('/webhook', methods=['POST']) def webhook(): # 可选:验证请求来自Telegram(防止恶意请求) # 验证逻辑可参考Telegram官方文档的Webhook签名验证 # 向Shelly发送请求 requests.post(SHELLY_API_URL, data=SHELLY_PARAMS) # 返回Telegram要求的空200响应 return '', 200 if __name__ == '__main__': # 部署时请使用生产级WSGI服务器,如Gunicorn app.run(host='0.0.0.0', port=5000)
配置步骤
- 将上述服务部署到公网可访问的服务器(或使用Vercel/Netlify/AWS Lambda等无服务器平台)
- 设置Telegram Webhook指向该服务的地址:
curl -X POST https://api.telegram.org/bot<你的Telegram Bot Token>/setWebhook --data-urlencode "url=https://<你的服务域名>/webhook"
- 发送消息到你的Telegram Bot,服务会自动转发请求到Shelly API,触发继电器开启
额外说明
- 可以在转发服务中添加逻辑,比如只响应特定关键词的消息(比如收到"/on"才触发继电器),避免误触发
- 务必开启Telegram Webhook的请求验证,防止被恶意调用
- 部署无服务器函数时,注意配置正确的请求方法(仅允许POST)和CORS设置(Telegram Webhook不需要CORS)
内容的提问来源于stack exchange,提问作者vtable
相关产品推荐
相关产品推荐

