-
Notifications
You must be signed in to change notification settings - Fork 852
Description
Summary
Although now we recommend considering Socket Mode as the primary option, I am still keen to work on the improvements of the RTMClient for the existing users of the API in Python. The reason why I'm passionate about it is that I understand a portion of Slack API users may have reasons to continue using RTM for a while.
I propose that we can offer slack_sdk.v2.RTMClient as a better RTM client implementation by reusing the built-in WebSocket client implementation for Socket Mode (see #883). The v2 RTMClient is not fully compatible with the existing slack_sdk.rtm.RTMClient, but it works mostly in the same manner and provides more functionalities like instance-based decorators (mentioned at #538).
If we do not have any concerns on this, I would like to have the new client since v3.3 releases.
Code Example
The following code is a simple example demonstrating how it works. You can use on method in an RTMClient instance for registering event listeners to it before starting the client. If you have two listeners as below and both of them match an event, both listeners will be executed in the scenario.
from slack_sdk.rtm.v2 import RTMClient
rtm = RTMClient(token="xoxb-classic-bot-token")
# This listener handles only "type":"message" events
# This is equivalent to RTMClient.run_on(event="message") in v1
@rtm.on("message")
def handle(client: RTMClient, event: dict):
client.web_client.chat_postMessage(
channel=event["channel"],
text=f"Hi there <@{event['user']}>!",
)
# This listener handles all the events
@rtm.on("*")
def handle(client: RTMClient, event: dict):
logger.info(event)
rtm.start()Remarkable Changes
Here are the remarkable changes in the v2 client:
- It does not have any external dependencies unlike v1
- v2 client uses the built-in WebSocket client implementation introduced for Socket Mode [3.2.x] Add Socket Mode implementation #883
- It does not rely on asyncio mechanism
- v2 client does not internally use async/await syntax and does not generate any Future objects. It should be free from the shutdown issue can't shutdown slackclient correctly when other async tasks/futures are running #522
- v2 client does not rely on aiohttp. This means aiohttp-specific issues like RTMClient.start fails when enabling proxy with Python 3.8.2 + Windows OS #642 won't occur with it. Also, it does not support aiohttp specific initialization options.
- It uses threads for resolving the concurrency issue Unexpected behavior in that dispatched events are not asynchronous #558
- It provides its decorators as instance methods for resolving RTM client should support instance-specific callbacks #538
- v2 client does not offer class/static methods
- As a plus point, the new event type matching logic support asterisk "*" for catching all events Handler for un-registered events in the rtm client api #533
Background
Looking back to the past, we have been improving the RTMClient particularly starting from v2.6 release. However, there are still a few remaining issues. I am thinking that some of them are not resolvable without breaking changes to its behavior and supported initialization options. In other words, trying to use aiohttp in non-asyncio settings is not the nature of asyncio concept. To eliminate all the issues, not using asyncio-based solutions is the most straight-forward way to go.
For supporting the Socket Mode feature #883, this project added its own WebSocket client implementation. It is just a general implementation of WebSocket communications (disclaimer: It overs only the features required for Slack WebSocket features) and it does not rely on asyncio APIs. Initially, we were not planning to reuse the code for RTM but I found that it can be reused for RTM (I've already verified if my prototype works). Then, I came to think there is no reason to stop providing a possibly helpful option to this SDK users.
Limitations
Offering a asyncio-compatible solution is not in our scope
It's also possible to make everything asyncio-based: using aiohttp along with AsyncWebClient. But it's not our priority at this point. For Socket Mode apps, you can write 100% asyncio based applications using aiohttp/websockets based SocketModeClient. If you would like to implement your own asyncio RTM client, please feel free to reuse those Socket Mode implementation (under the MIT license).
Category (place an x in each of the [ ])
- slack_sdk.web.WebClient (sync/async) (Web API client)
- slack_sdk.webhook.WebhookClient (sync/async) (Incoming Webhook, response_url sender)
- slack_sdk.models (UI component builders)
- slack_sdk.oauth (OAuth Flow Utilities)
- slack_sdk.socket_mode (Socket Mode client)
- slack_sdk.rtm.RTMClient (RTM client)
- slack_sdk.signature (Request Signature Verifier)
Requirements
Please read the Contributing guidelines and Code of Conduct before creating this issue or pull request. By submitting, you are agreeing to those rules.