基于TCL搭建Twitch API的HTTP请求回调处理器
Got it, let's break down how to add Twitch API HTTP POST handling to your existing TCL IRC/Discord bot. I get that TCL docs can be sparse, so let's make this practical and step-by-step.
核心思路先理清
Twitch sends event notifications via Webhooks (HTTP POST requests), not websockets (websockets are for your bot to pull real-time data from Twitch). So your goal is to embed a lightweight HTTP server in your existing TCL bot to:
- Listen for incoming POST requests from Twitch
- Validate the requests to ensure they're actually from Twitch
- Parse the event data
- Relay that data to your IRC/Discord channels
步骤1:用TCL Socket搭建轻量HTTP服务器
TCL's built-in socket command is perfect for this—no heavy frameworks needed. Here's a working example you can drop into your bot:
# 启动TCP监听端口(选一个Twitch能访问的端口,比如8080) set twitch_webhook_listener [socket -server handle_twitch_post 8080] puts "Twitch Webhook listener started on port 8080" # 处理Twitch POST请求的核心回调 proc handle_twitch_post {client_addr client_port} { # 配置socket编码和缓冲,避免乱码 fconfigure $client_addr -encoding utf-8 -buffering line # 读取请求首行,只处理POST请求 set request_line [gets $client_addr] if {![string match "POST *" $request_line]} { puts $client_addr "HTTP/1.1 405 Method Not Allowed" puts $client_addr "Content-Type: text/plain" puts $client_addr "" puts $client_addr "Only POST requests are accepted here" close $client_addr return } # 读取HTTP请求头,直到空行 set headers [dict create] while {[gets $client_addr line] >= 0 && $line ne ""} { if {[regexp {^([^:]+):\s*(.+)$} $line -> header_key header_val]} { dict set headers [string tolower $header_key] $header_val } } # 读取请求体(Twitch发送的是JSON格式数据) set content_length [dict get $headers content-length] set raw_body [read $client_addr $content_length] # 验证Twitch签名!这一步非常重要,防止伪造请求 if {![verify_twitch_signature $headers $raw_body]} { puts $client_addr "HTTP/1.1 403 Forbidden" puts $client_addr "Content-Type: text/plain" puts $client_addr "" puts $client_addr "Invalid Twitch signature" close $client_addr return } # 解析JSON数据(需要tcllib的json包,先安装) package require json set event_data [::json::json2dict $raw_body] # 这里把事件转发到你的IRC/Discord机器人 # 示例:发送到IRC频道 # irc::privmsg $your_irc_channel "Twitch Event: [dict get $event_data event] - [dict get $event_data data title]" # 示例:发送到Discord(根据你的Discord TCL库调整) # discord::send_message $your_discord_channel "New Twitch event: [dict get $event_data event]" # 打印调试信息(测试阶段用) puts "Received Twitch event: [dict get $event_data event]" puts "Event details: [dict get $event_data data]" # 返回Twitch成功响应(必须返回200 OK,否则Twitch会重试) puts $client_addr "HTTP/1.1 200 OK" puts $client_addr "Content-Type: application/json" puts $client_addr "" puts $client_addr "{\"status\": \"success\"}" close $client_addr } # 验证Twitch Webhook签名的函数 proc verify_twitch_signature {headers body} { # 替换成你在Twitch开发者后台设置的Webhook密钥 set your_webhook_secret "your_twitch_webhook_secret_here" # 从请求头获取Twitch的签名和时间戳 set twitch_signature [dict get $headers "twitch-eventsub-message-signature"] set twitch_timestamp [dict get $headers "twitch-eventsub-message-timestamp"] # 生成预期签名:HMAC-SHA256(timestamp + body, secret) set signature_content "${twitch_timestamp}${body}" set computed_hmac [binary encode hex [::md5::hmac -sha256 $your_webhook_secret $signature_content]] set expected_signature "sha256=$computed_hmac" # 安全比较签名(避免时序攻击) return [string equal $twitch_signature $expected_signature] } # 如果你的机器人已经有主循环(比如vwait),不需要这行 # vwait forever
步骤2:安装依赖
You'll need two packages from tcllib for JSON parsing and HMAC signatures:
# Debian/Ubuntu系统直接安装 sudo apt-get install tcllib # 或者用TCL的包管理器手动安装 tclsh <<EOF package require cmdline package require pkg_mkIndex pkg_mkIndex /usr/local/lib/tcl8.6 EOF
步骤3:集成到现有机器人
If your bot already runs an event loop (most IRC/Discord TCL bots use vwait or after), just add the socket -server line to your bot's initialization code. You don't need the extra vwait forever—your bot's existing loop will keep the HTTP listener running.
Example with an IRC bot:
# 假设你用的是tcl-irc包 package require irc set irc_bot [::irc::connect "irc.yourserver.com" 6667] ::irc::login $irc_bot "MyTwitchBot" "MyTwitchBot" "MyTwitchBot" ::irc::join $irc_bot "#mychannel" # 启动Twitch Webhook listener set twitch_webhook_listener [socket -server handle_twitch_post 8080] # 机器人主循环 vwait forever
步骤4:Twitch开发者后台配置
- 登录Twitch Developer Console,创建一个应用并获取你的Client ID。
- Go to EventSub and create a new Webhook subscription.
- 输入你的服务器公网URL(比如
https://your-public-ip:8080—for local testing, usengrok http 8080to get a public URL)。 - 设置Webhook密钥,要和代码里的
your_webhook_secret完全一致。
常见坑点&解决方案
- Local testing: Twitch can't reach your local port. Use
ngrokto expose your 8080 port to the internet. - HTTPS requirement: Twitch requires HTTPS for production Webhook URLs. Use Nginx as a reverse proxy to handle SSL, or add SSL support to your TCL socket with the
tlspackage. - Performance: For high-volume events, the basic socket server might struggle. If that happens, switch to
tclhttpd—a full TCL HTTP server that's more scalable.
内容的提问来源于stack exchange,提问作者Haxo201

