Skip to content

Instantly share code, notes, and snippets.

@WilliamBergamin
Last active March 13, 2024 05:25
Show Gist options
  • Save WilliamBergamin/e7ccc6ad4383b6883f832cbef2b6215a to your computer and use it in GitHub Desktop.
Save WilliamBergamin/e7ccc6ad4383b6883f832cbef2b6215a to your computer and use it in GitHub Desktop.
MVP python function handler
import logging
from slack_sdk import WebClient
from slack_bolt import App, Ack, Say, Complete, Fail, BoltContext
from slack_bolt.adapter.socket_mode import SocketModeHandler
logging.basicConfig(level=logging.DEBUG)
app = App()
@app.function("hello")
def handle_function_executed_events(
ack: Ack,
event: dict,
inputs: dict,
say: Say,
):
ack()
assert event["bot_access_token"] == say.client.token
user_id = inputs["user_id"]
say(
channel=user_id, # sending a DM to this user
text="Click this! Let's go!",
blocks=[
{
"type": "section",
"text": {"type": "mrkdwn", "text": "Click this!"},
"accessory": {
"type": "button",
"text": {"type": "plain_text", "text": "Let's go!"},
"action_id": "button_click",
},
}
],
)
@app.action("button_click")
def handle_button_clicks(
ack: Ack,
body: dict,
context: BoltContext,
client: WebClient,
complete: Complete,
fail: Fail,
):
ack()
assert body["bot_access_token"] == client.token
try:
# Since the button no longer works, we should remove it
client.chat_update(
channel=context.channel_id,
ts=body["message"]["ts"],
text="Thank you!",
)
# Tell the automation platform that this remote function completed
complete({"user_id": context.actor_user_id})
except Exception as e:
fail(f"Failed to handle a function request (error: {e})")
if __name__ == "__main__":
# export SLACK_APP_TOKEN=xapp-1-...
# export SLACK_BOT_TOKEN=xoxb-...
# python app.py
SocketModeHandler(app).start()
display_information:
name: manifest-test-app
features:
bot_user:
display_name: manifest-test-bot
always_online: true
oauth_config:
scopes:
bot:
- commands
- chat:write
settings:
interactivity:
is_enabled: true
org_deploy_enabled: true
socket_mode_enabled: true
token_rotation_enabled: false
hermes_app_type: remote
function_runtime: remote
functions:
hello:
title: Hello
description: Hello world!
input_parameters:
user_id:
type: slack#/types/user_id
title: User
description: Who to send it
is_required: true
hint: Select a user in the workspace
name: user_id
output_parameters:
user_id:
type: slack#/types/user_id
title: User
description: Who to send it
is_required: true
hint: Select a user in the workspace
name: user_id
@WilliamBergamin
Copy link
Author

  1. Create a new app
    a. Head to https://api.slack.com/apps/?new_app=1
    b. Click "From an app manifest"
    c. Select YAML and paste the above manifest.yml content
    d. Click create button
  2. Install the app into org/workspace
    a. Install the app anyways (when the workspace is in an Org, org-wide installation is required to publish functions)
    b. Grab the xoxb- token (Settings > Install App > Bot User OAuth Token)
    c. export SLACK_BOT_TOKEN=xoxb-...
  3. Set up Socket Mode
    a. Head to Settings > Basic Information > App-Level Tokens on the https://api.slack.com/apps page
    b. Generate a new token with connections:write scope
    c. export SLACK_APP_TOKEN=xapp-...
  4. Spin up the app
    a. Add app.py and async_app.py with the above source code
    b. Pull the latest PR branch of bolt python to your local
    c. Run scripts/build_pypi_package.sh this will generate a .whl in the dist/ folder
    d. (Optional) In your project set up a venv with python -m venv .venv and source .venv/bin/activate
    e. pip install global/path/to/bolt-python/dist/something.whl
    f. pip install aiohttp
    g python app.py or python async_app.py
  5. Add the custom step to a workflow
    a. Open the workflow builder
    b. Create a new workflow with a link trigger
    d. Seach "Hello" in the Steps view on the right side
    e. Add the step to the workflow (you can set any user ID as the input)
    f. Publish the workflow

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment