A Python framework to build Slack apps in a flash with the latest platform features.

Overview

Bolt Bolt logo for Python

Python Version pypi package Build Status Codecov

A Python framework to build Slack apps in a flash with the latest platform features. Read the getting started guide and look at our code examples to learn how to build apps using Bolt. The Python module documents are available here.

Setup

# Python 3.6+ required
python -m venv .venv
source .venv/bin/activate

pip install -U pip
pip install slack_bolt

Creating an app

Create a Bolt for Python app by calling a constructor, which is a top-level export. If you'd prefer, you can create an async app.

import logging
logging.basicConfig(level=logging.DEBUG)

from slack_bolt import App

# export SLACK_SIGNING_SECRET=***
# export SLACK_BOT_TOKEN=xoxb-***
app = App()

# Add functionality here

if __name__ == "__main__":
    app.start(3000)  # POST http://localhost:3000/slack/events

Running an app

export SLACK_SIGNING_SECRET=***
export SLACK_BOT_TOKEN=xoxb-***
python app.py

# in another terminal
ngrok http 3000

Running a Socket Mode app

If you use Socket Mode for running your app, SocketModeHandler is available for it.

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

# Install the Slack app and get xoxb- token in advance
app = App(token=os.environ["SLACK_BOT_TOKEN"])

# Add functionality here

if __name__ == "__main__":
    # Create an app-level token with connections:write scope
    handler = SocketModeHandler(app, os.environ["SLACK_APP_TOKEN"])
    handler.start()

Run the app this way:

export SLACK_APP_TOKEN=xapp-***
export SLACK_BOT_TOKEN=xoxb-***
python app.py

# SLACK_SIGNING_SECRET is not required
# Running ngrok is not required

Listening for events

Apps typically react to a collection of incoming events, which can correspond to Events API events, actions, shortcuts, slash commands or options requests. For each type of request, there's a method to build a listener function.

# Listen for an event from the Events API
app.event(event_type)(fn)

# Convenience method to listen to only `message` events using a string or re.Pattern
app.message([pattern ,])(fn)

# Listen for an action from a Block Kit element (buttons, select menus, date pickers, etc)
app.action(action_id)(fn)

# Listen for dialog submissions
app.action({"callback_id": callbackId})(fn)

# Listen for a global or message shortcuts
app.shortcut(callback_id)(fn)

# Listen for slash commands
app.command(command_name)(fn)

# Listen for view_submission modal events
app.view(callback_id)(fn)

# Listen for options requests (from select menus with an external data source)
app.options(action_id)(fn)

The recommended way to use these methods are decorators:

@app.event(event_type)
def handle_event(event):
    pass

Making things happen

Most of the app's functionality will be inside listener functions (the fn parameters above). These functions are called with a set of arguments, each of which can be used in any order. If you'd like to access arguments off of a single object, you can use args, an slack_bolt.kwargs_injection.Args instance that contains all available arguments for that event.

Argument Description
body Dictionary that contains the entire body of the request (superset of payload). Some accessory data is only available outside of the payload (such as trigger_id and authorizations).
payload Contents of the incoming event. The payload structure depends on the listener. For example, for an Events API event, payload will be the event type structure. For a block action, it will be the action from within the actions list. The payload dictionary is also accessible via the alias corresponding to the listener (message, event, action, shortcut, view, command, or options). For example, if you were building a message() listener, you could use the payload and message arguments interchangably. An easy way to understand what's in a payload is to log it.
context Event context. This dictionary contains data about the event and app, such as the botId. Middleware can add additional context before the event is passed to listeners.
ack Function that must be called to acknowledge that your app received the incoming event. ack exists for all actions, shortcuts, view submissions, slash command and options requests. ack returns a promise that resolves when complete. Read more in Acknowledging events.
respond Utility function that responds to incoming events if it contains a response_url (shortcuts, actions, and slash commands).
say Utility function to send a message to the channel associated with the incoming event. This argument is only available when the listener is triggered for events that contain a channel_id (the most common being message events). say accepts simple strings (for plain-text messages) and dictionaries (for messages containing blocks).
client Web API client that uses the token associated with the event. For single-workspace installations, the token is provided to the constructor. For multi-workspace installations, the token is returned by using the OAuth library, or manually using the authorize function.
logger The built-in logging.Logger instance you can use in middleware/listeners.

Creating an async app

If you'd prefer to build your app with asyncio, you can import the AIOHTTP library and call the AsyncApp constructor. Within async apps, you can use the async/await pattern.

# Python 3.6+ required
python -m venv .venv
source .venv/bin/activate

pip install -U pip
# aiohttp is required
pip install slack_bolt aiohttp

In async apps, all middleware/listeners must be async functions. When calling utility methods (like ack and say) within these functions, it's required to use the await keyword.

!") if __name__ == "__main__": app.start(3000) ">
# Import the async app instead of the regular one
from slack_bolt.async_app import AsyncApp

app = AsyncApp()

@app.event("app_mention")
async def event_test(body, say, logger):
    logger.info(body)
    await say("What's up?")

@app.command("/hello-bolt-python")
async def command(ack, body, respond):
    await ack()
    await respond(f"Hi <@{body['user_id']}>!")

if __name__ == "__main__":
    app.start(3000)

If you want to use another async Web framework (e.g., Sanic, FastAPI, Starlette), take a look at the built-in adapters and their examples.

Getting Help

The documentation has more information on basic and advanced concepts for Bolt for Python. Also, all the Python module documents of this library are available here.

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

  • Issue Tracker for questions, bug reports, feature requests, and general discussion related to Bolt for Python. Try searching for an existing issue before creating a new one.
  • Email our developer support team: [email protected]
