In the realm of high-performance hosting and versatile development tools, Kinsta stands out as a leading platform catering to WordPress, applications, databases, and even free Static Site Hosting.

Slack, renowned for its Slash Commands, seamlessly integrates with Kinsta-hosted apps and services, enabling users to automate tasks and significantly enhance efficiency.

This guide explains how to set up real-time communication between Slack and a Python application hosted on Kinsta. By harnessing Slash Commands, users of the application gain the ability to swiftly create, query, and delete products.

This integration empowers them to dynamically update their product inventory dynamically, ensuring prompt responses to customer needs.

Understanding Slack’s Slash Commands

Slack Slash Commands are text-based shortcuts. They begin with a forward slash (/) followed by a specific keyword and optional parameter.

Slash Commands trigger actions or directly interact with integrations within the Slack interface. For example, /remind enables setting reminders directly through Slack notifications.

With Slack integrations, you can configure tailored commands for your applications. In this tutorial, your team can effortlessly query our product app’s inventory using the /check_inventory Slash Command and other commands.

Integrating Slack with your apps fosters seamless interaction and streamlined workflows within a modern workplace. It enhances communication and productivity via:

  • A centralized communication hub — Slack acts as a unified space for teams. Integrating apps into Slack consolidates channels, keeping conversations and info in one place, and boosting efficiency.
  • Real-time updates — Integrated apps provide instant alerts about key events, ensuring everyone stays informed and reacts quickly to changes or updates.
  • Streamlined workflows — Integrations automate tasks like notifications from project management tools or triggering actions in CRM software, cutting down on manual work.
  • Enhanced collaboration — Team members accessing apps directly from Slack fosters seamless collaboration. They can easily share, edit files, and discuss projects, promoting teamwork across functions.

How To Build a Python Application on Kinsta

Let’s build and deploy a product management application on Kinsta. Then, integrate it with Slack to explore Slash Commands. Users can add, delete, and query the inventory’s products via Slash Commands in Slack.

Prerequisites

To follow along with this guide, we assume you have:

First, let’s set up a Python project on Kinsta. To do this, follow the steps below:

  1. Visit the Kinsta’s Python template on GitHub.
  2. Select Use this template > Create a new repository to copy the starter code into a repository within your GitHub account.
  3. Once your repository is ready, log in or create an account to view your MyKinsta dashboard.
  4. Authorize Kinsta with your Git provider (Bitbucket, GitHub, or GitLab).
  5. Click Applications on the left sidebar, then click Add application.
  6. Select the repository and the branch you wish to deploy from.
  7. Assign a unique name to your application and choose a data center location.
  8. Configure your build environment next. Select the Standard build machine config with the recommended Nixpacks option for this demo.
  9. Use all default configurations and then click Create application.

Deployment typically takes a few minutes, and upon success, you’ll receive a link to your application along with a dashboard containing deployment information.

How To Set Up Slack Integration In Python Application

Let’s get started by creating a Slack application and then configure Slash commands which would be connected to your Python application via some tokens. Let’s configure a Slack app:

  1. Access the Slack API dashboard.
  2. Click Create New App and choose From Scratch.
  3. Name your Slack app (e.g., product-inventory).
  4. Select the workspace and click Create App.

Now, for authentication:

  1. Enable Socket Mode in your Slack dashboard’s sidebar.
  2. Generate an app-level token by typing a token name and clicking Generate.
  3. Save this app-level token for configuring environmental variables later.

How To Configure Slash Commands

To set up your app’s Slash Commands:

  1. Navigate to the Features section under Basic Information in the Slack API dashboard. Choose Slash Commands.

    Slack API dashboard with options for adding features and functions
    Slack API dashboard with options for adding features and functions.

  2. Click Create New Command to configure a new command.

    Slack Create New Command page with options for command, short description, and usage hint. Also has details for escape channels, users, and links sent to your app and a preview of an autocomplete entry
    Create New Command page on Slack.

  3. On the Create New Command page, fill in the details for your new Slash Command. For instance, type /hi in the Command field. Optionally, add a brief description like “Says hello!” and provide a usage hint. Click Save.
  4. In the Install App section of the sidebar, click Install to Workspace.
  5. Access the bot user OAuth token by heading to OAuth & Permissions on the sidebar. Save this token for future reference.

