Slack Developer Kit for Python

Overview

Python Slack SDK

The Slack platform offers several APIs to build apps. Each Slack API delivers part of the capabilities from the platform, so that you can pick just those that fit for your needs. This SDK offers a corresponding package for each of Slack’s APIs. They are small and powerful when used independently, and work seamlessly when used together, too.

Comprehensive documentation on using the Slack Python can be found at https://slack.dev/python-slack-sdk/

pypi package Build Status Python Version codecov contact

Whether you're building a custom app for your team, or integrating a third party service into your Slack workflows, Slack Developer Kit for Python allows you to leverage the flexibility of Python to get your project up and running as quickly as possible.

The Python Slack SDK allows interaction with:

  • slack_sdk.web: for calling the Slack Web API methods (API Docs site)
  • slack_sdk.webhook: for utilizing the Incoming Webhooks and response_urls in payloads
  • slack_sdk.signature: for verifying incoming requests from the Slack API server
  • slack_sdk.socket_mode: for receiving and sending messages over Socket Mode connections
  • slack_sdk.audit_logs: for utilizing Audit Logs APIs
  • slack_sdk.scim: for utilizing SCIM APIs
  • slack_sdk.oauth: for implementing the Slack OAuth flow
  • slack_sdk.models: for constructing UI components using easy-to-use builders
  • slack_sdk.rtm: for utilizing the RTM API

If you want to use our Events API and Interactivity features, please check the Bolt for Python library. Details on the Tokens and Authentication can be found in our Auth Guide.

slackclient is in maintenance mode

Are you looking for slackclient? The website is live here just like before. However, the slackclient project is in maintenance mode now and this slack_sdk is the successor. If you have time to make a migration to slack_sdk v3, please follow our migration guide to ensure your app continues working after updating.

Table of contents

Requirements


This library requires Python 3.6 and above. If you require Python 2, please use our SlackClient - v1.x. If you're unsure how to check what version of Python you're on, you can check it using the following:

Note: You may need to use python3 before your commands to ensure you use the correct Python path. e.g. python3 --version

python --version

-- or --

python3 --version

Installation

We recommend using PyPI to install the Slack Developer Kit for Python.

$ pip install slack_sdk

Getting started tutorial


We've created this tutorial to build a basic Slack app in less than 10 minutes. It requires some general programming knowledge, and Python basics. It focuses on the interacting with Slack's Web and RTM API. Use it to give you an idea of how to use this SDK.

Read the tutorial to get started!

Basic Usage of the Web Client


Slack provide a Web API that gives you the ability to build applications that interact with Slack in a variety of ways. This Development Kit is a module based wrapper that makes interaction with that API easier. We have a basic example here with some of the more common uses but a full list of the available methods are available here. More detailed examples can be found in our guide.

Sending a message to Slack

One of the most common use-cases is sending a message to Slack. If you want to send a message as your app, or as a user, this method can do both. In our examples, we specify the channel name, however it is recommended to use the channel_id where possible. Also, if your app's bot user is not in a channel yet, invite the bot user before running the code snippet (or add chat:write.public to Bot Token Scopes for posting in any public channels).

import os
from slack_sdk import WebClient
from slack_sdk.errors import SlackApiError

client = WebClient(token=os.environ['SLACK_BOT_TOKEN'])

try:
    response = client.chat_postMessage(channel='#random', text="Hello world!")
    assert response["message"]["text"] == "Hello world!"
except SlackApiError as e:
    # You will get a SlackApiError if "ok" is False
    assert e.response["ok"] is False
    assert e.response["error"]  # str like 'invalid_auth', 'channel_not_found'
    print(f"Got an error: {e.response['error']}")

Here we also ensure that the response back from Slack is a successful one and that the message is the one we sent by using the assert statement.

Uploading files to Slack

We've changed the process for uploading files to Slack to be much easier and straight forward. You can now just include a path to the file directly in the API call and upload it that way. You can find the details on this api call here

import os
from slack_sdk import WebClient
from slack_sdk.errors import SlackApiError

client = WebClient(token=os.environ['SLACK_BOT_TOKEN'])

try:
    filepath="./tmp.txt"
    response = client.files_upload(channels='#random', file=filepath)
    assert response["file"]  # the uploaded file
except SlackApiError as e:
    # You will get a SlackApiError if "ok" is False
    assert e.response["ok"] is False
    assert e.response["error"]  # str like 'invalid_auth', 'channel_not_found'
    print(f"Got an error: {e.response['error']}")

Async usage

AsyncWebClient in this SDK requires AIOHttp under the hood for asynchronous requests.

AsyncWebClient in a script

import asyncio
import os
from slack_sdk.web.async_client import AsyncWebClient
from slack_sdk.errors import SlackApiError

client = AsyncWebClient(token=os.environ['SLACK_BOT_TOKEN'])

async def post_message():
    try:
        response = await client.chat_postMessage(channel='#random', text="Hello world!")
        assert response["message"]["text"] == "Hello world!"
    except SlackApiError as e:
        assert e.response["ok"] is False
        assert e.response["error"]  # str like 'invalid_auth', 'channel_not_found'
        print(f"Got an error: {e.response['error']}")

asyncio.run(post_message())

AsyncWebClient in a framework

If you are using a framework invoking the asyncio event loop like : sanic/jupyter notebook/etc.

import os
from slack_sdk.web.async_client import AsyncWebClient
from slack_sdk.errors import SlackApiError

client = AsyncWebClient(token=os.environ['SLACK_BOT_TOKEN'])
# Define this as an async function
async def send_to_slack(channel, text):
    try:
        # Don't forget to have await as the client returns asyncio.Future
        response = await client.chat_postMessage(channel=channel, text=text)
        assert response["message"]["text"] == text
    except SlackApiError as e:
        assert e.response["ok"] is False
        assert e.response["error"]  # str like 'invalid_auth', 'channel_not_found'
        raise e

from aiohttp import web

async def handle_requests(request: web.Request) -> web.Response:
    text = 'Hello World!'
    if 'text' in request.query:
        text = "\t".join(request.query.getall("text"))
    try:
        await send_to_slack(channel="#random", text=text)
        return web.json_response(data={'message': 'Done!'})
    except SlackApiError as e:
        return web.json_response(data={'message': f"Failed due to {e.response['error']}"})


if __name__ == "__main__":
    app = web.Application()
    app.add_routes([web.get("/", handle_requests)])
    # e.g., http://localhost:3000/?text=foo&text=bar
    web.run_app(app, host="0.0.0.0", port=3000)

Advanced Options

SSL

You can provide a custom SSL context or disable verification by passing the ssl option, supported by both the RTM and the Web client.

For async requests, see the AIOHttp SSL documentation.

For sync requests, see the urllib SSL documentation.

Proxy

A proxy is supported when making async requests, pass the proxy option, supported by both the RTM and the Web client.

For async requests, see AIOHttp Proxy documentation.

For sync requests, setting either HTTPS_PROXY env variable or the proxy option works.

DNS performance

Using the async client and looking for a performance boost? Installing the optional dependencies (aiodns) may help speed up DNS resolving by the client. We've included it as an extra called "optional":

$ pip install slack_sdk[optional]

Example

import os
from slack_sdk import WebClient
from ssl import SSLContext

sslcert = SSLContext()
# pip3 install proxy.py
# proxy --port 9000 --log-level d
proxyinfo = "http://localhost:9000"

client = WebClient(
    token=os.environ['SLACK_BOT_TOKEN'],
    ssl=sslcert,
    proxy=proxyinfo
)
response = client.chat_postMessage(channel="#random", text="Hello World!")
print(response)

Migrating from v2

If you're migrating from slackclient v2.x of slack_sdk to v3.x, Please follow our migration guide to ensure your app continues working after updating.

Check out the Migration Guide here!

Migrating from v1

If you're migrating from v1.x of slackclient to v2.x, Please follow our migration guide to ensure your app continues working after updating.

Check out the Migration Guide here!

Support


If you get stuck, we’re here to help. The following are the best ways to get assistance working through your issue:

Use our Github Issue Tracker for reporting bugs or requesting features. Visit the Slack Community for getting help using Slack Developer Kit for Python or just generally bond with your fellow Slack developers.

Comments
  • File Upload API succeeds despite 408 Request Timeout

    File Upload API succeeds despite 408 Request Timeout

    Reproducible in:

    # test.py
    import sys
    # Enable debug logging
    import logging
    
    from slack_sdk import WebClient
    
    def uploadToSlackChannel():
        client = WebClient(
            token="you-slack-token", timeout=300)
        try:
            filepath = "file-to-upload"
            response = client.files_upload(
                channels="your-slack-channel-name", file=filepath)
            assert response["file"]  # the uploaded file
        except Exception as e:
            print(e)
    
    uploadToSlackChannel()        
    
    

    The Slack SDK version

    slack-sdk==3.13.0

    Python runtime version

    Python 3.9.10

    OS info

    ProductName: Mac OS X ProductVersion: 10.15.7 BuildVersion: 19H1615 Darwin Kernel Version 19.6.0: Sun Nov 14 19:58:51 PST 2021; root:xnu-6153.141.50~1/RELEASE_X86_64

    Steps to reproduce:

    (Share the commands to run, source code, and project settings (e.g., setup.py))

    1. copy the above snippet to any file (e.g. upload_to_slack.py)
    2. run python3 upload_to_slack.py

    Expected result:

    Should succeed without any error

    Actual result:

    The file gets uploaded but also throws this error

    Received a response in a non-JSON format: stream timeout
    The server responded with: {'status': 408, 'headers': {'x-edge-backend': 'envoy-www', 'content-length': '14', 'content-type': 'text/plain', 'x-slack-edge-shared-secret-outcome': 'no-match', 'date': 'Wed, 26 Jan 2022 07:12:45 GMT', 'server': 'envoy', 'via': 'envoy-edge-bom-jbcm', 'connection': 'close'}, 'body': 'stream timeout'}
    

    Requirements

    For general questions/issues about Slack API platform or its server-side, could you submit questions at https://my.slack.com/help/requests/new instead. :bow:

    Please read the Contributing guidelines and Code of Conduct before creating this issue or pull request. By submitting, you are agreeing to those rules.

    bug web-client Version: 3x server-side-issue auto-triage-skip 
    opened by iamarjun 55
  • Getting 404 error from WS URL in RTMClient#start() with aiohttp 3.7.0 or lower versions

    Getting 404 error from WS URL in RTMClient#start() with aiohttp 3.7.0 or lower versions

    RTMClient.start() failing as of 2021-01-09. Connection attempted with both slack_sdk and (legacy) slackclient.

    The Slack SDK version

    slack-sdk 3.1.1

    (Also occuring on slackclient 2.9.3)

    Python runtime version

    Python 3.6.7

    OS info

    Microsoft Windows [Version 10.0.18362.1256]

    Steps to reproduce:

    > import slack_sdk.rtm as rtm
    
    > rtm_client = rtm.RTMClient(token=token) # also attempted with ssl_context provided
    > rtm_client.start()
    

    Testing via https://api.slack.com/methods/rtm.connect/test is successful with the same token as used when running code sample above.

    Actual result:

      File "C:\Program Files\Python36\lib\asyncio\base_events.py", line 473, in run_until_complete
        return future.result()
      File "D:\Repos\analysis-tools\slack-bot\src\env\lib\site-packages\slack_sdk\rtm\__init__.py", line 360, in _connect_and_read
        proxy=self.proxy,
      File "D:\Repos\analysis-tools\slack-bot\src\env\lib\site-packages\aiohttp\client.py", line 1012, in __aenter__
        self._resp = await self._coro
      File "D:\Repos\analysis-tools\slack-bot\src\env\lib\site-packages\aiohttp\client.py", line 738, in _ws_connect
        headers=resp.headers)
    aiohttp.client_exceptions.WSServerHandshakeError: 404, message='Invalid response status', url=URL('wss://cerberus-xxxx.lb.slack-msgs.com/websocket/XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX')
    
    Version: 2x bug rtm-client Version: 3x server-side-issue dependency-side-issue 
    opened by mgtech-sydney 42
  • Intermittent  concurrent.futures._base.TimeoutError with run_async=True

    Intermittent concurrent.futures._base.TimeoutError with run_async=True

    Description

    When i try to post a message to slack channel using one of the basic example to post a message to a channel, i see an error saying "concurrent.futures._base.TimeoutError". I am using python 3.6.7 on Ubuntu 18.0.4 with slackclient 2.

    What type of issue is this? (place an x in one of the [ ])

    • [x] bug
    • [ ] enhancement (feature request)
    • [x] question
    • [ ] documentation related
    • [ ] testing related
    • [ ] discussion

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

    • [x] I've read and understood the Contributing guidelines and have done my best effort to follow them.
    • [x] I've read and agree to the Code of Conduct.
    • [x] I've searched for any related issues and avoided creating a duplicate issue.

    Bug Report

    Filling out the following details about bugs will help us solve your issue sooner.

    Reproducible in:

    slackclient version: 2

    python version: 3.6.7

    OS version(s): Ubuntu 18.0.4

    Steps to reproduce:

    1. Set up virtualenv with python 3.6.7
    2. Example code from tutorial
    3. python3 testnotify.py

    My Code:

    import slack
    
    client = slack.WebClient(token='SLACK_API_TOKEN')
    
    response = client.chat_postMessage(
        channel='#sm-test',
        text="Hello world!")
    assert response["ok"]
    assert response["message"]["text"] == "Hello world!"
    

    Expected result:

    I am expecting to see the message 'Hello World!' posted to the slack channel '#sm-test'

    Actual result:

    I am seeing the following Error:

    Traceback (most recent call last):
      File "testnotify.py", line 9, in <module>
        text="Hello world!")
      File "/usr/local/lib/python3.6/dist-packages/slack/web/client.py", line 332, in chat_postMessage
        return self.api_call("chat.postMessage", json=kwargs)
      File "/usr/local/lib/python3.6/dist-packages/slack/web/base_client.py", line 154, in api_call
        return self._event_loop.run_until_complete(future)
      File "/usr/lib/python3.6/asyncio/base_events.py", line 473, in run_until_complete
        return future.result()
      File "/usr/local/lib/python3.6/dist-packages/slack/web/base_client.py", line 211, in _send
        http_verb=http_verb, api_url=api_url, req_args=req_args
      File "/usr/local/lib/python3.6/dist-packages/slack/web/base_client.py", line 240, in _request
        async with session.request(http_verb, api_url, **req_args) as res:
      File "/usr/local/lib/python3.6/dist-packages/aiohttp/client.py", line 1005, in __aenter__
        self._resp = await self._coro
      File "/usr/local/lib/python3.6/dist-packages/aiohttp/client.py", line 575, in _request
        break
      File "/usr/local/lib/python3.6/dist-packages/aiohttp/helpers.py", line 585, in __exit__
        raise asyncio.TimeoutError from None
    concurrent.futures._base.TimeoutError
    

    Attachments:

    Logs, screenshots, screencast, sample project, funny gif, etc.

    Version: 2x bug area:concurrency 
    opened by smslack 36
  • SSL Certification error

    SSL Certification error

    Description

    I've built a bot in python 3.7 using a virtual engine, when I come to run the code I get this error:

    /Users/sophie/Dropbox/Programming/gallagherbot/lib/python3.7/site-packages/urllib3/connectionpool.py:857: InsecureRequestWarning: Unverified HTTPS request is being made. Adding certificate verification is strongly advised. See: https://urllib3.readthedocs.io/en/latest/advanced-usage.html#ssl-warnings
      InsecureRequestWarning)
    Traceback (most recent call last):
      File "/Users/sophie/Dropbox/Programming/gallagherbot/lib/python3.7/site-packages/slackclient/server.py", line 179, in connect_slack_websocket
        http_proxy_auth=proxy_auth)
      File "/Users/sophie/Dropbox/Programming/gallagherbot/lib/python3.7/site-packages/websocket/_core.py", line 494, in create_connection
        websock.connect(url, **options)
      File "/Users/sophie/Dropbox/Programming/gallagherbot/lib/python3.7/site-packages/websocket/_core.py", line 217, in connect
        options.pop('socket', None))
      File "/Users/sophie/Dropbox/Programming/gallagherbot/lib/python3.7/site-packages/websocket/_http.py", line 126, in connect
        sock = _ssl_socket(sock, options.sslopt, hostname)
      File "/Users/sophie/Dropbox/Programming/gallagherbot/lib/python3.7/site-packages/websocket/_http.py", line 253, in _ssl_socket
        sock = _wrap_sni_socket(sock, sslopt, hostname, check_hostname)
      File "/Users/sophie/Dropbox/Programming/gallagherbot/lib/python3.7/site-packages/websocket/_http.py", line 232, in _wrap_sni_socket
        server_hostname=hostname,
      File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/ssl.py", line 412, in wrap_socket
        session=session
      File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/ssl.py", line 850, in _create
        self.do_handshake()
      File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/ssl.py", line 1108, in do_handshake
        self._sslobj.do_handshake()
    ssl.SSLCertVerificationError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:1045)
    

    During handling of the above exception, another exception occurred:

    Traceback (most recent call last):
      File "/Users/sophie/Dropbox/Programming/gallagherbot/lib/python3.7/site-packages/slackclient/client.py", line 52, in rtm_connect
        self.server.rtm_connect(use_rtm_start=with_team_state, **kwargs)
      File "/Users/sophie/Dropbox/Programming/gallagherbot/lib/python3.7/site-packages/slackclient/server.py", line 147, in rtm_connect
        self.connect_slack_websocket(self.ws_url)
      File "/Users/sophie/Dropbox/Programming/gallagherbot/lib/python3.7/site-packages/slackclient/server.py", line 186, in connect_slack_websocket
        raise SlackConnectionError(message=str(e))
    slackclient.server.SlackConnectionError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:1045)
    

    Connection failed. Exception traceback printed above.

    This seems similar to this: https://github.com/slackapi/python-slackclient/issues/325 but I tried the User's suggestion and it hasn't changed anything.

    I have the bot's 'Bot User OAuth Access Token' stored as a variable which I refer to in the code

    Any suggestions?

    Describe your issue here.

    What type of issue is this? (place an x in one of the [ ])

    • [x ] bug
    • [ ] enhancement (feature request)
    • [ ] question
    • [ ] documentation related
    • [ ] testing related
    • [ ] discussion

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

    • [x ] I've read and understood the Contributing guidelines and have done my best effort to follow them.
    • [x ] I've read and agree to the Code of Conduct.
    • [x ] I've searched for any related issues and avoided creating a duplicate issue.

    Bug Report

    Filling out the following details about bugs will help us solve your issue sooner.

    Reproducible in:

    slackclient version:

    python version: 3.7

    OS version(s):

    Steps to reproduce:

    Expected result:

    What you expected to happen

    Actual result:

    What actually happened

    Attachments:

    Logs, screenshots, screencast, sample project, funny gif, etc.

    opened by sophiefitzpatrick 33
  • Upload a file

    Upload a file

    It says here: https://api.slack.com/methods/files.upload that files need to be uploaded via multipart/form-data, which it looks like the current client doesn't support.

    If we moved to requests #54, it would make it easier to use their files argument for that.

    opened by jonathan-s 31
  • Handling Rate Limiting With v2 Commands

    Handling Rate Limiting With v2 Commands

    Description

    What is the best way to handle web API rate limiting with the new v2 client? The docs https://slack.dev/python-slackclient/basic_usage.html [slack.dev] don't seem to work anymore and the release notes and migration notes didn't suggest anything. I now get this error when hitting rate limiting but there appears no way to handle it like before since the response is never returned to me it is just output as an error.

    slack.errors.SlackApiError: The request to the Slack API failed. The server responded with: {'ok': False, 'error': 'ratelimited'}

    What type of issue is this? (place an x in one of the [ ])

    • [X] question
    • [X] documentation related

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

    • [X ] I've read and understood the Contributing guidelines and have done my best effort to follow them.
    • [X ] I've read and agree to the Code of Conduct.
    • [X ] I've searched for any related issues and avoided creating a duplicate issue.

    Reproducible in:

    slackclient version: v2

    python version: Python 3.7.3

    OS version(s): Mac Logs, screenshots, screencast, sample project, funny gif, etc.

    Version: 2x bug enhancement 
    opened by CyTheGuy 29
  • Jupyter lab -

    Jupyter lab - "RuntimeError: Cannot run the event loop while another loop is running"

    Bug Report

    Reproducible in:

    slackclient version: 2.0.1

    python version: 3.7

    OS version(s): MACOSX

    Description

    The code below, produces an error (see screenshot) when run in Jupyter Lab, and not when run from a simple python script. This comes after trying to upgrade slack client from a previous version, when I was successfully able to run from my Jupyter lab notebook

    from slack import WebClient
    sc = WebClient(token='<my-token>')
    sc.chat_postMessage(channel='<my-channel>', text='testing2')
    

    JupyterLab

    Version: 2x bug area:concurrency 
    opened by ecatkins 26
  • rtm_connect() is now always returning False

    rtm_connect() is now always returning False

    • [X] I've read and understood the Contributing guidelines and have done my best effort to follow them.
    • [X] I've read and agree to the Code of Conduct.
    • [X] I've searched for any related issues and avoided creating a duplicate issue.

    Description

    rtm_connect() is always returning False

    Reproducible in:

    following guide here will show the issue: http://slackapi.github.io/python-slackclient/real_time_messaging.html#connecting-to-the-real-time-messaging-api

    For my project I was using docker with python 2.75 + ubuntu 16.04

    Steps to reproduce:

    1. Follow guide the line sc.rtm_connect() will always return False
    • This was working up to a week ago. I rebuilt containers with slack project and they all started seeing this. Nothing else was change in container except moving them to a different instance. Retried on the old instance to verify it wasn't network and problem was also seen then.

    Expected result:

    sc.rtm_connect() should return true

    Actual result:

    Always returns false.

    Extra Info:

    I got feedback from slack about the issue and they were suggesting that I try out the newer rtm.connect method https://api.slack.com/changelog/2017-04-start-using-rtm-connect-and-stop-using-rtm-start

    I believe this is in reference to this line: https://github.com/slackapi/python-slackclient/blob/master/slackclient/_server.py#L70

    opened by Zechtitus 25
  • files_upload API - timeout response by server regardless of timeout value passed to web client

    files_upload API - timeout response by server regardless of timeout value passed to web client

    Hi, I have this little snippet of code that used to work for me until recently:

    slackClient=slack_sdk.WebClient(token=slackToken, timeout=300)
    upload = slackClient.files_upload(file=file, filename=file)
    

    now I am suddenly getting this response: slack_sdk.errors.SlackApiError: Received a response in a non-JSON format: stream timeout The server responded with: {'status': 408, 'headers': {'x-edge-backend': 'envoy-www', 'content-length': '14', 'content-type': 'text/plain', 'x-slack-edge-shared-secret-outcome': 'no-match', 'date': 'Tue, 18 Jan 2022 08:12:58 GMT', 'server': 'envoy', 'via': 'envoy-edge-fra-f6ad', 'connection': 'close'}, 'body': 'stream timeout'}

    it seems like the client or server are not considering the timeout parameter that is passed to the WebClient, this response returns exactly 30 seconds after the request initiated, as well as when testing it with a smaller file that takes less than 30 seconds to upload everything works fine

    since no changes were made to the code, and the slack_sdk was not updated, I am assuming it is related to a server issue? can any one shed some more information regarding this issue?

    using python slack-sdk version 3.13.0

    needs info server-side-issue 
    opened by daniel-moonactive 24
  • RFC: Python Slack Client v2.0

    RFC: Python Slack Client v2.0

    Abstract

    Python developers are an important part of the Slack platform ecosystem. From internal apps for a specific organization or team to publicly distributed apps listed in our App Directory, tools and products built upon our SDKs improve people's working lives.

    This issue proposes a redesign of the Slack Python SDK/Client to address several design flaws that surfaced as the scope and complexity of the platform grew. Currently every app built on RTM is required to implement a loop over the stream of events coming in. Web HTTP requests could be simpler to write and more performant when scaled.

    This issue proposes that we split up the client into an RTM client and a Web client. We'd like to remove any state not explicitly used for the client's function. As well as make it simpler for developers to interact with the Web API and respond to RTM events.

    Motivation

    The goal of our Python SDK is to make it simple for Python developers to create Slack apps. We believe that developers should be able to go from Readme to a running app in less than 10 minutes.

    Currently there are a number of limitations in our existing project that prevent this goal from being realized. From a high level, the complexity in our SDK has led to a number of tough to triage bugs. It also makes it harder for new app developers or possible first time contributors to get up and running quickly.

    Working with the Slack Web API:

    • There’s no clear separation between the RTM API Client and the Web API Client.
      • To make an Slack API call, there are 4 nested objects created. Developers who only need to communicate via the Web API deal with unnecessary complexity.
        • Client#api_call→Server#api_call→SlackRequest#do→requests#post
      • For developers who don’t use RTM we also unnecessarily store information such as channel data on what’s currently called Server.py.

    Working with the Slack RTM API:

    • Every developer has to create a “while connected” loop that constantly reads line by line from the websocket. What’s worse is that they also have to create nested if statement to check for their event types on every event that comes in. This makes building complex apps rather cumbersome.
    • We’re loosely caching data on the Server object. Which should only be responsible for managing the web socket connection. The problem with this ad hoc approach to caching is sooner or later apps built on this infrastructure will inevitably experience performance and scalability problems as their app increases in complexity or is installed on larger enterprise teams. This approach also lacks proper caching support such as removing or updating stale data.

    Other challenges:

    • There are a number of unnecessary/old/deprecated methods and variables that need to be removed. e.g. Refresh tokens
    • We’ve not defined an official API for the Client. This makes it harder to deprecated old code or significantly change code that was intended to be private.

    Existing Slack Client Architecture:

    Python Slack Client 1.0 Architecture

    Example App in v1:

    Here's a simple example app that replies "Hi <@userid>!" in a thread if you send it a message containing "Hello".

    from slackclient import SlackClient
    
    slack_token = os.environ["SLACK_API_TOKEN"]
    client = SlackClient(slack_token)
    
    def say_hello(data):
        if 'Hello' in data['text']:
            channel_id = data['channel']
            thread_ts = data['ts']
            user = data['user']
    
            client.api_call('chat.postMessage',
                channel=channel_id,
                text="Hi <@{}>!".format(user),
                thread_ts=thread_ts
            )
    
    if client.rtm_connect():
        while client.server.connected is True:
            for data in client.rtm_read():
                if "type" in data and data["type"] == "message":
                    say_hello(data)
    else:
        print "Connection Failed"
    

    Proposal

    Primary Changes

    1. Client Decomposition: Create two independent Slack clients. An HTTP client focused on Slack's Web API and a websocket client focused on Slack's RTM API.
    2. Removal of any pseudo caching layers. Developers should be given a migration guide on how to properly store information for their Slack app.
    3. Event-driven architecture: Whether you're using Slack's RTM API or Events API, the simplest and most efficient way to build apps and bots that respond to activities in Slack is to model your app as an event based system. The new RTMClient would allow you to simply link your application's callbacks to corresponding Slack events.

    v2 Slack Client Architecture

    Python Slack Client 2.0 Architecture

    Example App in v2:

    Here's that same simple example app that replies "Hi <@userid>!" in a thread if you send it a message containing "Hello".

    import slack
    
    slack_token = os.environ["SLACK_API_TOKEN"]
    rtmclient = slack.RTMClient(slack_token)
    
    def say_hello(data):
        if 'Hello' in data['text']:
            channel_id = data['channel']
            thread_ts = data['ts']
            user = data['user']
    
            webclient = slack.WebClient(slack_token)
            webclient.chat_postMessage(
                channel=channel_id,
                text="Hi <@{}>!".format(user),
                thread_ts=thread_ts
            )
    
    rtmclient.on(event='message', callback=say_hello)
    rtmclient.start()
    

    Additional Features and enhancements

    WebClient

    • By default we now use requests.Sessions. This takes advantage of built-in connection-pooling which improves the performance of web requests by reusing an established TCP connection.
    • SlackAPIMixin: Built-in support for all Slack API methods.
      • Docstrings: Getting Slack API information in your editor increases developer productivity.
      • xoxb vs xoxp: We validate the token used is supported for that method. This solves issues like #326.
    • JSON support: By default and where applicable leverage the requests library's json feature. This ensures all data sent will be automatically properly encoded. This solves issues like #337.
    • Requests return a SlackResponse object. This is an iterable container. It allows users to access the response data like a normal dict. It also allows us to easily build pagination support for any responses that contain the next_cursor attribute. See #343.
    • It’s completely decoupled from RTMClient so it can be imported independently without the bloat.

    RTMClient

    • The event-driven architecture of this new client removes complexity from existing apps. No more manual looping! - This was heavily inspired by the open-source Ruby Slack SDK by Daniel Doubrovkine.
      • This also encourages developers to build their apps in a way that’s easily portable to the Slack Events API.
    • Short lived internal Web Client. We locally create a WebClient in RTM to retrieve the websocket url, but then quickly dispose of it. This encourages developers to rely on the RTMClient only to receive events from Slack.

    Issues resolved

    Unresolved discussions:

    • Decorators: Decorators in Python enable developers to modify the behavior of a function or class. It's possible to use a class decorator on the RTMClient to store callbacks. This could in theory simplify the code. However, storing event-based callbacks on the class would mean every instance every created of an RTMClient would be impacted. This could lead to erroneous behaviors that are hard to triage because the state of the class could be modified in another function.

    Detailed design

    slack.WebClient

    A WebClient allows apps to communicate with the Slack Platform's Web API. The Slack Web API is an interface for querying information from and enacting change in a Slack workspace. This client handles constructing and sending HTTP requests to Slack as well as parsing any responses received into a SlackResponse.

    Attributes:

    • #token (str): A string specifying an xoxp or xoxb token.
    • #use_session (bool): An boolean specifying if the client should take advantage of urllib3's connection pooling. Default is True.
    • #base_url (str): A string representing the Slack API base URL. Default is https://www.slack.com/api/
    • #proxies (dict): If you need to use a proxy, you can pass a dict of proxy configs. e.g. {'https': "https://127.0.0.1:8080"} Default is None.
    • #timeout (int): The maximum number of seconds the client will wait to connect and receive a response from Slack. Default is 30 seconds.

    Methods:

    • #api_call(): Constructs a request and executes the API call to Slack.

    Recommended usage:

    import slack
    
    client = slack.WebClient(token=os.environ['SLACK_API_TOKEN'])
    response = client.chat_postMessage(
        channel='#random',
        text="Hello world!")
    assert response["ok"]
    assert response["message"]["text"] == "Hello world!"
    

    Example manually creating an API request: (Mostly for backwards compatibility)

    import slack
    
    client = slack.WebClient(token=os.environ['SLACK_API_TOKEN'])
    response = client.api_call(
        api_method='chat.postMessage',
        json={'channel': '#random', 'text': "Hello world!"}
    )
    assert response["ok"]
    assert response["message"]["text"] == "Hello world!"
    

    Note:

    • All Slack API methods are available thanks to the SlackAPIMixin class. By using the methods provided you allow the client to handle the heavy lifting of constructing the requests as it is expected. This mixin also serves users as a reference to Slack's API.
    • Any attributes or methods prefixed with _underscores are intended to be "private" internal use only. They may be changed or removed at anytime.

    slack.web.SlackResponse

    An iterable container of response data.

    Attributes:

    • #data (dict): The json-encoded content of the response. Along with the headers and status code information.

    Methods:

    • #validate(): Check if the response from Slack was successful.
    • #get(): Retrieves any key from the response data.
    • #next(): Retrieves the next portion of results, if 'next_cursor' is present.

    Example:

    import slack
    
    client = slack.WebClient(token=os.environ['SLACK_API_TOKEN'])
    
    response1 = client.auth_revoke(test='true')
    assert not response1['revoked']
    
    response2 = client.auth_test()
    assert response2.get('ok', False)
    
    users = []
    for page in client.users_list(limit=2):
        users = users + page['members']
    

    Note:

    • Some responses return collections of information like channel and user lists. If they do it's likely that you'll only receive a portion of results. This object allows you to iterate over the response which makes subsequent API requests until your code hits 'break' or there are no more results to be found.
    • Any attributes or methods prefixed with _underscores are intended to be "private" internal use only. They may be changed or removed at anytime.

    slack.RTMClient

    An RTMClient allows apps to communicate with the Slack Platform's RTM API. The event-driven architecture of this client allows you to simply link callbacks to their corresponding events. When an event occurs this client executes your callback while passing along any information it receives.

    Attributes:

    • #token (str): A string specifying an xoxp or xoxb token.
    • #connect_method (str): An string specifying if the client will connect with rtm.connect or rtm.start. Default is rtm.connect.
    • #auto_reconnect (bool): When true the client will automatically reconnect when (not manually) disconnected. Default is True.
    • #ping_interval (int): automatically send "ping" command every specified period of seconds. If set to 0, do not send automatically. Default is 30.
    • #ping_timeout (int): The amount of seconds the ping should timeout. If the pong message is not received. Default is 10.
    • #proxies (dict): If you need to use a proxy, you can pass a dict of proxy configs. e.g. {'https': "https://user:[email protected]:8080"} Default is None.
    • #base_url (str): A string representing the Slack API base URL. Default is https://www.slack.com/api/

    Methods:

    • #ping(): Sends a ping message over the websocket to Slack.
    • #typing(): Sends a typing indicator to the specified channel.
    • #on(): Stores and links callbacks to websocket and Slack events.
    • #start(): Starts an RTM Session with Slack.
    • #stop(): Closes the websocket connection and ensures it won't reconnect.

    Example:

    import slack
    
    slack_token = os.environ["SLACK_API_TOKEN"]
    rtmclient = slack.RTMClient(slack_token)
    
    def say_hello(data):
        if 'Hello' in data['text']:
            channel_id = data['channel']
            thread_ts = data['ts']
            user = data['user']
    
            webclient = slack.WebClient(slack_token)
            webclient.api_call('chat.postMessage',
                channel=channel_id,
                text="Hi <@{}>!".format(user),
                thread_ts=thread_ts
            )
    
    rtmclient.on(event='message', callback=say_hello)
    rtmclient.start()
    

    Note:

    • The initial state returned when establishing an RTM connection will be available as the payload to the open event. This data is not and will not be stored on the RTM Client.
    • Any attributes or methods prefixed with _underscores are intended to be "private" internal use only. They may be changed or removed at anytime.

    Migrating to 2.x

    Import changes: The goal of this project is to provide a set of tools that ease the creation of Python Slack apps. To better align with this goal we’re renaming the main module to slack. From slack developers can import various tools.

    # Before:
    # import slackclient
    
    # After:
    from slack import WebClient
    

    RTM Client API Changes:

    The RTM client has been completely redesigned please refer above for the new API.

    We no longer store any team data.: In the current 1.x version of the client we store some channel and user information internally on Server.py in client. This data will now be available in the open event for consumption. Developers are then free to store any information they choose. Here's an example:

    # Retrieving the team domain.
    # Before:
    # team_domain = client.server.login_data["team"]["domain"]
    
    # After:
    def get_team_data(data):
        team_domain = data['team']['domain']
    rtm_client.on(event='open', callback=get_team_data)
    

    Web Client API Changes:

    Token refresh removed: This feature originally shipped as a part of Workspace Tokens. Since we're heading in a new direction it's safe to remove this, along with any related attributes stored on the client.

    • ~refresh_token~
    • ~token_update_callback~
    • ~client_id~
    • ~client_secret~

    #api_call():

    • timeout param has been removed. Timeout is passed at the client level now.
    • kwargs param has been removed. You must specify where the data you pass belongs in the request. e.g. 'data' vs 'params' vs 'files'...etc
    # Before:
    # from slackclient import SlackClient
    #
    # client = SlackClient(os.environ["SLACK_API_TOKEN"])
    # client.api_call('chat.postMessage',
    #     timeout=30,
    #     channel='C0123456',
    #     text="Hi!")
    
    # After:
    import slack
    
    client = slack.WebClient(os.environ["SLACK_API_TOKEN"], timeout=30)
    client.api_call('chat.postMessage', json={
        'channel': 'C0123456',
        'text': 'Hi!'})
    
    # Note: The SlackAPIMixin allows you to write it like this.
    client.chat_postMessage(
        channel='C0123456',
        text='Hi!')
    

    SlackAPIMixin: The Slack API mixin provides built-in methods for Slack's Web API. These methods act as helpers enabling you to focus less on how the request is constructed. Here are a few things that this mixin provides:

    • Basic information about each method through the docstring.
    • Easy File Uploads: You can now pass in the location of a file and the library will handle opening and retrieving the file object to be transmitted.
    • Token type validation: This gives you better error messaging when you're attempting to consume an api method that your token doesn't have access to.
    • Constructs requests using Slack's preferred HTTP methods and content-types.

    Costs and Tradeoffs

    Separating Web from RTM:

    • Slack apps built using the Events API and Web API do not need RTM. So we’re separating the Web HTTP Client from the RTM Websocket Client so that you only have to import the parts that your app needs.
      • This change requires all apps built on top of RTM to create their own instance of the WebClient.

    WebClient SlackAPIMixin:

    • Maintenance:
      • Until this is automated 130+ methods (including their docstrings) need to be kept up-to-date manually.
    • Developer Interface: In order to mirror Slack’s API with . separated methods we’d have to implement nested classes for each method family. However valuing maintainability we’ve opted to use a partial snake_case naming convention replacing every . with an _.
      • We’ve deviated from Slack’s API which could add cognitive load when building apps.

    RTMClient redesign:

    • Event-driven architecture: Most basic Slack apps are essentially a collection of functions that are called when an event occurs. By developing your app with an event-driven architecture the components of your app can be loosely coupled and easier to maintain.
      • With increasingly complex functions your app can become exponentially slower. Implementing some sort of threading/concurrency is an inevitability.
    • Data Store Removed: Data was originally being stored on Server.py as a convenience for apps to reuse the initial state without having to query for additional data. The challenge with this approach is that this data can become stale/inaccurate very quickly depending on the team. We also didn't store all of the information available.
      • No longer storing any data requires all apps to implement a mechanism to cache the initial RTM payload.

    Rejected Alternatives

    Do Nothing

    If we avoid a redesign we’d still have to address existing bugs in v1. New features will be slower to add and first-time contributors would face an increasingly steep ramp-up period. Debugging will also remain difficult as the existing classes today are tightly coupled.

    Requirements

    opened by RodneyU215 24
  • Mostly type-hinted helper classes for inclusion in v2

    Mostly type-hinted helper classes for inclusion in v2

    Summary

    This is a direct copy-paste of the pseudo-library that wraps python-slackclient I use internally. The big advantage is obviously typed interactions - especially the newer stuff (ie, blockkit) has pretty solid type hinting throughout.

    I'm offering up this PR without any adjustments having been made - if it's something y'all are interested in, I could potentially spend some time making changes to better fit it into this library. Happy to review with anybody - I'm also in the dev4slack group semi-often if you want to reach me realtime.

    Requirements (place an x in each [ ])

    Version: 2x enhancement 
    opened by paul-griffith 21
  • Using the new channel parameter with a single str

    Using the new channel parameter with a single str

    I write a script to upload a file and in my call I get the message. But I can't find anything in the doc related to this message. In the examples there is not even client.files_upload_v2() which is recommended.

    /Users/spyros.m/Developer/Scripts/Python/audit_macos/venv/lib/python3.11/site-packages/slack_sdk/web/client.py:3032: UserWarning: Although the channels parameter is still supported for smooth migration from legacy files.upload, we recommend using the new channel parameter with a single str value instead for more clarity.

    How to solve this warning?

    question web-client Version: 3x 
    opened by GreekGreenGeek 1
  • Add support for admin_roles_{addAssignments|listAssignments|removeAssignments} methods

    Add support for admin_roles_{addAssignments|listAssignments|removeAssignments} methods

    Not sure if this is a bug or not. Slack API documentation lists methods with the admin_roles prefix that contain some pretty important functions that I need to be able to do via Python:

    https://api.slack.com/methods/admin.roles.addAssignments https://api.slack.com/methods/admin.roles.listAssignments https://api.slack.com/methods/admin.roles.removeAssignments

    However, looking at the slack-sdk code, I don't see any references to these methods even though the API documentation says they exist. Do they have yet to be implemented?

    enhancement 
    opened by csallen1204 1
  • Listening to events in slackClient v3 RTM CLIENT

    Listening to events in slackClient v3 RTM CLIENT

    Hi guys, I'm currently migrating my code from using slack client v1 to v3. A big change affecting me is migrating my code related rtm. In the new code I'll use RTMClient (imported from slack_sdk.rtm_v2), and use @rtmclient.on() I'm having trouble finding the relevant available events I can use. My main event is "message", but in the original code I have actions in various exceptions that I don't understand how they should be implemented with the new way of listening to events.

    Examples:

    KeyboardInterrupt, SlackConnectionError, WebSocketConnectionClosedException, socket.error and finally a general Exception.

    I found this as a list of events: https://api.slack.com/events?filter=RTM but could not find anything relating errors Any help will be great :) Thanks!!

    The Slack SDK version

    3.9.14

    Python runtime version

    3.7.3

    question auto-triage-stale 
    opened by YaelMagrafta 6
  • Implement auto_acknowledge feature for socket clients.

    Implement auto_acknowledge feature for socket clients.

    Summary

    The goal is to allow the Socket Mode Client to automatically send the acknowledgment notification to reduce the likelihood that a message could expire while waiting in the event queue.

    The default is currently False to prevent any backwards compatibility issues.

    fixes: https://github.com/slackapi/python-slack-sdk/issues/1299

    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)
    • [x] slack_sdk.socket_mode (Socket Mode client)
    • [ ] slack_sdk.signature (Request Signature Verifier)
    • [ ] slack_sdk.oauth (OAuth Flow Utilities)
    • [ ] slack_sdk.models (UI component builders)
    • [ ] slack_sdk.scim (SCIM API client)
    • [ ] slack_sdk.audit_logs (Audit Logs API client)
    • [ ] slack_sdk.rtm_v2 (RTM client)
    • [ ] /docs-src (Documents, have you run ./scripts/docs.sh?)
    • [x] /docs-src-v2 (Documents, have you run ./scripts/docs-v2.sh?)
    • [ ] /tutorial (PythOnBoardingBot tutorial)
    • [ ] tests/integration_tests (Automated tests for this library)

    Requirements (place an x in each [ ])

    • [x] I've read and understood the Contributing Guidelines and have done my best effort to follow them.
    • [x] I've read and agree to the Code of Conduct.
    • [x] I've run python3 -m venv .venv && source .venv/bin/activate && ./scripts/run_validation.sh after making the changes.
    enhancement Version: 3x socket-mode 
    opened by amshamah419 2
  • Add param to enable

    Add param to enable "Auto-Acknowledgment" of Events to the SocketModeClient

    One issue we have noticed in our deployment of a Slack app is that when there are a burst of messages being received, the built-in queue can become too large and can cause messages to expire within the 3-5 second acknowledgment period.

    For example, our app receives 200 messages within a 5 second window. They are then received and queued for the message listeners to process. If the queue gets too large, it may take longer than 3-5 seconds for a listener to dequeue and process a message. This results in the app being restricted and unable to receive new messages. This can get exponentially worse when the burst is followed up by a burst of retry messages as well.

    Reproducible in:

    The Slack SDK version

    slack-sdk==3.19.2

    Python runtime version

    Python 3.10.5

    OS info

    ProductName: macOS ProductVersion: 11.5.2 BuildVersion: 20G95 Darwin Kernel Version 20.6.0: Wed Jun 23 00:26:31 PDT 2021; root:xnu-7195.141.2~5/RELEASE_X86_64

    Steps to reproduce:

    (Share the commands to run, source code, and project settings (e.g., setup.py))

    1. Setup async socket client
    2. Append one listener
    3. Receive burst of events

    Expected result:

    So the thought was to set a parameter which would allow messages to be auto-acknowledged as they enter the queue. This would allow the listeners to handle the events irrespective of their processing time.

    It could work something like this:

        async def enqueue_message(self, message: str):
            await self.message_queue.put(message)
            if self.auto_acknowledge_messages:
                await self.auto_acknowledge_message(raw_message=message)
            if self.logger.level <= logging.DEBUG:
                queue_size = self.message_queue.qsize()
                session_id = await self.session_id()
                self.logger.debug(f"A new message enqueued (current queue size: {queue_size}, session: {session_id})")
                
        async def auto_acknowledge_message(self, raw_message):
            if raw_message.startswith("{"):
                message = json.loads(raw_message)
                if message.envelope_id:
                    response = SocketModeResponse(envelope_id=message.envelope_id)
                    await self.send_socket_mode_response(response)
    

    Actual result:

    Socket connection is closed due to missing too many acknowledgements.

    Requirements

    For general questions/issues about Slack API platform or its server-side, could you submit questions at https://my.slack.com/help/requests/new instead. :bow:

    Please read the Contributing guidelines and Code of Conduct before creating this issue or pull request. By submitting, you are agreeing to those rules.

    enhancement discussion Version: 3x socket-mode 
    opened by amshamah419 1
  • SlackApiError cannot be unpickled

    SlackApiError cannot be unpickled

    SlackApiError raises an error when trying to unpickle it.

    This is particularly annoying in a Celery task since another bug in celery will cause the whole worker node to fail.

    The Slack SDK version

    2.9.4

    Python runtime version

    3.11.0

    OS info

    ProductName: macOS ProductVersion: 13.0 BuildVersion: 22A380 Darwin Kernel Version 22.1.0: Sun Oct 9 20:15:09 PDT 2022; root:xnu-8792.41.9~2/RELEASE_ARM64_T6000

    Steps to reproduce:

    import pickle
    from slack.errors import SlackApiError
    
    e = SlackApiError("Internal server error", "<response>")
    
    dumped = pickle.dumps(e)
    pickle.loads(dumped) 
    

    Expected result:

    No error.

    Actual result:

    Traceback (most recent call last):
      File "/private/tmp/pickle_exc/bug.py", line 7, in <module>
        pickle.loads(dumped)
    TypeError: SlackApiError.__init__() missing 1 required positional argument: 'response'
    

    Solution

    The SlackApiError could be implemented in such a way that the constructor accepts only the message, and the response defaults to None. Then the string representation can be delegated to __str__:

    class SlackApiError(Exception):
    
        def __init__(self, message, response=None):
            super().__init__(message)
            self.response = response
        
        def __str__(self):
            return f"{self.args[0]}\nThe server responded with: {self.response}"
    
    enhancement question web-client auto-triage-skip 
    opened by youtux 6
