Slack API:如何按时间先后顺序获取线程与消息
解决Slack消息(含线程)按时间顺序排列的问题
我刚好之前也踩过这个坑!你现在的问题核心有两个:一是还没把线程里的回复消息完整整合到消息列表中,二是排序时要用每条消息自身的ts字段,而不是线程标识thread_ts。
关键知识点回顾
你提到的字段逻辑完全正确:
- 主消息的
ts和thread_ts是同一个值 - 每条线程回复都有自己独立的
ts(这条消息的发送时间),同时thread_ts指向对应的主消息ts - 所有消息的
ts都是带微秒精度的Unix时间戳,这就是我们排序的核心依据
修正后的完整流程
- 先获取频道内所有主消息(和你原来的
conversations_history逻辑一致) - 遍历每条主消息,若有回复(
reply_count > 0),调用conversations_replies获取该线程的所有消息 - 将主消息和所有线程回复合并到同一个列表
- 按照所有消息的
ts字段转换为浮点数后排序
代码实现(适配你的原有逻辑)
import time from slack_sdk import WebClient from slack_sdk.errors import SlackApiError # 假设你已初始化Slack客户端:client = WebClient(token="YOUR_SLACK_TOKEN") MESSAGES_PER_PAGE = 100 MAX_MESSAGES = 1000 UNIXTime = # 替换为你需要的过去一周截止时间戳 for channel_id in channel_ID_list: messages_all = [] page = 0 # 第一步:获取频道内所有主消息 response = client.conversations_history( channel=channel_id, limit=MESSAGES_PER_PAGE, latest=UNIXTime ) assert response["ok"] messages_all.extend(response['messages']) # 分页获取剩余主消息 while len(messages_all) + MESSAGES_PER_PAGE <= MAX_MESSAGES and response['has_more']: page += 1 print(f"Retrieving main messages page {page}") time.sleep(1) response = client.conversations_history( channel=channel_id, limit=MESSAGES_PER_PAGE, cursor=response['response_metadata']['next_cursor'], latest=UNIXTime ) assert response["ok"] messages_all.extend(response['messages']) # 第二步:获取所有线程回复并合并 thread_messages = [] for msg in messages_all: # 只处理有回复的主消息 if msg.get('reply_count', 0) > 0: page_thread = 0 response_reply = client.conversations_replies( channel=channel_id, ts=msg['thread_ts'], limit=MESSAGES_PER_PAGE ) assert response_reply["ok"] # 去重:conversations_replies会返回主消息本身,过滤掉重复项 thread_replies = [reply for reply in response_reply['messages'] if reply['ts'] != msg['ts']] thread_messages.extend(thread_replies) # 分页获取剩余线程回复 while response_reply['has_more']: page_thread += 1 print(f"Retrieving thread replies page {page_thread} for message {msg['ts']}") time.sleep(1) response_reply = client.conversations_replies( channel=channel_id, ts=msg['thread_ts'], limit=MESSAGES_PER_PAGE, cursor=response_reply['response_metadata']['next_cursor'] ) assert response_reply["ok"] thread_replies = [reply for reply in response_reply['messages'] if reply['ts'] != msg['ts']] thread_messages.extend(thread_replies) # 合并主消息和线程回复 all_messages = messages_all + thread_messages # 第三步:按时间顺序排序(从小到大=旧到新,从大到小=新到旧) all_messages_sorted = sorted(all_messages, key=lambda x: float(x['ts'])) # 现在all_messages_sorted就是按时间顺序排列的所有消息了! print(f"Total sorted messages for channel {channel_id}: {len(all_messages_sorted)}")
重要细节说明
- 去重处理:
conversations_replies默认会返回主消息本身,所以我们通过reply['ts'] != msg['ts']过滤掉重复的主消息 - 排序逻辑:把
ts转成浮点数是因为Slack的ts是字符串格式的带小数时间戳(比如"1663055350.830049"),直接排序字符串会出错,转成浮点数后才能正确按时间排序 - Rate Limit:Slack API对请求频率有限制,分页请求时保留
time.sleep(1)可避免触发限流
内容的提问来源于stack exchange,提问作者AaravS
相关产品推荐
相关产品推荐