How To Add Tokens to Kinsta’s Application Deployment

  1. Go to the Environment Variables section under Settings of your application deployment in MyKinsta.
  2. Click Add environment variable.

    Slack Add environment variable popup with keys, values, and the option to remove them or add another
    Slack Add environment variable popup.

  3. For Key 1, SLACK_BOT_TOKEN, paste the bot user OAuth token in Value 1. For Key 2, SLACK_APP_TOKEN, paste the app-level token in Value 2.
  4. Ensure both options are checked and click Deploy now so Kinsta can redeploy your application with the environment variables.

How To Implement Real-Time Communication

For this demo, you use the Kinsta’s Python template, which contains the following files:

  • Procfile — Specifies the commands to run your application.
  • requirements.txt — Lists the dependencies required for the Python application.
  • server.py — The main file of the Python application, handling server-side functionality or operations.

Kinsta automatically creates a process based on the Procfile in the repository root when deploying an application. The Procfile contains the following code.

web: python server.py

This command runs the code that server.py contains. Kinsta also installs the Python dependencies in requirements.txt during deployment and redeployment.

Now, let’s use the Bolt framework to set up real-time communication with your application. Add the following lines to your requirements.txt file to automatically install Bolt on your Python application when you update the repository.

slack-bolt==1.18.0
slack-sdk==3.23.0

Also, add the psycopg2 library to the requirements.txt file. This will be used to connect to a Postgres database.

psycopg2-binary==2.9.9

How To Implement a Postgres Database With Kinsta

The product inventory app needs a way to persist product data that Slash Commands add to the database. To create persistent data storage, you can use Kinsta’s hosted database.

  1. First, deploy a Postgres database on your Kinsta dashboard by navigating to the Databases section on the sidebar of MyKinsta’s dashboard.
  2. Click Create a database. Configure your database details by entering a name and selecting the database type. Select the PostgreSQL option and configure your desired size. A Database username and password is automatically generated:

    Form for creating a database. The fields include the database name, display name, database type and version, database username and password, data center location, and size. There are two buttons at the bottom of the form: Cancel and Continue
    Form for creating a database.

  3. Click Continue to finish setting up your database. Wait for the PostgreSQL database to be created.
    Once successful, to get your connection string for external access to your database, navigate to the External connections section of your deployed database dashboard and copy the External connection string.
    The info page for the deployed database dashboard. Details include resources, location, version, creation date, a list of internal connections, and information about internal connections, including the connection string.
    Database external connection information.

    Now, you can use this connection string to connect to the database from your Python application.

  4. In your Python project, create a db.py file within your project directory for database initialization functions. Add the following code:
    import psycopg2
    import os
    
    # get connection string from environment variable
    connection_string = os.environ.get("DATABASE_CONNECTION_STRING")
     
    def get_conn():
       # create connection
       conn = psycopg2.connect(connection_string)
    
       # Return connection to the database
       return conn
         
    def init_db():
       # get connection
       conn = get_conn()
    
       # get cursor
       cur = conn.cursor()
    
       cur.execute("""
           DROP TABLE IF EXISTS products;
                       
           CREATE TABLE products (
               id INTEGER PRIMARY KEY,
               name TEXT UNIQUE NOT NULL,
               quantity INTEGER NOT NULL
           );
       """)
    
       cur.close()
       conn.commit()
       conn.close()

    When the get_conn() function is called, it creates and returns a connection to the deployed Kinsta database using your external connection string.

    The init_db() function gets a database connection, defines the database schema, and creates the table while also committing the changes. You should only call the init_db() function once when initially setting up the application server. Use the get_conn() function in subsequent calls to get a connection to the database.

How To Implement the Slash Command Handlers