Releases(v3.19.5)
  • v3.19.5(Dec 2, 2022)

    Changes

    • #1303 Fix #1302 by updating the warning logs in WebClient to be consistent with Node SDK - Thanks @mar3mar3
    • #1307 Fix #1304 ssl_context is not passed from async web_client to aiohttp socket client - Thanks @seratch @giwrgos-skouras
    • #1308 Fix #1305 by fixing pagination with async for syntax - Thanks @seratch @WilliamYuhangLee

    • All issues/pull requests: https://github.com/slackapi/python-slack-sdk/milestone/75?closed=1
    • All changes: https://github.com/slackapi/python-slack-sdk/compare/v3.19.4...v3.19.5
    Source code(tar.gz)
    Source code(zip)
  • v3.19.4(Nov 17, 2022)

    Changes

    • #1301 Fix #1297 Building user_auth_blocks with slack_sdk.models class objects for chat.unfurl API call fails - Thanks @seratch @injust

    • All issues/pull requests: https://github.com/slackapi/python-slack-sdk/milestone/73?closed=1
    • All changes: https://github.com/slackapi/python-slack-sdk/compare/v3.19.3...v3.19.4
    Source code(tar.gz)
    Source code(zip)
  • v3.19.3(Nov 8, 2022)

    Changes

    • #1288 Add datetimepicker, url, email, number block elements - Thanks @WilliamBergamin
    • #1294 Fix #1292 files_upload_v2 does not work with io.BytesIO file parameters - Thanks @seratch
    • #1290 Update RTM API documents - Thanks @ryan-aldaz

    • All issues/pull requests: https://github.com/slackapi/python-slack-sdk/milestone/72?closed=1
    • All changes: https://github.com/slackapi/python-slack-sdk/compare/v3.19.2...v3.19.3
    Source code(tar.gz)
    Source code(zip)
  • v3.19.2(Oct 27, 2022)

    Changes

    • #1282 Add request_file_info arg to files_upload_v2 method - Thanks @seratch @eddyg
    • #1278 Improve clarity of 'content' error message for files_upload_v2 - Thanks @eddyg
    • #1283 Improve typing when using 'get' on an API response - Thanks @eddyg
    • #1284 Add Python 3.11 support - Thanks @seratch
    • #1281 Fix selected_option type hint - Thanks @taekop

    • All issues/pull requests: https://github.com/slackapi/python-slack-sdk/milestone/71?closed=1
    • All changes: https://github.com/slackapi/python-slack-sdk/compare/v3.19.1...v3.19.2
    Source code(tar.gz)
    Source code(zip)
  • v3.19.1(Oct 6, 2022)

    Changes

    • Improve WebClient#files_upload_v2() to use given filename as the default title value - Thanks @seratch @mattpr

    • All changes: https://github.com/slackapi/python-slack-sdk/compare/v3.19.0...v3.19.1
    Source code(tar.gz)
    Source code(zip)
  • v3.19.0(Oct 5, 2022)

    New Features

    files.upload v2 in WebClient / AsyncWebClient

    We've received many reports on the performance issue of the existing files.upload API (refer to #1191 #1165 for details). So, to cope with the problem, our platform team decided to unlock a new way to upload files to Slack via public APIs. To utilize the new approach, developers need to implement the following steps on their code side:

    1. Call WebClient#files_getUploadURLExternal() method to receive a URL to use for each file
    2. Perform an HTTP POST request to the URL you received in step 1 for each file
    3. Call WebClient#files_completeUploadExternal() method with the pairs of file ID and title to complete the whole process, plus share the files in a channel
    4. If you need the full metadata of the files, call WebClient#files_info() method for each file

    We do understand that writing the above code requires many lines of code. Also, the existing WebClient#files_upload() users have to take a certain amount of time for migration. To mitigate the pain, we've added a wrapper method named WebClient#files_upload_v2() on the SDK side.

    Also, in addition to the performance improvements, another good news is that 3rd party apps can now upload multiple files at a time!

    See the following code examples demonstrating how the wrapper method works:

    import os
    from slack_sdk import WebClient
    client = WebClient(token=os.environ["SLACK_BOT_TOKEN"])
    
    # Legacy way
    response = client.files_upload(
        file="./logo.png",
        title="New company logo",
        channels=["C12345"],
        initial_comment="Here is the latest version of our new company logo :wave:",
    )
    response.get("file")  # returns the full metadata of the uploaded file
    
    # New way - the same parameters works in most cases
    response = client.files_upload_v2(
        file="./logo.png",
        title="New company logo",
        # Note that channels still works but going with channel="C12345" is recommended
        # channels=["C111", "C222"] is no longer supported. In this case, an exception can be thrown 
        channels=["C12345"],
        initial_comment="Here is the latest version of our new company logo :wave:",
    )
    response.get("file")  # returns the full metadata of the uploaded file
    
    # New way with multiple files!
    response = client.files_upload_v2(
        file_uploads=[
            {
                "file": "./logo.png",
                "title": "New company logo",
            },
            {
                "content": "Minutes ....",
                "filename": "team-meeting-minutes-2022-03-01.md",
                "title": "Team meeting minutes (2022-03-01)",
            },
        ],
        channel="C12345",
        initial_comment="Here is the latest version of our new company logo :wave:",
    )
    response.get("files")  # returns the full metadata of all the uploaded files
    

    When migrating to the v2 method, please note that the new method requires both files:write and files:read scopes. If your existing apps have only files:write scope for uploading files, you need to add files:read to the scopes plus re-install the app to issue an updated token.

    Changes

    • #1272 Add files.upload v2 support, which resolves #1191 #1165 - Thanks @seratch

    • All issues/pull requests: https://github.com/slackapi/python-slack-sdk/milestone/64?closed=1
    • All changes: https://github.com/slackapi/python-slack-sdk/compare/v3.18.5...v3.19.0
    Source code(tar.gz)
    Source code(zip)
  • v3.18.5(Oct 4, 2022)

    Changes

    • #1271 Add more revert to #1269 - Thanks @seratch @yardensachs

    • All issues/pull requests: https://github.com/slackapi/python-slack-sdk/milestone/68?closed=1
    • All changes: https://github.com/slackapi/python-slack-sdk/compare/v3.18.4...v3.18.5
    Source code(tar.gz)
    Source code(zip)
  • v3.18.4(Sep 30, 2022)

    Changes

    • #1264 Fix retry_handlers type hint in AsyncBaseClient - Thanks @ronyb29
    • #1265 #1266 Add selected_time (timepicker) to ViewStateValue class - Thanks @rei-0
    • #1270 Add include_all_metadata to conversations.replies API arguments - Thanks @seratch
    • #1269 Adjust the logic added by #1246 - Thanks @seratch @eddyg

    • All issues/pull requests: https://github.com/slackapi/python-slack-sdk/milestone/67?closed=1
    • All changes: https://github.com/slackapi/python-slack-sdk/compare/v3.18.3...v3.18.4
    Source code(tar.gz)
    Source code(zip)
  • v3.18.3(Sep 6, 2022)

    Changes

    • #1262 Fix #1261 blocks/attachments as str for chat.* API calls should be clearly supported - Thanks @seratch

    • All issues/pull requests: https://github.com/slackapi/python-slack-sdk/milestone/66?closed=1
    • All changes: https://github.com/slackapi/python-slack-sdk/compare/v3.18.2...v3.18.3
    Source code(tar.gz)
    Source code(zip)
  • v3.18.2(Sep 1, 2022)

    Changes

    • #1259 Fix #1258 Tuple value for blocks argument does not work for Web API calls - Thanks @tommasobertoni
    • #1253 Minor update: max elements in ActionsBlock to 25 - Thanks @YSaxon
    • #1249 #1251 Add in timezone property for timepicker element - Thanks @hello-ashleyintech

    • All issues/pull requests: https://github.com/slackapi/python-slack-sdk/milestone/65?closed=1
    • All changes: https://github.com/slackapi/python-slack-sdk/compare/v3.18.1...v3.18.2
    Source code(tar.gz)
    Source code(zip)
  • v3.18.1(Jul 25, 2022)

    Changes

    • #1246 rtm_v2 api spins in infinite loop under gevent - Thanks @mattbillenstein

    Document Changes

    • #1244 #1245 Update aiohttp documentation sampleUpdate aiohttp documentation sample - Thanks @srajiang @DonDebonair

    • All issues/pull requests: https://github.com/slackapi/python-slack-sdk/milestone/63?closed=1
    • All changes: https://github.com/slackapi/python-slack-sdk/compare/v3.18.0...v3.18.1
    Source code(tar.gz)
    Source code(zip)
  • v3.18.0(Jul 19, 2022)

    Changes

    • #1237 Fix #1236 Add video block to Block Kit model classes - Thanks @seratch
    • #1241 Fix #1240 Update chat_unfurl to support source/unfurl_id parameters - Thanks @seratch @angrychimp
    • #1234 #1235 Fix many type hint errors - Thanks @ehdgua01

    • All issues/pull requests: https://github.com/slackapi/python-slack-sdk/milestone/54?closed=1
    • All changes: https://github.com/slackapi/python-slack-sdk/compare/v3.17.2...v3.18.0
    Source code(tar.gz)
    Source code(zip)
  • v3.17.2(Jun 22, 2022)

    Changes

    • #1232 Fix #1230 "unpack requires a buffer of 2 bytes" error when we have many options / option groups - Thanks @seratch @adamtheturtle

    • All issues/pull requests: https://github.com/slackapi/python-slack-sdk/milestone/61?closed=1
    • All changes: https://github.com/slackapi/python-slack-sdk/compare/v3.17.1...v3.17.2
    Source code(tar.gz)
    Source code(zip)
  • v3.17.1(Jun 14, 2022)

    Changes

    • #1221 Use 125 chars for max line length for both flake8 and black - Thanks @seratch
    • #1223 Improve the installation data queries to always return the latest bot token - Thanks @seratch
    • #1226 Upgrade pytype to the latest - Thanks @seratch
    • #1225 Update the maintainers guide - Thanks @WilliamBergamin

    • All issues/pull requests: https://github.com/slackapi/python-slack-sdk/milestone/60?closed=1
    • All changes: https://github.com/slackapi/python-slack-sdk/compare/v3.17.0...v3.17.1
    Source code(tar.gz)
    Source code(zip)
  • v3.17.0(May 27, 2022)

    Changes

    • #1213 Fix #1212 auth.teams.list API method is not supported in WebClient - Thanks @filmaj @prziborowski
    • #1215 Add more documentation around constructor parameters - Thanks @filmaj
    • #1219 Fix #1218 - Reduce minimum number of overflow options - Thanks @misscoded @wilhelmklopp

    • All issues/pull requests: https://github.com/slackapi/python-slack-sdk/milestone/53?closed=1
    • All changes: https://github.com/slackapi/python-slack-sdk/compare/v3.16.2...v3.17.0
    Source code(tar.gz)
    Source code(zip)
  • v3.16.2(May 18, 2022)

    Changes

    • #1210 Fix #1209 Add __all__ to __init__.py - Thanks @seratch @kezabelle

    • All issues/pull requests: https://github.com/slackapi/python-slack-sdk/milestone/58?closed=1
    • All changes: https://github.com/slackapi/python-slack-sdk/compare/v3.16.1...v3.16.2
    Source code(tar.gz)
    Source code(zip)
  • v3.16.1(May 10, 2022)

    Changes

    • #1208 Tweaking warnings related to missing accessibility fields text and fallback - Thanks @filmaj
    • Add new properties to Audit Logs API response classes - Thanks @seratch

    • All issues/pull requests: https://github.com/slackapi/python-slack-sdk/milestone/57?closed=1
    • All changes: https://github.com/slackapi/python-slack-sdk/compare/v3.16.0...v3.16.1
    Source code(tar.gz)
    Source code(zip)
  • v3.16.0(May 3, 2022)

    Changes

    • #1207 Add message metadata support - Thanks @seratch
    • #1195 Add domain to team.info API parameters - Thanks @seratch
    • #1206 Fix #1200 Model to_dict doesn't handle tuple sequences - Thanks @kezabelle @seratch

    • All issues/pull requests: https://github.com/slackapi/python-slack-sdk/milestone/56?closed=1
    • All changes: https://github.com/slackapi/python-slack-sdk/compare/v3.15.2...v3.16.0
    Source code(tar.gz)
    Source code(zip)
  • v2.9.4(Apr 22, 2022)

  • v3.15.2(Mar 3, 2022)

    Changes

    • #1187 Add file_ids to chat.update parameters - Thanks @seratch
    • #1187 Fix user_ids parameter bug in conversations.inviteShared API method - Thanks @seratch
    • Update Audit Logs API response - Thanks @seratch

    • All issues/pull requests: https://github.com/slackapi/python-slack-sdk/milestone/55?closed=1
    • All changes: https://github.com/slackapi/python-slack-sdk/compare/v3.15.1...v3.15.2
    Source code(tar.gz)
    Source code(zip)
  • v3.15.1(Feb 19, 2022)

    Changes

    • #1183 Fix #1178 text type hint in LinkButtonElement does not accept PlainTextObject/dict - Thanks @seratch
    • #1182 Fix #1181 Add exception handling for socket mode - socket.timeout: the read operation timed out - Thanks @seratch @tom0010
    • #1185 Fix #1184 Add exception handling for socket mode - BlockingIOError: Resource temporarily unavailable - Thanks @seratch @tom0010

    • All issues/pull requests: https://github.com/slackapi/python-slack-sdk/milestone/51?closed=1
    • All changes: https://github.com/slackapi/python-slack-sdk/compare/v3.15.0...v3.15.1
    Source code(tar.gz)
    Source code(zip)
  • v3.15.0(Feb 17, 2022)

    Changes


    • All issues/pull requests: https://github.com/slackapi/python-slack-sdk/milestone/50?closed=1
    • All changes: https://github.com/slackapi/python-slack-sdk/compare/v3.14.1...v3.15.0
    Source code(tar.gz)
    Source code(zip)
  • v3.14.1(Feb 8, 2022)

    Changes

    • #1173 Fix a bug where some of the files.remote API parameters do not work since v3.10 - Thanks @seratch

    • All issues/pull requests: https://github.com/slackapi/python-slack-sdk/milestone/52?closed=1
    • All changes: https://github.com/slackapi/python-slack-sdk/compare/v3.14.0...v3.14.1
    Source code(tar.gz)
    Source code(zip)
  • v3.14.0(Feb 7, 2022)

    Changes

    • #1172 #1169 The built-in SocketMode client fails to establish WS connections via proxy server - Thanks @seratch @Lordshinjo
    • #1161 Add admin.apps.requests.cancel API method support - Thanks @seratch
    • #1152 Stop raising asyncio.CancelledError if the connection is already closed - Thanks @seratch @vectoralpha
    • #1167 Add accessibility_label to button block element - Thanks @seratch
    • #1171 Fix #1170 Add TimePickerElement to BlockElement.parse - Thanks @iress-willygo

    Document Updates

    • #1163 #1160 Links in README don't render properly on PyPi project page - Thanks @seratch @misscoded

    • All issues/pull requests: https://github.com/slackapi/python-slack-sdk/milestone/49?closed=1
    • All changes: https://github.com/slackapi/python-slack-sdk/compare/v3.13.0...v3.14.0
    Source code(tar.gz)
    Source code(zip)
  • v3.13.0b1(Dec 15, 2021)

    What's Changed

    Add Support for Subscribe in Slack (apps.manifest.*) by @srajiang in #1151

    Subscribe in Slack

    This release includes support for apps.notifications.subscriptions.* endpoints and adds message metadata field to the chat.postMessage and chat.update arguments.

    apps.notifications.subscriptions.create apps.notifications.subscriptions.update apps.notifications.subscriptions.delete


    Full Changelog: v3.13.0...v3.130b1

    Source code(tar.gz)
    Source code(zip)
  • v3.13.0(Dec 10, 2021)

    Changes

    • #1140 Add focus_on_load support in Block Kit - Thanks @seratch
    • #1147 Add cursor parameter to Audit Logs API method - Thanks @seratch
    • #1143 #1148 Capitalized Retry-After header missing since 3.12.0 - Thanks @joekohlsdorf @seratch
    • #1141 Add GitHub stale action for better triaging issues - Thanks @srajiang @seratch
    • #1149 Upgrade black, flake8, and pytype - Thanks @seratch

    Document Updates

    • #1139 #1086 Add interactivity patterns in SocketModeClient document - Thanks @ruberVulpes

    • All issues/pull requests: https://github.com/slackapi/python-slack-sdk/milestone/46?closed=1
    • All changes: https://github.com/slackapi/python-slack-sdk/compare/v3.12.0...v3.13.0
    Source code(tar.gz)
    Source code(zip)
  • v3.12.0(Nov 24, 2021)

    Changes

    • #1129 Add Python 3.10 to the supported versions - Thanks @seratch
    • #1132 Add team.* & admin.users.session.resetBulk APIs - Thanks @seratch
    • #1127 #1135 Add more docstrings to slack_sdk.models classes - Thanks @seratch
    • #1134 Make the aiohttp-based SocketModeClient's debug logging more consistent with the built-in one (#1122) - Thanks @seratch
    • #1131 #1137 Add the method to check equality in Block Kit model classes - Thanks @kokko-san @uroboro
    • #1130 Audit Logs API: Add new details properties for channel_posting_permissions_updated action - Thanks @seratch
    • #1128 #1136 Enable pytype and fix detected issues - Thanks @seratch

    • All issues/pull requests: https://github.com/slackapi/python-slack-sdk/milestone/45?closed=1
    • All changes: https://github.com/slackapi/python-slack-sdk/compare/v3.11.2...v3.12.0
    Source code(tar.gz)
    Source code(zip)
  • v3.12.0b1(Oct 8, 2021)

    What's Changed

    • Add Support for App Manifest Endpoints (apps.manifest.*) by @misscoded in https://github.com/slackapi/python-slack-sdk/pull/1123

    App Manifests

    This release includes support for app manifests. The apps.manifest.* endpoints can be used to create, delete, update, and copy your Slack apps with ease. New endpoints include:

    Full Changelog: https://github.com/slackapi/python-slack-sdk/compare/v3.11.2...v3.12.0b1

    Source code(tar.gz)
    Source code(zip)
  • v3.11.2(Sep 21, 2021)

    Changes

    • #1120 Change a websockets import to make it compatible with older versions - Thanks @seratch

    • All issues/pull requests: https://github.com/slackapi/python-slack-sdk/milestone/48?closed=1
    • All changes: https://github.com/slackapi/python-slack-sdk/compare/v3.11.1...v3.11.2
    Source code(tar.gz)
    Source code(zip)
  • v3.11.1(Sep 18, 2021)

    Changes

    • #1117 asyncio-based Socket Mode client improvements - Thanks @seratch @matthieucan

    • All issues/pull requests: https://github.com/slackapi/python-slack-sdk/milestone/47?closed=1
    • All changes: https://github.com/slackapi/python-slack-sdk/compare/v3.11.0...v3.11.1
    Source code(tar.gz)
    Source code(zip)
