Integrating Api.ai Recipe Bot with Telegram

In my previous post, I explained how we can create a recipe finder bot. In this post, we will Integration it with Telegram and customize the returned message.

API.ai provides one-click integration for many platforms. We will enable Telegram integration in this tutorial.

Create a new Telegram Bot

Following these step from api.ai to create and setup a new BOT.

Now if you go back to our “find recipe” intent, you will see a new tab for Telegram under Response.

You can create Text, Image, Card or Custom payload type of message here for Telegram bot. But we will let our Webhook handle it.

Returning message for Telegram from Webhook

In the response from webhook, we can put a message for Telegram, or any other integrations, under data field. It will be processed by Telegram.

Read more about it here.

Here is a sample of how it should look like:

{
"speech": "Lorem Ipsum,Lorem Ipsum",
"displayText": "Lorem IpsumLorem IpsumLorem",
"data": {
"telegram": {
< telegram_message >
}
},
"contextOut": [...],
"source": "Google"
}

Telegram Bot Api Doc  is a good resource to get an idea of what <telegram_message> can be. We will be using it’s “sendMessage” method by supplying text and parse_mode fields. We want out Recipe bot to return a rich text message with some bold text. We will be passing parse_mode=Markdown for that purpose.

Here is an early preview of an example message return by our webhook:

{
"speech": "Found recipe for: Darn Good Chocolate Cake ( Cake Mix Cake) at http://www.recipezaar.com/Darn-Good-Chocolate-Cake-Cake-Mix-Cake-87205",
"displayText": "Found recipe for: Darn Good Chocolate Cake ( Cake Mix Cake) at http://www.recipezaar.com/Darn-Good-Chocolate-Cake-Cake-Mix-Cake-87205",
"data": {
"telegram": {
"text": "*Title* Darn Good Chocolate Cake ( Cake Mix Cake)\n*Ingredients* frosting, cake mix, eggs, chocolate pudding, sour cream, vegetable oil, water\n*Link* http://www.recipezaar.com/Darn-Good-Chocolate-Cake-Cake-Mix-Cake-87205",
"parse_mode": "Markdown"
}
}
}

Notice the “*” in our text field for the telegram. That’s the markdown formatting.

There are several other html tags we can use with this markdown.

*bold text*
_italic text_

(http://www.example.com/)
`inline fixed-width code`
“`text
pre-formatted fixed-width code block
“`

Final Webhook code in Node.js

I won’t go in too deep about the webhook implementation.

const http = require('http');
const express = require('express');
const bodyParser = require('body-parser');
const app = express();

app.use(bodyParser.json());

const recipepuppyHost = 'http://www.recipepuppy.com/api/?q=';

app.post('/webhook', function (req, res) {
	if (req.body.result.parameters['FoodItem']) {
		var fooditem = req.body.result.parameters['FoodItem'];
		callRecipePuppy(fooditem)
		.then((output) =  & gt; {

			let displayText = `Found recipe for: ${output.title} at ${output.href}`;
			let telegramText = htmlEntities('*Found*-' + output.title + '\n' + '* It has following Ingredients*-' + output.ingredients + '\n' + '* You can check it out at*- ' + output.href);
			let result = toApiAiResponseMessage(displayText, displayText, toTelgramObject(telegramText, 'Markdown'));
			console.log(result);
			res.setHeader('Content-Type', 'application/json');
			res.send(JSON.stringify(result));
		})
		.catch ((error) =  & gt; {
			console.log(error);
			res.setHeader('Content-Type', 'application/json');
			res.send(JSON.stringify({
					'speech': error,
					'displayText': error
				}));
		});
	} else {
		res.setHeader('Content-Type', 'application/json');
		res.send(JSON.stringify({
				'speech': "No Proper hook found",
				'displayText': "No Proper hook found"
			}));
	}
});

function callRecipePuppy(fooditem) {
	return new Promise((resolve, reject) =  & gt; {
		http.get(recipepuppyHost + fooditem, (res) =  & gt; {
			let body = '';
			res.on('data', (d) =  & gt; body += d);
			res.on('end', () =  & gt; {
				let jO = JSON.parse(body);
				let firstItem = jO.results[Math.floor((Math.random() * jO.results.length))];
				console.log(firstItem);
				resolve(firstItem);
			});

			res.on('error', (error) =  & gt; {
				reject(error);
			});
		});
	});
}

function toTelgramObject(text, parse_mode) {
	return {
		text: text,
		parse_mode: parse_mode
	}
}

function toApiAiResponseMessage(speech, displayText, telegramObject = null) {
	return {
		speech: speech,
		displayText: displayText,
		data: {
			telegram: telegramObject
		}
	}
}

function htmlEntities(str) {
	return String(str).replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/"/g, '"');
}

app.listen((process.env.PORT || 5000), function () {
	console.log("Server listening");
});

You can find the complete project on my GitHub.

Here is a screenshot of the telegram bot live:

 

Sandeep

a dev, an amateur photographer and a father

 

Leave a Reply

Your email address will not be published. Required fields are marked *

%d bloggers like this: