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

使用Slack API上传PNG图表失败,提示invalid_auth问题求助

问题:Slack文件上传报错invalid_auth,文本消息正常发送

原本有两个函数,一个生成图表,另一个将PNG图表和文本发送给Telegram机器人。改为适配Slack的版本后,文本消息能正常发送,但PNG图表无法上传,报错:File upload failed. Error: invalid_auth。已获取以下权限:

  • files:write - 以roman_test身份上传、编辑和删除文件
  • incoming-webhook - 向Slack特定频道发送消息

相关代码

import matplotlib.pyplot as plt
import seaborn as sns
import numpy as np
import pandas as pd
import io
import requests

SLACK_WEBHOOK_URL = 'https://hooks.slack.com/services/*****'
SLACK_CHANNEL = "#test-channel"
SLACK_TOKEN = '******2'

def alert_to_slack(plot_object=None, caption=None):
    files = {
        'file': plot_object
    }
    payload = {
        'filename': plot_object.name,
        'token': SLACK_TOKEN,
        'channels': SLACK_CHANNEL
    }

    response = requests.post('https://slack.com/api/files.upload', params=payload, files=files)
    data = response.json()

    if response.status_code == 200 and data['ok']:
        file_url = data['file']['url_private']
        print(f"File uploaded successfully. URL: {file_url}")
    else:
        print("File upload failed.")
        print(f"Error: {data['error']}")

    data = {
        "text": f"*Spending Sum Alert Manager*\n\n{caption}",
        "username": "Spending",
        "channel": SLACK_CHANNEL,
        "mrkdwn": True
    }

    r = requests.post(SLACK_WEBHOOK_URL, json=data)
    return r.status_code


def slack_send():
    # 获取文本及DataFrame最后一天与预测日的天数间隔
    text = 'hahahaha'

    # X轴示例数据
    dates = pd.date_range(start='2023-01-01', end='2023-12-31', freq='D')

    # Y轴示例数据
    values = np.random.randint(1, 100, size=len(dates))  # 替换为你的数据

    # 创建DataFrame
    df = pd.DataFrame({'ds': dates, 'y': values})

    # 设置图表尺寸
    sns.set(rc={'figure.figsize': (16, 8)})

    # 基于DataFrame创建折线图
    ax = sns.lineplot(data=df, x='ds', y='y', color='#1c1c1c')

    # 设置X轴和Y轴标签
    ax.set_xlabel('date')
    ax.set_ylabel('Spending sum')

    # 设置图表标题
    plt.title(f'Alert in Spending sum', size=16)

    # 调整图表布局
    plt.tight_layout()

    # 将图表保存到BytesIO对象
    plot_object = io.BytesIO()
    plt.savefig(plot_object)
    plot_object.seek(0)
    plot_object.name = 'alert.png'
    plt.close()

    # 发送图表和文本信息
    alert_to_slack(plot_object=plot_object, caption=text)


slack_send()

解决方案

1. 确认Token有效性与权限

  • 确保SLACK_TOKEN是Bot Token(格式为xoxb-xxxxxx),而非User Token或Webhook URL。
  • 验证Bot已被添加到目标#test-channel频道,且files:write权限已正确赋予该Bot(在Slack应用管理后台的OAuth & Permissions页面确认)。

2. 修正API请求的Token传递方式

Slack API要求Token通过请求头的Authorization字段传递,而非URL参数或表单payload。修改alert_to_slack函数中的请求部分:

def alert_to_slack(plot_object=None, caption=None):
    files = {
        'file': (plot_object.name, plot_object, 'image/png')
    }
    payload = {
        'channels': SLACK_CHANNEL
    }
    # 添加Authorization请求头
    headers = {
        'Authorization': f'Bearer {SLACK_TOKEN}'
    }

    response = requests.post(
        'https://slack.com/api/files.upload',
        headers=headers,
        data=payload,
        files=files
    )
    data = response.json()

    if response.status_code == 200 and data['ok']:
        file_url = data['file']['url_private']
        print(f"File uploaded successfully. URL: {file_url}")
        # 可选:在webhook消息中引用上传的文件
        caption = f"{caption}\n图表链接: {file_url}"
    else:
        print("File upload failed.")
        print(f"Error: {data['error']}")

    data = {
        "text": f"*Spending Sum Alert Manager*\n\n{caption}",
        "username": "Spending",
        "channel": SLACK_CHANNEL,
        "mrkdwn": True
    }

    r = requests.post(SLACK_WEBHOOK_URL, json=data)
    return r.status_code

3. 额外优化点

  • 在files字典中明确指定文件类型为image/png,避免Slack自动识别错误。
  • 可以将文件上传成功后的URL添加到文本消息中,让用户直接在消息中看到图表链接。

内容的提问来源于stack exchange,提问作者Roman Stasiuk

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 15:27:49