見出し画像

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])

GASでSlack APIでメッセージに取得するスクリプト


この記事が気に入ったらサポートをしてみませんか?