How to implement a REST API?
In many occasions we need to send a message via HTTP request is very useful to send reminders or order confirmations. In this case each provider implements a handleCtx
function which allows you to inject the bot instantiation and access its functions from a controller.
Send Single Message
Request
curl https://api.example.chat/v1/messages \
-d number="34000000" \
-d message="Hello!"
In the exercise below you can get an example of how it works. It is interesting to understand that internally the library already implements a very light version of HTTP similar to express but called polka.
app.ts
import 'dotenv/config'
import { createBot, MemoryDB, createProvider } from '@builderbot/bot'
import { BaileysProvider } from '@builderbot/provider-baileys'
import flow from './flows';
const PORT = process.env.PORT ?? 3001
const main = async () => {
const provider = createProvider(BaileysProvider)
const { handleCtx, httpServer } = await createBot({
database: new MemoryDB(),
provider,
flow,
})
httpServer(+PORT)
provider.server.post('/v1/messages', handleCtx(async (bot, req, res) => {
const { number, message } = req.body
await bot.sendMessage(number, message, {})
return res.end('send')
}))
}
main()
Send with Media
Request
curl https://api.example.chat/v1/messages \
-d number="34000000" \
-d message="Ey! send media"
In the following example you will understand how to send files, images or videos from an api when the file is in a public URL or also if you want to upload it through a request.
import 'dotenv/config'
import { createBot, MemoryDB, createProvider } from '@builderbot/bot'
import { BaileysProvider } from '@builderbot/provider-baileys'
import flow from './flows';
const PORT = process.env.PORT ?? 3001
const main = async () => {
const provider = createProvider(BaileysProvider)
const { handleCtx, httpServer } = await createBot({
database: new MemoryDB(),
provider,
flow,
})
httpServer(+PORT)
provider.server.post('/v1/messages', handleCtx(async (bot, req, res) => {
const { number, message, media } = req.body
await bot.sendMessage(number, message, { media }) // https://i.imgur.com/0HpzsEm.png
return res.end('send')
}))
}
main()
Block Users
Request
curl https://api.example.chat/v1/blacklist \
-d number="34000000" \
-d intent="'add' or 'remove'"
In the following example you will understand how to add numbers to a blacklist to prevent the bot from answering those numbers, very useful when we want to talk to a person without the bot answering.
blacklist-api.ts
import { createBot, MemoryDB, createProvider } from '@builderbot/bot'
import { BaileysProvider } from '@builderbot/provider-baileys'
import flow from './flows';
const PORT = process.env.PORT ?? 3001
const main = async () => {
const provider = createProvider(BaileysProvider)
const { handleCtx, httpServer } = await createBot({
database: new MemoryDB(),
provider,
flow,
})
httpServer(+PORT)
provider.server.post('/v1/blacklist', handleCtx(async (bot, req, res) => {
const { number, intent } = req.body
if (intent === 'remove') bot.blacklist.remove(`340000000`)
if (intent === 'add') bot.blacklist.add(`340000000`)
res.writeHead(200, { 'Content-Type': 'application/json' })
return res.end(JSON.stringify({ status: 'ok', number, intent }))
}))
}
main()
Trigger Flows
Request
curl https://api.example.chat/v1/register \
-d number="34000000" \
-d name ="Joe"
In the following example you will understand how to start a flow to a given number from an API request, it is a new experimental function that may undergo changes in the future.
trigger-flow-api.ts
import { createBot, MemoryDB, createProvider } from '@builderbot/bot'
import { BaileysProvider } from '@builderbot/provider-baileys'
const PORT = process.env.PORT ?? 3001
const registerFlow = addKeyword(utils.setEvent('EVENT_REGISTER'))
.addAnswer(`What is your name?`, { capture: true }, async (ctx, { state }) => {
await state.update({ name: ctx.body })
})
.addAnswer('What is your age?', { capture: true }, async (ctx, { state }) => {
await state.update({ age: ctx.body })
})
.addAction(async (_, { flowDynamic, state }) => {
await flowDynamic(`${state.get('name')}, thanks for your information!: Your age: ${state.get('age')}`)
})
const main = async () => {
const provider = createProvider(BaileysProvider)
const { handleCtx, httpServer } = await createBot({
database: new MemoryDB(),
provider,
flow: createFlow([registerFlow]),
})
httpServer(+PORT)
provider.server.post('/v1/register', handleCtx(async (bot, req, res) => {
const { number, name } = req.body
await bot.dispatch('EVENT_REGISTER', { from: number, name })
return res.end('trigger')
}))
}
main()