
PythonでSlack APIを使用してスレッドに紐づいている絵文字を取得するスクリプト
CSVやPDFを操作するとき、GASではやりにくいイメージがあって、Microsoft Copilot(中身はChat GPT)と壁打ちしながら、Pythonで書いてみました。時折、間違ったコードを返すので、一つ一つ試行錯誤しながら完成に繋げました。
スクリプト
import re
import requests
from datetime import datetime, timezone
"""
token, channel, message_timestampを指定して、絵文字の一覧を取得する
:param token: User OAuth Token
:param channel: チャンネルID
:param message_timestamp: Slackの投稿日時のタイムスタンプ
:return: 絵文字をすべて配列で取得
"""
def get_slack_reactions(token, channel, message_timestamp):
url = "https://slack.com/api/reactions.get"
headers = {"Authorization": "Bearer "+token}
data = {
'channel': channel,
'timestamp': message_timestamp, # リアクションを取得したいメッセージのタイムスタンプ
}
response = requests.post(url, headers=headers, data=data)
json = response.json()
message = json['message']
reactions = message.get('reactions', [])
emoji_names = []
for reaction in reactions:
emoji_names.append(reaction['name'])
print(f'emoji_names: {emoji_names}')
return emoji_names
"""
Slackの投稿内容を取得する
limitで取得内容をコントロールする
:param token: User OAuth Token
:param channel: チャンネルID
:return: 絵文字をすべて配列で取得
"""
def get_slack_messages(token, channel):
url = "https://slack.com/api/conversations.history"
headers = {"Authorization": "Bearer "+token}
data = {'channel': channel, 'limit': 5 }
response = requests.post(url, headers=headers, data=data)
messages = response.json()
values = []
for message in messages['messages']:
# メッセージがボットからのものであるかを確認
if message.get('subtype') == 'bot_message':
text = message.get('text')
ts = message.get('ts')
# 正しいタイムスタンプを渡さないと値が返ってこない
reactions = get_slack_reactions(token, channel, ts)
timestamp = convert_timestamp_to_date(ts)
reaction_info = {
"Timestamp": timestamp,
"Message": text,
"Reactions": reactions
}
print(f'reaction_info: ${reaction_info}\n')
values.append(list(reaction_info.values()))
print(f'${values}]\n\n')
return values
"""
Unixタイムスタンプを 'yyyy/MM/dd HH:mm:ss' 形式の日時文字列に変換する関数。
:param timestamp: Unixタイムスタンプ(秒単位)
:return: 指定されたフォーマットの日時文字列
"""
def convert_timestamp_to_date(timestamp):
# タイムスタンプを整数に変換
timestamp = int(float(timestamp))
# Unixタイムスタンプをdatetimeオブジェクトに変換
dt_object = datetime.fromtimestamp(timestamp, timezone.utc)
formatted_date = dt_object.strftime('%Y/%m/%d %H:%M:%S')
return formatted_date
"""
与えられた行(リスト)内に'csv'の絵文字が含まれているかどうかを調べます。
:param row: チェックする行。形式は ['2024/04/13 08:12:58', '投稿内容のテキスト', ['melting_face', 'eyes', 'csv']]
:return: 'csv'の絵文字が含まれている場合はTrue、そうでない場合はFalse
"""
def check_csv_emoji_in_data(row):
# アイテムがリストかどうかを確認します
if isinstance(row, list):
# 各要素に対して、この関数を再帰的に呼び出します
for item in row:
if 'csv' in item:
return True
else:
# リストでなければ、'csv'が含まれているかを確認します
if 'csv' in row:
return True
return False
"""
Slackの投稿内容から応募者名を取得する
"""
def extract_applicant_name_from_message(message):
values = []
url_matched = re.search(r'URL:.*\n', message)
target_reg_exp = re.compile(r'.*さんからメッセージを受信しました!.*\n\n')
replaced_reg_exp = re.compile(r'さんからメッセージを受信しました!.*\n\n')
# HRMOSのCSVに合わせる必要があるかも
info = {
'applicant_name': extract_target_word(message, target_reg_exp, replaced_reg_exp, re.compile(r'さん.*'), ' '),
'url': replace_elements_in_array(url_matched[0]) if url_matched else '-',
'position': extract_target_word(message, re.compile(r'求人タイトル:.*'), re.compile(r'\n.*'), re.compile(r'.*:'))
}
print(info)
values.append(list(info.values()))
print(values)
return values
"""
リストを元に置換する
"""
def replace_elements_in_array(string):
lists = [
{'target': re.compile(r'<|>'), 'replaced': ''},
{'target': re.compile(r'\n'), 'replaced': ''},
{'target': re.compile(r"'"), 'replaced': ''},
{'target': 'URL: ', 'replaced': ''},
]
for list in lists:
string = re.sub(list['target'], list['replaced'], string)
print(f'置換後:{string}')
return string
"""
指定した単語を置換する
"""
def extract_target_word(string, regex, *replaced_words):
result = re.search(regex, string)
if result:
for word in replaced_words:
result = re.sub(word, '', result.group(0))
return result if result else ''
token = '*******************************'
channel = '****************' # #05_want_imageの内容を取得する
values = get_slack_messages(token, channel)
for row in values:
# リストにcsvという文字列が含まれているかを検索する
has_csv_emoji = check_csv_emoji_in_data(row)
if has_csv_emoji:
# row - ['2024/04/13 08:12:58', '投稿内容のテキスト', ['melting_face', 'eyes', 'csv']]
print(row)
print(f'rowには、csvのスタンプが含まれています\n')
# row[1]の投稿内容から、応募者内容、URLなどを取得する
# extract_applicant_name_from_message(row[1])