Owner
SlackAPI
https://api.slack.com
SlackAPI
Autov2new - Pro Auto Filter Bot V2

Pro Auto Filter Bot V2 Deploy You can deploy this bot anywhere. Watch Deploying

1 Jan 06, 2022
Simple software that can send WhatsApp message to a single or multiple users (including unsaved number**)

wp-automation Info: this is a simple automation software that sends WhatsApp message to single or multiple users. Key feature: -Sends message to multi

3 Jan 31, 2022
Protection-UB - Simple Group Protection userbot running on python3 with ARQ

Protection-UB Simple Group Protection userbot running on python3 with ARQ ⚠️ Not

szsupunma 1 Feb 06, 2022
A Discord token grabber written in Python3, with awesome obfuscation and anti-debug protection.

☣️ Plague ☣️ Plague is a Discord token grabber written in Python3, obfuscated with Kramer, protected from traffic analysers with Scarecrow and using t

Billy 125 Dec 20, 2022
New developed moderation discord bot by archisha

Monitor42 New developed moderation discord bot by αrchιshα#5518. Details Prefix: 42! Commands: Moderation Use 42!help to get command list. Invite http

Kamilla Youver 0 Jun 29, 2022
Auto Liker, Auto Reaction, Auto Comment, Auto Follower Tool. RajeLiker Credit Hacker.

