使用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
相关产品推荐
相关产品推荐