Comments
  • Cannot listen to the messages posted by users who hasn't installed the app

    Cannot listen to the messages posted by users who hasn't installed the app

    Hello! I am developing a slack app with python, which should work on user behalf. The event listener should retrieve all the messages, from the workspace's channels and direct messages that the user, who installed the app, has access to. To achieve that goal I am using Events API with Oauth authorization and user scopes.

    Reproducible in:

    The slack_bolt version

    slack-bolt==1.14.3 slack-sdk==3.18.3 slackeventsapi==3.0.1

    Python runtime version

    Python 3.8.10

    Steps to reproduce:

    1. Here is my Oauth settings and App setup.
    oauth_settings = OAuthSettings(
        client_id=os.environ["SLACK_CLIENT_ID"],
        client_secret=os.environ["SLACK_CLIENT_SECRET"],
        user_scopes=user_scopes,
        installation_store=FileInstallationStore(base_dir="./data/installations"),
        state_store=FileOAuthStateStore(expiration_seconds=600, base_dir="./data/states")
    )
    
    app = App(signing_secret=os.environ["SLACK_SIGNING_SECRET"], oauth_settings=oauth_settings)
    
    api = FastAPI()
    app_handler = SlackRequestHandler(app)
    
    1. You can see that I am using FastAPI to handle the requests. Here is the FastAPI setup.
    @api.get("/slack/oauth_redirect")
    async def oauth_redirect(req: Request):
        await app_handler.handle(req)
        return logging.info('Installation completed.')
    
    
    @api.get("/slack/install")
    async def install(req: Request):
        return await app_handler.handle(req)
    
    
    @api.post("/slack/events")
    async def endpoint(req: Request):
        return await app_handler.handle(req)
    
    1. And this is the example test event listener function, that should just print out in the console the payload of the message.
    @app.event('message')
    def listener(payload, client):
        print(payload)
    

    Expected result:

    I am expecting to see every message's payload in the console posted in all the channels and direct messages, where the user is added (in this stage I am the user who installed the app to the workspace, also I am the admin of the workspace where the app is installed to).

    Actual result:

    Every time that the message is posted by a user, who hasn't installed the app, I am getting this message in my console: Screenshot from 2022-09-23 14-45-53

    Thanks in advance!

    question 
    opened by johngrigoryan 27
  • slack is posting two/three messages with chat_postMessage

    slack is posting two/three messages with chat_postMessage

    Description

    Describe your issue here. I am using slack-bolt python framework for my slack bolt which is going through some logic. I am using chat_postMessage method to send a message from bot. But currently it is sending three messages even though it's having single API call. I read about it and notices that it can be avoided with making X-Slack-Retry-Num =1 in header.(https://api.slack.com/apis/connections/events-api#graceful_retries) But i am wondering how can i change the header of the api call in res_out = app.client.chat_postMessage(channel=message['channel'],thread_ts = original_thread_id,blocks=block_final)

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

    • [ ] bug
    • [ ] enhancement (feature request)
    • [ ] question
    • [ ] documentation related
    • [x] example code 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:

    package version:

    node version:

    OS version(s):

    Steps to reproduce:

    1. use res_out = app.client.chat_postMessage(channel=message['channel'],thread_ts = original_thread_id,blocks=block_final) in the bot's code and due to retry mechanism it tries and sends the same message thrice on single call.

    Expected result:

    Bot should only post single message.

    Actual result:

    Bot is posting two/three same messages

    Attachments:

    question 
    opened by kunalrc2022 16
  • Socket mode say() sends some of the data to another user

    Socket mode say() sends some of the data to another user

    When someone else then me writing to the slack bot, some of the response is sent to me the bot creator instead of them.

    Why is that happening? I have no ability to control the user to send the data in say(). Could it be some memory leak across threads?

    question need info 
    opened by nitz-iron 14
  • Make cookies extraction on AWS Lambda compatible with its format v1.0

    Make cookies extraction on AWS Lambda compatible with its format v1.0

    I tried to deploy a slack bolt application on AWS Lambda with SQLAlchemy. In the process of the verification of oauth redirect, the app could not be installed properly. I found that the slack request handler could not extract cookie from the lambda event. So, I modified the to_bolt_request to meet the format of the lambda event.

    enhancement area:adapter 
    opened by tattee 14
  • Re: External Data Selection in Select Menu

    Re: External Data Selection in Select Menu

    I posted an issue: https://github.com/slackapi/bolt-python/issues/336 where I'm unable to access external data from different blocks within the same form.

    Is there a workaround to this? I think there must be some way to use the action block (we're able to access the input data from the first block here) to somehow update the view with a list of options for the next block? A solution similar to this is mentioned here but some input here would be helpful.

    Thank you!

    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.

    question 
    opened by mariebarrramsey 14
  • Shortcut modal does not close after submit

    Shortcut modal does not close after submit

    Hi,

    I developed a shortcut but after submitting by submit button, the modal is not closed.

    After the submit, several validations are carried out and a message is sent to the user, but I want the modal to be closed and these processes to be in the background, as it consumes a lot of time and there is no need for the user to wait.

    In the documentation it asks to be done this way:

    # Handle a view_submission request
    @app.view("view_1")
    def handle_submission(ack, body, client, view, logger):
        # Assume there's an input block with `input_c` as the block_id and `dreamy_input`
        hopes_and_dreams = view["state"]["values"]["input_c"]["dreamy_input"]
        user = body["user"]["id"]
        # Validate the inputs
        errors = {}
        if hopes_and_dreams is not None and len(hopes_and_dreams) <= 5:
            errors["input_c"] = "The value must be longer than 5 characters"
        if len(errors) > 0:
            ack(response_action="errors", errors=errors)
            return
        # Acknowledge the view_submission request and close the modal
        ack()
        # Do whatever you want with the input data - here we're saving it to a DB
        # then sending the user a verification of their submission
    
        # Message to send user
        msg = ""
        try:
            # Save to DB
            msg = f"Your submission of {hopes_and_dreams} was successful"
        except Exception as e:
            # Handle error
            msg = "There was an error with your submission"
    
        # Message the user
        try:
            client.chat_postMessage(channel=user, text=msg)
        except e:
            logger.exception(f"Failed to post a message {e}")
    

    I did it this way:

    @app.view("aws_access_request")
        def handle_view_events(ack, body, client, view):
            # Assume there's an input block with `input_c` as the block_id and `dreamy_input`
            awsname = view["state"]["values"]["input_aws_select"]["aws_access_select"]["selected_option"]["value"]
            awsrole = view["state"]["values"]["input_aws_role_select"]["aws_access_role_select"]["selected_option"]["value"]
            managermail = view["state"]["values"]["input_aws_access_manager"]["aws_access_manager"]["value"]
            squad = view["state"]["values"]["input_aws_access_squad"]["aws_access_squad"]["value"]
            reason = view["state"]["values"]["input_aws_access_reason"]["aws_access_reason"]["value"]
    
            senderid = body["user"]["id"]
            senderobj = client.users_profile_get(user=senderid)
            sendermail = senderobj["profile"]["email"]
            sendermention = f"<@{senderid}>"
            sendername = senderobj["profile"]["display_name"]
    
            # Validate inputs
            errors = {}
            mincaracter = 25
    
            inputs = {...}
    
            if reason is not None and len(reason) <= mincaracter:
                errors["input_aws_access_reason"] = f"The value must be longer than {mincaracter} characters"
            elif awsname == "nothing":
                errors["input_aws_select"] = "Please select valid option"
    
            if len(errors) > 0:
                ack(response_action="errors", errors=errors)
                return
    
            # Acknowledge the view_submission request and close the modal
            ack()
    
            checkinputname = Ot.check_inputs(inputs, INPUT_AWS_NAME)
            checkinputmanager = Ot.check_inputs(inputs, INPUT_MANAGER_MAIL)
    
            # Caso o usuário não tenha informado corretamente o Acesso/Gestor, não envia a solicitação
            if not checkinputname or not checkinputmanager:...
            else...
    

    After ack() "Acknowledge the view_submission request and close the modal" It is not closing the modal and continues running the code below.

    The problem is that the code below ack() takes about 10 seconds to run, so this error appears: image

    As I said, I wanted the form to close immediately after ack() and not wait for all the code to run to close.

    question need info 
    opened by BSouzaDock 13
  • Questions on how to run a bolt-python app on AWS Lambda

    Questions on how to run a bolt-python app on AWS Lambda

    (Describe your issue and goal here)

    Using FastAPI with bolt-python

    Question 1.

    1. Within app.message("xxx") listener, I am sending 3 API requests to receive some status
    2. Using the responses, I am sending combined summary into slack channel with Say().

    image

    1. For ReadTimeOut Error Exception, it sends error message fine
    2. But When other exceptions (e.g) TypeError) is catched, say() function spits below exception message Traceback (most recent call last): File "/opt/anaconda3/envs/slack-lambda-api/lib/python3.9/site-packages/slack_bolt/listener/asyncio_runner.py", line 67, in run returned_value = await listener.run_ack_function( File "/opt/anaconda3/envs/slack-lambda-api/lib/python3.9/site-packages/slack_bolt/listener/async_listener.py", line 120, in run_ack_function return await self.ack_function( File "/Users/xxx/Workspace/slack-lambda-api/app/slack/handler/messages.py", line 40, in message_status await say( TypeError: __call__() got multiple values for argument 'text'
    • Above Exception was catched on my local environment where I deliberately turned off API Server

    Question2 (perhaps related to above error).

    1. In production, I am deploying bolt-python in AWS Lambda
    2. I am trying to use lazy listener to bypass 3 seconds limit on slack api, I moved above listener logic to lazy parameter then used respond_to_slack_within_3_seconds() to ack() as written in documentation. (as below)

    image image image

    1. When I test in local above seems to work fine, but when deployed to AWS Lambda (using Mangum handler), it gives following errors ( same error as Question 1) image

    Thank you in advance!!

    The slack_bolt version

    slack-bolt==1.11.1 slack-sdk==3.13.0

    Python runtime version

    Python 3.9.7

    OS info

    ProductName: macOS ProductVersion: 12.0.1 BuildVersion: 21A559 Darwin Kernel Version 21.1.0: Wed Oct 13 17:33:24 PDT 2021; root:xnu-8019.41.5~1/RELEASE_ARM64_T8101

    Expected result:

    • Regarding Question 1, it should send message instead of exception
    • Regarding Question 2, lazy function should be executed followed by ack function but only ack is run in AWS Lambda

    Actual result:

    (Included in descriptions)

    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.

    question area:async 
    opened by imageschool 12
  • Django Bolt Python Example Doesn't Run w/o Oauth_Flow Object

    Django Bolt Python Example Doesn't Run w/o Oauth_Flow Object

    I believe the Django examples for the oauth flow are incomplete. Currently, when running the app, it returns a page "Not Found", which seems to be because the Bolt Python app is initialized without self.app.oauth_flow, which per the code below returns a 404.

    def handle(self, req: HttpRequest) -> HttpResponse:
        if req.method == "GET":
            if self.app.oauth_flow is not None:
                oauth_flow: OAuthFlow = self.app.oauth_flow
                if req.path == oauth_flow.install_path:
                    bolt_resp = oauth_flow.handle_installation(to_bolt_request(req))
                    return to_django_response(bolt_resp)
                elif req.path == oauth_flow.redirect_uri_path:
                    bolt_resp = oauth_flow.handle_callback(to_bolt_request(req))
                    return to_django_response(bolt_resp)
        elif req.method == "POST":
            bolt_resp: BoltResponse = self.app.dispatch(to_bolt_request(req))
            return to_django_response(bolt_resp)
    
        return HttpResponse(status=404, content=b"Not Found")
    

    The slack_bolt version

    slack-bolt==1.11.4

    Python runtime version

    Python 3.10.2

    Steps to reproduce:

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

    1. Clone the django oauth example app
    2. Visit /slack/install

    Expected result:

    Option to install Slack

    Actual result:

    Receive a page with the text "not found"

    question area:examples need info 
    opened by ghabs 12
  • Scope and Permissions to install Application under oAuth in Django Example

    Scope and Permissions to install Application under oAuth in Django Example

    (Describe your issue and goal here)

    Reproducible in:

    The slack_bolt version

    django-slack-app==1.0.40 django-slack-oauth==1.5.0 slack-bolt==1.5.0 slack-sdk==3.5.1 slackclient==2.9.3

    Python runtime version

    Python 3.8.2

    OS info

    ProductName: macOS ProductVersion: 11.1 BuildVersion: 20C69 Darwin Kernel Version 20.2.0: Wed Dec 2 20:40:21 PST 2020; root:xnu-7195.60.75~1/RELEASE_ARM64_T8101

    Steps to reproduce:

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

    python manage.py runserver

    Expected result:

    I expect the app to install with the requested scope & permissions and are set in the Slack App settings in: https://api.slack.com/apps/

    Actual result:

    It tells me that there are no redirect URL and scopes set... Screenshot 2021-05-05 at 20 54 34

    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.

    docs area:adapter area:examples 
    opened by ManuelBuri 12
  • "Operation Timeout Error" on first load for AWS Lambda with SSM

    I am experiencing an issue when running slack bolt on AWS Lambda, specifically the module does not load fast enough for the ack() to be sent before 3 seconds on first load. Whenever the loaded modules are no longer cached, this issue happens again. We moved to slack bolt from a previous method where we had an SQS queue -> Lambda -> Lambda where the first lambda would return a 200 and the second would do the actual processing because slack bolt promises to be more simple and feature rich. We have some special wrapping to support creating a Class wrapper around the app to prevent issues with caching global variables in Lambda as well as support for a single entrypoint /command from which a subcommand can be supplied with arguments in order to support more dynamic additions of commands to the bot without needing to create extra /commands on api.slack.com.

    My main question is: Are we using this module incorrectly or is there some sort of tuning we can preform to eliminate this error?

    Reproducible in:

    MCVE

    def supply_self(func, this):
        """
        Adapts from a three argument function to a two argument function
        :param func: the function to supply self to
        :param this: renamed self to prevent conflicts with how bolt wires its functions
        :return: a function which can be called by bolt
        """
        return lambda respond, body: func(this, respond, body)
    
    class BasicBot:
        """
        Instead of making app global (which could cause caching issues), we want to make it a field of an object we can create
        """
    
        def __init__(self, entrypoint_name: str, *args):
            self.app = slack_bolt.App(process_before_response=True,
                                      signing_secret=SSMParameter(os.environ["SIGNING_SECRET_LOCATION"], max_age=3600).value,
                                      token=SSMParameter(os.environ["SLACK_API_LOCATION"], 3600).value)
            self.app.command(entrypoint_name)(ack=lambda body, ack: ack(),
                                                      # unable to call self.func here because slack bolt assumes
                                                      # procedural code, by supplying self as a different argument we can
                                                      # circumvent this
                                                      lazy=[supply_self(func, self)])
            # the above `func` comes from a decorated method within the class
            # ...
    
    def lambda_handler(event, context):
        aws_lambda_logging.setup(aws_request_id=context.aws_request_id, level="INFO")
        logging.info(event)
        bot = BasicBot(os.environ["COMMAND_ENTRYPOINT"])
        return SlackRequestHandler(app=bot.app).handle(event, context)
    

    The slack_bolt version

    Latest version

    Python runtime version

    3.8

    OS info

    AWS Lambda's python environment

    Steps to reproduce:

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

    1. Deploy Labmda
    2. call /entrypoint with some say()
    3. observe operation timeout
    4. observe say() message being sent
    5. call /entrypoint again
    6. observe no timeout

    Expected result:

    No "Operation Timeout Error" on first call

    Actual result:

    Timeout when module is not cached then no timeout when Lambda caches it. Message is sent in both cases but the first degrades user experience.

    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.

    question area:adapter 
    opened by RyanSchaefer 12
  • Messages are received four times

    Messages are received four times

    Hello,

    I have a similar error I had with the regular slack client : cf issue.

    I switched to bolt in order to solve this issue and it was working for a couple of days but now I received the same message three to four times each time.

    When I look at the logs, I have this for the same message:

    {'client_msg_id': '59c755aa-80cf-4a77-8852-6073f776ca07', 'type': 'message', 'text': 'HPSM,.', 'user': 'U7PDK2W1J', 'ts': '1599757663.004700', 'team': 'T7P9RQX35', 'blocks': [{'type': 'rich_text', 'block_id': 'YhMu', 'elements': [{'type': 'rich_text_section', 'elements': [{'type': 'text', 'text': 'MESSAGE'}]}]}], 'channel': 'D8X4RT3PW', 'event_ts': '1599757663.004700', 'channel_type': 'im'}
    
    {'client_msg_id': 'eece3ee7-2dab-4585-8bef-6be776645e80', 'type': 'message', 'text': 'HPSM,.', 'user': 'U7PDK2W1J', 'ts': '1599757626.004100', 'team': 'T7P9RQX35', 'blocks': [{'type': 'rich_text', 'block_id': 'oH4=p', 'elements': [{'type': 'rich_text_section', 'elements': [{'type': 'text', 'text': 'HPSM,.'}]}]}], 'channel': 'D8X4RT3PW', 'event_ts': '1599757626.004100', 'channel_type': 'im'}
    
    (etc.)
    

    And when I look at the IP sent, there are different.

    Thank you in advance.

    question 
    opened by alexattia 12
  • How to manage errors?

    How to manage errors?

    Hello everybody,

    I'm using this FW to build a slack bot, but i don't have any idea on how to manage errors and restrictions.

    There are some actions in the bot dedicated to only a part of the customers (but visible to everybody) and i'd like to do do some kind of error message describing why that action wasn't possible etc.

    The only way idea that come in my mind to reach this goal is to use a modal for each different exception, but i should write a lot of different cases to manage every scenario.

    Is there anything that i didn't find that can help me?

    Thank you very much!

    Luca

    question 
    opened by lucafx 1
  • POST request received but @app.event(message.channels) not called

    POST request received but @app.event(message.channels) not called

    Hi there! When I send a message on a channelI, I receive the post request (127.0.0.1 - - [15/Dec/2022 17:19:31] "POST /slack/events HTTP/1.1" 200 -) but @app.event("message.channels") is not invoked.

    The bot is in the channel and I'm subscribed to message.channels as well (see image below) Should I be using another event type to listen to new messages in the channel?

    Screenshot 2022-12-15 at 17 23 12

    Code as following:

    import os
    from pathlib import Path
    from dotenv import load_dotenv
    from slack_bolt import App
    import logging
    
    # logger in a global context
    # requires importing logging
    logging.basicConfig(level=logging.DEBUG)
    
    env_path = Path('maestro-bot')/'.env'
    load_dotenv(dotenv_path=env_path)
    
    # Initializes your app with your bot token and signing secret
    app = App(
        token=os.environ['SLACK_TOKEN'],
        signing_secret=os.environ['SIGNING_SECRET']
    )
    
    @app.event("message.channels")
    def handle_message(payload, say, logger, context):
        event = payload.get('event', {})
        user_id = event.get('user')
        bot_id = context.get('botId')
        text = event.get('text')  
    
        logger.debug(payload)
        say(text)
    
    # Start your app
    if __name__ == "__main__":
        app.start(port=2000)
    

    Reproducible in:

    pip freeze | grep slack
    python --version
    sw_vers && uname -v # or `ver`
    

    The slack_bolt version

    (Paste the output of pip freeze | grep slack)

    slack-bolt==1.16.0
    slack-sdk==3.19.5
    slackclient==2.9.4
    slackeventsapi==3.0.1
    

    Python runtime version

    (Paste the output of python --version) Python 3.9.6

    OS info

    (Paste the output of sw_vers && uname -v on macOS/Linux or ver on Windows OS)

    ProductName:		macOS
    ProductVersion:		13.0.1
    BuildVersion:		22A400
    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:

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

    1. Send a message on the channel

    Expected result:

    def handle_message(payload, say, logger, context): should get called, the message received should be posted again by the bot.

    Actual result:

    While I can see in the terminal that I'm receiving a post request, the handler is not called.

    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.

    question 
    opened by marcocapano 5
  • [Feature Request] Multiple Listener Dispatching

    [Feature Request] Multiple Listener Dispatching

    This is a proposal to allow Bolt to support triggering multiple functions for a common listener, below is an example of what this could look like

    @app.event({"type": "message"})
    def tag_message():
        # finds and associates tags with the current channel
         
    @app.event({"type": "message"})
    def activity_monitor():
        # increments activity of the user sending the message
    
    ....
    
    

    Currently the second function is never called.

    This was originally brought up in #786

    Lets open a discussing to figure out if this is in the scope of Bolt, and wether this should be included in the project

    Category

    • [x] slack_bolt.App and/or its core components
    • [x] slack_bolt.async_app.AsyncApp and/or its core components
    • [ ] Adapters in slack_bolt.adapter
    • [ ] Others

    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.

    enhancement area:async area:sync discussion 
    opened by WilliamBergamin 1
  • not receiving entire thread of messages when passing ts of a message in thread

    not receiving entire thread of messages when passing ts of a message in thread

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

    Reproducible in:

    slack-bolt==1.15.5
    slack-sdk==3.19.4
    Python 3.10.8
    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:

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

    1. create a thread on slack with a parent message and 2 replies
    2. take ts value of reply and call app.client.conversations_replies(channel_id, ts)
    3. the response does not include entire thread and only includes information about the reply message

    also reproducible in tester section of the API's page: https://api.slack.com/methods/conversations.replies/test

    Expected result:

    (Tell what you expected to happen) expected all messages in the thread to be returned from parent message of thread + both replies.

    Actual result:

    (Tell what actually happened with logs, screenshots) receiving only the specific message's information instead of the whole thread Screenshot 2022-12-10 at 10 29 50 PM

    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.

    server-side 
    opened by lavishsaluja 2
  • Multi Workspace app installation with slack bolt sdk

    Multi Workspace app installation with slack bolt sdk

    Hello, I am trying to create a Slack Bolt SDK app which I can install in multiple workspaces. I am an admin in multiple workspaces, but so far I am only able to install the bot to one of the two spaces. I believe I've implemented the OAuth flow properly but in my logs I keep seeing the second one can't.

    https://slack.dev/python-slack-sdk/oauth/ https://slack.dev/bolt-python/concepts#authenticating-oauth

    I am running a flask app with gunicorn on the digitalocean platform.

    I know FileInstallationStore is the default to store the data, should I change that? or I know other parts of my app use mongoDB. is there an equivalent for Mongo storage? Right now I see there's sqlalchemy and sqlite3, but didnt know if that was what was going wrong here.

    import logging
    import os
    from slack_bolt import App
    from slack_bolt.oauth.oauth_settings import OAuthSettings
    from slack_sdk.oauth.installation_store import FileInstallationStore
    from slack_sdk.oauth.state_store import FileOAuthStateStore
    from slack_bolt.adapter.flask import SlackRequestHandler
    from datetime import datetime
    
    # https://slack.dev/bolt-python/concepts#authenticating-oauth
    oauth_settings = OAuthSettings(
        client_id=os.environ["SLACK_CLIENT_ID"],
        client_secret=os.environ["SLACK_CLIENT_SECRET"],
        scopes=["chat:write","chat:write.public","commands","mpim:write"],
        installation_store=FileInstallationStore(base_dir="./data/installations"),
        state_store=FileOAuthStateStore(expiration_seconds=600, base_dir="./data/states")
    )
    
    app = App(
        signing_secret=os.environ["SLACK_SIGNING_SECRET"],
        oauth_settings=oauth_settings
    )
    
    
    logging.basicConfig(level=logging.DEBUG)
    
    ### CORE FLASK APP ###
    @app.middleware  # or app.use(log_request)
    def log_request(logger, body, next):
        logger.debug(body)
        return next()
    
    # push
    
    @app.event("app_home_opened")
    def handle_app_home_opened_events(body, logger):
        print(body)
        logger.info(body)
        postMessage([{
                    "type": "divider"
                },
                {
                    "type": "section",
                    "text": {
                    "type": "mrkdwn",
                    "text": "*This works!* :partying_face:"
                    }
                }],"Hello from Slack", body['event']['user'])
    
    
    @app.event("message")
    def handle_message():
        pass
    
    @app.command("/hello")
    def test_the_test(ack, body):
        ack()
        print(body)
        postMessage([{
                    "type": "divider"
                },
                {
                    "type": "section",
                    "text": {
                    "type": "mrkdwn",
                    "text": "*HELLO?!*."
                    }
                }],"Hello from Slack", body['user_id'])
    
    from flask import Flask, request
    
    flask_app = Flask(__name__)
    handler = SlackRequestHandler(app)
    
    
    @flask_app.route("/slack/events", methods=["POST"])
    def slack_events():
        return handler.handle(request)
    
    
    @flask_app.route("/slack/install", methods=["GET"])
    def install():
        return handler.handle(request)
    
    
    @flask_app.route("/slack/oauth_redirect", methods=["GET"])
    def oauth_redirect():
        return handler.handle(request)
    
    @flask_app.route('/')
    def hello_world():
        return 'Hello World from the Slack bot instance! Now trying OAuth'
    
    def postMessage(message, text, userID):
        result = app.client.chat_postMessage(
        channel = userID,
        text=str(text).replace("', '", "").replace("['", "").replace("']", "").replace(
                    '",', '').replace("', '", "").replace("',", "").replace(' "', '').replace(" '", "").replace("\\n", "\n"),
        blocks= message
        )
        print(result)
    

    gunicorn_config.py bind = "0.0.0.0:8080" workers = 2

    The slack_bolt version

    slack-bolt==1.15.5 slack-sdk==3.19.5

    Python runtime version

    apps@flask-app-856f4cc5dc-wcjq4:~$ python --version Python 3.10.8

    OS info

    not sure since its on digitalocean, looks like it ight be a python docker container right now, but ideally I'll eventually put this in an ubuntu container.

    Steps to reproduce:

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

    1. gunicorn --worker-tmp-dir /dev/shm app:flask_app

    Expected result:

    Should be able to install the app from /slack/install into a workspace , see success message and open slack.. then when you visit the app_home_mention to trigger a message or try the /hello command see a message

    Actual result:

    install is successful, but home mention and command produce nothing in the second installation.

    [flask-app] [2022-12-09 17:14:58] DEBUG:slack_sdk.oauth.installation_store.file:Installation data missing for enterprise: none, team: T03G4RLT3K3: [Errno 2] No such file or directory: './data/installations/none-T03G4RLT3K3/installer-latest'
    [flask-app] [2022-12-09 17:14:58] DEBUG:slack_sdk.oauth.installation_store.file:Installation data missing for enterprise: none, team: T03G4RLT3K3: [Errno 2] No such file or directory: './data/installations/none-T03G4RLT3K3/bot-latest'
    [flask-app] [2022-12-09 17:14:58] DEBUG:slack_bolt.oauth.oauth_settings:No installation data found for enterprise_id: None team_id: T03G4RLT3K3
    [flask-app] [2022-12-09 17:14:58] ERROR:slack_bolt.MultiTeamsAuthorization:Although the app should be installed into this workspace, the AuthorizeResult (returned value from authorize) for it was not found.
    [flask-app] [2022-12-09 17:14:58] 10.244.3.81 - - [09/Dec/2022:17:14:58 +0000] "POST /slack/events HTTP/1.1" 200 52 "-" "Slackbot 1.0 (+https://api.slack.com/robots)"
    [flask-app] [2022-12-09 17:23:43] 10.244.0.1 - - [09/Dec/2022:17:23:43 +0000] "GET /slack/install HTTP/1.1" 200 646 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36"
    [flask-app] [2022-12-09 17:24:05] DEBUG:slack_sdk.oauth.installation_store.file:Installation data missing for enterprise: none, team: T03G4RLT3K3: [Errno 2] No such file or directory: './data/installations/none-T03G4RLT3K3/installer-latest'
    [flask-app] [2022-12-09 17:24:05] DEBUG:slack_sdk.oauth.installation_store.file:Installation data missing for enterprise: none, team: T03G4RLT3K3: [Errno 2] No such file or directory: './data/installations/none-T03G4RLT3K3/bot-latest'
    [flask-app] [2022-12-09 17:24:05] DEBUG:slack_bolt.oauth.oauth_settings:No installation data found for enterprise_id: None team_id: T03G4RLT3K3
    [flask-app] [2022-12-09 17:24:05] ERROR:slack_bolt.MultiTeamsAuthorization:Although the app should be installed into this workspace, the AuthorizeResult (returned value from authorize) for it was not found.
    [flask-app] [2022-12-09 17:24:05] 10.244.0.1 - - [09/Dec/2022:17:24:05 +0000] "POST /slack/events HTTP/1.1" 200 52 "-" "Slackbot 1.0 (+https://api.slack.com/robots)"
    
    

    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.

    question 
    opened by ryanrestivo 27
  • Sporadic unstable tests due to SimpleHTTPServer performance

    Sporadic unstable tests due to SimpleHTTPServer performance

    This it an inconsistent bug found in 2 tests TestEventsSharedChannels.test_uninstallation_and_revokes and TestEventsSocketMode.test_middleware I believe it sometimes happen in the CI pipeline, but I encountered it locally

    The goal of this issue is to add stability to the unit tests

    Reproducible in:

    slack-sdk==3.19.5 Python 3.9.6 ProductName: macOS ProductVersion: 12.6.1 BuildVersion: 21G217 Darwin Kernel Version 21.6.0

    Steps to reproduce:

    Hard to encounter locally

    1. run the tests
    2. a lot

    Expected result:

    All tests pass

    Actual result:

    =================================================================== FAILURES ===================================================================
    ___________________________________________ TestEventsSharedChannels.test_uninstallation_and_revokes ___________________________________________
    
    self = <tests.scenario_tests.test_events_shared_channels.TestEventsSharedChannels object at 0x116f32bb0>
    
        def test_uninstallation_and_revokes(self):
            app = App(
                client=self.web_client,
                signing_secret=self.signing_secret,
                authorize=authorize,
            )
            app._client = WebClient(token="uninstalled-revoked", base_url=self.mock_api_server_base_url)
        
            @app.event("app_uninstalled")
            def handler1(say: Say):
                say(channel="C111", text="What's up?")
        
            @app.event("tokens_revoked")
            def handler2(say: Say):
                say(channel="C111", text="What's up?")
        
            app_uninstalled_body = {
                "token": "verification_token",
                "team_id": "T_INSTALLED",
                "enterprise_id": "E_INSTALLED",
                "api_app_id": "A111",
                "event": {"type": "app_uninstalled"},
                "type": "event_callback",
                "event_id": "Ev111",
                "event_time": 1599616881,
                "authorizations": [
                    {
                        "enterprise_id": "E_INSTALLED",
                        "team_id": "T_INSTALLED",
                        "user_id": "W111",
                        "is_bot": True,
                        "is_enterprise_install": False,
                    }
                ],
            }
        
            timestamp, body = str(int(time())), json.dumps(app_uninstalled_body)
            request: BoltRequest = BoltRequest(body=body, headers=self.build_headers(timestamp, body))
            response = app.dispatch(request)
            assert response.status == 200
        
            tokens_revoked_body = {
                "token": "verification_token",
                "team_id": "T_INSTALLED",
                "enterprise_id": "E_INSTALLED",
                "api_app_id": "A111",
                "event": {
                    "type": "tokens_revoked",
                    "tokens": {"oauth": ["UXXXXXXXX"], "bot": ["UXXXXXXXX"]},
                },
                "type": "event_callback",
                "event_id": "Ev111",
                "event_time": 1599616881,
                "authorizations": [
                    {
                        "enterprise_id": "E_INSTALLED",
                        "team_id": "T_INSTALLED",
                        "user_id": "W111",
                        "is_bot": True,
                        "is_enterprise_install": False,
                    }
                ],
            }
        
            timestamp, body = str(int(time())), json.dumps(tokens_revoked_body)
            request: BoltRequest = BoltRequest(body=body, headers=self.build_headers(timestamp, body))
            response = app.dispatch(request)
            assert response.status == 200
        
            # this should not be called when we have authorize
            assert self.mock_received_requests.get("/auth.test") is None
            sleep(1)  # wait a bit after auto ack()
    >       assert self.mock_received_requests["/chat.postMessage"] == 2
    E       assert 3 == 2
    
    tests/scenario_tests/test_events_shared_channels.py:494: AssertionError
    ------------------------------------------------------------- Captured stderr call -------------------------------------------------------------
    127.0.0.1 - - [07/Dec/2022 14:49:01] "POST /chat.postMessage HTTP/1.1" 200 -
    ----------------------------------------
    Exception occurred during processing of request from ('127.0.0.1', 58680)
    Traceback (most recent call last):
      File "/.pyenv/versions/3.9.6/lib/python3.9/socketserver.py", line 316, in _handle_request_noblock
        self.process_request(request, client_address)
      File "/.pyenv/versions/3.9.6/lib/python3.9/socketserver.py", line 347, in process_request
        self.finish_request(request, client_address)
      File "/.pyenv/versions/3.9.6/lib/python3.9/socketserver.py", line 360, in finish_request
        self.RequestHandlerClass(request, client_address, self)
      File "/.pyenv/versions/3.9.6/lib/python3.9/http/server.py", line 653, in __init__
        super().__init__(*args, **kwargs)
      File "/.pyenv/versions/3.9.6/lib/python3.9/socketserver.py", line 747, in __init__
        self.handle()
      File "/.pyenv/versions/3.9.6/lib/python3.9/http/server.py", line 427, in handle
        self.handle_one_request()
      File "/.pyenv/versions/3.9.6/lib/python3.9/http/server.py", line 416, in handle_one_request
        self.wfile.flush() #actually send the response if not already done.
    ValueError: I/O operation on closed file.
    ----------------------------------------
    127.0.0.1 - - [07/Dec/2022 14:49:01] "POST /chat.postMessage HTTP/1.1" 200 -
    ----------------------------------------
    Exception occurred during processing of request from ('127.0.0.1', 58682)
    Traceback (most recent call last):
      File "/.pyenv/versions/3.9.6/lib/python3.9/socketserver.py", line 316, in _handle_request_noblock
        self.process_request(request, client_address)
      File "/.pyenv/versions/3.9.6/lib/python3.9/socketserver.py", line 347, in process_request
        self.finish_request(request, client_address)
      File "/.pyenv/versions/3.9.6/lib/python3.9/socketserver.py", line 360, in finish_request
        self.RequestHandlerClass(request, client_address, self)
      File "/.pyenv/versions/3.9.6/lib/python3.9/http/server.py", line 653, in __init__
        super().__init__(*args, **kwargs)
      File "/.pyenv/versions/3.9.6/lib/python3.9/socketserver.py", line 747, in __init__
        self.handle()
      File "/.pyenv/versions/3.9.6/lib/python3.9/http/server.py", line 427, in handle
        self.handle_one_request()
      File "/.pyenv/versions/3.9.6/lib/python3.9/http/server.py", line 416, in handle_one_request
        self.wfile.flush() #actually send the response if not already done.
    ValueError: I/O operation on closed file.
    ----------------------------------------
    [Errno 61] Connection refused - goodbye
    127.0.0.1 - - [07/Dec/2022 14:49:02] "POST /chat.postMessage HTTP/1.1" 200 -
    ----------------------------------------
    Exception occurred during processing of request from ('127.0.0.1', 58687)
    Traceback (most recent call last):
      File "/.pyenv/versions/3.9.6/lib/python3.9/socketserver.py", line 316, in _handle_request_noblock
        self.process_request(request, client_address)
      File "/.pyenv/versions/3.9.6/lib/python3.9/socketserver.py", line 347, in process_request
        self.finish_request(request, client_address)
      File "/.pyenv/versions/3.9.6/lib/python3.9/socketserver.py", line 360, in finish_request
        self.RequestHandlerClass(request, client_address, self)
      File "/.pyenv/versions/3.9.6/lib/python3.9/http/server.py", line 653, in __init__
        super().__init__(*args, **kwargs)
      File "/.pyenv/versions/3.9.6/lib/python3.9/socketserver.py", line 747, in __init__
        self.handle()
      File "/.pyenv/versions/3.9.6/lib/python3.9/http/server.py", line 427, in handle
        self.handle_one_request()
      File "/.pyenv/versions/3.9.6/lib/python3.9/http/server.py", line 416, in handle_one_request
        self.wfile.flush() #actually send the response if not already done.
    ValueError: I/O operation on closed file.
    ----------------------------------------
    [Errno 61] Connection refused - goodbye
    -------------------------------------------------------------- Captured log call ---------------------------------------------------------------
    2022-12-07 14:49:01 DEBUG Applying slack_bolt.middleware.ssl_check.ssl_check.SslCheck
    2022-12-07 14:49:01 DEBUG Applying slack_bolt.middleware.request_verification.request_verification.RequestVerification
    2022-12-07 14:49:01 DEBUG Applying slack_bolt.middleware.authorization.multi_teams_authorization.MultiTeamsAuthorization
    2022-12-07 14:49:01 DEBUG Applying slack_bolt.middleware.ignoring_self_events.ignoring_self_events.IgnoringSelfEvents
    2022-12-07 14:49:01 DEBUG Applying slack_bolt.middleware.url_verification.url_verification.UrlVerification
    2022-12-07 14:49:01 DEBUG Checking listener: handler1 ...
    2022-12-07 14:49:01 DEBUG Running listener: handler1 ...
    2022-12-07 14:49:01 DEBUG Sending a request - url: http://localhost:8888/chat.postMessage, query_params: {}, body_params: {}, files: {}, json_body: {'channel': 'C111', 'text': "What's up?", 'team_id': 'T_INSTALLED'}, headers: {'Content-Type': 'application/json;charset=utf-8', 'User-Agent': 'Python/3.9.6 slackclient/3.19.5 Darwin/21.6.0'}
    2022-12-07 14:49:01 DEBUG Responding with status: 200 body: "" (0 millis)
    2022-12-07 14:49:01 DEBUG Applying slack_bolt.middleware.ssl_check.ssl_check.SslCheck
    2022-12-07 14:49:01 DEBUG Applying slack_bolt.middleware.request_verification.request_verification.RequestVerification
    2022-12-07 14:49:01 DEBUG Applying slack_bolt.middleware.authorization.multi_teams_authorization.MultiTeamsAuthorization
    2022-12-07 14:49:01 DEBUG Applying slack_bolt.middleware.ignoring_self_events.ignoring_self_events.IgnoringSelfEvents
    2022-12-07 14:49:01 DEBUG Applying slack_bolt.middleware.url_verification.url_verification.UrlVerification
    2022-12-07 14:49:01 DEBUG Checking listener: handler1 ...
    2022-12-07 14:49:01 DEBUG Checking listener: handler2 ...
    2022-12-07 14:49:01 DEBUG Running listener: handler2 ...
    2022-12-07 14:49:01 DEBUG Sending a request - url: http://localhost:8888/chat.postMessage, query_params: {}, body_params: {}, files: {}, json_body: {'channel': 'C111', 'text': "What's up?", 'team_id': 'T_INSTALLED'}, headers: {'Content-Type': 'application/json;charset=utf-8', 'User-Agent': 'Python/3.9.6 slackclient/3.19.5 Darwin/21.6.0'}
    2022-12-07 14:49:01 DEBUG Responding with status: 200 body: "" (0 millis)
    2022-12-07 14:49:01 ERROR Failed to send a request to Slack API server: [Errno 54] Connection reset by peer
    2022-12-07 14:49:01 INFO A retry handler found: ConnectionErrorRetryHandler for POST http://localhost:8888/chat.postMessage - [Errno 54] Connection reset by peer
    2022-12-07 14:49:01 ERROR Failed to send a request to Slack API server: [Errno 54] Connection reset by peer
    2022-12-07 14:49:01 INFO A retry handler found: ConnectionErrorRetryHandler for POST http://localhost:8888/chat.postMessage - [Errno 54] Connection reset by peer
    2022-12-07 14:49:01 INFO Starting to receive messages from a new connection
    2022-12-07 14:49:01 ERROR [Errno 61] Connection refused - goodbye
    2022-12-07 14:49:01 ERROR on_error invoked (error: ConnectionRefusedError, message: [Errno 61] Connection refused)
    2022-12-07 14:49:01 DEBUG on_close invoked: (code: None, message: None)
    2022-12-07 14:49:01 INFO Stopped receiving messages from a connection
    2022-12-07 14:49:02 INFO Going to retry the same request: POST http://localhost:8888/chat.postMessage
    2022-12-07 14:49:02 DEBUG Received the following response - status: 200, headers: {'Server': 'SimpleHTTP/0.6 Python/3.9.6', 'Date': 'Wed, 07 Dec 2022 19:49:02 GMT', 'content-type': 'application/json;charset=utf-8', 'connection': 'close'}, body: {"ok": false, "error": "invalid_auth"}
    2022-12-07 14:49:02 ERROR Failed to run listener function (error: The request to the Slack API failed. (url: http://localhost:8888/chat.postMessage)
    The server responded with: {'ok': False, 'error': 'invalid_auth'})
    Traceback (most recent call last):
      File "/Documents/slack/tools/forks/bolt-python/slack_bolt/listener/thread_runner.py", line 120, in run_ack_function_asynchronously
        listener.run_ack_function(request=request, response=response)
      File "/Documents/slack/tools/forks/bolt-python/slack_bolt/listener/custom_listener.py", line 50, in run_ack_function
        return self.ack_function(
      File "/Documents/slack/tools/forks/bolt-python/tests/scenario_tests/test_events_shared_channels.py", line 432, in handler1
        say(channel="C111", text="What's up?")
      File "/Documents/slack/tools/forks/bolt-python/slack_bolt/context/say/say.py", line 49, in __call__
        return self.client.chat_postMessage(
      File "/Documents/slack/tools/forks/bolt-python/env_3.11.0/lib/python3.9/site-packages/slack_sdk/web/client.py", line 2072, in chat_postMessage
        return self.api_call("chat.postMessage", json=kwargs)
      File "/Documents/slack/tools/forks/bolt-python/env_3.11.0/lib/python3.9/site-packages/slack_sdk/web/base_client.py", line 156, in api_call
        return self._sync_send(api_url=api_url, req_args=req_args)
      File "/Documents/slack/tools/forks/bolt-python/env_3.11.0/lib/python3.9/site-packages/slack_sdk/web/base_client.py", line 187, in _sync_send
        return self._urllib_api_call(
      File "/Documents/slack/tools/forks/bolt-python/env_3.11.0/lib/python3.9/site-packages/slack_sdk/web/base_client.py", line 309, in _urllib_api_call
        return SlackResponse(
      File "/Documents/slack/tools/forks/bolt-python/env_3.11.0/lib/python3.9/site-packages/slack_sdk/web/slack_response.py", line 199, in validate
        raise e.SlackApiError(message=msg, response=self)
    slack_sdk.errors.SlackApiError: The request to the Slack API failed. (url: http://localhost:8888/chat.postMessage)
    The server responded with: {'ok': False, 'error': 'invalid_auth'}
    2022-12-07 14:49:02 INFO Starting to receive messages from a new connection
    2022-12-07 14:49:02 ERROR [Errno 61] Connection refused - goodbye
    2022-12-07 14:49:02 ERROR on_error invoked (error: ConnectionRefusedError, message: [Errno 61] Connection refused)
    2022-12-07 14:49:02 DEBUG on_close invoked: (code: None, message: None)
    2022-12-07 14:49:02 INFO Stopped receiving messages from a connection
    _____________________________________________________ TestEventsSocketMode.test_middleware _____________________________________________________
    
    self = <tests.scenario_tests.test_events_socket_mode.TestEventsSocketMode object at 0x116c51af0>
    
        def test_middleware(self):
            app = App(client=self.web_client)
        
            @app.event("app_mention")
            def handle_app_mention(body, say, payload, event):
                assert body == self.valid_event_body
                assert body["event"] == payload
                assert payload == event
                say("What's up?")
        
            request: BoltRequest = BoltRequest(body=self.valid_event_body, mode="socket_mode")
            response = app.dispatch(request)
            assert response.status == 200
            assert_auth_test_count(self, 1)
            sleep(1)  # wait a bit after auto ack()
    >       assert self.mock_received_requests["/chat.postMessage"] == 1
    E       assert 2 == 1
    
    tests/scenario_tests/test_events_socket_mode.py:76: AssertionError
    ------------------------------------------------------------- Captured stderr call -------------------------------------------------------------
    127.0.0.1 - - [07/Dec/2022 14:49:02] "POST /auth.test HTTP/1.1" 200 -
    [Errno 61] Connection refused - goodbye
    127.0.0.1 - - [07/Dec/2022 14:49:02] "POST /chat.postMessage HTTP/1.1" 200 -
    ----------------------------------------
    Exception occurred during processing of request from ('127.0.0.1', 58695)
    Traceback (most recent call last):
      File "/.pyenv/versions/3.9.6/lib/python3.9/socketserver.py", line 316, in _handle_request_noblock
        self.process_request(request, client_address)
      File "/.pyenv/versions/3.9.6/lib/python3.9/socketserver.py", line 347, in process_request
        self.finish_request(request, client_address)
      File "/.pyenv/versions/3.9.6/lib/python3.9/socketserver.py", line 360, in finish_request
        self.RequestHandlerClass(request, client_address, self)
      File "/.pyenv/versions/3.9.6/lib/python3.9/http/server.py", line 653, in __init__
        super().__init__(*args, **kwargs)
      File "/.pyenv/versions/3.9.6/lib/python3.9/socketserver.py", line 747, in __init__
        self.handle()
      File "/.pyenv/versions/3.9.6/lib/python3.9/http/server.py", line 427, in handle
        self.handle_one_request()
      File "/.pyenv/versions/3.9.6/lib/python3.9/http/server.py", line 416, in handle_one_request
        self.wfile.flush() #actually send the response if not already done.
    ValueError: I/O operation on closed file.
    ----------------------------------------
    127.0.0.1 - - [07/Dec/2022 14:49:02] "POST /chat.postMessage HTTP/1.1" 200 -
    ----------------------------------------
    Exception occurred during processing of request from ('127.0.0.1', 58699)
    Traceback (most recent call last):
      File "/.pyenv/versions/3.9.6/lib/python3.9/socketserver.py", line 316, in _handle_request_noblock
        self.process_request(request, client_address)
      File "/.pyenv/versions/3.9.6/lib/python3.9/socketserver.py", line 347, in process_request
        self.finish_request(request, client_address)
      File "/.pyenv/versions/3.9.6/lib/python3.9/socketserver.py", line 360, in finish_request
        self.RequestHandlerClass(request, client_address, self)
      File "/.pyenv/versions/3.9.6/lib/python3.9/http/server.py", line 653, in __init__
        super().__init__(*args, **kwargs)
      File "/.pyenv/versions/3.9.6/lib/python3.9/socketserver.py", line 747, in __init__
        self.handle()
      File "/.pyenv/versions/3.9.6/lib/python3.9/http/server.py", line 427, in handle
        self.handle_one_request()
      File "/.pyenv/versions/3.9.6/lib/python3.9/http/server.py", line 416, in handle_one_request
        self.wfile.flush() #actually send the response if not already done.
    ValueError: I/O operation on closed file.
    ----------------------------------------
    [Errno 61] Connection refused - goodbye
    [Errno 61] Connection refused - goodbye
    -------------------------------------------------------------- Captured log call ---------------------------------------------------------------
    2022-12-07 14:49:02 DEBUG Sending a request - url: http://localhost:8888/auth.test, query_params: {}, body_params: {}, files: {}, json_body: None, headers: {'Content-Type': 'application/x-www-form-urlencoded', 'Authorization': '(redacted)', 'User-Agent': 'Python/3.9.6 slackclient/3.19.5 Darwin/21.6.0'}
    2022-12-07 14:49:02 DEBUG Received the following response - status: 200, headers: {'Server': 'SimpleHTTP/0.6 Python/3.9.6', 'Date': 'Wed, 07 Dec 2022 19:49:02 GMT', 'content-type': 'application/json;charset=utf-8', 'connection': 'close'}, body: 
    {
        "ok": true,
        "url": "https://subarachnoid.slack.com/",
        "team": "Subarachnoid Workspace",
        "user": "bot",
        "team_id": "T0G9PQBBK",
        "user_id": "W23456789",
        "bot_id": "BZYBOTHED"
    }
    
    2022-12-07 14:49:02 DEBUG Applying slack_bolt.middleware.ssl_check.ssl_check.SslCheck
    2022-12-07 14:49:02 DEBUG Applying slack_bolt.middleware.request_verification.request_verification.RequestVerification
    2022-12-07 14:49:02 DEBUG Applying slack_bolt.middleware.authorization.single_team_authorization.SingleTeamAuthorization
    2022-12-07 14:49:02 DEBUG Applying slack_bolt.middleware.ignoring_self_events.ignoring_self_events.IgnoringSelfEvents
    2022-12-07 14:49:02 DEBUG Applying slack_bolt.middleware.url_verification.url_verification.UrlVerification
    2022-12-07 14:49:02 DEBUG Checking listener: handle_app_mention ...
    2022-12-07 14:49:02 DEBUG Running listener: handle_app_mention ...
    2022-12-07 14:49:02 DEBUG Sending a request - url: http://localhost:8888/chat.postMessage, query_params: {}, body_params: {}, files: {}, json_body: {'channel': 'C111', 'text': "What's up?", 'team_id': 'T111'}, headers: {'Content-Type': 'application/json;charset=utf-8', 'Authorization': '(redacted)', 'User-Agent': 'Python/3.9.6 slackclient/3.19.5 Darwin/21.6.0'}
    2022-12-07 14:49:02 DEBUG Responding with status: 200 body: "" (0 millis)
    2022-12-07 14:49:02 INFO Starting to receive messages from a new connection
    2022-12-07 14:49:02 INFO request: /chat.postMessage {'channel': 'C111', 'text': "What's up?", 'team_id': 'T111'}
    2022-12-07 14:49:02 ERROR [Errno 61] Connection refused - goodbye
    2022-12-07 14:49:02 ERROR on_error invoked (error: ConnectionRefusedError, message: [Errno 61] Connection refused)
    2022-12-07 14:49:02 DEBUG on_close invoked: (code: None, message: None)
    2022-12-07 14:49:02 INFO Stopped receiving messages from a connection
    2022-12-07 14:49:02 DEBUG Received the following response - status: 200, headers: {'Server': 'SimpleHTTP/0.6 Python/3.9.6', 'Date': 'Wed, 07 Dec 2022 19:49:02 GMT', 'content-type': 'application/json;charset=utf-8', 'connection': 'close'}, body: {"ok": true}
    2022-12-07 14:49:02 INFO Going to retry the same request: POST http://localhost:8888/chat.postMessage
    2022-12-07 14:49:02 DEBUG Received the following response - status: 200, headers: {'Server': 'SimpleHTTP/0.6 Python/3.9.6', 'Date': 'Wed, 07 Dec 2022 19:49:02 GMT', 'content-type': 'application/json;charset=utf-8', 'connection': 'close'}, body: {"ok": false, "error": "invalid_auth"}
    2022-12-07 14:49:02 ERROR Failed to run listener function (error: The request to the Slack API failed. (url: http://localhost:8888/chat.postMessage)
    The server responded with: {'ok': False, 'error': 'invalid_auth'})
    Traceback (most recent call last):
      File "/Documents/slack/tools/forks/bolt-python/slack_bolt/listener/thread_runner.py", line 120, in run_ack_function_asynchronously
        listener.run_ack_function(request=request, response=response)
      File "/Documents/slack/tools/forks/bolt-python/slack_bolt/listener/custom_listener.py", line 50, in run_ack_function
        return self.ack_function(
      File "/Documents/slack/tools/forks/bolt-python/tests/scenario_tests/test_events_shared_channels.py", line 436, in handler2
        say(channel="C111", text="What's up?")
      File "/Documents/slack/tools/forks/bolt-python/slack_bolt/context/say/say.py", line 49, in __call__
        return self.client.chat_postMessage(
      File "/Documents/slack/tools/forks/bolt-python/env_3.11.0/lib/python3.9/site-packages/slack_sdk/web/client.py", line 2072, in chat_postMessage
        return self.api_call("chat.postMessage", json=kwargs)
      File "/Documents/slack/tools/forks/bolt-python/env_3.11.0/lib/python3.9/site-packages/slack_sdk/web/base_client.py", line 156, in api_call
        return self._sync_send(api_url=api_url, req_args=req_args)
      File "/Documents/slack/tools/forks/bolt-python/env_3.11.0/lib/python3.9/site-packages/slack_sdk/web/base_client.py", line 187, in _sync_send
        return self._urllib_api_call(
      File "/Documents/slack/tools/forks/bolt-python/env_3.11.0/lib/python3.9/site-packages/slack_sdk/web/base_client.py", line 309, in _urllib_api_call
        return SlackResponse(
      File "/Documents/slack/tools/forks/bolt-python/env_3.11.0/lib/python3.9/site-packages/slack_sdk/web/slack_response.py", line 199, in validate
        raise e.SlackApiError(message=msg, response=self)
    slack_sdk.errors.SlackApiError: The request to the Slack API failed. (url: http://localhost:8888/chat.postMessage)
    The server responded with: {'ok': False, 'error': 'invalid_auth'}
    2022-12-07 14:49:03 INFO Starting to receive messages from a new connection
    2022-12-07 14:49:03 ERROR [Errno 61] Connection refused - goodbye
    2022-12-07 14:49:03 ERROR on_error invoked (error: ConnectionRefusedError, message: [Errno 61] Connection refused)
    2022-12-07 14:49:03 DEBUG on_close invoked: (code: None, message: None)
    2022-12-07 14:49:03 INFO Stopped receiving messages from a connection
    2022-12-07 14:49:03 INFO Starting to receive messages from a new connection
    2022-12-07 14:49:03 ERROR [Errno 61] Connection refused - goodbye
    2022-12-07 14:49:03 ERROR on_error invoked (error: ConnectionRefusedError, message: [Errno 61] Connection refused)
    2022-12-07 14:49:03 DEBUG on_close invoked: (code: None, message: None)
    2022-12-07 14:49:03 INFO Stopped receiving messages from a connection
    =========================================================== short test summary info ============================================================
    FAILED tests/scenario_tests/test_events_shared_channels.py::TestEventsSharedChannels::test_uninstallation_and_revokes - assert 3 == 2
    FAILED tests/scenario_tests/test_events_socket_mode.py::TestEventsSocketMode::test_middleware - assert 2 == 1
    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! KeyboardInterrupt !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    
    

    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.

    bug 
    opened by WilliamBergamin 2
Releases(v1.16.1)
  • v1.16.1(Dec 19, 2022)

    Changes

    • #794 Fix #793 by adding pyramid_request property to Bolt context - Thanks @dz0ny @seratch

    Document / Project Updates

    • #792 Adding Handling views on close documentation - Thanks @BrandonDalton
    • #762 Add documentation related to how to handle view_closed events - Thanks @filmaj

    References

    • Release Milestone: https://github.com/slackapi/bolt-python/milestone/72?closed=1
    • All Diff: https://github.com/slackapi/bolt-python/compare/v1.16.0...v1.16.1
    Source code(tar.gz)
    Source code(zip)
  • v1.16.0(Dec 8, 2022)

    New Features

    ASGI Adapter

    Since this version, a new adapter that implements the ASGI standard is available. The novel adapter brings the following benefits to developers:

    • A builtin way to deploy HTTP apps to production using the ASGI standard
    • Allow bolt to be deployed on a web servers such as daphne, uvicorn and hypercorn without other dependencies
    • A way to create small, lightweight and efficient docker images for bolt python

    The adapter is compatible with both App and AsyncApp. You can run both of the following app code by running uvicorn app:api --reload --port 3000 --log-level debug:

    
    from slack_bolt import App
    from slack_bolt.adapter.asgi import SlackRequestHandler
    
    app = App()
    
    @app.event("app_mention")
    def handle_app_mentions(say):
        say("What's up?")
    
    api = SlackRequestHandler(app)
    

    Here is an asyncio-based app:

    from slack_bolt.async_app import AsyncApp
    from slack_bolt.adapter.asgi.async_handler import AsyncSlackRequestHandler
    
    app = AsyncApp()
    
    @app.event("app_mention")
    async def handle_app_mentions(say):
        await say("What's up?")
    
    api = AsyncSlackRequestHandler(app)
    

    To learn more on the implementation and grab more code examples, please check @WilliamBergamin's pull request adding the feature: https://github.com/slackapi/bolt-python/pull/780

    Changes

    • #780 Add ASGI adapter - Thanks @WilliamBergamin

    Document / Project Updates

    • #779 Fixing link to message event subtypes docs - Thanks @filmaj
    • #776 CI python 3.6 bug fix - Thanks @WilliamBergamin
    • #770 Fix #757 by using Falcon 3.1.1 - Thanks @seratch

    References

    • Release Milestone: https://github.com/slackapi/bolt-python/milestone/65?closed=1
    • All Diff: https://github.com/slackapi/bolt-python/compare/v1.15.5...v1.16.0
    Source code(tar.gz)
    Source code(zip)
  • v1.15.5(Nov 17, 2022)

    Changes

    • #769 Fix #768 The client arg in a listener does not respect the singleton WebClient's retry_handlers - Thanks @seratch

    References

    • Release Milestone: https://github.com/slackapi/bolt-python/milestone/70?closed=1
    • All Diff: https://github.com/slackapi/bolt-python/compare/v1.15.4...v1.15.5
    Source code(tar.gz)
    Source code(zip)
  • v1.15.4(Nov 17, 2022)

    Changes

    • #766 Fix #763 by improving the suggestion logging for view_closed patterns - Thanks @seratch @filmaj

    References

    • Release Milestone: https://github.com/slackapi/bolt-python/milestone/69?closed=1
    • All Diff: https://github.com/slackapi/bolt-python/compare/v1.15.3...v1.15.4
    Source code(tar.gz)
    Source code(zip)
  • v1.15.3(Nov 8, 2022)

    Changes

    • #751 Add Python 3.11 to the supported language versions - Thanks @seratch
    • #758 Fix #754 by adding the async version of Tornado adapter - Thanks @seratch @castrapel
    • #748 Fix #747 by updating async SQLAlchemy OAuth example code - Thanks @ntarora
    • #752 Update code_cov upload method - Thanks @WilliamBergamin
    • #745 Remove 2020-resolver - Thanks @WilliamBergamin

    References

    • Release Milestone: https://github.com/slackapi/bolt-python/milestone/68?closed=1
    • All Diff: https://github.com/slackapi/bolt-python/compare/v1.15.2...v1.15.3
    Source code(tar.gz)
    Source code(zip)
  • v1.15.2(Oct 18, 2022)

    Changes

    • #741 Fix #738 Add more keyword args to say utility - Thanks @seratch @jacklowrie
    • #736 Add context 'user_id' extraction for 'message_changed' and 'message_deleted' events - Thanks @eddyg

    References

    • Release Milestone: https://github.com/slackapi/bolt-python/milestone/67?closed=1
    • All Diff: https://github.com/slackapi/bolt-python/compare/v1.15.1...v1.15.2
    Source code(tar.gz)
    Source code(zip)
  • v1.15.1(Oct 6, 2022)

    Changes

    • #734 Fix context.team_id for view interactions in a Slack Connect channel - Thanks @seratch

    References

    • Release Milestone: https://github.com/slackapi/bolt-python/milestone/64?closed=1
    • All Diff: https://github.com/slackapi/bolt-python/compare/v1.15.0...v1.15.1
    Source code(tar.gz)
    Source code(zip)
  • v1.15.0(Sep 30, 2022)

    Changes

    • #722 Fix #721 Passing a global dict object without channel prop can cause issues among requests - Thanks @seratch @gk-patel
    • #714 Change to create a WebClient per request for safety - Thanks @seratch
    • #726 #727 Bump Sanic, websockets packages to the latest major versions - Thanks @e-zim @JWZepf

    Document Changes

    • #725 Development release steps in guide - Thanks @WilliamBergamin
    • #690 Issue #660: Replace HTML entities before markdownify in docs - Thanks @acq688

    References

    • Release Milestone: https://github.com/slackapi/bolt-python/milestone/60?closed=1
    • All Diff: https://github.com/slackapi/bolt-python/compare/v1.14.3...v1.15.0
    Source code(tar.gz)
    Source code(zip)
  • v1.14.3(Jul 26, 2022)

    Changes

    • #689 Fix #688 kwarg injection does not work with decorated functions - Thanks @seratch @deppe

    Document Changes

    • #686 Add anchors and add contribute link to sidebar - Thanks @wongjas

    References

    • Release Milestone: https://github.com/slackapi/bolt-python/milestone/63?closed=1
    • All Diff: https://github.com/slackapi/bolt-python/compare/v1.14.2...v1.14.3
    Source code(tar.gz)
    Source code(zip)
  • v1.14.2(Jul 21, 2022)

    Changes

    • #684 Fix #683 IgnoringSelfEvents middleware does not filter out Message sent via response_url - Thanks @seratch @deppe

    References

    • Release Milestone: https://github.com/slackapi/bolt-python/milestone/62?closed=1
    • All Diff: https://github.com/slackapi/bolt-python/compare/v1.14.1...v1.14.2
    Source code(tar.gz)
    Source code(zip)
  • v1.14.1(Jul 12, 2022)

    Changes

    • #679 Allow lazy function invocation to target version/alias - Thanks @angrychimp
    • #662 Make the flake8 and black settings consistent - Thanks @seratch

    Document / Example Updates

    • #665 Fix #664 Django example installation store improvement - Thanks @seratch @DataGreed
    • #659 #661 Change AWS API Gateway to Lambda Function URL in documents - Thanks @Globart1337

    References

    • Release Milestone: https://github.com/slackapi/bolt-python/milestone/61?closed=1
    • All Diff: https://github.com/slackapi/bolt-python/compare/v1.14.0...v1.14.1
    Source code(tar.gz)
    Source code(zip)
  • v1.14.0(May 18, 2022)

    Changes

    • #649 Add Google Cloud Functions adapter (ref #646) - Thanks @seratch
    • #647 Remove noqa comments and add __all__ to __init__.py files - Thanks @seratch

    Document Updates

    • #648 Clarify "Setting up events" section - Thanks @hestonhoffman

    References

    • Release Milestone: https://github.com/slackapi/bolt-python/milestone/56?closed=1
    • All Diff: https://github.com/slackapi/bolt-python/compare/v1.13.2...v1.14.0
    Source code(tar.gz)
    Source code(zip)
  • v1.13.2(May 11, 2022)

    Changes

    • #645 Fix #644 app.message listener does not handle events when a file is attached - Thanks @seratch

    References

    • Release Milestone: https://github.com/slackapi/bolt-python/milestone/58?closed=1
    • All Diff: https://github.com/slackapi/bolt-python/compare/v1.13.1...v1.13.2
    Source code(tar.gz)
    Source code(zip)
  • v1.13.1(Apr 29, 2022)

    Changes

    • #640 Fix #639 is_enterprise_install does not exist in context object - Thanks @seratch @Sadisms
    • #636 Upgrade pytype version to the latest - Thanks @seratch
    • #638 Enable Flake8 in the CI builds - Thanks @seratch

    Document Updates

    • #621 Improve the OAuth Lambda deployment instructs - Thanks @srajiang
    • #623 Add Socket Mode healthcheck endpoint examples (#622) - Thanks @ImRohan01 @seratch
    • #633 Update AWS example documentation with correct AWS Lambda roles required - Thanks @cp2423 @filmaj

    References

    • Release Milestone: https://github.com/slackapi/bolt-python/milestone/57?closed=1
    • All Diff: https://github.com/slackapi/bolt-python/compare/v1.13.0...v1.13.1
    Source code(tar.gz)
    Source code(zip)
  • v1.13.0(Mar 18, 2022)

    Changes

    • #618 Fix #617 Respect the configuration of logger parameter across App/AsyncApp loggers - Thanks @seratch @brian-nguyen-bolt
    • #616 Fix type hint for event constraint to allow None subtypes - Thanks @alexrashed

    References

    • Release Milestone: https://github.com/slackapi/bolt-python/milestone/55?closed=1
    • All Diff: https://github.com/slackapi/bolt-python/compare/v1.12.0...v1.13.0
    Source code(tar.gz)
    Source code(zip)
  • v1.12.0(Mar 17, 2022)

    Changes

    • #614 Add Falcon (ASGI) adapter - Thanks @sarayourfriend

    References

    • Release Milestone: https://github.com/slackapi/bolt-python/milestone/51?closed=1
    • All Diff: https://github.com/slackapi/bolt-python/compare/v1.11.6...v1.12.0
    Source code(tar.gz)
    Source code(zip)
  • v1.11.6(Mar 2, 2022)

    Changes

    • #608 Fix #604 Respect the proxy_url in respond- Thanks @seratch @gpiks

    Document Updates

    • #609 Docs on handling options listeners with a filtering example - Thanks @filmaj

    References

    • Release Milestone: https://github.com/slackapi/bolt-python/milestone/54?closed=1
    • All Diff: https://github.com/slackapi/bolt-python/compare/v1.11.5...v1.11.6
    Source code(tar.gz)
    Source code(zip)
  • v1.11.5(Feb 25, 2022)

    Changes

    • #602 Fix #601 Allow for host option for AsyncSlackAppServer start method - Thanks @seratch @ucgw
    • #588 Upgrade test dependencies & fix Falcon warning - Thanks @seratch

    Document Updates

    • #587 Update ngrok link to point to official guide - Thanks @misscoded

    References

    • Release Milestone: https://github.com/slackapi/bolt-python/milestone/53?closed=1
    • All Diff: https://github.com/slackapi/bolt-python/compare/v1.11.4...v1.11.5
    Source code(tar.gz)
    Source code(zip)
  • v1.11.4(Feb 1, 2022)

    Changes

    • #586 Fix #584 Wrong user_token assigned to new user (affected versions: v1.11.2, v1.11.3) - Thanks @stantonius @seratch

    References

    • Release Milestone: https://github.com/slackapi/bolt-python/milestone/52?closed=1
    • All Diff: https://github.com/slackapi/bolt-python/compare/v1.11.3...v1.11.4
    Source code(tar.gz)
    Source code(zip)
  • v1.11.3(Jan 28, 2022)

    Changes

    • #580 Fix #468 Replying with 0 results for a multi-select external option display previous successful results - Thanks @seratch @prziborowski
    • #581 Upgrade pytype version to the latest (2022.1.13) - Thanks @seratch
    • #578 Add more org-wide installation patterns to the SDK tests - Thanks @seratch

    References

    • Release Milestone: https://github.com/slackapi/bolt-python/milestone/50?closed=1
    • All Diff: https://github.com/slackapi/bolt-python/compare/v1.11.2...v1.11.3
    Source code(tar.gz)
    Source code(zip)
  • v1.11.2(Jan 17, 2022)

    Changes

    • #576 Improve the built-in authorize for better support of user-scope only installations - Thanks @seratch
    • #577 Fix #561 matchers can be called even when app.message keyword does not match - Thanks @seratch @caddac

    References

    • Release Milestone: https://github.com/slackapi/bolt-python/milestone/48?closed=1
    • All Diff: https://github.com/slackapi/bolt-python/compare/v1.11.1...v1.11.2
    Source code(tar.gz)
    Source code(zip)
  • v1.11.1(Dec 24, 2021)

    Changes

    • #555 Fix #552 Unable to use request body with lazy listener when socket mode is enabled - Thanks @seratch @JordanGibson

    References

    • Release Milestone: https://github.com/slackapi/bolt-python/milestone/49?closed=1
    • All Diff: https://github.com/slackapi/bolt-python/compare/v1.11.0...v1.11.1
    Source code(tar.gz)
    Source code(zip)
  • v1.11.0(Dec 14, 2021)

    Changes

    • #546 Fix #545 Enable to use lazy listeners even when having any custom context data - Thanks @seratch
    • #543 Fix url_verification error with the Flask adapter - Thanks @seratch
    • #544 Fix #542 Add additional context values for FastAPI apps - Thanks @kafejo @seratch
    • #528 Add GitHub stale action for better triaging process - Thanks @srajiang
    • #547 Upgrade pytype, black versions - Thanks @seratch

    Document Updates

    • #519 #518 An error in the HTTP mode Getting Started document (JP) - Thanks @TORIFUKUKaiou
    • #523 Improve the Django app example to be more robust - Thanks @seratch
    • #538 Update the respond utility guide - Thanks @seratch
    • #541 Fix #525 Japanese translation for #524 (lazy listeners doc updates) - Thanks @wongjas
    • #534 Update link to view submissions doc - Thanks @wongjas
    • #535 Fixes #534, updates link to view submissions - Thanks @wongjas
    • #524 Update lazy lambda docs - Thanks @srajiang

    References

    • Release Milestone: https://github.com/slackapi/bolt-python/milestone/42?closed=1
    • All Diff: https://github.com/slackapi/bolt-python/compare/v1.10.0...v1.11.0
    Source code(tar.gz)
    Source code(zip)
  • v1.10.0(Nov 4, 2021)

    New Features

    Improvement of Django ORM database connection management

    Since this release, the Django adapter has been improved to properly manage the thread-local database connections bound to the threads managed by Bolt framework. If you use the Django adapter, we highly recommend upgrading to this version or newer.

    Please refer to #514 #512 #509 for more details.

    Changes

    • #514 #512 #509 Introduce ListenerStartHandler in the listener runner for better managing Django DB connections - Thanks @ross @seratch
    • #516 Improve the GitHub Actions job settings - Thanks @seratch

    Document Updates

    • #507 #505 #508 #506 Bunch of Japanese document updates - Thanks @TORIFUKUKaiou
    • #500 Update OAuth link to point to JP docs instead of EN - Thanks @wongjas

    References

    • Release Milestone: https://github.com/slackapi/bolt-python/milestone/47?closed=1
    • All Diff: https://github.com/slackapi/bolt-python/compare/v1.9.4...v1.10.0
    Source code(tar.gz)
    Source code(zip)
  • v1.9.4(Oct 29, 2021)

    Changes

    • #497 Add Python 3.10 to the supported versions - Thanks @seratch
    • #503 Fix a bug in the asyncio based token rotation support - Thanks @dkzk22
    • #504 Bump optional dependencies for v1.9.4 release - Thanks @seratch
    • #496 Upgrade pytype to the latest - Thanks @seratch

    References

    • milestone: https://github.com/slackapi/bolt-python/milestone/46?closed=1
    • diff: https://github.com/slackapi/bolt-python/compare/v1.9.3...v1.9.4
    Source code(tar.gz)
    Source code(zip)
  • v1.9.3(Oct 13, 2021)

    Changes

    • #488 app.message listeners do not catch messages with subtype: thread_broadcast - Thanks @seratch @kanny

    Document updates:

    • Fix #480 #479 Adds updating views on submission for Japanese docs - Thanks @wongjas

    References

    • milestone: https://github.com/slackapi/bolt-python/milestone/45?closed=1
    • diff: https://github.com/slackapi/bolt-python/compare/v1.9.2...v1.9.3
    Source code(tar.gz)
    Source code(zip)
  • v1.9.2(Sep 28, 2021)

    Changes

    • #477 Add more guide message in the HTML generated by the default failure handler - Thanks @seratch @misscoded @filmaj
    • #476 Improve the error message in the case where AuthorizeResult is not found - Thanks @seratch

    Document updates:

    • #479 Adds update view on submission docs - Thanks @srajiang
    • #472 update block id from listening modals - Thanks @bodepd

    References

    • milestone: https://github.com/slackapi/bolt-python/milestone/44?closed=1
    • diff: https://github.com/slackapi/bolt-python/compare/v1.9.1...v1.9.2
    Source code(tar.gz)
    Source code(zip)
  • v1.9.1(Sep 7, 2021)

    Changes

    • #460 Fix #459 Invalid type hints in App / AsyncApp - Thanks @seratch @chrisbouchard

    References

    • milestone: https://github.com/slackapi/bolt-python/milestone/43?closed=1
    • diff: https://github.com/slackapi/bolt-python/compare/v1.9.0...v1.9.1
    Source code(tar.gz)
    Source code(zip)
  • v1.9.0(Aug 31, 2021)

    New Features

    More Customization for Apps

    Since this release, developers can customize listener_executor in apps. Also, to support the use case where Enterprise Grid Org admins install apps from their app management page, we've added a new option to disable state parameter validation in the OAuth flow. Please note that we still don't recommend disabling the state validation for usual OAuth apps.

    Changes

    • #452 #453 Enable to customize the listener_executor in App - Thanks @chrisbouchard
    • #455 #454 Add oauth_settings.state_validation_enabled to customize the OAuth flow - Thanks @seratch

    References

    • milestone: https://github.com/slackapi/bolt-python/milestone/41?closed=1
    • diff: https://github.com/slackapi/bolt-python/compare/v1.8.1...v1.9.0
    Source code(tar.gz)
    Source code(zip)
  • v1.8.1(Aug 28, 2021)

    Changes

    • #451 Fix cookie extraction during OAuth for REST based AWS API GW + Lambda app - Thanks @naveensan1
    • #449 Fix typo in App / AsyncApp comments and API documents - Thanks @objectfox
    • #446 Update the entity name - Thanks @seratch

    References

    • milestone: https://github.com/slackapi/bolt-python/milestone/38?closed=1
    • diff: https://github.com/slackapi/bolt-python/compare/v1.8.0...v1.8.1
    Source code(tar.gz)
    Source code(zip)
Owner
SlackAPI
https://api.slack.com
SlackAPI
A RESTful API for creating and monitoring resource components of a hypothetical build system. Built with FastAPI and pydantic. Complete with testing and CI.

diskspace-monitor-CRUD Background The build system is part of a large environment with a multitude of different components. Many of the components hav

Nick Hopewell 67 Dec 14, 2022
A Flask extension that enables or disables features based on configuration.

Flask FeatureFlags This is a Flask extension that adds feature flagging to your applications. This lets you turn parts of your site on or off based on

Rachel Greenfield 131 Sep 26, 2022
Qwerkey is a social media platform for connecting and learning more about mechanical keyboards built on React and Redux in the frontend and Flask in the backend on top of a PostgreSQL database.

Flask React Project This is the backend for the Flask React project. Getting started Clone this repository (only this branch) git clone https://github

Peter Mai 22 Dec 20, 2022
Learn to deploy a FastAPI application into production DigitalOcean App Platform

Learn to deploy a FastAPI application into production DigitalOcean App Platform. This is a microservice for our Try Django 3.2 project. The goal is to extract any and all text from images using a technique called OCR.

Coding For Entrepreneurs 59 Nov 29, 2022
Sample-fastapi - A sample app using Fastapi that you can deploy on App Platform

Getting Started We provide a sample app using Fastapi that you can deploy on App

Erhan BÜTE 2 Jan 17, 2022
This is an API developed in python with the FastApi framework and putting into practice the recommendations of the book Clean Architecture in Python by Leonardo Giordani,

This is an API developed in python with the FastApi framework and putting into practice the recommendations of the book Clean Architecture in Python by Leonardo Giordani,

null 0 Sep 24, 2022
API using python and Fastapi framework

Welcome ?? CFCApi is a API DEVELOPMENT PROJECT UNDER CODE FOR COMMUNITY ! Project Walkthrough ?? CFCApi run on Python using FASTapi Framework Docs The

Abhishek kushwaha 7 Jan 2, 2023
FastAPI framework plugins

Plugins for FastAPI framework, high performance, easy to learn, fast to code, ready for production fastapi-plugins FastAPI framework plugins Cache Mem

RES 239 Dec 28, 2022
FastAPI framework plugins

Plugins for FastAPI framework, high performance, easy to learn, fast to code, ready for production fastapi-plugins FastAPI framework plugins Cache Mem

RES 93 Feb 16, 2021
A FastAPI Framework for things like Database, Redis, Logging, JWT Authentication and Rate Limits

A FastAPI Framework for things like Database, Redis, Logging, JWT Authentication and Rate Limits Install You can install this Library with: pip instal

Tert0 33 Nov 28, 2022
An extension library for FastAPI framework

FastLab An extension library for FastAPI framework Features Logging Models Utils Routers Installation use pip to install the package: pip install fast

Tezign Lab 10 Jul 11, 2022
Flask-vs-FastAPI - Understanding Flask vs FastAPI Web Framework. A comparison of two different RestAPI frameworks.

Flask-vs-FastAPI Understanding Flask vs FastAPI Web Framework. A comparison of two different RestAPI frameworks. IntroductionIn Flask is a popular mic

Mithlesh Navlakhe 1 Jan 1, 2022
Light, Flexible and Extensible ASGI API framework

Starlite Starlite is a light and flexible ASGI API framework. Using Starlette and pydantic as foundations. Check out the Starlite documentation ?? Cor

null 1.5k Jan 4, 2023
FastAPI-Amis-Admin is a high-performance, efficient and easily extensible FastAPI admin framework. Inspired by django-admin, and has as many powerful functions as django-admin.

简体中文 | English 项目介绍 FastAPI-Amis-Admin fastapi-amis-admin是一个拥有高性能,高效率,易拓展的fastapi管理后台框架. 启发自Django-Admin,并且拥有不逊色于Django-Admin的强大功能. 源码 · 在线演示 · 文档 · 文

AmisAdmin 318 Dec 31, 2022
Cookiecutter API for creating Custom Skills for Azure Search using Python and Docker

cookiecutter-spacy-fastapi Python cookiecutter API for quick deployments of spaCy models with FastAPI Azure Search The API interface is compatible wit

Microsoft 379 Jan 3, 2023
Generate modern Python clients from OpenAPI

openapi-python-client Generate modern Python clients from OpenAPI 3.x documents. This generator does not support OpenAPI 2.x FKA Swagger. If you need

Triax Technologies 558 Jan 7, 2023
Docker image with Uvicorn managed by Gunicorn for high-performance FastAPI web applications in Python 3.6 and above with performance auto-tuning. Optionally with Alpine Linux.

Supported tags and respective Dockerfile links python3.8, latest (Dockerfile) python3.7, (Dockerfile) python3.6 (Dockerfile) python3.8-slim (Dockerfil

Sebastián Ramírez 2.1k Dec 31, 2022
High-performance Async REST API, in Python. FastAPI + GINO + Arq + Uvicorn (w/ Redis and PostgreSQL).

fastapi-gino-arq-uvicorn High-performance Async REST API, in Python. FastAPI + GINO + Arq + Uvicorn (powered by Redis & PostgreSQL). Contents Get Star

Leo Sussan 351 Jan 4, 2023
Turns your Python functions into microservices with web API, interactive GUI, and more.

Instantly turn your Python functions into production-ready microservices. Deploy and access your services via HTTP API or interactive UI. Seamlessly export your services into portable, shareable, and executable files or Docker images.

Machine Learning Tooling 2.8k Jan 4, 2023