For Developers
Getting Started

Getting Started

In this section, we'll create a simple integration that can send text messages to Telegram and a bot to try it out. This tutorial make use of both the Botpress CLI and the Botpress SDK.

Setup

Installing the Botpress CLI globally.

npm install -g @botpress/cli

Initialize the project

Create a new integration project using the init command. This will create a new folder with the name you specified and generate a basic project structure.

bp init --name <UNIQUE_INTEGRATION_NAME> --type integration
cd <UNIQUE_INTEGRATION_NAME>
pnpm install

Define the integration and generate typings

Inside the file called integration.definition.ts add the following code:

import { IntegrationDefinition, messages } from '@botpress/sdk'
import { z } from 'zod'
 
export default new IntegrationDefinition({
  name: '<UNIQUE_INTEGRATION_NAME>',
  version: '0.0.1',
  configuration: {
    schema: z.object({
      botToken: z.string(),
    }),
  },
  channels: {
    group: {
      messages: {
        text: messages.defaults.text,
      },
      message: {
        tags: {
          id: {},
        },
      },
      conversation: {
        tags: {
          id: {},
        },
      },
    },
  },
  user: {
    tags: {
      id: {},
    },
  },
})

There is a lot going on there, so let's break it down.

Name and version

The name and version are used to identify the integration. The name is used to generate the integration ID, which is a unique identifier for the integration. The version is used to identify the version of the integration. For now, only one version of an integration can be deployed at a time and 0.0.1 is enforced.

⚠️

Integration Names
The integration names are unique. If you try to create an integration with the same name as an existing one, the CLI will throw an error.


Configuration

The configuration is used to define the configuration schema of the integration. The schema is used to validate the configuration of the integration. The configuration is used to store sensitive information such as API keys and tokens. This configuration will be provided by the user when added the integration to his bot.

Channels

The channels are used to define which channels the integration supports. In this case, we defined a channel named group, this will be used to send messages to a specific group channel in telegram. The messages property is used to define the message types that the integration supports. For now, we will only implement the text message. The defaults object that comes from the SDK is used to define the default messages that the integration supports. We highly recommend implementing all message types provided by the SDK.

Tags

The tags are used to define the tags that the integration supports. In this case, we added a tag named id to the users, conversations and messages. Those tags will be used to identify the users, conversations and messages in the telegram system.

Generate typings

The integration definition is used to generate typings for the integration. This will allow us to use the integration in our code without having to worry about the types.

bp build

Implement the integration

Inside the folder src, there is a file called index.ts add the following code to it:

import { Telegraf } from 'telegraf'
import { Integration } from '.botpress'
 
export default new Integration({
  register: async ({ webhookUrl, ctx }) => {
    const telegraf = new Telegraf(ctx.configuration.botToken)
    await telegraf.telegram.setWebhook(webhookUrl)
  },
  unregister: async ({ ctx }) => {
    const telegraf = new Telegraf(ctx.configuration.botToken)
    await telegraf.telegram.deleteWebhook({ drop_pending_updates: true })
  },
  handler: async ({ req, client }) => {
    const data = JSON.parse(req.body)
 
    const conversationId = data?.message?.chat?.id
    const userId = data?.message?.from?.id
    const messageId = data?.message?.message_id
 
    if (!conversationId || !userId || !messageId) {
      throw new Error("Handler didn't receive a valid message")
    }
 
    const { conversation } = await client.getOrCreateConversation({
      channel: 'group',
      tags: { 'telegram:id': `${conversationId}` },
    })
 
    const { user } = await client.getOrCreateUser({
      tags: { 'telegram:id': `${userId}` },
    })
 
    await client.createMessage({
      tags: { 'telegram:id': `${messageId}` },
      type: 'text',
      userId: user.id,
      conversationId: conversation.id,
      payload: { text: data.message.text },
    })
  },
  channels: {
    group: {
      messages: {
        text: async ({ payload, ctx, conversation, ack }) => {
          const client = new Telegraf(ctx.configuration.botToken)
          const message = await client.telegram.sendMessage(conversation.tags['telegram:id']!, payload.text)
          await ack({ tags: { 'telegram:id': `${message.message_id}` } })
        },
      },
    },
  },
})

Once again, there is a lot going on there, so let's break it down.

Register and unregister

The register and unregister functions are used to to manage the lifecycle of an integration. The register function is called when the integration is added to a bot and the unregister function is called when the integration is removed from a bot. The register function is used to setup the integration, in this case, we are setting up the webhook for telegram. The unregister function is used to clean up the integration, in this case, we are removing the webhook for telegram. Those functions should also be used to validate the configuration of the integration.

Handler

The handler function is used to handle the incoming requests from the integration. Which means that this function will be called every time the telegram integration sends a request to the webhook url set in the register function.

In this case, we are parsing the incoming request from telegram and extracting the conversation id, user id and message id. Then, we are using those ids to create or retrieve the conversation, user and message from the botpress client. Finally, we are creating a message in the conversation. This message will be sent to the bot as an incoming message from telegram.

Channels

The channels object is used to implement the channels that the integration defined previously. In this case, we defined a channel named group, this will be used to send messages to a specific group channel in telegram. The text message type that we defined is implemented in the messages object. This function will be called every time the bot sends a text message to the group channel.

Develop the Bot

Create a new project for the bot

bp init --name tuto-bot --type bot
cd tuto-bot
pnpm install

Add the integration to your bot

Now that we have a bot, we need to add the integration to it. To do so, we need to run the following command:

bp add <integration-id> # replace <integration-id> with the integration ID that was logged when you started the integration

This command will add the integration to the bot. Once the integration is added, we need to configure it. Add the following code to the index.ts file in the src folder:

import { <UNIQUE_INTEGRATION_NAME> } from '.botpress'
 
const bot = new Bot({
  integrations: [
    new UNIQUE_INTEGRATION_NAME({
      enabled: true,
      config: {
        botToken: '<TELEGRAM_BOT_TOKEN>',
      },
    })
  ],
})

Now that the integration is configured, we can add a little bit of code to the index.ts file to send a message to the group channel every time the bot receives a message from the user.

bot.message('', async ({ message, client, ctx }) => {
  await client.createMessage({
    conversationId: message.conversationId,
    userId: ctx.botId,
    tags: {},
    type: 'text',
    payload: {
      text: `Hello. You said: "${message.payload.text}"`,
    },
  })
})

We have a parrot bot! Now, let's test it.

Deploy the Integration

Now that we're happy with our integration, we can deploy it to the cloud. To do so, all we need to do is run the following command:

bp deploy

This command will deploy the integration to the cloud. Once the deployment is done, the integration will be available in the Integrations section of your workspace settings of the Botpress Cloud. You will also see this integration available in the Integrations tab of your bot.

Congratulations! You've just created your first integration and deployed it to the cloud. Now, you can use this integration in any bot that you create in this workspace.

For in depth documentation about the SDK, CLI and concepts continue to the next section