github workflows actions相关

image
image

Pull-AWS-bills-at-regular-intervals-everyday.yml


name: AWS Monthly Cost Report

on:
  schedule:
    - cron: '0 1 * * *'
  workflow_dispatch:

jobs:
  report:
    runs-on: ubuntu-latest

    env:
      AWS_REGION: us-east-1

    steps:
      - name: Checkout
        uses: actions/checkout@v4

      - name: Configure AWS
        uses: aws-actions/configure-aws-credentials@v4
        with:
          aws-access-key-id: ${{ secrets.AWS_BILL_ACCESS_KEY_ID }}
          aws-secret-access-key: ${{ secrets.AWS_BILL_SECRET_ACCESS_KEY }}
          aws-region: ${{ env.AWS_REGION }}

      - name: Install jq
        run: sudo apt-get update && sudo apt-get install jq -y

      - name: Generate Cost Report
        run: |
          TODAY=$(date +%Y-%m-%d)
          FIRST_DAY=$(date +%Y-%m-01)
          LAST_DAY=$(date -d "$(date +%Y-%m-01) +1 month -1 day" +%Y-%m-%d)
          TOMORROW=$(date -d "+1 day" +%Y-%m-%d)

          echo "Current execution time (UTC): $(date)"

          # 获取当月已使用金额(1号到今天)
          CURRENT=$(aws ce get-cost-and-usage \
            --time-period Start=$FIRST_DAY,End=$TODAY \
            --granularity MONTHLY \
            --metrics "UnblendedCost" \
            --query "ResultsByTime[0].Total.UnblendedCost.Amount" \
            --output text 2>/dev/null || echo "0")

          # 获取整月预测金额(从明天到月底,AWS 会返回整个月的预测)
          FORECAST_JSON=$(aws ce get-cost-forecast \
            --time-period Start=$TOMORROW,End=$LAST_DAY \
            --metric "UNBLENDED_COST" \
            --granularity "MONTHLY" \
            --output json 2>/dev/null || echo '{"Total":{"Amount":"0"}}')

          # 提取 Total.Amount
          FORECAST=$(echo "$FORECAST_JSON" | jq -r '.Total.Amount // "0"')

          # 如果预测失败,用已使用金额
          if [ "$FORECAST" == "None" ] || [ -z "$FORECAST" ] || [ "$FORECAST" == "0" ]; then
            FORECAST=$CURRENT
          fi

          # 获取服务明细
          SERVICES=$(aws ce get-cost-and-usage \
            --time-period Start=$FIRST_DAY,End=$TODAY \
            --granularity MONTHLY \
            --metrics "UnblendedCost" \
            --group-by Type=DIMENSION,Key=SERVICE 2>/dev/null || echo '{"ResultsByTime":[{"Groups":[]}]}')

          SERVICE_LIST=$(echo "$SERVICES" | jq -r '
            .ResultsByTime[0].Groups // []
            | map(select(.Metrics.UnblendedCost.Amount | tonumber > 1))
            | sort_by(.Metrics.UnblendedCost.Amount | tonumber)
            | reverse
            | .[:10]
            | .[] 
            | "• \(.Keys[0]): $\(.Metrics.UnblendedCost.Amount | tonumber | floor)"
          ')

          if [ -z "$SERVICE_LIST" ]; then
            SERVICE_LIST="暂无详细数据"
          fi

          # 已使用和预测都保留两位小数
          CURRENT_FMT=$(echo "$CURRENT" | awk '{printf "%.2f", $1}')
          FORECAST_FMT=$(echo "$FORECAST" | awk '{printf "%.2f", $1}')

          MESSAGE=$(printf "🧾 AWS 账单播报(%s月)\n\n📊 当月已使用(1号至今): $%s\n🔮 当月预测总额: $%s\n\n🛠️ 服务明细(Top 10):\n%s" "$(date +%m)" "$CURRENT_FMT" "$FORECAST_FMT" "$SERVICE_LIST")

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

          curl -X POST "${{ secrets.AWS_BILL_WEBHOOK_URL }}" \
            -H "Content-Type: application/json" \
            -d "$JSON_PAYLOAD"


deploy-aliyun-oss.yaml

name: Deploy to OSS

on:
  push:
    branches: [main, test]
  pull_request:
    branches: [main, test]
    types: [opened, synchronize, reopened]
  workflow_dispatch:
    inputs:
      environment:
        description: '部署环境'
        type: choice
        options:
          - test
          - prod
        default: 'prod'
      


env:
  NODE_VERSION: '20.12.2'
  OSS_REGION: oss-cn-hangzhou
  # 飞书通知渠道 (1=生产,通知到前端群, 2=测试,通话到自己的测试群)
  FEISHU_CHANNEL: '2' 

jobs:
  deploy:
    runs-on: ubuntu-latest
    
    steps:
      - name: Checkout code
        uses: actions/checkout@v4
        with:
          fetch-depth: 0

      - name: Determine Environment
        id: env
        run: |
          if [ "${{ github.event_name }}" == "workflow_dispatch" ]; then
            echo "ENV=${{ github.event.inputs.environment }}" >> $GITHUB_ENV
            echo "DEPLOY=true" >> $GITHUB_ENV
          elif [ "${{ github.event_name }}" == "pull_request" ]; then
            if [ "${{ github.base_ref }}" == "main" ]; then
              echo "ENV=prod" >> $GITHUB_ENV
            else
              echo "ENV=test" >> $GITHUB_ENV
            fi
            echo "DEPLOY=false" >> $GITHUB_ENV
          elif [ "${{ github.ref_name }}" == "main" ]; then
            echo "ENV=prod" >> $GITHUB_ENV
            echo "DEPLOY=true" >> $GITHUB_ENV
          else
            echo "ENV=test" >> $GITHUB_ENV
            echo "DEPLOY=true" >> $GITHUB_ENV
          fi

      - name: Set Environment Variables
        run: |
          if [ "$ENV" == "prod" ]; then
            echo "OSS_BUCKET=pro-hive" >> $GITHUB_ENV
            echo "API_DOMAIN=mainapi.yisuitec.com" >> $GITHUB_ENV
            echo "ENV_NAME=生产环境" >> $GITHUB_ENV
            echo "CDN_DOMAIN=bit.yisuitec.com" >> $GITHUB_ENV
          else
            echo "OSS_BUCKET=test-hives" >> $GITHUB_ENV
            echo "API_DOMAIN=testapi.yisuitec.com" >> $GITHUB_ENV
            echo "ENV_NAME=测试环境" >> $GITHUB_ENV
            echo "CDN_DOMAIN=bittest.yisuitec.com" >> $GITHUB_ENV
          fi

      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: ${{ env.NODE_VERSION }}
          cache: 'npm'

      - name: Prepare Environment File
        run: |
          cp .env.example .env
          if [ "$ENV" == "prod" ]; then
            sed -i 's|http://localhost:8000/api/v1|https://mainapi.yisuitec.com/api/v1 |g' .env
          else
            sed -i 's|http://localhost:8000/api/v1|https://testapi.yisuitec.com/api/v1 |g' .env
          fi
          
      - name: Build
        run: |
          npm ci
          npm run build

      - name: Setup ossutil
        if: env.DEPLOY == 'true'
        uses: manyuanrong/setup-ossutil@v3.0
        with:
          endpoint: ${{ env.OSS_REGION }}.aliyuncs.com
          access-key-id: ${{ secrets.ALIYUN_OSS_ACCESS_KEY_ID }}
          access-key-secret: ${{ secrets.ALIYUN_OSS_ACCESS_KEY_SECRET }}

      - name: Deploy to OSS
        if: env.DEPLOY == 'true'
        run: |
          ossutil cp -r -f ./dist oss://${{ env.OSS_BUCKET }}/

      # ==================== 新增:CDN 刷新 ====================
      - name: Install aliyun-cli
        if: env.DEPLOY == 'true'
        run: |
          curl -L -o aliyun-cli-linux-latest-amd64.tgz https://aliyuncli.alicdn.com/aliyun-cli-linux-latest-amd64.tgz
          tar -xzf aliyun-cli-linux-latest-amd64.tgz
          sudo mv aliyun /usr/local/bin/
          aliyun --version

      - name: Configure aliyun-cli
        if: env.DEPLOY == 'true'
        run: |
          aliyun configure set \
            --access-key-id "${{ secrets.ALIYUN_OSS_ACCESS_KEY_ID }}" \
            --access-key-secret "${{ secrets.ALIYUN_OSS_ACCESS_KEY_SECRET }}" \
            --region "${{ env.OSS_REGION }}"

      - name: Refresh CDN Cache
        if: env.DEPLOY == 'true'
        run: |
          echo "正在刷新 CDN 缓存: ${{ env.CDN_DOMAIN }}"
          
          aliyun cdn RefreshObjectCaches \
            --ObjectPath "https://${{ env.CDN_DOMAIN }}/" \
            --ObjectType Directory 

      # =====================================================

      - name: Send Feishu Notification
        if: always()
        env:
          WEBHOOK_URL_TEST: ${{ secrets.FEISHU_WEBHOOK_URL_TEST }}
          WEBHOOK_URL_PROD: ${{ secrets.FEISHU_WEBHOOK_URL }}
        run: |
          if [ "$FEISHU_CHANNEL" == "1" ]; then
            WEBHOOK_URL="$WEBHOOK_URL_PROD"
          else
            WEBHOOK_URL="$WEBHOOK_URL_TEST"
          fi

          STATUS="${{ job.status }}"
          IS_PR="${{ github.event_name == 'pull_request' }}"
          
          if [ "$IS_PR" == "true" ]; then
            if [ "$STATUS" == "success" ]; then
              EMOJI="📦"
              TITLE="PR 构建成功(预览模式,未部署)"
            else
              EMOJI="❌"
              TITLE="PR 构建失败"
            fi
            COMMIT_MSG="${{ github.event.pull_request.title }}"
            COMMIT_AUTHOR="${{ github.event.pull_request.user.login }}"
            COMMIT_HASH="${{ github.event.pull_request.head.sha }}"
            BRANCH="${{ github.head_ref }} → ${{ github.base_ref }}"
            INVALIDATION_LINE="无"
          else
            if [ "$STATUS" == "success" ]; then
              EMOJI="✅"
              TITLE="${{ env.ENV_NAME }} 部署成功"
            else
              EMOJI="❌"
              TITLE="${{ env.ENV_NAME }} 部署失败"
            fi
            COMMIT_MSG="${{ github.event.head_commit.message || 'manual trigger' }}"
            COMMIT_AUTHOR="${{ github.actor }}"
            COMMIT_HASH="${{ github.sha }}"
            BRANCH="${{ github.ref_name }}"
            INVALIDATION_LINE="CDN 已刷新"
          fi
          
          COMMIT_MSG=$(echo "$COMMIT_MSG" | tr '\n' ' ' | cut -c1-100)

          MESSAGE=$(printf "%s %s\n项目:%s\n编号:#%s\n分支:%s\n提交信息:%s\n作者:%s\n版本:%s\n目标:%s\n失效:%s\n详情:https://github.com/%s/actions/runs/%s " \
            "$EMOJI" "$TITLE" \
            "${{ github.repository }}" \
            "${{ github.run_number }}" \
            "$BRANCH" \
            "$COMMIT_MSG" \
            "$COMMIT_AUTHOR" \
            "${COMMIT_HASH:0:7}" \
            "${{ env.OSS_BUCKET }}" \
            "$INVALIDATION_LINE" \
            "${{ github.repository }}" \
            "${{ github.run_id }}")

          curl -X POST "$WEBHOOK_URL" \
            -H 'Content-Type: application/json' \
            -d "$(jq -n --arg text "$MESSAGE" '{msg_type:"text",content:{text:$text}}')"



deploy-prod.yml

name: Deploy to S3

on:
  push:
    branches: [main, test]
  pull_request:
    branches: [main, test]
    types: [opened, synchronize, reopened]
  workflow_dispatch:
    inputs:
      environment:
        description: '部署环境'
        type: choice
        options:
          - test
          - prod
        default: 'test'
      


env:
  NODE_VERSION: '20.12.2'
  AWS_REGION: ap-northeast-1
  # 飞书通知渠道 (1=生产,通知到前端群, 2=测试,通话到自己的测试群)
  FEISHU_CHANNEL: '1' 

jobs:
  deploy:
    runs-on: ubuntu-latest
    
    steps:
      - name: Checkout code
        uses: actions/checkout@v4
        with:
          fetch-depth: 0

      - name: Determine Environment
        id: env
        run: |
          if [ "${{ github.event_name }}" == "workflow_dispatch" ]; then
            echo "ENV=${{ github.event.inputs.environment }}" >> $GITHUB_ENV
            echo "DEPLOY=true" >> $GITHUB_ENV
          elif [ "${{ github.event_name }}" == "pull_request" ]; then
            if [ "${{ github.base_ref }}" == "main" ]; then
              echo "ENV=prod" >> $GITHUB_ENV
            else
              echo "ENV=test" >> $GITHUB_ENV
            fi
            echo "DEPLOY=false" >> $GITHUB_ENV
          elif [ "${{ github.ref_name }}" == "main" ]; then
            echo "ENV=prod" >> $GITHUB_ENV
            echo "DEPLOY=true" >> $GITHUB_ENV
          else
            echo "ENV=test" >> $GITHUB_ENV
            echo "DEPLOY=true" >> $GITHUB_ENV
          fi

      - name: Set Environment Variables
        run: |
          if [ "$ENV" == "prod" ]; then
            echo "S3_BUCKET=bit.yisuitec.com" >> $GITHUB_ENV
            echo "API_DOMAIN=mainapi.yisuitec.com" >> $GITHUB_ENV
            echo "ENV_NAME=生产环境" >> $GITHUB_ENV
            echo "CLOUDFRONT_DIST_ID=${{ secrets.CLOUDFRONT_DIST_ID_PROD }}" >> $GITHUB_ENV
          else
            echo "S3_BUCKET=bittest.yisuitec.com" >> $GITHUB_ENV
            echo "API_DOMAIN=testapi.yisuitec.com" >> $GITHUB_ENV
            echo "ENV_NAME=测试环境" >> $GITHUB_ENV
            echo "CLOUDFRONT_DIST_ID=${{ secrets.CLOUDFRONT_DIST_ID_TEST }}" >> $GITHUB_ENV
          fi

      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: ${{ env.NODE_VERSION }}
          cache: 'npm'

      - name: Prepare Environment File
        run: |
          cp .env.example .env
          if [ "$ENV" == "prod" ]; then
            sed -i 's|http://localhost:8000/api/v1|https://mainapi.yisuitec.com/api/v1 |g' .env
          else
            sed -i 's|http://localhost:8000/api/v1|https://testapi.yisuitec.com/api/v1 |g' .env
          fi
          
      - name: Build
        run: |
          npm ci
          npm run build

      - name: Configure AWS credentials
        if: env.DEPLOY == 'true'
        uses: aws-actions/configure-aws-credentials@v4
        with:
          aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
          aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
          aws-region: ${{ env.AWS_REGION }}

      - name: Deploy to S3
        if: env.DEPLOY == 'true'
        run: |
          aws s3 sync ./dist s3://${{ env.S3_BUCKET }}/ --delete

      - name: Invalidate CloudFront
        if: env.DEPLOY == 'true'
        id: invalidate
        run: |
          INVALIDATION_ID=$(aws cloudfront create-invalidation \
            --distribution-id ${{ env.CLOUDFRONT_DIST_ID }} \
            --paths "/*" \
            --query 'Invalidation.Id' \
            --output text)
          echo "invalidation_id=$INVALIDATION_ID" >> $GITHUB_OUTPUT

      - name: Send Feishu Notification
        if: always()
        env:
          WEBHOOK_URL_TEST: ${{ secrets.FEISHU_WEBHOOK_URL_TEST }}
          WEBHOOK_URL_PROD: ${{ secrets.FEISHU_WEBHOOK_URL }}
        run: |


          # 根据渠道选择 webhook
          if [ "$FEISHU_CHANNEL" == "1" ]; then
            WEBHOOK_URL="$WEBHOOK_URL_PROD"
          else
            WEBHOOK_URL="$WEBHOOK_URL_TEST"
          fi

          STATUS="${{ job.status }}"
          IS_PR="${{ github.event_name == 'pull_request' }}"
          
          if [ "$IS_PR" == "true" ]; then
            if [ "$STATUS" == "success" ]; then
              EMOJI="📦"
              TITLE="PR 构建成功(预览模式,未部署)"
            else
              EMOJI="❌"
              TITLE="PR 构建失败"
            fi
            COMMIT_MSG="${{ github.event.pull_request.title }}"
            COMMIT_AUTHOR="${{ github.event.pull_request.user.login }}"
            COMMIT_HASH="${{ github.event.pull_request.head.sha }}"
            BRANCH="${{ github.head_ref }} → ${{ github.base_ref }}"
            INVALIDATION_LINE="无"
          else
            if [ "$STATUS" == "success" ]; then
              EMOJI="✅"
              TITLE="${{ env.ENV_NAME }} 部署成功"
            else
              EMOJI="❌"
              TITLE="${{ env.ENV_NAME }} 部署失败"
            fi
            COMMIT_MSG="${{ github.event.head_commit.message || 'manual trigger' }}"
            COMMIT_AUTHOR="${{ github.actor }}"
            COMMIT_HASH="${{ github.sha }}"
            BRANCH="${{ github.ref_name }}"
            INVALIDATION_LINE="${{ steps.invalidate.outputs.invalidation_id || '无' }}"
          fi
          
          COMMIT_MSG=$(echo "$COMMIT_MSG" | tr '\n' ' ' | cut -c1-100)

          # 使用 printf 生成带换行的消息
          MESSAGE=$(printf "%s %s\n项目:%s\n编号:#%s\n分支:%s\n提交信息:%s\n作者:%s\n版本:%s\n目标:%s\n失效:%s\n详情:https://github.com/%s/actions/runs/%s " \
            "$EMOJI" "$TITLE" \
            "${{ github.repository }}" \
            "${{ github.run_number }}" \
            "$BRANCH" \
            "$COMMIT_MSG" \
            "$COMMIT_AUTHOR" \
            "${COMMIT_HASH:0:7}" \
            "${{ env.S3_BUCKET }}" \
            "$INVALIDATION_LINE" \
            "${{ github.repository }}" \
            "${{ github.run_id }}")


          curl -X POST "$WEBHOOK_URL" \
            -H 'Content-Type: application/json' \
            -d "$(jq -n --arg text "$MESSAGE" '{msg_type:"text",content:{text:$text}}')"


get_tencentcloud_sms.py

# -*- coding: utf-8 -*-
import os
import json
import sys
from datetime import datetime, timedelta
import requests

from tencentcloud.common import credential
from tencentcloud.common.profile.client_profile import ClientProfile
from tencentcloud.common.profile.http_profile import HttpProfile
from tencentcloud.common.exception.tencent_cloud_sdk_exception import TencentCloudSDKException
from tencentcloud.sms.v20210111 import sms_client, models


def send_feishu_message(webhook_url: str, content: dict):
    """发送飞书富文本卡片消息"""
    headers = {"Content-Type": "application/json; charset=utf-8"}
    data = {
        "msg_type": "interactive",
        "card": {
            "config": {"wide_screen_mode": True},
            "header": {
                "title": {"tag": "plain_text", "content": "📱 腾讯云短信余量提醒"},
                "template": "blue"
            },
            "elements": [
                {
                    "tag": "div",
                    "text": {
                        "tag": "lark_md",
                        "content": f"**剩余条数:{content['remaining']} 条**\n\n"
                                   f"总量:{content['total']} 条\n"
                                   f"已用:{content['used']} 条\n"
                                   f"有效期至:{content['expired']}"
                    }
                },
                {"tag": "hr"},
                {
                    "tag": "note",
                    "elements": [
                        {"tag": "plain_text", "content": f"查询时间:{datetime.now().strftime('%Y-%m-%d %H:%M:%S')}"}
                    ]
                }
            ]
        }
    }
    try:
        resp = requests.post(webhook_url, headers=headers, json=data, timeout=10)
        if resp.status_code == 200:
            print("✅ 飞书消息发送成功")
        else:
            print(f"❌ 飞书发送失败: {resp.status_code} - {resp.text}", file=sys.stderr)
    except Exception as e:
        print(f"❌ 飞书请求异常: {e}", file=sys.stderr)


def main():
    # 从环境变量直接读取(适配 GitHub Actions)
    secret_id = os.getenv("TENCENTCLOUD_SECRET_ID")
    secret_key = os.getenv("TENCENTCLOUD_SECRET_KEY")
    sdk_app_id = os.getenv("TENCENT_SMS_SDK_APP_ID")
    feishu_webhook = os.getenv("FEISHU_SMS_WEBHOOK_URL")

    if not all([secret_id, secret_key, sdk_app_id]):
        print("❌ 缺少必要环境变量: TENCENTCLOUD_SECRET_ID, TENCENTCLOUD_SECRET_KEY, TENCENT_SMS_SDK_APP_ID", file=sys.stderr)
        sys.exit(1)

    try:
        cred = credential.Credential(secret_id, secret_key)
        httpProfile = HttpProfile()
        httpProfile.endpoint = "sms.tencentcloudapi.com"
        clientProfile = ClientProfile()
        clientProfile.httpProfile = httpProfile
        client = sms_client.SmsClient(cred, "ap-guangzhou", clientProfile)

        end_time = datetime.now()
        begin_time = end_time - timedelta(days=730)

        params = {
            "SmsSdkAppId": sdk_app_id,
            "Limit": 100,
            "Offset": 0,
            "BeginTime": begin_time.strftime("%Y%m%d%H"),
            "EndTime": end_time.strftime("%Y%m%d%H")
        }

        req = models.SmsPackagesStatisticsRequest()
        req.from_json_string(json.dumps(params))
        resp = client.SmsPackagesStatistics(req)

        # 输出原始响应(和你示例一致)
        result_str = resp.to_json_string()
        print("✅ 查询成功!")
        print(result_str)

        # 解析并发送飞书
        data = json.loads(result_str)
        packages = data.get("SmsPackagesStatisticsSet", [])
        if packages:
            pkg = packages[0]
            total = pkg["PackageAmount"]
            used = pkg["CurrentUsage"]
            remaining = total - used
            expired_str = datetime.fromtimestamp(pkg["PackageExpiredTime"]).strftime("%Y-%m-%d")

            if feishu_webhook:
                send_feishu_message(feishu_webhook, {
                    "total": total,
                    "used": used,
                    "remaining": remaining,
                    "expired": expired_str
                })

    except TencentCloudSDKException as e:
        print(f"❌ 腾讯云 API 错误: {e.code} - {e.message}", file=sys.stderr)
        sys.exit(1)
    except Exception as e:
        print(f"❌ 未知错误: {e}", file=sys.stderr)
        sys.exit(1)


if __name__ == "__main__":
    main()


get_tencentcloud_sms.yaml

name: Check Tencent SMS Balance

on:
  workflow_dispatch:

  schedule:
    - cron: '1 1 * * *'

jobs:
  check-balance:
    runs-on: ubuntu-latest
    env:
      TENCENTCLOUD_SECRET_ID: ${{ secrets.TENCENT_SMS_SECRET_ID }}
      TENCENTCLOUD_SECRET_KEY: ${{ secrets.TENCENT_SMS_SECRET_KEY }}
      TENCENT_SMS_SDK_APP_ID: ${{ secrets.TENCENT_SMS_SDK_APP_ID }}
      FEISHU_SMS_WEBHOOK_URL: ${{ secrets.FEISHU_SMS_WEBHOOK_URL }}

    steps:
      - name: Checkout code
        uses: actions/checkout@v4

      - name: Set up Python
        uses: actions/setup-python@v5
        with:
          python-version: '3.10'

      - name: Install dependencies
        run: |
          pip install tencentcloud-sdk-python requests

      - name: Run SMS balance check
        run: python .github/workflows/get_tencentcloud_sms.py

      - name: Send fallback Feishu notification on failure
        if: failure()
        env:
          FEISHU_SMS_WEBHOOK_URL: ${{ secrets.FEISHU_SMS_WEBHOOK_URL }}
        run: |
          MESSAGE="❌ 腾讯云短信余量检查失败!\n项目:${{ github.repository }}\n工作流:Check SMS Balance\n详情:https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}"
          curl -X POST "$FEISHU_SMS_WEBHOOK_URL" \
            -H 'Content-Type: application/json' \
            -d "$(jq -n --arg text "$MESSAGE" '{msg_type:"text",content:{text:$text}}')"


posted @ 2026-03-17 13:58  六月OvO  阅读(1)  评论(0)    收藏  举报