Midio docs
  • Getting Started
    • Welcome
    • Quick Start Guide
  • Your First Midio App
  • Guides
    • HTTP
      • Making HTTP Requests
      • Uploading Files (multipart/form-data)
      • Responding to HTTP Requests
      • How to reach your own endpoints
      • CORS
      • Server-Sent Events (SSE)
    • Branching
    • Loops
    • Map, filter, reduce
    • Working with Data
    • Expressions
    • Building Agents
      • Streaming Agent API (experimental)
    • Debugging
    • Secrets and Environment variables
    • Convert JSON to data nodes
    • Writing tests
    • Cleaning up your flows
  • Package Manager
  • Integrating with third party services
  • Troubleshooting
  • Tutorials
    • Connecting LLMs to MCP-servers using the MCP-client package
    • Making Your Own MCP Server in Midio
    • A Fast Path to Functional RAG Agents
    • How to build a streaming agent using Server-Sent Events (SSE)
  • Reference
    • The Midio Editor
      • The Node Editor
      • User Traces
      • Traces (execution)
      • Processes
      • Log
      • Services
      • Problems
      • Function Signature
      • Data
      • Settings
    • The Midio Language
      • Nodes and execution
      • Functions and Events
        • Anonymous functions
      • Modules
      • Contexts
      • Data type
      • Local variables
      • Portals
      • Waypoint node
      • Partial function application
  • The Midio Engine
  • Built in Nodes
    • Core (std)
    • HTTP
    • LLM
Powered by GitBook
On this page
  • Web API setup
  • Create our bot
  • Getting started
  • Registering our endpoint with Slack
  • Sentiment analysis
  • Store in Airtable
  • A final bug

Was this helpful?

Edit on GitHub

Step-by-step Tutorial: Build an AI App

Last updated 2 months ago

Was this helpful?

In this tutorial we will build a simple Slack bot, which uses OpenAI to perform sentiment analysis on messages, and then store the result in Airtable.

We will need to access three separate web APIs, and obtain an API key for each of them. Follow the short tutorials below to retrieve API keys from each of them.

Web API setup

    • If you want to use Groq instead, go to . The API is similar to OpenAI.

Create our bot

Getting started

First off, create a new module called Main (or any other name you might want to use).

Add these two nodes using the :

Connect the onRequest trigger on the endpoint to the execute trigger on the response node. Leave the status input at 200 (which means our response is considered OK). We now have a basic endpoint setup that just returns an empty response. Enter /slack-event in the path field of Http.Endpoint and select POST in the method dropdown.

Registering our endpoint with Slack

Add the url of our endpoint in the text box marked 'Request url'. Our url will be 'midio.com/slack-event',,, . TODO(Kristian): Add the actual url here.

Slack will try to verify our endpoint by sending us a POST request with a JSON body which looks something like this: { "challenge": "somechallgengeid" }. To verify our endpoint, we must return the value in the challenge field.

We still haven't implemented this part, so Slack will show us an error message explaining that it can't verify our endpoint. We will fix this next.

To do this in Midio, we need the following nodes:

  • Json.Parse - Converts JSON encoded text to Midio objects

  • Map.ContainsKey - Returns true if the input map contains a given key

  • Std.If - Lets us choose a different path based on whether the input value is true or false.

  • Std.Log - Writes to the log panel (just to make it easier to see what happens)

Add and hook up the nodes as shown here:

Note that you can add the 'waypoint' node, which is the small node between Parse.value and HttpResponse.body, by first creating a connection between them, and then double clicking he connection.

This is a waypoint node. Add one by double clicking a blue dotted connection, or search for waypoint using the node palette (space bar).

What you've hooked up everything, go back to the slack portal and click retry.

If everything is working correctly, slack will display a success message, and you'll see a trace of the execution in the Midio editor. Hover or click the blue dots on the arrows to view the data which have passed through your code.

Cleanup

We can then clean up our code by converting some of the nodes into a function, which hides them behind a single node. Lets do this by selecting (hold shift and drag the mouse) the nodes which are only related to handling the challenge event. Right click on one of them, and select 'Convert to function' from the dropdown menu. Give the function a name, like 'Handle slack challenge event'.

Sentiment analysis

Next up, we will create a Midio function which uses the OpenAI completion API to perform sentiment analysis on the content of the slack event.

First, create an empty function by right clicking on the Main module in the left side panel, and then clicking 'Add'. Then select 'function' from the popup window. Name the function something like 'Perform sentiment analysis'.

