Send Slack messages with classified leads with Baseten

Many business processes benefit from integration with existing interfaces. Baseten’s Slack integration abstracts away all of the boilerplate code required to send a message to a Slack channel, and in this tutorial we’ll build a lead classifier with a pre-trained zero-shot classification model that sends its results directly to Slack.

In this tutorial, you’ll learn:

  • How to deploy a pre-trained model and use it to build an internal tool
  • How to serve your model, plus glue code, behind an API
  • How to use Baseten’s Slack integration

To implement this project, you’ll need:

  • A Baseten account (sign up for free!)
  • A Slack account and webhook
  • Some way of running Python. This can be through terminal, a Jupyter notebook, your IDE, anything goes, with the popular requests package installed.

Let’s set the scene for this project. You’re a data scientist at Nulla Gifts, a fictional gifting platform that offers a variety of gift baskets that can be purchased individually or in bulk. You’ve noticed that users who sign up with an email alias, like hr@customer.com, tend to enter much larger orders, but require more attention from sales reps. So the marketing team has asked you to build a system that lets them know right away when a new user signs up for the platform with an email alias.

While some users making corporate orders may use an individual email address, what matters in this example is sending alias addresses to a higher-touch channel right away. This tutorial centers on using the Slack integration; use it as inspiration to set up a similar system with a classifier that matches your individual needs.

Step 1: Running the model

First, we’ll deploy the pre-trained zero-shot classification model from Baseten’s model library. This model uses the Hugging Face zero-shot classification pipeline to classify text into unseen categories. To deploy the model:

  1. Go to the models page in your Baseten account
  2. Click “Deploy a model” then select “Use a pre-trained model”
  3. Find Zero-shot classification on the list, select it, and click Next
  4. Turn off the toggle for “Create a starter application” as we’ll be creating a different application in this tutorial.
  5. Click “Deploy model” and it’ll be deployed!

To make the model easier to use, we’ll build an API that takes user input, formats it for the model, invokes the model and parses the model’s results.

We’ll build this API from a worklet in the app builder. To get started:

  1. Go to the applications page in your Baseten account
  2. Click “Create an application”
  3. Name your application by clicking on its name in the upper left side of the window and entering a new name like “Classified leads Slack notification”

Then, we need to write glue code to format input for the model. Copy the following into main.py:

def parse_email(block_input, env, context):
   username = block_input["email"].split("@")[0]
   return [
       {
           "sequences": [username],  # The model expects a list of strings
           "candidate_labels": ["name", "thing"],  # The categories of email username
           "multi_class": False,
       }
   ]

Part of working with machine learning models is finding parameters that work well. The two categories we want to classify emails into are “name” and “alias,” or perhaps “name” and “not a name.” However, while experimenting with the pre-trained zero-shot classification model, I discovered the categorizations were most accurate with candidate labels “name” and “thing.” While I could have taken the time to build a custom model for this exact use case, I was quite happy with the performance of this model out of the box once I’d found an appropriate candidate_labels parameter.

To put this code around the model invocation in an API, we need to build a worklet. Click over to the Worklets editor through the left-side menu by selecting “Worklet1,” which you can rename if you would like.

  1. Add a code block by clicking “Add block” and selecting “Code.”
  2. Configure the code block to call the function you just added to main.py
  3. Select main.py for file
  4. Select parse_email for function. 
  5. Add another block, this time a Model block.
  6. Configure this block to call the zero-shot classification model.

How did I run the model while experimenting with candidate_labels? In the testing tab, I was able to run my worklet on JSON input to test different emails to make sure “Philip,” “Samishka,” “Bill” and others came back as names, while aliases like “developers,” “team,” and “sales” were appropriately classified. Try it out with your new worklet to make sure the model is giving you the results you would expect.

Step 2: Sending the Slack message

This is a great start, but a model invocation on its own isn’t going to be useful to the sales team. The whole point of this service is to notify sales reps about high-potential leads. So, we’ll add a decision block to route leads from alias email accounts to a separate Slack channel that the sales reps can check more often, and send the rest to an ordinary sign-ups channel.

Create two webhooks: one pointed at the high-priority channel and the other at the normal channel. Then, add the following functions to your main.py code file:

def is_name(block_input, env, context):
   return block_input["predictions"][0]["labels"][0] == "name"
 
def write_name_message(block_input, env, context):
   return f":new: an individual lead: {env['email']}"
 
def write_alias_message(block_input, env, context):
   return f":rotating_light: a team account lead: {env['email']}"

Returning to the worklet graph, create the following:

  1. A decision block calling is_name from main.py
  2. On the “then” side: a code block calling write_name_message
  3. On the “then” side: a Slack block with the webhook for the less important channel
  4. On the “else” side: a code block calling write_alias_message
  5. On the “else” side: a Slack block with the webhook for the more important channel

Your final worklet should look like this:

And guess what? Our final worklet looks just like the process diagram we referenced at the start of the article! This makes the process easy to understand, explain, and update.

Step 3: Integrate your API

There are 1001 ways to invoke an API; how you send email addresses into the classifier will depend on your stack. To use the worklets you’ve built as an API, you’ll need an API key. To generate an API key:

  1. Click on the blue-and-green circle in the upper-right corner of the page
  2. Select “Personal account settings.”
  3. Go to the API Keys tab then click “+ New.”

Be sure to copy the value and store it somewhere safe, as once you exit the modal you will not be able to see the secret key again.

For lead scoring, it would make sense to pass along the email address during the signup process. Here is some sample Python code for the invocation in a vacuum.

import requests
import os
import json

email = "team@example.com"

r = requests.post(
    "https://app.baseten.co/applications/1Bbwk04/worklets/2qRddw0/invoke",
    headers={"Authorization": f"Api-Key {os.environ['BASETEN_API_KEY']}"},
    data=json.dumps({"worklet_input": {"email": email}})
)

print(r.text)

All of the parsing and formatting is handled by the API you just built, so the application itself just needs to call the API and pass along the email address, and the Slack message will arrive in the appropriate channel.

In this tutorial, you built an ML-powered classifier for sorting leads and integrated it with Slack. You created an API key, wrote a worklet, and wrote Python to use in code blocks. If you want to use Baseten to run your own ML-powered business processes, we’re here to help at support@baseten.co