Git Product home page Git Product logo

python-message-menu-example's Introduction

Maximizing your Slack app's usefulness

When we think about how bots and humans interact within Slack, we often think of two types of interaction: Notification and Conversation.

The simplest form of Slack integration is to have your app post important information from another service into a slack channel. This works well for a variety of situations, such as package arrival notifications or an alert that one of your servers has caught on fire. Notifications are simple, timely, and informative. When your app is a part of a much more complex workflow, notifications are just a jumping point into another application or process.

As your processes and workflows become more complex, involving several applications across multiple windows, things can get ...complicated.

Message Buttons

Back in June, we released Message Buttons. Using these new interactive elements, developers were able to bring common workflow actions right into the bot's message. Users could not only see the notification message, but take action from inside Slack. This also eased a lot of the complexity with conversational bots. Rather than requiring a user to type a specific confirmation message, you were able to show the user a set of buttons to complete or cancel an action.

Message Buttons demo GIF

While Message Buttons are a great way to increase the usability of your Slack application, there are some limitations. One limitation is the amount of real estate buttons take up. When you have a large set of options, you'll end up with a message that takes up the user's entire chat window or gets truncated.

See our Message Buttons with Node.js tutorial for more information on how to add message buttons to your app.

Message Menus

Today we've released message menus ๐ŸŽ‰

Message menus are the newest interactive feature for Slack apps: clickable dropdown menus that you can add to message attachments. They can have static options, or they can load dynamically. You can build with five types of message menu today, each achieving a different flavor of use case: static menus, user menus, channel menus, conversation menus, and dynamic menus.

Slack message menu example

Read more about how apps are using message menus on our blog.

Adding message menus to your app

In this tutorial, we'll focus on adding dynamic option menus to your app. Here's a summary of how dynamic interactive message menus work:

  1. Post a message containing one or more attachments containing one or more interactive elements
  2. Slack sends a request to your registered Options Load URL containing the context you need to generate relevant menu options. You simply respond to this request with a JSON array of options.
  3. Users click a button or select an option from a menu
  4. A request is sent to your registered Action URL containing all the context you need to understand: who clicked it, which option they clicked, which message callback_id was associated with the message, and the original message inciting the selection
  5. You respond to your Action URL's invocation with a message to replace the original, and/or a new ephemeral message, and/or you utilize the invocation's response_url to update the original message out of band for a limited time.

Let's build it!

๐Ÿ’ก This code is also available as a complete example application on GitHub.

While we're building this example in Python, we haven't forgotten about the Node fans. We've put together a really neat example for Node.js over here ๐ŸŽ‰

For this example, we're going to need Python, the Python Slack client (slackclient) and a webserver (Flask).

First you'll create the basic elements of the app: A Slack client and webserver

from flask import Flask, request, make_response, Response
from slackclient import SlackClient
import json

# Your app's Slack bot user token
SLACK_BOT_TOKEN = os.environ["SLACK_BOT_TOKEN"]

# Slack client for Web API requests
slack_client = SlackClient(SLACK_BOT_TOKEN)

# Flask webserver for incoming traffic from Slack
app = Flask(__name__)

Then we'll add the two endpoints Slack will POST requests to. The first endpoint is where Slack will send a request for items to populate the menu options, we'll call this one message_options.

@app.route("/slack/message_options", methods=["POST"])
def message_options():
    # Parse the request payload
    form_json = json.loads(request.form["payload"])

    menu_options = {
        "options": [
            {
                "text": "Chess",
                "value": "chess"
            },
            {
                "text": "Global Thermonuclear War",
                "value": "war"
            }
        ]
    }

    return Response(json.dumps(menu_options), mimetype='application/json')

The second endpoint you'll need is where Slack will send data when a user makes a selection. We'll call this one message_actions.

@app.route("/slack/message_actions", methods=["POST"])
def message_actions():

    # Parse the request payload
    form_json = json.loads(request.form["payload"])

    # Check to see what the user's selection was and update the message
    selection = form_json["actions"][0]["selected_options"][0]["value"]

    if selection == "war":
        message_text = "The only winning move is not to play.\nHow about a nice game of chess?"
    else:
        message_text = ":horse:"

    response = slack_client.api_call(
      "chat.update",
      channel=form_json["channel"]["id"],
      ts=form_json["message_ts"],
      text=message_text,
      attachments=[]
    )

    return make_response("", 200)

Now that our endpoints are configured, we can build the message containing the menu and send it to a channel.

In order to show the menu, we'll have to build the message attachment which will contain it.

message_attachments = [
    {
        "fallback": "Upgrade your Slack client to use messages like these.",
        "color": "#3AA3E3",
        "attachment_type": "default",
        "callback_id": "menu_options_2319",
        "actions": [
            {
                "name": "games_list",
                "text": "Pick a game...",
                "type": "select",
                "data_source": "external"
            }
        ]
    }
]

Once the attachment JSON is ready, simply post a message to the channel, adding the attachment containing the menu.

slack_client.api_call(
  "chat.postMessage",
  channel="C09EM2073",
  text="Shall we play a game?",
  attachments=message_attachments
)

Take note of the "data_source": "external" attribute in the attachment JSON. This is how Slack knows to pull the menu options from the message_options endpoint we set up above.

slack_client.api_call(
  "chat.postMessage",
  channel="C09EM2073",
  text="Shall we play a game?",
  attachments=attachments_json
)

Support

Need help? Join Bot Developer Hangout and talk to us in #slack-api.

You can also create an Issue right here on GitHub.

python-message-menu-example's People

Contributors

roach avatar

Watchers

James Cloos avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.