sms_forward: add Feishu bot script by #127
This commit is contained in:
@@ -232,7 +232,17 @@ generate_api_config() {
|
||||
[ -n "$endpoint" ] && config_json="$config_json,\"endpoint\":\"$endpoint\""
|
||||
config_json="$config_json}"
|
||||
;;
|
||||
"feishu")
|
||||
local webhook_key
|
||||
config_get webhook_key "$section" feishu_webhook_key
|
||||
|
||||
[ -z "$webhook_key" ] && {
|
||||
echo "Error: Feishu requires webhook_key"
|
||||
return 1
|
||||
}
|
||||
|
||||
config_json="{\"webhook_key\":\"$webhook_key\"}"
|
||||
;;
|
||||
"custom_script")
|
||||
local script_path
|
||||
config_get script_path "$section" custom_script_path
|
||||
|
||||
130
application/sms_forwarder/files/usr/bin/sms_forward_feishu.sh
Executable file
130
application/sms_forwarder/files/usr/bin/sms_forward_feishu.sh
Executable file
@@ -0,0 +1,130 @@
|
||||
#!/bin/sh
|
||||
# QModem SMS → Feishu message card webhook
|
||||
# Version: 2025-11-02
|
||||
# author: XRSec <github.com/XRSec>
|
||||
|
||||
API_CONFIG="$1"
|
||||
# {"webhook_key":"xxxxxx"}
|
||||
|
||||
|
||||
# 飞书 webhook
|
||||
WEBHOOK="https://open.feishu.cn/open-apis/bot/v2/hook/"
|
||||
|
||||
# 设备 / 应用信息
|
||||
DEVICE_NAME="自定义"
|
||||
APP_NAME="QModem"
|
||||
CALL_TYPE="SMS"
|
||||
TITLE="短信通知"
|
||||
WEBHOOK_KEY=$(echo "$API_CONFIG" | jq -r .webhook_key)
|
||||
WEBHOOK="${WEBHOOK}${WEBHOOK_KEY}"
|
||||
|
||||
# 从环境变量读取短信信息
|
||||
FROM="${SMS_SENDER:-unknown}"
|
||||
RECEIVE_TIME="${SMS_TIME:-$(date '+%Y-%m-%d %H:%M:%S')}"
|
||||
MSG="${SMS_CONTENT:-<empty>}"
|
||||
|
||||
# 限制短信长度(防止过长)
|
||||
MAX_LEN=800
|
||||
if [ "${#MSG}" -gt "$MAX_LEN" ]; then
|
||||
MSG="$(printf '%s' "$MSG" | cut -c1-${MAX_LEN})..."
|
||||
fi
|
||||
|
||||
# JSON 转义
|
||||
escape_json() {
|
||||
printf '%s' "$1" | sed -e 's/\\/\\\\/g' -e 's/"/\\"/g' -e ':a;N;$!ba;s/\n/\\n/g'
|
||||
}
|
||||
|
||||
FROM_ESC="$(escape_json "$FROM")"
|
||||
MSG_ESC="$(escape_json "$MSG")"
|
||||
RECEIVE_TIME_ESC="$(escape_json "$RECEIVE_TIME")"
|
||||
|
||||
# 构造飞书卡片 JSON
|
||||
JSON_PAYLOAD=$(cat <<EOF
|
||||
{
|
||||
"msg_type": "interactive",
|
||||
"card": {
|
||||
"header": {
|
||||
"template": "blue",
|
||||
"title": {
|
||||
"content": "💬${DEVICE_NAME}",
|
||||
"tag": "plain_text"
|
||||
}
|
||||
},
|
||||
"elements": [
|
||||
{
|
||||
"tag": "div",
|
||||
"fields": [
|
||||
{
|
||||
"is_short": true,
|
||||
"text": {"tag": "lark_md","content": "**🕙接收时间:** ${RECEIVE_TIME_ESC}"}
|
||||
},
|
||||
{
|
||||
"is_short": true,
|
||||
"text": {"tag": "lark_md","content": "**📞来源号码:** ${FROM_ESC}"}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"tag": "div",
|
||||
"fields": [
|
||||
{
|
||||
"is_short": true,
|
||||
"text": {"tag": "lark_md","content": "**📱设备名称:** ${DEVICE_NAME}"}
|
||||
},
|
||||
{
|
||||
"is_short": true,
|
||||
"text": {"tag": "lark_md","content": "**📲App应用名:** ${APP_NAME}"}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"tag": "div",
|
||||
"fields": [
|
||||
{
|
||||
"is_short": true,
|
||||
"text": {"tag": "lark_md","content": "**📞通话类型:** ${CALL_TYPE}"}
|
||||
},
|
||||
{
|
||||
"is_short": true,
|
||||
"text": {"tag": "lark_md","content": "**📢通知标题:** ${TITLE}"}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"tag": "div",
|
||||
"fields": [
|
||||
{
|
||||
"is_short": true,
|
||||
"text": {"tag": "lark_md","content": "**📝通知内容:** ${MSG_ESC}"}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
EOF
|
||||
)
|
||||
|
||||
# 日志输出到系统 logread
|
||||
logger -t sms_forward "📩 短信来自 ${FROM},长度 ${#MSG} 字符,准备推送到飞书..."
|
||||
|
||||
# 简单重试机制(最多 3 次)
|
||||
RETRY=0
|
||||
MAX_RETRY=3
|
||||
while [ "$RETRY" -lt "$MAX_RETRY" ]; do
|
||||
RETRY=$((RETRY + 1))
|
||||
curl -sS -m 10 -X POST -H "Content-Type: application/json" \
|
||||
-d "${JSON_PAYLOAD}" "${WEBHOOK}" >/dev/null 2>&1
|
||||
STATUS=$?
|
||||
|
||||
if [ "$STATUS" -eq 0 ]; then
|
||||
logger -t sms_forward "✅ 成功转发短信至飞书 (${FROM})"
|
||||
exit 0
|
||||
else
|
||||
logger -t sms_forward "⚠️ 第 ${RETRY} 次发送失败 (code=${STATUS}),重试中..."
|
||||
sleep 3
|
||||
fi
|
||||
done
|
||||
|
||||
logger -t sms_forward "❌ 最终发送失败 (${FROM}),放弃重试。"
|
||||
exit 1
|
||||
@@ -74,6 +74,13 @@
|
||||
- `$sms_time`: 时间戳
|
||||
- `$raw_pdu`: 原始PDU数据
|
||||
|
||||
实例脚本示例:
|
||||
```shell
|
||||
FROM="${SMS_SENDER:-unknown}"
|
||||
RECEIVE_TIME="${SMS_TIME:-$(date '+%Y-%m-%d %H:%M:%S')}"
|
||||
MSG="${SMS_CONTENT:-<empty>}"
|
||||
```
|
||||
|
||||
示例脚本请参考: `/usr/share/qmodem/sms_forward_example.sh`
|
||||
|
||||
## 服务管理
|
||||
|
||||
@@ -75,6 +75,7 @@ api_type:value("webhook", translate("Webhook"))
|
||||
api_type:value("serverchan", translate("ServerChan"))
|
||||
api_type:value("pushdeer", translate("PushDeer"))
|
||||
api_type:value("custom_script", translate("Custom Script"))
|
||||
api_type:value("feishu", translate("Feishu Bot"))
|
||||
|
||||
-- 删除已转发短信选项
|
||||
delete_after_forward = s2:option(Flag, "delete_after_forward", translate("Delete After Forward"))
|
||||
@@ -130,6 +131,12 @@ pushdeer_endpoint:depends("api_type", "pushdeer")
|
||||
pushdeer_endpoint.placeholder = "https://api2.pushdeer.com"
|
||||
pushdeer_endpoint.description = translate("Custom PushDeer API endpoint, leave empty to use default")
|
||||
|
||||
feishu_webhook_key = s2:option(Value, "feishu_webhook_key", translate("Feishu Webhook Key"))
|
||||
feishu_webhook_key:depends("api_type", "feishu")
|
||||
feishu_webhook_key.placeholder = "xxxxxx"
|
||||
feishu_webhook_key.description = translate("Feishu Webhook Key from your Feishu bot configuration")
|
||||
|
||||
|
||||
-- Custom Script 配置
|
||||
custom_script_path = s2:option(Value, "custom_script_path", translate("Script Path"))
|
||||
custom_script_path:depends("api_type", "custom_script")
|
||||
|
||||
@@ -113,6 +113,9 @@ msgstr "自定义脚本"
|
||||
msgid "PushDeer"
|
||||
msgstr "PushDeer"
|
||||
|
||||
msgid "Feishu Bot"
|
||||
msgstr "飞书机器人"
|
||||
|
||||
msgid "Push Key"
|
||||
msgstr "推送密钥"
|
||||
|
||||
|
||||
@@ -113,6 +113,9 @@ msgstr "自定义脚本"
|
||||
msgid "PushDeer"
|
||||
msgstr "PushDeer"
|
||||
|
||||
msgid "Feishu Bot"
|
||||
msgstr "飞书机器人"
|
||||
|
||||
msgid "Push Key"
|
||||
msgstr "推送密钥"
|
||||
|
||||
|
||||
Reference in New Issue
Block a user