Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[3.2.x] Add Socket Mode implementation #883

Merged
merged 27 commits into from
Jan 12, 2021
Merged

[3.2.x] Add Socket Mode implementation #883

merged 27 commits into from
Jan 12, 2021

Conversation

seratch
Copy link
Member

@seratch seratch commented Dec 1, 2020

Summary

This pull request is still work in progress. We may change the APIs and/or implementations before releasing this.

The changes here include all required functionalities for Socket Mode support, such as WSS URL acquisition, bidirectional communications with the Slack server over a WebSocket connection, maintaining WS connections, and relaying only envelope messages to Bolt framework or something similar.

The basic usage of the module would be:

from threading import Event
from slack_sdk.socket_mode.response import SocketModeResponse
from slack_sdk.socket_mode.request import SocketModeRequest
from slack_sdk.socket_mode import SocketModeClient

def listener(client: SocketModeClient, req: SocketModeRequest):
    if req.type == "events_api":
        # acknowledge the incoming request from Slack
        client.send_socket_mode_response(SocketModeResponse(envelope_id=req.envelope_id))

        # can call Web APIs and whatever you want to do here
        client.web_client.reactions_add(
            token="xoxb-___",
            name="eyes",
            channel=req.payload["event"]["channel"],
            timestamp=req.payload["event"]["ts"],
        )

if __name__ == "__main__":
    client = SocketModeClient(app_token="xapp-___")
    client.socket_mode_request_listeners.append(listener)
    client.connect()
    Event().wait()

If you want to use Socket Mode along with asyncio, the default way is to use AIOHTTP library as with the AsyncWebClient.

import asyncio
from slack_sdk.socket_mode.response import SocketModeResponse
from slack_sdk.socket_mode.request import SocketModeRequest
from slack_sdk.socket_mode.async_client import SocketModeClient

async def listener(client: SocketModeClient, req: SocketModeRequest):
    if req.type == "events_api":
        await client.send_socket_mode_response(SocketModeResponse(envelope_id=req.envelope_id))
        await client.web_client.reactions_add(
            token="xoxb-___",
            name="eyes",
            channel=req.payload["event"]["channel"],
            timestamp=req.payload["event"]["ts"],
        )

async def main():
    client = SocketModeClient(app_token="xapp-___")
    client.socket_mode_request_listeners.append(listener)
    await client.connect()
    await asyncio.sleep(float("inf"))

asyncio.run(main())

Supported External Libraries

In the initial version, the SDK is going to support the following major libraries for the low-level WebSocket client layer, in addition to its own built-in implementation.

We decided not to support the following libraries at least in v3.2 series.

The BaseSocketModeClient and AsyncBaseSocketModeClient provide good abstraction and the interface never depends on any of these specific library's interface. We accept the difference of a bit detailed configuration in the subtypes of the interface. For instance, websockets library does not support proxy settings at this moment. As aiohttp does not have OPEN message events, the implementation for this library does not offer on_open_listeners. These differences never appear in the base class (interface) level.

Other things that should be mentioned

  • The GA release date is not yet publicly announced
  • Documentation is out of scope in this PR

Category (place an x in each of the [ ])

  • slack_sdk.socket_mode (New one!)

Requirements (place an x in each [ ])

  • I've read and understood the Contributing Guidelines and have done my best effort to follow them.
  • I've read and agree to the Code of Conduct.
  • I've run python setup.py validate after making the changes.

@seratch seratch added this to the 3.2.0 milestone Dec 1, 2020
@seratch seratch self-assigned this Dec 1, 2020
@seratch seratch force-pushed the v3.2-socket-mode branch 2 times, most recently from 072861e to 07febd8 Compare December 2, 2020 12:34
@codecov
Copy link

codecov bot commented Dec 2, 2020

Codecov Report

Merging #883 (0e6d613) into main (e05af1f) will decrease coverage by 1.85%.
The diff coverage is 80.93%.

Impacted file tree graph

@@            Coverage Diff             @@
##             main     #883      +/-   ##
==========================================
- Coverage   87.94%   86.09%   -1.86%     
==========================================
  Files          35       51      +16     
  Lines        3385     4602    +1217     
==========================================
+ Hits         2977     3962     +985     
- Misses        408      640     +232     
Impacted Files Coverage Δ
slack_sdk/socket_mode/builtin/connection.py 65.90% <65.90%> (ø)
slack_sdk/socket_mode/async_listeners.py 75.00% <75.00%> (ø)
slack_sdk/socket_mode/listeners.py 75.00% <75.00%> (ø)
slack_sdk/socket_mode/request.py 75.00% <75.00%> (ø)
slack_sdk/socket_mode/response.py 76.19% <76.19%> (ø)
slack_sdk/socket_mode/client.py 77.57% <77.57%> (ø)
slack_sdk/socket_mode/async_client.py 79.54% <79.54%> (ø)
slack_sdk/socket_mode/aiohttp/__init__.py 80.91% <80.91%> (ø)
slack_sdk/socket_mode/builtin/internals.py 82.03% <82.03%> (ø)
slack_sdk/socket_mode/builtin/client.py 88.40% <88.40%> (ø)
... and 24 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update e05af1f...0e6d613. Read the comment docs.

@seratch seratch force-pushed the v3.2-socket-mode branch 2 times, most recently from f0452ff to 2fd040b Compare December 8, 2020 13:02
@seratch seratch force-pushed the v3.2-socket-mode branch 3 times, most recently from 1317b44 to c98cc16 Compare January 9, 2021 13:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants