Telegram frontend for Watson using NodeRED
Hickmat 100000QA3T Comments (2) Visits (12627)
Following on from my last blog post around calling Watson from NodeRED, I decided to look at creating a Telegram Bot to handle the interaction with my Watson flow. For anyone not familiar with Telegram, details can be found Here . Telegram is basically a chat app but it has a really neat way (well I like it ) to create bots. Once a bot is created there is (to be expected these days) a rich API to allow you to receive and respond to messages sent to the bot. Armed with this API and some sample NodeJS code I set about creating a flow in NodeRED.
The flow I created ended up looking as follows:
So now to go into a little bit more detail around how this all works To start with I probably need to explain a little bit about how the API to get messages sent to the bot works. So the API can work in two ways:
For my purposes long polling was the only option. The way the API (called getUpdates) works is that it returns all the updates sent to the bot which haven't been committed yet. An update is committed by retrieving entries based on a passed "update id". Passing an update id commits all the updates sent to the bot whic
From the earlier flow image you can see that I loop around calling this function until a null is emitted from output 3. In terms of actually getting the messages from my Telegram bot, I created the Telegram Listener function for this. This function node was configured as follows:
Finally I needed to send a response to the person chatting with my bot. Given this response would be based on the output from my Watson Dialog flow (still using the Pizza sample but now also wired in to Retrieve and Rank - more on that in another blog post as its still work in progress) I needed to pass the in bound message sent to the bot on to Watson so a response could be formed. The first thing I needed to do was figure out if this was a new or existing conversation and this is where the "Switch" node came in. Within the "Process Messages" function I look at a global context collection which holds existing chats. If I find one and the message that is being sent isn't the command to start a new conversation ("/start") then I flag that this is an existing conversation in my message object. The "Switch" node looks at this flag and routes the message on accordingly. In the case of a new conversation I call my Watson flow's REST endpoint to start a conversation, if not I call the end point for handling input from a user. Both of these routes end up a my Send Message function to return the Watson response to the Telegram user interacting with my bot (NB: there is a loop at the end of the user input on existing conversation path as Watson can return several lines of response). This Send Message function was configured as shown below:
With this all wired together I was able to happily chat away to my bot and order some Pizza as show in the following screen capture...
So job done My next challenge may well be to look at doing something similar with a Slack bot but before I do that I need to finish of my work on getting Retrieve and Rank fully wired into my Watson flow.