slackapi / bolt-python

A framework to build Slack apps using Python

Home Page:https://slack.dev/bolt-python/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

how to receive new messages to process them?

paantya opened this issue · comments

I saw your work and was inspired by the solution, thank you for your work!

I decided to rewrite the existing bot, which was written using slack_sdk, to use slack_bolt, but I encountered difficulties that the bot does not respond to commands in the new version (niche code).

The slack_bolt version

slack-bolt==1.18.1
slack_sdk==3.27.1
Note: you may need to restart the kernel to use updated packages.

Python runtime version

Python 3.10.12

Steps to reproduce:

  1. I have an old code that responds to chat messages
  2. I made a minimally reproducible version of this functionality to test the transition
  3. studied the slack_bolt library and wrote code that, in my opinion, should work the same way
  4. I ran the code, received a message about the successful launch of the bot, but for some reason I did not receive a response to ping.

old code that responds to a "ping" message with "pong".

from slack_sdk import WebClient
import json
import logging
import time


class MenagerBot:

     def __init__(self, channel_id=None, token=None, bot_name= None, config="config.json"):
         try:
             if token is None:
                 token = SLACK_BOT_TOKEN
             self.token = token
             if bot_name is None:
                 bot_name = 'Bot Name'
             self.bot_name = bot_name
             if channel_id is None:
                 self.channel_id = config["CHANNEL_ID"]
             else:
                 self.channel_id = channel_id
             self.client = WebClient(token=self.token, timeout=120)
             logging.info(f'{self.bot_name} initialized at channel {self.channel_id}')
         except Exception as e:
             logging.warning(f'{self.bot_name} failed initializing\nException: {e}')
         #self.logger = logging.getLogger("ClothoBot")

     def read_chat(self, max_tries=3):

         try_number = 1
         read_succ = False
         while not read_succ and try_number <= max_tries:
             try:
                 try_number += 1
                 resp = self.client.conversations_history(channel=self.channel_id)
                 read_succ = True
                 last_msg = resp['messages'][0]
                 return resp, last_msg

             except Exception as e:
                 logging.warning(f'{self.bot_name} failed reading chat, retrying\nException: {e}')
                 time.sleep(10)

     def send_text(self, text):

         try:
             msg = self.client.chat_postMessage(channel=self.channel_id, text=text)
             print('all ok')
             return msg

         except Exception as e:
             logging.warning(f'{self.bot_name} failed at sending message.'
                             f'Exception: {e}\nChannel_id: {self.channel_id}')



if __name__ == "__main__":

     bot = MenagerBot(channel_id=CHANNEL_ID, token=SLACK_BOT_TOKEN, bot_name='test_name_sen_WebClient')

     while True:
         resp, last_msg = bot.read_chat()
         print(last_msg)
         if last_msg['text']=='ping':
             msg = bot.send_text('pong')
             time.sleep(1)
         time.sleep(10)

The new code, which I understand should do the same thing, but for some reason it doesn’t:

import os
from slack_bolt import App
from slack_bolt.adapter.socket_mode import SocketModeHandler

# Initializes your app with your bot token and socket mode handler
app = App(token=SLACK_BOT_TOKEN)


# Listens to incoming messages that contain "hello"
# To learn available listener arguments,
# visit https://slack.dev/bolt-python/api-docs/slack_bolt/kwargs_injection/args.html
@app.message("ping")
def message_hello(message, say):
     # say() sends a message to the channel where the event was triggered
     say(f"pong")


# Start your app
if __name__ == "__main__":
     SocketModeHandler(app, SLACK_APP_TOKEN).start()

Expected result:

The new code will repeat the work of the old code

Actual result:

The message ⚡️ Bolt app is running! is displayed.
but the bot does not respond to messages in the channel and nothing is written to the channel from the bot’s name to the ping message

Hey @paantya! 👋 Thanks so much for the kind words and for giving Bolt a try 🐍 ⚡

The code you shared looks like it should respond to ping with pong but there might be a few changes to how the bot listens for events! Instead of requesting conversation history, you'll receive events for any new messages that your bot is listening for. Your setup all looks good for this!

To make sure messages are actually being sent to your app could you check that you've subscribed to the message event and have added your bot to the channel you're sending ping to? I'm hoping your app starts to receive message events after this, but please let me know if nothing is being received!

@zimeg
Thank you very much for your prompt response and suggestions for further action!

I’ll orient you right away,

  1. we have one bot configured in slack and it is added to one channel
  2. if we pass the token of this bot into the old code, then the bot reacts to messages and responds “pong” in the same channel
  3. if we transfer the same token to a new bot, then there are not reactions.

I'll check the rest later. I'll get back to you with an answer when I get the chance

@zimeg Please tell me where I need to check these additional settings? in the bot settings? I don’t fully understand what and where I should try to check

I also have an assumption that if the old code with the same token works, then the problem is not in the settings of the ebot token, but in something else - in the settings of the bot or the method of receiving messages, perhaps in the APP token

I repeated the runs now, and the behavior is still the same - the old code works, but the new one does not work

I rewrote the latest minimal version to eliminate problems of not understanding the functions, but it still doesn’t work

import os
from slack_bolt import App
from slack_bolt.adapter.socket_mode import SocketModeHandler
#  SocketModeHandler
    
# slack_bolt.adapter.socket_mode.websockets

# from slack_bolt.adapter.socket_mode.websocket_client import  SocketModeHandler
# Initializes your app with your bot token and socket mode handler
app = App(token=SLACK_BOT_TOKEN)


# Listens to incoming messages that contain "hello"
# To learn available listener arguments,
# visit https://slack.dev/bolt-python/api-docs/slack_bolt/kwargs_injection/args.html
@app.message("ping")
def message_hello(message, say):
    # say() sends a message to the channel where the event was triggered
    print('in')
    say(f"pong")


    
@app.message("pong")
def message_hello(message, say):
    # say() sends a message to the channel where the event was triggered
    print('in2')
    say(f"ping")


cln = SocketModeHandler(app, SLACK_APP_TOKEN)
cln.connect()
cln.start()

Both tokens should remain working alright but you'll have to enable events from the App Config page. From this page, check that Features > Event Subscriptions > Enable Events: On > Subscribe to bot events > Add Bot User Event > message.channels is on for your app. Then your app should start to receive message events for channels it has joined.

I also think you can remove the cln.connect() from your latest example since .start() will maintain a connection and is calling this behind the scenes.

Let me know if this seems to change anything! You might also add DEBUG logging for a bit more detail, but this might not show anything if no events are being sent in the first place:

import logging

logging.basicConfig(level=logging.DEBUG)

Thank you very much for such a detailed guide! this helped, I didn't really have Add Bot User Event > message.channels enabled

I will continue to immerse myself in your creation, thank you for your work!