Now, build the application server code.

  1. Delete the server.py file’s contents and import the following libraries:
    import os
    from slack_bolt import App
    from slack_bolt.adapter.socket_mode import SocketModeHandler
    from db import get_conn, init_db
    from psycopg2 import DatabaseError

    These are required for Slack app functionality, database connections, and error handling.

  2. Add the following code to the server.py file after the import statements:
    # Initialize your app with your bot token
    app = App(
      token=os.environ.get("SLACK_BOT_TOKEN"),
    )

    The App class from slack_bolt is used to create an instance of the Slack app. It initializes the app with the bot user OAuth token retrieved from the environment variable SLACK_BOT_TOKEN.

  3. Next, deploy a handler for the /hi Slash Command you added to your Slack application earlier. Add the following lines to the server.py file.
    # The hi command simply sends back a greeting
    @app.command("/hi")
    def send_hello(ack, respond, command):
      # Acknowledge command request
      ack()
      respond(f"Hello!")

    The @app.command() creates a listener for the command string passed as an argument and maps the following function for that Slash Command’s requests. The send_hello() function handles the request logic.

    The code also passes the request variables ack, respond, and command for the function to use. Call ack to acknowledge the Slash Command request, as this is the first step before continuing processing, and call respond to send back a text response.

    When the user types the Slash Command /hi in your Slack workspace, they get the response, “Hello!”

  4. Return to your Slack application dashboard and add the following commands.
    Command Short Description Usage Hint
    /add_product Add a product to the inventory. product_id, product_name, product_quantity
    /check_inventory Check for a product with a matching ID in inventory. product_id
    /delete_product Delete product with matching ID from inventory. product_id

    Now, your Slash Commands page should look like the following screenshot containing a list of commands and their details.

    Slash Commands page listing each one's name and description with options to edit or delete, and a Create New Command button
    Slack API Slash Commands page.

  5. Add the /add_product handler to the server.py file.
    # command to add products
    @app.command("/add_product")
    def add_product(ack, respond, command, request):
     #Acknowledge command request
     ack()
    
     # Extract payload from request
     payload = request.body['text']
     id, name, quantity = [i.strip() for i in payload.split(",")]
      
     # conn object
     conn = None
    
     try:
       # get conn
       conn = get_conn()
    
       # get cursor
       cur = conn.cursor()
    
       # Insert product into the database
       cur.execute(
         "INSERT INTO products (id, name, quantity) VALUES (%s, %s, %s)",
           (int(id), name, int(quantity))
       )
       
       # close communication with postgresql
       cur.close()
       
       # commit changes
       conn.commit()
       
       # Response
       respond(f"""Added product to inventory:
         id - {id},
         name - {name},
         quantity - {quantity}
       """)
    
     except DatabaseError:
       # Send a response
       respond(f"Product with ID {id} exists in inventory!")
      
     finally:
       # close connection
       if conn is not None:
         conn.close()

    request.body accesses the full request payload Slack sends during the handling process.

    When a user types the /add_product Slash Command, the application sends the following sample JSON payload as a POST request.

    {
        'token': , 
        'team_id': , 
        'team_domain': , 
        'channel_id': , 
        'channel_name': , 
        'user_id': , 
        'user_name': , 
        'command': '/add_product', 
        'text': '1, notebook, 5', 
        'api_app_id': , 
        'is_enterprise_install': , 
        'response_url': , 
        'trigger_id': 
    }

    The command and text fields are included. command contains the triggered Slash Command while text contains its additional text. For example, if the user types the command /add_product 1, notebook, 5, text contains “1, notebook, 5”.

    The add_product handler extracts the product’s ID, name, and quantity from the user’s request and connects to the database using the get_conn() helper function. It also executes an insert SQL operation to add the product to the database. If the product ID already exists in the database, the code handles the error and responds that the ID already exists.

  6. Now, add the rest of the command handlers to the server.py file.
    # command to check inventory for a product_id
    @app.command("/check_inventory")
    def check_inventory(ack, respond, command, request):
       # Acknowledge command request
       ack()
    
       # Extract payload from request
       id = request.body['text'].strip()
    
       # Get a database connection
       conn = None
       try:
           # get conn
           conn = get_conn()
    
           # get cursor
           cur = conn.cursor()
     
           # Fetch matching product with ID from database
           cur.execute(
               "SELECT * FROM products WHERE id=%s",
               (int(id),)
           )
    
           product = cur.fetchone()
    
           # close comms
           cur.close()
    
           if product is None:
               respond(f"No product with matching ID {id} found.")
           else:
               # Deconstruct tuple if the product exists
               _, name, quantity = product
              
               respond(f"""Product with ID {id} found:
                          name - {name},
                          quantity - {quantity}
                      """)
             
       except Exception as e:
           print("Connection error: %s", e)
             
       finally:
           # close connection
           if conn is not None:
               conn.close()
    
    # command to delete the matching product_id from inventory
    @app.command("/delete_product")
    def delete_product(ack, respond, command, request):
        #Acknowledge command request
        ack()
    
        # Extract payload from request
        id = request.body['text'].strip()
        
        # Get connection
        conn = None
        try:
            # Get connection
            conn = get_conn()
       	 
            # get cursor
            cur = conn.cursor()
       	 
            # Insert the product into the database
            cur.execute(
            	"DELETE FROM products WHERE id = %s",
            	(int(id),)
            )
            cur.close()
            conn.commit()
       	 
            # Response
            respond(f"Product with ID {id} deleted from inventory!")
        except Exception as e:
            print("Connection error: %s", e)
        finally:
            # close connection
            if conn is not None:
                conn.close()
    

    These two command handlers query and delete the matching product ID in the inventory, respectively.

