Я создаю Slackbot на Python и хочу повторять сообщение, пока к этому сообщению не будет добавлена ​​реакция. Что я делаю не так?

как говорится в заголовке, я пишу Slack Bot на Python и использую NGROK для его локального размещения. У меня нет большого опыта работы с декораторами, и я могу заставить бота публиковать сообщения в slack, однако я не могу обрабатывать два события одновременно. Например, я хочу обработать сообщение и повторять его в спящем режиме до тех пор, пока к этому сообщению не будет добавлена ​​реакция "большой палец вверх". Проблема в том, что я не могу понять, как обрабатывать событие, пока другое событие все еще выполняется, см. следующий код:

rom slack import WebClient
import os
import time
from pathlib import Path
from dotenv import load_dotenv
from flask import Flask
from slackeventsapi import SlackEventAdapter

env_path = Path('.') / '.env'
load_dotenv(dotenv_path=env_path)

app = Flask(__name__)
slack_event_adapter = SlackEventAdapter(
    os.environ['SIGNING_SECRET'],'/slack/events',app)

client = WebClient(token=os.environ['SLACK_TOKEN'])
BOT_ID = client.api_call("auth.test")['user_id']

state = {}

@slack_event_adapter.on('message')
def handle_message(event_data):
    message = event_data.get('event', {})
    channel_id = message.get('channel')
    user_id = message.get('user')
    text = message.get('text')
    messageid = message.get('ts')
    state[messageid] = {"channel_id": channel_id, "user_id": user_id, "text": text}

    if BOT_ID != user_id:
        if text[0:12] == ":red_circle:":
            time.sleep(5)
            client.chat_postMessage(channel=channel_id, text=text)
        if text[0:21] == ":large_yellow_circle:":
            client.chat_postMessage(channel=channel_id, text = "it's a yellow question!")
        if text[0:14] == ":white_circle:":
            client.chat_postMessage(channel=channel_id, text = "it's a white question!")


@slack_event_adapter.on('reaction_added')
def reaction_added(event_data):
    reaction = event_data.get('event',{})
    emoji = reaction.get('reaction')
    emoji_id = reaction.get('item',{}).get('ts')
    emoji_channel_id = reaction.get('item',{}).get('channel')
    client.chat_postMessage(channel=emoji_channel_id, text=emoji)


for message_id, message_data in state.items():
    channel_id = message_data["channel_id"]
    text = message_data["text"]
    client.chat_postMessage(channel=channel_id, text=text)
    print(message_id,message_data)

if __name__ == "__main__":
    app.run(debug=True)

Я могу обрабатывать отдельные события, но я не могу обрабатывать их, пока выполняется другое. Пожалуйста помоги! :)

Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
0
0
50
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Flask — это синхронный веб-фреймворк.

Когда он запускает обработчик представления, он использует рабочий веб-поток. Если вы сделаете что-то вроде time.sleep(...), этот рабочий поток все еще будет занят и недоступен для обработки других запросов, пока не завершится сон.

Есть несколько вариантов, которые вы можете сделать здесь.

Вы можете использовать Bolt для Python, библиотеку Python Slack, изначально поддерживающую асинхронную равномерную обработку. Вместо time.sleep() вы можете использовать await asyncio.sleep(...), которая возвращает поток в асинхронный цикл и позволяет рабочему потоку обрабатывать другие события.

Если у вас уже есть слабое приложение и вы не хотите переписывать всю свою кодовую базу в Bolt, вам придется самостоятельно обрабатывать события. Вы можете сделать это, выполнив свою работу в ThreadLoopExecutor, создав собственный механизм очереди асинхронных событий или используя Celery. Или, если ваш слабый бот имеет очень низкий объем, вы, вероятно, можете просто добавить больше веб-воркеров и надеяться на лучшее, что у вас не закончатся рабочие.

Довольно технично, но спасибо, что разобрали это для меня.

Mirage24 10.02.2023 06:14

Другие вопросы по теме