Shell脚本如何配置飞书消息推送

wen 实用脚本 1

Shell脚本如何配置飞书消息推送:从零到实战的完整指南

目录导读

  • 为什么要用Shell脚本推送飞书消息?

    Shell脚本如何配置飞书消息推送

  • 前置准备:获取飞书机器人Webhook地址

  • 基础配置:使用curl发送消息

  • 高级技巧:格式化消息与变量传递

  • 实战案例:定时任务监控服务器状态

  • 常见问题与解决方案(Q&A)

为什么要用Shell脚本推送飞书消息?

在运维和开发工作中,我们经常需要实时获取服务器状态、部署结果或异常告警,飞书作为企业协作工具,通过机器人Webhook接口,可以快速将消息推送到群聊或用户。

核心场景包括:

  • 服务器CPU/内存/磁盘告警
  • 自动化部署成功/失败通知
  • 定时任务执行结果反馈
  • 日志异常实时监控

使用Shell脚本配置飞书消息推送,无需额外安装SDK,仅依赖Linux内置的curl命令即可实现,轻量、高效、可移植性强。

前置准备:获取飞书机器人Webhook地址

1 创建飞书群组机器人

  1. 打开飞书桌面端或移动端,进入目标群聊(或创建新群)
  2. 点击群设置 → 群机器人 → 添加机器人 → 选择“自定义机器人”
  3. 设置机器人名称和头像(可选),点击“完成”
  4. 复制生成的Webhook地址,格式如下:
    https://open.feishu.cn/open-apis/bot/v2/hook/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx

2 安全提醒

  • Webhook地址包含鉴权信息,请勿泄露到公开代码库
  • 可在飞书机器人设置页面开启“IP白名单”或“签名校验”(推荐)

基础配置:使用curl发送消息

1 最简单的推送脚本

#!/bin/bash
# 定义Webhook地址变量
WEBHOOK_URL="https://open.feishu.cn/open-apis/bot/v2/hook/你的Webhook地址"
# 定义消息内容(JSON格式)
MESSAGE='{
    "msg_type": "text",
    "content": {
        "text": "这是一条来自Shell脚本的测试消息"
    }
}'
# 使用curl发送POST请求
curl -X POST -H "Content-Type: application/json" -d "$MESSAGE" "$WEBHOOK_URL"

执行方法:

chmod +x send_feishu.sh
./send_feishu.sh

2 支持中文与特殊字符

飞书API要求消息内容为UTF-8编码,使用$MESSAGE变量时建议用单引号包裹JSON,避免Shell解析字符,若需动态拼接,可用双引号并转义。

高级技巧:格式化消息与变量传递

1 使用Markdown增强可读性

飞书支持post(富文本)和interactive(卡片消息)格式,下面展示最常用的Markdown格式:

#!/bin/bash
WEBHOOK_URL="你的Webhook地址"
# 定义时间变量
CURRENT_TIME=$(date "+%Y-%m-%d %H:%M:%S")
# 构建Markdown消息
CONTENT="**服务器状态报告**\n时间:${CURRENT_TIME}\n---\n- 主机名:\`$(hostname)\`\n- 磁盘使用率:$(df -h / | tail -1 | awk '{print $5}')"
MESSAGE=$(cat <<EOF
{
    "msg_type": "interactive",
    "card": {
        "header": {
            "title": {"tag": "plain_text", "content": "系统告警通知"}
        },
        "elements": [
            {
                "tag": "markdown",
                "content": "${CONTENT}"
            }
        ]
    }
}
EOF
)
curl -X POST -H "Content-Type: application/json" -d "$MESSAGE" "$WEBHOOK_URL"

说明:

  • interactive类型支持卡片样式,headerelements
  • markdown标签支持标准Markdown语法,如**粗体**- 无序列表、代码块``
  • 变量通过${CONTENT}注入,注意JSON内不要出现未转义的双引号

2 传递函数参数

若脚本需要被多次调用,可将Webhook地址和消息作为参数传入:

#!/bin/bash
send_to_feishu() {
    local webhook="$1"
    local msg="$2"
    local payload=$(cat <<EOF
{
    "msg_type": "text",
    "content": {"text": "$msg"}
}
EOF
)
    curl -X POST -H "Content-Type: application/json" -d "$payload" "$webhook"
}
# 调用示例
send_to_feishu "https://open.feishu.cn/open-apis/bot/v2/hook/xxx" "任务执行完成"

实战案例:定时任务监控服务器状态

1 编写监控脚本(monitor.sh)

#!/bin/bash
WEBHOOK="你的Webhook地址"
# 定义阈值
CPU_THRESHOLD=80   # CPU使用率>80%告警
MEM_THRESHOLD=90   # 内存使用率>90%告警
DISK_THRESHOLD=85  # 磁盘使用率>85%告警
# 获取系统指标
CPU_USAGE=$(top -bn1 | grep "Cpu(s)" | awk '{print $2}' | cut -d'%' -f1)
MEM_USAGE=$(free | grep Mem | awk '{print $3/$2 * 100.0}')
DISK_USAGE=$(df / | tail -1 | awk '{print $5}' | sed 's/%//')
# 判断是否告警
ALERT_MSG=""
if (( $(echo "$CPU_USAGE > $CPU_THRESHOLD" | bc -l) )); then
    ALERT_MSG+="⚠️  **CPU告警**:当前使用率 ${CPU_USAGE}%(阈值 ${CPU_THRESHOLD}%)\n"
fi
if (( $(echo "$MEM_USAGE > $MEM_THRESHOLD" | bc -l) )); then
    ALERT_MSG+="⚠️  **内存告警**:当前使用率 ${MEM_USAGE}%(阈值 ${MEM_THRESHOLD}%)\n"
fi
if (( "$DISK_USAGE" > "$DISK_THRESHOLD" )); then
    ALERT_MSG+="⚠️  **磁盘告警**:当前使用率 ${DISK_USAGE}%(阈值 ${DISK_THRESHOLD}%)\n"
fi
# 若有告警则推送
if [ -n "$ALERT_MSG" ]; then
    CONTENT="**服务器异常通知**\n服务器:$(hostname)\n时间:$(date '+%Y-%m-%d %H:%M:%S')\n\n${ALERT_MSG}"
    MESSAGE=$(cat <<EOF
{
    "msg_type": "interactive",
    "card": {
        "header": {"title": {"tag": "plain_text", "content": "🚨 服务器告警"}},
        "elements": [{"tag": "markdown", "content": "${CONTENT}"}]
    }
}
EOF
)
    curl -X POST -H "Content-Type: application/json" -d "$MESSAGE" "$WEBHOOK"
fi

2 添加定时任务

使用crontab每5分钟执行一次:

crontab -e
# 添加以下行(注意使用绝对路径)
*/5 * * * * /path/to/monitor.sh

说明:

  • 脚本中使用了bc进行浮点数比较,需确保系统已安装bc(通过yum install bcapt install bc
  • df /监控根分区,可根据实际挂载点调整

常见问题与解决方案(Q&A)

Q1:消息发送失败,返回400错误?

A: 通常是因为Webhook地址错误或JSON格式不正确,解决方案:

  • 检查curl -v输出,确认响应体中的errmsg字段
  • 使用在线JSON验证工具检查消息格式
  • 确保msg_type字段正确("text","post","interactive"之一)

Q2:如何发送@某人的消息?

A: 使用interactive卡片消息时,在content中加入@user_id,注意飞书API要求传入用户ID(非手机号):

"content": "@{user_id_xxxx} 请查看告警信息"

Q3:Shell脚本中变量包含空格或特殊字符怎么办?

A: 使用双引号包裹变量,并对特殊字符进行转义:

# 错误示例(变量含空格会被拆分为多个参数)
MESSAGE='{"text":"'$VAR'"}'
# 正确做法:使用printf或jq工具
MESSAGE=$(printf '{"msg_type":"text","content":{"text":"%s"}}' "$VAR")

推荐安装jq工具进行JSON构建(yum install jq):

MESSAGE=$(jq -n --arg msg "$VAR" '{msg_type:"text", content: {text: $msg}}')

Q4:如何实现发送后自动重试?

A: 在curl命令后添加清理逻辑,失败时重试一定次数:

MAX_RETRIES=3
for i in $(seq 1 $MAX_RETRIES); do
    RESPONSE=$(curl -s -o /dev/null -w "%{http_code}" -X POST -H "Content-Type: application/json" -d "$MESSAGE" "$WEBHOOK")
    if [ "$RESPONSE" -eq 200 ]; then
        echo "发送成功"
        break
    else
        echo "发送失败,重试第${i}次"
        sleep 2
    fi
done

Q5:脚本可以同时推送多个群组吗?

A: 可以,定义多个Webhook数组,遍历发送:

WEBHOOKS=("url1" "url2" "url3")
for url in "${WEBHOOKS[@]}"; do
    curl -X POST -H "Content-Type: application/json" -d "$MESSAGE" "$url"
done

通过Shell脚本配置飞书消息推送,是自动化运维中成本最低、最灵活的方案之一,从简单的文本通知到复杂的卡片告警,只需清楚JSON格式化要点和飞书API接口规范,推荐结合crontab、Prometheus告警回调或Jenkins构建后任务,实现全流程自动化。

延伸学习:

  • 飞书开放平台官方文档:open.feishu.cn(搜索“自定义机器人”)
  • 进阶技巧:使用飞书签名校验(HMAC-SHA1)提高安全性
  • 配合jqyq等工具处理复杂JSON结构

注意: 实际生产环境中,建议将敏感信息(如Webhook地址)通过环境变量或密钥管理服务存储,而非硬编码在脚本中。

抱歉,评论功能暂时关闭!