How To Run the Server

  1. To bring the database initialization and socket connection together, add the following lines to your server.py file.
    # Start your app
    if __name__ == "__main__":
        # Initialize database on start
        init_db()
    
        # Connect socket
        handler = SocketModeHandler(app, os.environ["SLACK_APP_TOKEN"])
        handler.start()

    You must initialize SocketModeHandler with your app-level token. Use the SLACK_APP_TOKEN to access the environment variable deployed in the Kinsta application.

  2. Commit the changes to your remote repository to deploy them to Kinsta automatically. Now, server.py initializes the database and establishes the socket connection. Kinsta will trigger an automatic re-deployment of your Python application.

Test and Troubleshoot Your Application

You can test your application on Slack using the configured Slash Commands.

    1. Go to the workspace associated with your app. Type the slash (‘/’) character to view the app’s commands:

      Kinsta-demo channel with a list of commands, including check inventory product ID, add product ID, name, or quantity, delete product ID, and Hi
      The kinsta-demo channel.

    2. Test each Slash Command. For example, type /hi. You get the response “Hello!”

      Response to the Hi command with the message 'Hello!'
      Response to Hi command.

    3. Test what happens when you add the same product twice. Run the slash command /add_product 1, notepad, 2 two times.
      Result of running the add product command twice. It shows a quantity of 2
      Adding a product twice.

      As the screenshot above shows, the first command worked. It added a new product. The second command prompted the response that the ID already exists.

    4. Try querying for the product ID we just added. Type /check_inventory 1.
      Querying a product ID with the check inventory command. It lists the ID, name, and quantity
      Checking the inventory.

      The query returned the product with the matching ID.

    5. Finally, try deleting the product you added. Type /delete_product 1.

      After deleting the product, the message says, Product with ID 1 deleted from inventory!
      Deleting a product.

How To Troubleshoot

When configuring and deploying your application, you might encounter errors to resolve for your application to function correctly. Try the following methods to detect and fix typical errors.

      • Verify your tokens: Ensure you configure your app-level token correctly with the connections:write scope to enable access using Socket Mode. Also, use the correct tokens for the app class. The bot user token begins with xoxb-<...>. Use the app-level token (xapp-<...>) for the SocketModeHandler class.
      • Verify your slash commands: Ensure you’ve configured the Slash Commands on your Slack app’s dashboard and configured the correct handlers in your application server code.
      • Employ better error handling: Ensure your application logic correctly handles errors, for example, when executing database operations.

Summary

In this guide, you learned how to build a Python application with real-time communication via Slack’s Slash commands. You also learned how to deploy the application to Kinsta.

Integrating a Kinsta-hosted application with Slack enables users to quickly make changes using Slash Commands, enhancing interactivity and workflow efficiency while offering immediate access to real-time data. Staff can now seamlessly add, delete, or check product inventory without leaving their communications platform, boosting productivity during a busy work day.

Kinsta’s PaaS offers even more possibilities—you can connect applications and databases, deploying full-stack solutions for companies and businesses. And the best part? Your first $20 is covered by us!

Jeremy Holcombe Kinsta

Senior Editor at Kinsta, WordPress Web Developer, and Content Writer. Outside of all things WordPress, I enjoy the beach, golf, and movies. I also have tall people problems.