Auto Liker, Auto Reaction, Auto Comment, Auto Follower Tool. RajeLiker Credit Hacker. Unlimited RajeLiker Credit Hack. Thanks To RajeLiker.

Md. Mehedi Hasan 32 Dec 28, 2022
A simple test repo created following docker docs.

docker_sampleRepo A simple test repo created following docker docs. Link to docs: https://docs.docker.com/language/python/develop/ Other links: https:

Suraj Verma 2 Sep 16, 2022
Okaeri Robot: a modular bot running on python3 with anime theme and have a lot features

OKAERI ROBOT Okaeri Robot is a modular bot running on python3 with anime theme a

Dream Garden (rey) 2 Jan 19, 2022
Simple screen recorder

Kooha Simple screen recorder Description Kooha is a simple screen recorder built with GTK. It allows you to record your screen and also audio from you

Dave Patrick 1.2k Jan 03, 2023
A bot that is an updated & modified version of calvinnfernando's WebReg-Bot

WaitList-Bot A bot that is an updated & modified version of calvinnfernando's WebReg-Bot to automate getting into waitlisted classes in UCSD WebReg on

Issac In 1 Dec 01, 2022
Library written in Python that wraps Halo Infinite API.

haloinfinite Library written in Python that wraps Halo Infinite API. Before start It's unofficial, reverse-engineered, neither stable nor production r

