You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Github Action无法发送带图片的Slack消息求助

问题

我尝试通过Github Action发送带图片的Slack消息,但发送步骤始终失败。我的实现目标是:

  • 将图片上传至Slack
  • 提取已上传图片的永久链接
  • 将该链接加入Slack消息并发送

目前除发送带图片的消息外,其余步骤均正常执行。上传图片的代码和发送消息的代码如下,错误提示显示缺失filetype,且图片上传后的输出也无filetype字段。

上传图片并提取永久链接的代码

# 📤 Upload Doughnut Chart to Slack & Get Image URL
      - name: Upload Chart to Slack
        if: always()
        run: |
          response=$(curl -s -X POST \
            -H "Authorization: Bearer ${{ secrets.SLACK_BOT_TOKEN }}" \
            -H "Content-Type: application/x-www-form-urlencoded" \
            --data "filename=test_results.png&length=$(stat -c%s test_results.png)" \
            https://slack.com/api/files.getUploadURLExternal)

          echo "Slack Upload URL Response: $response"

          upload_url=$(echo "$response" | jq -r '.upload_url')
          file_id=$(echo "$response" | jq -r '.file_id')

          if [ "$upload_url" == "null" ] || [ "$file_id" == "null" ]; then
            echo "⚠️ Failed to get upload URL from Slack."
            exit 1
          fi

          # Step 2: Upload the file to the received URL
          upload_response=$(curl -X POST \
            -H "Content-Type: image/png" \
            -F file=@test_results.png \
            "$upload_url")

          echo "Slack File Upload Response: $upload_response"

          # Step 3: Complete the upload and get the file permalink
          complete_response=$(curl -s -X POST \
            -H "Authorization: Bearer ${{ secrets.SLACK_BOT_TOKEN }}" \
            -H "Content-Type: application/json" \
            -d '{
                  "files": [{"id": "'"$file_id"'", "title": "Test Results"}]
                }' \
            https://slack.com/api/files.completeUploadExternal)

          echo "Slack Complete Upload Response: $complete_response"

          image_url=$(echo "$complete_response" | jq -r '.files[0].permalink')

          if [ "$image_url" == "null" ]; then
            echo "⚠️ Failed to upload image to Slack."
            exit 1
          else
            echo "✅ Image uploaded: $image_url"
            echo "IMAGE_URL=$image_url" >> $GITHUB_ENV
          fi

上传步骤输出截图:
上传结果截图

发送带图片的Slack消息代码

# 📢 Send Cypress Results to Slack (With Image & Test Summary)
      - name: Send Cypress Results to Slack
        if: always()
        run: |
          curl -X POST \
            -H "Authorization: Bearer ${{ secrets.SLACK_BOT_TOKEN }}" \
            -H "Content-Type: application/json" \
            -d '{
              "channel": "XXXXXXX",
              "blocks": [
                {
                  "type": "header",
                  "text": {
                    "type": "plain_text",
                    "text": "🧪 API Test Report",
                    "emoji": true
                  }
                },
                {
                  "type": "rich_text",
                  "elements": [
                    {
                      "type": "rich_text_section",
                      "elements": [
                        {
                          "type": "text",
                          "text": "'"${{ steps.cypress-results.outputs.failed == '0' && '✅ All Tests Passed!' || (steps.cypress-results.outputs.failed != '0' && steps.cypress-results.outputs.passed != '0') && '⚠️ Some Tests Failed' || '❌ All Tests Failed!' }}'",
                          "style": {
                            "bold": true,
                            "italic": true
                          }
                        }
                      ]
                    }
                  ]
                },
                {
                  "type": "divider"
                },
                {
                  "type": "section",
                  "fields": [
                    {
                      "type": "mrkdwn",
                      "text": "*Total:* `${{ steps.cypress-results.outputs.total }}`\n✅ Pass: `${{ steps.cypress-results.outputs.passed }}`\n❌ Fail: `${{ steps.cypress-results.outputs.failed }}`\n⏭️ Skip: `${{ steps.cypress-results.outputs.skipped }}`"
                    },
                    {
                      "type": "mrkdwn",
                      "text": "⏱️ Duration: `${{ steps.cypress-results.outputs.duration }} sec`\n📈 Success Rate: `${{ steps.cypress-results.outputs.success_rate }}%`"
                    }
                  ],
                  "accessory": {
                    "type": "image",
                    "image_url": "${{ env.IMAGE_URL }}",
                    "alt_text": "Test Results Doughnut Chart"
                  }
                },
                {
                  "type": "context",
                  "elements": [
                    {
                      "type": "mrkdwn",
                      "text": "📋 *Reports:* • 🔍 <https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}|GitHub Actions Run> • 📊 <https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}/artifacts/${{ env.ARTIFACT_ID }}|Download HTML Report>"
                    }
                  ]
                }
              ]
            }' \
            https://slack.com/api/chat.postMessage

发送步骤输出截图:
发送结果截图

疑问:缺失filetype是否是发送失败的原因?为何Slack API上传图片时未设置filetype?求原因分析及解决方案。


原因分析

  1. 缺失filetype是发送失败的核心原因:Slack的chat.postMessage接口在使用图片附件时,要求图片链接对应的文件必须有明确的filetype标识,否则无法正确解析和展示图片,进而导致消息发送失败。
  2. 上传流程未显式指定filetype:你使用的files.getUploadURLExternal接口虽然传入了带.png后缀的文件名,但Slack不会自动从文件名推断filetype,需要显式指定该参数;后续的files.completeUploadExternal步骤也没有补充filetype信息,导致最终上传的文件元数据中缺失该字段。

解决方案

步骤1:在获取上传URL时显式指定filetype

修改files.getUploadURLExternal的请求参数,添加filetype=png:

response=$(curl -s -X POST \
  -H "Authorization: Bearer ${{ secrets.SLACK_BOT_TOKEN }}" \
  -H "Content-Type: application/x-www-form-urlencoded" \
  --data "filename=test_results.png&length=$(stat -c%s test_results.png)&filetype=png" \
  https://slack.com/api/files.getUploadURLExternal)

步骤2:可选优化:在完成上传时补充文件类型(增强兼容性)

在files.completeUploadExternal的请求体中,为文件添加filetype字段:

complete_response=$(curl -s -X POST \
  -H "Authorization: Bearer ${{ secrets.SLACK_BOT_TOKEN }}" \
  -H "Content-Type: application/json" \
  -d '{
        "files": [{"id": "'"$file_id"'", "title": "Test Results", "filetype": "png"}]
      }' \
  https://slack.com/api/files.completeUploadExternal)

验证修改后的流程

  1. 重新运行Github Action,检查上传步骤的输出,确认complete_response中包含filetype: "png"字段。
  2. 发送消息步骤会自动使用包含正确filetype的图片链接,消息即可正常发送并展示图片。

内容的提问来源于stack exchange,提问作者Md. Samsul Kabir

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 18:56:07