【问题标题】:Pulling historical channel messages python拉取历史频道消息python
【发布时间】:2019-06-24 21:47:09
【问题描述】:

我正在尝试通过从我参与的松弛通道中提取消息/响应来创建一个小型数据集。我想使用 python 从通道中提取数据,但是我无法找出我的 api 密钥。我在 slack 上创建了一个应用程序,但我不确定如何找到我的 api 密钥。我看到了我的客户端密码、签名密码和验证令牌,但找不到我的 api 密钥

这是我认为我正在努力完成的一个基本示例:

import slack
sc = slack.SlackClient("api key")
sc.api_call(
  "channels.history",
  channel="C0XXXXXX"
)

如果可能的话,我也愿意手动下载数据。非常感谢任何帮助。

【问题讨论】:

  • 您需要安装您的应用程序才能获取令牌。您可以从应用程序管理屏幕执行此操作,您还可以在其中看到客户端密码等。
  • 您也想查看conversations.history。它是较新的版本,更适合分页,还可以检索所有类型的频道。
  • 您为您的 Slack 应用授予了哪些权限以访问来自频道的消息?

标签: python slack slack-api


【解决方案1】:

消息

请参阅下面的示例代码,了解如何在 Python 中从频道中提取消息。

  • 它使用官方 Python Slack 库并调用 conversations_history 带分页。因此,它将与 任何类型的通道,并且可以获取大量消息,如果 需要。
  • 结果将作为 JSON 数组写入文件。
  • 您可以指定要检索的频道和最大消息

线程

请注意,conversations.history 端点不会返回线程消息。对于您要为其检索消息的每个线程,必须通过调用conversations.replies 来额外检索这些内容。

通过检查消息中的threads_ts 属性,可以在每个通道的消息中识别线程。如果它存在,则附有一个线程。有关线程如何工作的更多详细信息,请参阅此page

ID

不过,此脚本不会用名称替换 ID。如果你需要,这里有一些如何实现它的指针:

  • 您需要替换用户、频道、机器人、用户组的 ID(如果在付费计划中)
  • 您可以分别使用users_listconversations_listusergroups_list从API中获取用户、频道和用户组的列表,bots需要使用bots_info一一获取(如果需要)
  • ID 出现在消息中的许多地方:
    • 用户顶级属性
    • bot_id 顶级属性
    • 作为允许文本的任何属性中的链接,例如<@U12345678> 用于用户或<#C1234567> 用于渠道。这些可以出现在顶级 text 属性中,也可以出现在附件和块中。

示例代码

import os
import slack
import json
from time import sleep

CHANNEL = "C12345678"
MESSAGES_PER_PAGE = 200
MAX_MESSAGES = 1000

# init web client
client = slack.WebClient(token=os.environ['SLACK_TOKEN'])

# get first page
page = 1
print("Retrieving page {}".format(page))
response = client.conversations_history(
    channel=CHANNEL,
    limit=MESSAGES_PER_PAGE,
)
assert response["ok"]
messages_all = response['messages']

# get additional pages if below max message and if they are any
while len(messages_all) + MESSAGES_PER_PAGE <= MAX_MESSAGES and response['has_more']:
    page += 1
    print("Retrieving page {}".format(page))
    sleep(1)   # need to wait 1 sec before next call due to rate limits
    response = client.conversations_history(
        channel=CHANNEL,
        limit=MESSAGES_PER_PAGE,
        cursor=response['response_metadata']['next_cursor']
    )
    assert response["ok"]
    messages = response['messages']
    messages_all = messages_all + messages

print(
    "Fetched a total of {} messages from channel {}".format(
        len(messages_all),
        CHANNEL
))

# write the result to a file
with open('messages.json', 'w', encoding='utf-8') as f:
  json.dump(
      messages_all, 
      f, 
      sort_keys=True, 
      indent=4, 
      ensure_ascii=False
    )

【讨论】:

  • 嗨,Erik,感谢您回答这个问题,这很有帮助。这似乎只接收通道中的消息,而不是初始消息的响应消息线程。检索那些通过元数据的最佳方法是什么?
  • 是的,让我更新答案以添加线程的工作原理。
  • 非常感谢,我一直在努力寻找一个没有 api 限制问题或花费很长时间的解决方案
  • 乐于助人。正如您在代码中看到的,我的函数在每次 API 调用后等待 1 秒,以确保它不违反速率限制。
  • 是的,我也有这个,我之前只是单独提取每个响应,而不是使用回复 api,所以我的代码非常慢。你知道我是否可以减少代码中的等待?
【解决方案2】:

这是使用 slack webapi。您需要安装 requests 包。这应该抓取频道中的所有消息。您需要一个可以从应用程序管理页面获取的令牌。您可以使用 getChannels() 函数。获取所有消息后,您将需要查看谁编写了您需要进行 id 匹配的消息(将 id 映射到用户名),您可以使用 getUsers() 函数。如果您不想使用应用中的令牌,请按照此 https://api.slack.com/custom-integrations/legacy-tokens 生成旧令牌。

def getMessages(token, channelId):
    print("Getting Messages")
    # this function get all the messages from the slack team-search channel
    # it will only get all the messages from the team-search channel
    slack_url = "https://slack.com/api/conversations.history?token=" + token + "&channel=" + channelId
    messages = requests.get(slack_url).json()
    return messages


def getChannels(token):
    ''' 
    function returns an object containing a object containing all the
    channels in a given workspace
    ''' 
    channelsURL = "https://slack.com/api/conversations.list?token=%s" % token
    channelList = requests.get(channelsURL).json()["channels"] # an array of channels
    channels = {}
    # putting the channels and their ids into a dictonary
    for channel in channelList:
        channels[channel["name"]] = channel["id"]
    return {"channels": channels}

def getUsers(token):
    # this function get a list of users in workplace including bots 
    users = []
    channelsURL = "https://slack.com/api/users.list?token=%s&pretty=1" % token
    members = requests.get(channelsURL).json()["members"]
    return members

【讨论】:

  • 这些是对 OP 的一些有用建议。但是,我建议使用官方 Python Slack 库,而不是自己编写所有 API 调用。容易得多。这是链接:github.com/slackapi/python-slackclient。安装pip3 install slackclient==2.0.0
  • 另外:检索消息和用户时需要添加分页逻辑,否则只会得到一部分(例如前 200 个)。
猜你喜欢
  • 2013-08-07
  • 2010-09-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-10-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多