Miguel Ferrer 4 Dec 28, 2022
Portal Backend for Yuta management

Portal Backend for Yuta management Prerequisites Python 3.10 or above. pip, pdm installed. Quickstart Install the required packages: pdm install Runn

Loc Mai 1 Dec 20, 2021
A collection of discord tools I've made.

Discord A collection of discord tools i've made. What's in here? Basically every discord related project i've worked on can be found here, i'll try an

?? ?? ?? 6 Nov 13, 2021
A Python script to create customised Spotify playlists using the JSON, Spotipy Library and Spotify Web API, based on seed tracks in your history.

A Python script to create customised Spotify playlists using the JSON, Spotipy Library and Spotify Web API, based on seed tracks in your history.

Youngseo Park 1 Feb 01, 2022
Simple tool to gather domains from crt.sh using the organization name

Domain Collector: _ _ ___ _ _ _ __| | ___ _ __ ___ __ _(_)_ __ / __\___ | |

Cyber Guy 63 Dec 24, 2022
Request based Python module(s) to help with the Newegg raffle.

Newegg Shuffle Python module(s) to help you with the Newegg raffle How to use $ git clone https://github.com/Matthew17-21/Newegg-Shuffle $ cd Newegg-S

Matthew 45 Dec 01, 2022
Simple Discord bot which logs several events in your server

logging-bot Simple Discord bot which logs several events in your server, including: Message Edits Message Deletes Role Adds Role Removes Member joins

1 Feb 14, 2022
😈 Discord RAGE is a Python tool that allows you to automatically spam messages in Discord

😈 Discord RAGE Python tool that allows you to automatically spam messages in Discord 🏹 Setup Make sure you have Python installed and PIP is added to

Alphalius 4 Jun 12, 2022
A simple Telegram bot which handles images in whole different way

zeroimagebot thezeroimagebot 🌟 I Can Edit Dimension Of An image which is required by @stickers 🌟 I Can Extract Text From An Image 🌟 !!! New Updates

RAVEEN KUMAR 4 Jul 01, 2021
AirDrive lets you store unlimited files to cloud for free. Upload & download files from your personal drive at any time using its super-fast API.

AirDrive lets you store unlimited files to cloud for free. Upload & download files from your personal drive at any time using its super-fast API.

Sougata 4 Jul 12, 2022