---
title: Build a Slack Chatbot with MindsDB and OpenAI
sidebarTitle: Slack Chatbot
---

The objective of this tutorial is to create an AI-powered personalized chatbot by utilizing the MindsDB's Slack connector, and combining it with OpenAI's GPT-4 Model.

To illustrate practically, we will create a Slack bot - **@Whiz_Fizz** - which will reply to the user's queries with proper context and with a unique persona while responding. It is a weird magician 🪄 and a Space Science Expert! Let's see how it responds.


<p align="center">
    <img src="/assets/SLBot-Hero-Whizfizz.png" />
</p>

Before jumping more into it. Let's first see how to create a bot and connect it to our Slack Workspace.

## Getting Started

- Install MindsDB locally via [Docker](/setup/self-hosted/docker) or [Docker Desktop](/setup/self-hosted/docker-desktop)
- [Create a Slack Account](https://slack.com/get-started#/createnew) and follow [this instruction](/integrations/app-integrations/slack) to connect Slack to MindsDB.
- Go to your MindsDB Editor

## Usage

This query will create a database called `mindsdb_slack` that comes with the `channels` table.

```sql
CREATE DATABASE mindsdb_slack
WITH
  ENGINE = 'slack',
  PARAMETERS = {
      "token": "xoxb-..."
    };
```

Here is how to retrieve the 10 messages after specific timestamp:

```sql
SELECT *
FROM mindsdb_slack.messages
WHERE channel_id = "<channel-id>"
AND created_at > '2023-07-25 00:13:07'   -- created_at stores the timestamp when the message was created
LIMIT 10;
```

You can also retrieve messages in alphabetical order:

```sql
SELECT *
FROM mindsdb_slack.messages
WHERE channel_id = "<channel-id>"
ORDER BY text ASC
LIMIT 5;
```

By default, it retrieves by the order the messages were sent, unless specified as ascending/descending.

Here is how to post messages:

```sql
INSERT INTO mindsdb_slack.messages (channel_id, text)
VALUES
    ("<channel-id>", "Hey MindsDB, Thanks to you! Now I can respond to my Slack messages through SQL Queries. 🚀 "),
    ("<channel-id>", "It's never been that easy to build ML apps using MindsDB!");
```

Whoops! Sent it by mistake? No worries! Use this to delete a specific message:

```sql
DELETE FROM mindsdb_slack.messages
WHERE channel_id = "<channel-id>" AND ts = "1688863707.197229";
```

Now, let's roll up our sleeves and start building the GPT-4 Model together. 

### 1. Crafting the GPT-4 Model:

_Generating a [Machine Learning model](https://docs.mindsdb.com/nlp/nlp-mindsdb-openai) with MindsDB feels like taking a thrilling elevator ride in Burj Khalifa (You don't realize, that you made it)!_

Here `gpt_model` represents our GPT-4 Model.

<Tip>
Before creating an OpenAI model, please create an engine, providing your OpenAI API key:

```sql
CREATE ML_ENGINE openai_engine
FROM openai
USING
	openai_api_key = 'your-openai-api-key';
```
</Tip>

```sql
CREATE MODEL mindsdb.gpt_model
PREDICT response
USING
engine = 'openai_engine',
max_tokens = 300,
model_name = 'gpt-4',
prompt_template = 'From input message: {{text}}\
write a short response to the user in the following format:\
Hi, I am an automated bot here to help you, Can you please elaborate the issue which you are facing! ✨🚀 ';
```

The critical attribute here is `prompt_template` where we tell the GPT model how to respond to the questions asked by the user.

Let's see how it works:

```sql
SELECT
  text, response
FROM mindsdb.gpt_model
WHERE text = 'Hi, can you please explain me more about MindsDB?';
```

<p align="center">
    <img src="/assets/SLBot-response1.png" />
</p>

### 2. Feeding Personality into Our Model

Alright, so the old model's replies were *good*. But hey, we can use some prompt template tricks to make it respond the way we want. Let's do some Prompt Engineering.

Now, let's make a model called `whizfizz_model` with a prompt template that gives GPT a wild personality that eludes a playful and magical aura. Imagine scientific knowledge with whimsical storytelling to create a unique and enchanting experience. We'll call him **WhizFizz**:

```sql
CREATE MODEL mindsdb.whizfizz_model
PREDICT response
USING
engine = 'openai_engine',
max_tokens = 300,
model_name = 'gpt-4',
prompt_template = 'From input message: {{text}}\
write a short response in less than 40 words to some user in the following format:\
Hi there, WhizFizz here! <respond with a mind blowing fact about Space and describe the response using cosmic and scientific analogies, where wonders persist. In between quote some hilarious appropriate raps statements based on the context of the question answer as if you are a Physics Space Mad Scientist who relates everythign to the Universe and its strange theories. So lets embark on a journey, where science and magic intertwine. Stay tuned for more enchantment! ✨🚀 -- mdb.ai/bot by @mindsdb';
```

Let's test this in action:

```sql
SELECT
  text, response
FROM mindsdb.whizfizz_model
WHERE text = 'Hi, can you please explain me more about MindsDB?';
```

<p align="center">
    <img src="/assets/SLBot-response2.png" />
</p>

You see the difference! Now, I'm getting excited, let's try again.

```sql
SELECT
  text, response
FROM mindsdb.whizfizz_model
WHERE text = 'if a time-traveling astronaut had a dance-off with a black hole, what mind-bending moves would they showcase, and how would gravity groove to the rhythm?!';
```

<p align="center">
    <img src="/assets/SLBot-response3.png" />
</p>

### 3. Let's Connect our GPT Model to Slack!

The `messages` table can be used to search for `channels`, `messages`, and `timestamps`, as well as to post messages into Slack conversations. These functionalities can also be done by using Slack API or Webhooks.

Let's query the user's question and see how our GPT model responds to it, by joining the model with the `messages` table:

```sql
SELECT
    t.channel_id as channel_id,
    t.text as input_text, 
    r.response as output_text
FROM mindsdb_slack.messages as t
JOIN mindsdb.whizfizz_model as r
WHERE t.channel_id = "<channel-id>"
LIMIT 3;
```

### 4. Posting Messages using SQL

We want to respond to the user's questions by posting the output of our newly created **WhizFizz** Model. Let's post the message by querying and joining the user's questions to our model:

```sql
INSERT INTO mindsdb_slack.messages(channel_id, text)
  SELECT
    t.channel_id as channel_id,
    r.response as text
  FROM mindsdb_slack.messages as t
  JOIN mindsdb.whizfizz_model as r
  WHERE t.channel_id = "<channel-id>"
  LIMIT 3;
```

Works like a charm!!

<p align="center">
    <img src="/assets/SLBot-response4.png" />
</p>

### 5. Let's automate this

We will `CREATE JOB` to schedule periodical execution of SQL statements. The job will execute every hour and do the following:
    1. Check for new messages using the [`LAST` keyword](/mindsdb_sql/sql/create/jobs#last).
    2. Generate an appropriate response with the `whizfizz_model` model.
    3. Insert the response into the channel.

Let's do it in single SQL statement:

```sql
CREATE JOB mindsdb.gpt4_slack_job AS (

   -- insert into channels the output of joining model and new responses
  INSERT INTO mindsdb_slack.messages(channel_id, text)
    SELECT
      t.channel_id as channel_id,
      r.response as text
    FROM mindsdb_slack.messages as t
    JOIN mindsdb.whizfizz_model as r
    WHERE t.channel_id = "<channel-id>"
    AND t.created_at > LAST
    AND t.user = 'user_id' -- to avoid the bot replying to its own messages, include users to which bot should reply
    --AND t.user != 'bot_id' -- alternatively, to avoid the bot replying to its own messages, exclude the user id of the bot
)
EVERY hour;
```

The `LAST` keyword is used to ensure the query fetches only the newly added messages. Learn more [here](/mindsdb_sql/sql/create/jobs#last).

That sums up the tutorial! Here it will continually check for new messages posted in the channel and will respond to all newly added messages providing responses generated by OpenAI's GPT model in the style of WhizFizz.

To check the `jobs` and `jobs_history`, we can use the following:

```sql
SHOW JOBS WHERE name = 'gpt4_slack_job';

SELECT * FROM mindsdb.jobs WHERE name = 'gpt4_slack_job';

SELECT * FROM log.jobs_history WHERE project = 'mindsdb' AND name = 'gpt4_slack_job';
```

To stop the scheduled job, we can use the following:

```sql
DROP JOB gpt4_slack_job;
```

<Note>
Alternatively, you can create a trigger on Slack, instead of scheduling a job. This way, every time new messages are posted, the trigger executes.

```sql
CREATE TRIGGER slack_trigger ON mindsdb_slack.messages (

    INSERT INTO mindsdb_slack.messages(channel_id, text)
      SELECT t.channel_id as channel_id, a.sentiment as text, 
      FROM data_table t              
      JOIN model_table as a
      WHERE t.channel_id = '<channel-id>' 
      AND t.user != 'bot_id'  -- exclude bot
);
```
</Note>

<Tip>
**What's next?**

Check out [How to Generate Images using OpenAI with MindsDB](/sql/tutorials/image-generator) to see another interesting use case of OpenAI integration.
</Tip>