We will now add inputs and outputs to the function. Select the function from the left side panel, then click the 'add input' button in the top center, and select 'trigger'. Name it something like 'execute'.

You should then have something like this:

Call the OpenAI API.

For this, we need a couple new functions and a new node type:

  • Http.FetchUrl - lets us perform an http request to a url

  • Math.NumberFromString - Lets us convert a string to a number

  • Data objects - to create the data expected by the Open AI API.

This is what a data object looks like in Midio:

Implement the function like this:

The data nodes can be built by adding a 'data object' node from the node palette (space bar), or by pasting the following JSON objects using control-v/cmd-v.

To paste JSON data into Midio, first copy the JSON to your clipboard as you normally copy text, then click anywhere in the midio node editor, and finally paste using control-/cmd-v. You shouldn't open the node palette first, as that would paste the text into the search box and have you create a text object with the JSON value as a text object.

{
  "Authorization": "Bearer <your API Key>",
  "content-type": "application/json"
}
{
  "messages": [
    {
      "content": "You perform sentiment analysis on user messages. Return a number between 0 and 10, where 0 represents a very negative sentiment, and 10 represents a very positive sentiment. Return the number and the number only!",
      "role": "system"
    },
    {
      "content": "prompt",
      "role": "user"
    }
  ],
  "model": "gpt-3.5-turbo",
  "temperature": "0.7"
}

To convert the messages.1.content item to an input, hover it, and click the 'convert to input'-icon. This will allow you to hook it up to the function input we created earlier.

Add it to the main flow

We can now use this function in our main flow. Select the 'Main' module from the left side panel. Then add an instance of our new function using the node palette (space bar).

We can now test our flow by sendimg a message to a channel in our slack workspace. Note that we are using the Std.FormatLog function to print the resulting sentiment to the log. You can also hover/click on the blue dots appearing on the connections between nodes to inspect the data which has passed through our flow.

Store in Airtable

The last step of our slack bot, is to store the analysis along with the original message in our airtable database (which you set up here).

We start by creating a new function, like we did in the previous step. Name the function something like 'Store analysis in Airtable'.

The function also uses Http.FetchUrl to interact with the API. Implement the function as shown here:

Note that the url you pass to `Http.FetchUrl` should be constructed as follows:

https://api.airtable.com/v0/<your base id>/<your table id>

If you navigate to your base in the airtable dashboard, you can get these IDs from the url. For example:

https://airtable.com/appzte7M4AptpTo3T/tblg2Z1Th1mKEjc3i/viwWhPV8Uo8zVLbH4?blocks=hide
                     <-----base id --> <---table id --->

The headers object looks the same as the one we used with OpenAI, but make sure you fill in your Airtable API-key:

{
  "Authorization": "Bearer patl3AnvCPtzEDTOm.3e674e850a1993e30a96e1d890f3a078e4fc44ae1434d66d44d687e365b0d2d9",
  "Content-Type": "application/json"
}
{
  "records": [
    {
      "fields": {
        "Message": "message",
        "Sentiment": "sentiment"
      }
    }
  ]
}

Finally, add an instance of this function to the main flow, and hook it up. The final top level code should look like this:

Now, write another message in slack to verify that everything works as expected, and that you can see a new row appear in your airtable table.

A final bug

We've forgotten a small detail, which causes our bot to potentially receive the same event multiple times. Slack expects a '200 OK' response from us, to indicate that the event has been handled, but we currently only do this for the challenge event. Lets respond to normal events as well by adding an instance of Http.Response just before we start our sentiment analysis.

Next up, we need to register our endpoint with Slack. Go to , select your app (which you can set up following the steps here), and then select the 'Event subscriptions' item from the left side menu.

Then add another input, this time a 'data' input, name it something like 'message', and pick String as its type (if you're ever unsure about which type to pick for an input or ouput, you can select the type Any, which means we don't care about the type. Read more about types . Add outputs using the 'add output' button right next to the 'add input'-button. First add an output, select trigger, and name it 'continue'. Then add another output, pick data, and call it 'sentiment'. Select Number as its type when prompted for a type.

https://api.slack.com/apps
Slack setup
OpenAI setup
Groq setup
Airtable setup
Available
First select the items to group
Right click any of the selected nodes to bring up the context menu
Select 'convert to function' in order to group them in a function
The add input and add output buttons
Http Endpoint
Http Response
#data-types
Node Palette