Interactive Slack Messages

Meet your team where they are! In this blog post we will learn how to build interactive Slack messages that can be sent from any MAP or CRM, which will allow your team to do things like route meetings/leads/accounts or approve emails, documents, or duplicate merges all without having to leave Slack.

This blog post will be quite technical since it uses the Slack API and Python scripts to enable the interactivity. If you are not familiar with APIs and you do not know how to program with an LLM as your coding partner then I recommend checking out the Demystify the API and Python for RevOps crash courses.

The Slack Block Kit Builder is THE starting place for building your interactive Slack messages. It offers a graphic drag and drop builder where you can:

  1. Drag in components from the left hand side of the screen
  2. See the rendered message on the left
  3. See the underlying JSON code on the right that you can use to modify the message text
  4. Send a test message to Slack using the button at the top right hand corner of the screen
  5. Copy the finalized JSON code into your Python script or webhook payload
Screenshot of the block kit builder used to create interactive Slack messages
Slack Block Kit Builder

In this blog post we will be using a simple template with a single button that will bring up a modal when pressed.

A simple Slack message template with a single interactive button
Simple template

Once we have the design of our Slack message configured, we need to create a Slack App that will allow us to send automated messages to Slack.

These are the first steps necessary to create the app and stylize it.

  1. Go to https://api.slack.com/apps
  2. Click “Create New App”
  3. Choose “From scratch”
  4. Enter an app name and choose the correct Slack workspace
  5. Click “Create App”
  6. Under “Basic Information” > “Display Information” you have the option to upload an image/icon for your app, set the background color, and enter a short and long description
Screenshot of a Slack app for sending Marketo notifications showing the Marketo logo
Slack app for Marketo notifications

These define the permissions that our App will have and therefore the actions it will be able to carry out.

  1. Go to “OAuth & Permissions” > “Bot Token Scopes” and add:
    • chat:write
    • users.profile:read
    • reactions:write
  2. Click “Install to Workspace” under the “OAuth Tokens” section
  3. Approve the app install
  4. Note the bot token that starts with “xoxb”, you will need to put this in your .env file later on
  5. Open “Basic Information”
  6. Note the “Signing Secret”, you will need to put this in your .env file later on
  7. Add the app to any channels it needs to post to by going to “Integrations” > “Add apps” for each channel

Finally, we need to enable interactivity so that we can have a pop-up modal where people can enter information.

  • Open “Interactivity & Shortcuts”
  • Turn the toggle button to “On”
  • Set the “Request URL” to either the ngrok or Replit base URL followed by “/slack/interactions” e.g. https://dd56-2600-1700-42c0-12f0-6587-8828-7de9-6801.ngrok-free.app/slack/interactions
  • Click “Save Changes”

The flow for Slack interactivity is as follows:

  1. The initial message is sent to Slack either using the send_slack_message.py script or from a webhook in your CRM or MAP e.g. using the payload in marketo_webhook_payload.json
Screenshot of an interactive Slack message containing information about an MQL sent from Marketo
Initial Slack Message
  1. Clicking the “Review” button will cause Slack to send a request to the listener server containing the signing token for authentication. The slack_interactions_listener.py script then calls the build_review_modal function which uses the information passed from Slack to populate the modal JSON body.
Flow diagram showing Slack sending a request to the listener server which will call the "build modal" function
Slack requesting modal information
  1. The modal JSON body is then returned to Slack
Flow diagram showing the modal information being sent from the listener server back to Slack from the "build modal" function
Modal information sent back to Slack
  1. Slack uses the JSON body to create the modal that is then displayed to the user
Screenshot showing the rendering of the pop-up modal in Slack
Pop-up modal in Slack
  1. The user fills out the fields in the modal and hits the “Submit” button
Screenshot showing the Slack modal with the status, status reason, and sales owner fields populated
Submitting the modal
  1. Slack sends the submitted information along with the signing token for authentication to the listener server. The slack_interactions_listener.py script then goes down the “view_submission” branch and parses out the status, status reason, and Slack user id of the selected sales owner. The email address of the Slack user is then retrieved using the get_sales_owner_email function and then sent along with the lead id, status, and status reason to the update_lead function to update the lead in Marketo with these values via API.
Flow diagram showing the modal information being sent from Slack to the listener server where the information is parsed and then used to update the lead in Marketo
Handling modal submission
Screenshot showing the status, status reason, and sales owner email address fields updated in the Marketo activity log
Marketo activity log
  1. Finally, the add_reaction function is called so that a check mark reaction is added to the message in Slack to denote that the message has been actioned
Flow diagram showing the confirmation being sent back to Slack from the "Handle Submission" branch of the listener server
Confirming submission & adding reaction
Screenshot showing how a check mark reaction is added to the interactive Slack message to indicate that it has been actioned
Reaction added to message

The README.md is a great place to start for either you or your LLM coding partner to understand the repo structure and learn how to get things set up e.g. creating your virtual environment and .env file.

If you find yourself struggling doing the set up, running the scripts, setting up ngrok, publishing in Replit, or troubleshooting errors then check out the Python for RevOps crash course, which will teach you how to work with an LLM coding partner to do all these things with ease.

Once you have sent the initial message to Slack, you can test the modal by running slack_interactions_listener.py in one terminal, which runs the flask app on port 8080 of your local machine. The only change you will need to make to this script is to insert the Marketo API field names of the fields where you want to store the values parsed from Slack. Alternatively, you can modify this script so that the information is sent to another platform e.g. Salesforce or HubSpot.

Screenshot of the code section where the Marketo API field names need to be updated
Marketo API field names to update

Then in a second terminal run the the command ngrok http 8080 to expose your local port 8080 to the internet so that Slack can see and send information to this port. As shown in the diagram below, ngrok acts as a middleman forwarding information between your local machine and Slack.

You will then take the forwarding URL returned by ngrok e.g. https://dd56-2600-1700-42c0-12f0-6587-8828-7de9-6801.ngrok-free.app and put that in the “Request URL” field in the “Interactivity & Shortcuts” section of your Slack app followed by /slack/interactions.

Flow diagram showing ngrok acting as a middleman to forward information between Slack and the listener server
ngrok tunnelling

Once you have tested the modal functionality locally and pushed your code to GitHub, you are ready to deploy your listener server to Replit so that it is publicly accessible on the internet i.e. no more need for ngrok as a middleman.

From the Replit home page:

  1. Click “Import code or design”
  2. Click “GitHub”
  3. Enter the “GitHub Repo URL”
  4. Click “Import from GitHub”

Replit’s AI agent will then do the necessary set up e.g. creating a .replit file and installing dependencies. All you need to do is populate the Replit secrets with your Marketo and Slack credentials: I recommend clicking the “More” button and then “Edit as .env” so that you simply paste in the content of the .env file you have from testing locally on your laptop.

I will use the example of sending a webhook from Marketo but the payload in the marketo_webhook_payload.json template could be used in any MAP or CRM, you will just need to replace the tokens with those from your MAP or CRM.

If you need help setting up your webhook then check out the Marketo Slack Integration post to see how to get the Slack URL for the channel that you want to post messages to.

Screenshot of the webhook configuration in Marketo to send interactive messages to Slack
Marketo webhook configuration

Now that you know how to create interactive Slack messages and have seen the power of combining APIs and Python, you should check out the AI for RevOps crash course to learn how you can add AI intelligence to your workflows using tools like MCP, fine-tuning, batch API, RAG, and multi-agent orchestration.