check_vps_stock.sh
· 3.0 KiB · Bash
原始檔案
#!/usr/bin/env bash
[[ -n "${DEBUG:-}" ]] && set -eux || set -euo pipefail
WEBHOOK_SECRET="${WEBHOOK_SECRET:-}"
# ==================== 配置 ====================
URL="${1:-https://billing.chunkserve.com/index.php?rp=/store/let-vm-special/xeon-yearly-deal-3-at-let}"
#WEBHOOK_URL="https://open.feishu.cn/open-apis/bot/v2/hook/xxxxxxxxxx" # ← 改成你的真实 webhook
WEBHOOK_URL="https://open.larksuite.com/open-apis/bot/v2/hook/${WEBHOOK_SECRET}"
PRODUCT_NAME="${2:-Xeon Yearly Deal 3 - Yearly}"
STATE_FILE="/tmp/vps_stock_status.txt"
LOG_FILE="/tmp/vps_monitor.log"
# ================================================
# 检查是否有货(宽松匹配多种缺货表述)
if curl -s -L --max-time 15 "$URL" | grep -qiE "out\s*(of|for)\s*stock|售罄|无货|缺货|Out of Stock"; then
CURRENT="out_of_stock"
else
CURRENT="in_stock"
fi
LAST=$(cat "$STATE_FILE" 2>/dev/null || echo "unknown")
if [ "$CURRENT" = "in_stock" ] && [ "$LAST" != "in_stock" ]; then
DETECT_TIME=$(date '+%Y-%m-%d %H:%M:%S')
# 使用 heredoc 发送符合你示例的卡片格式
curl -s -X POST "$WEBHOOK_URL" \
-H "Content-Type: application/json" \
-d @- << EOF
{
"msg_type": "interactive",
"card": {
"schema": "2.0",
"config": {
"update_multi": true,
"style": {
"text_size": {
"normal_v2": {
"default": "normal",
"pc": "normal",
"mobile": "heading"
}
}
}
},
"header": {
"title": {
"tag": "plain_text",
"content": "✅ 商品到货提醒"
},
"template": "green",
"padding": "12px 12px 12px 12px"
},
"body": {
"direction": "vertical",
"padding": "12px 12px 12px 12px",
"elements": [
{
"tag": "markdown",
"content": "**${PRODUCT_NAME}** 现在**有货啦!** \n快去抢购,别错过了!",
"text_align": "left",
"text_size": "normal_v2",
"margin": "0px 0px 16px 0px"
},
{
"tag": "button",
"text": {
"tag": "plain_text",
"content": "立即抢购"
},
"type": "primary",
"width": "default",
"size": "medium",
"behaviors": [
{
"type": "open_url",
"default_url": "${URL}"
}
],
"margin": "0px 0px 0px 0px"
},
{
"tag": "markdown",
"content": "检测时间:${DETECT_TIME}",
"text_align": "left",
"text_size": "normal_v2",
"margin": "16px 0px 0px 0px"
}
]
}
}
}
EOF
if [ $? -eq 0 ]; then
echo "[${DETECT_TIME}] 有货 → 卡片通知已发送" >> "$LOG_FILE"
else
echo "[${DETECT_TIME}] 通知发送失败(检查Webhook?)" >> "$LOG_FILE"
fi
fi
# 更新上次状态
echo "$CURRENT" > "$STATE_FILE"
# 记录当前状态(用于调试)
echo "[$(date '+%Y-%m-%d %H:%M:%S')] 状态: $CURRENT" >> "$LOG_FILE"
| 1 | #!/usr/bin/env bash |
| 2 | |
| 3 | [[ -n "${DEBUG:-}" ]] && set -eux || set -euo pipefail |
| 4 | |
| 5 | WEBHOOK_SECRET="${WEBHOOK_SECRET:-}" |
| 6 | |
| 7 | # ==================== 配置 ==================== |
| 8 | URL="${1:-https://billing.chunkserve.com/index.php?rp=/store/let-vm-special/xeon-yearly-deal-3-at-let}" |
| 9 | #WEBHOOK_URL="https://open.feishu.cn/open-apis/bot/v2/hook/xxxxxxxxxx" # ← 改成你的真实 webhook |
| 10 | WEBHOOK_URL="https://open.larksuite.com/open-apis/bot/v2/hook/${WEBHOOK_SECRET}" |
| 11 | |
| 12 | PRODUCT_NAME="${2:-Xeon Yearly Deal 3 - Yearly}" |
| 13 | STATE_FILE="/tmp/vps_stock_status.txt" |
| 14 | LOG_FILE="/tmp/vps_monitor.log" |
| 15 | # ================================================ |
| 16 | |
| 17 | # 检查是否有货(宽松匹配多种缺货表述) |
| 18 | if curl -s -L --max-time 15 "$URL" | grep -qiE "out\s*(of|for)\s*stock|售罄|无货|缺货|Out of Stock"; then |
| 19 | CURRENT="out_of_stock" |
| 20 | else |
| 21 | CURRENT="in_stock" |
| 22 | fi |
| 23 | |
| 24 | LAST=$(cat "$STATE_FILE" 2>/dev/null || echo "unknown") |
| 25 | |
| 26 | if [ "$CURRENT" = "in_stock" ] && [ "$LAST" != "in_stock" ]; then |
| 27 | DETECT_TIME=$(date '+%Y-%m-%d %H:%M:%S') |
| 28 | |
| 29 | # 使用 heredoc 发送符合你示例的卡片格式 |
| 30 | curl -s -X POST "$WEBHOOK_URL" \ |
| 31 | -H "Content-Type: application/json" \ |
| 32 | -d @- << EOF |
| 33 | { |
| 34 | "msg_type": "interactive", |
| 35 | "card": { |
| 36 | "schema": "2.0", |
| 37 | "config": { |
| 38 | "update_multi": true, |
| 39 | "style": { |
| 40 | "text_size": { |
| 41 | "normal_v2": { |
| 42 | "default": "normal", |
| 43 | "pc": "normal", |
| 44 | "mobile": "heading" |
| 45 | } |
| 46 | } |
| 47 | } |
| 48 | }, |
| 49 | "header": { |
| 50 | "title": { |
| 51 | "tag": "plain_text", |
| 52 | "content": "✅ 商品到货提醒" |
| 53 | }, |
| 54 | "template": "green", |
| 55 | "padding": "12px 12px 12px 12px" |
| 56 | }, |
| 57 | "body": { |
| 58 | "direction": "vertical", |
| 59 | "padding": "12px 12px 12px 12px", |
| 60 | "elements": [ |
| 61 | { |
| 62 | "tag": "markdown", |
| 63 | "content": "**${PRODUCT_NAME}** 现在**有货啦!** \n快去抢购,别错过了!", |
| 64 | "text_align": "left", |
| 65 | "text_size": "normal_v2", |
| 66 | "margin": "0px 0px 16px 0px" |
| 67 | }, |
| 68 | { |
| 69 | "tag": "button", |
| 70 | "text": { |
| 71 | "tag": "plain_text", |
| 72 | "content": "立即抢购" |
| 73 | }, |
| 74 | "type": "primary", |
| 75 | "width": "default", |
| 76 | "size": "medium", |
| 77 | "behaviors": [ |
| 78 | { |
| 79 | "type": "open_url", |
| 80 | "default_url": "${URL}" |
| 81 | } |
| 82 | ], |
| 83 | "margin": "0px 0px 0px 0px" |
| 84 | }, |
| 85 | { |
| 86 | "tag": "markdown", |
| 87 | "content": "检测时间:${DETECT_TIME}", |
| 88 | "text_align": "left", |
| 89 | "text_size": "normal_v2", |
| 90 | "margin": "16px 0px 0px 0px" |
| 91 | } |
| 92 | ] |
| 93 | } |
| 94 | } |
| 95 | } |
| 96 | EOF |
| 97 | |
| 98 | if [ $? -eq 0 ]; then |
| 99 | echo "[${DETECT_TIME}] 有货 → 卡片通知已发送" >> "$LOG_FILE" |
| 100 | else |
| 101 | echo "[${DETECT_TIME}] 通知发送失败(检查Webhook?)" >> "$LOG_FILE" |
| 102 | fi |
| 103 | fi |
| 104 | |
| 105 | # 更新上次状态 |
| 106 | echo "$CURRENT" > "$STATE_FILE" |
| 107 | |
| 108 | # 记录当前状态(用于调试) |
| 109 | echo "[$(date '+%Y-%m-%d %H:%M:%S')] 状态: $CURRENT" >> "$LOG_FILE" |
| 110 |