Adds an easy to use Telegram Bot API wrapper.
Installation
meteor add benjick:telegram-bot
Usage
First of all, follow the instructions at https://core.telegram.org/bots go get your authkey.
Now you can either set the environment variable TELEGRAM_TOKEN
to your token or you can run TelegramBot.token = 'MY_TOKEN_HERE'
on startup.
Now you can add listeners and listen for incoming webHooks.
API
TelegramBot.addListener(command, callback, type = text)
Add a command which should be listened for by the server. If this command is found the callback will be called. The callback takes three arguments:
- command - the command parsed to an array (see Telegram.parseCommandString)
- username - username of the sender as a string
- original - the original object sent from Telegram
See examples below
If you set type to anything else than 'text'
(default value) in type command
has no effect and that function will run every time you get something with that type (for example document
(getting files) or voice
(voice recordings)).
TelegramBot.start();
Starts polling the Telegram-servers
TelegramBot.stop();
Stops polling
TelegramBot.poll();
Does the actual request to Telegrams server with the method getUpdates
and sets the offset so we can mark the messages as read
TelegramBot.parsePollResult(data);
Parses the result from the polling and executes callbacks from addListener
TelegramBot.requestUrl(method);
Creates an URL which is GETable with baseUrl + token + method
TelegramBot.method(method, object);
Call a Telegram Bot API method. Full spec at https://core.telegram.org/bots/api#available-methods
Check if the auth token is correct:
TelegramBot.method(getMe)
TelegramBot.send(message, chatId);
Shorthand for TelegramBot.method('sendMessage', { chat_id: chatId, text: message })
.
TelegramBot.triggers = []
Array containing all the added listeners and their callbacks
TelegramBot.parseCommandString(msg)
Takes the incoming message, strips the @botname out if any (used in channels with multiple bots) and returns an array where every key represents a command or argument.
For example:
1var msg = "/test@thisbot is fun"; 2msg = TelegramBot.parseCommandString(msg); 3console.log(msg); // [ '/test', 'is', 'fun' ]
This means you can get the arguments in a nice way. This is done when a webHook is received.
TelegramBot.startConversation(username, chat_id, callback, init_vars)
Starts a conversation with a specific user in a specific chat. callback
method is called whenever the user replies to this conversation. The callback method takes 3 parameters: username
, message
, chat_id
.
The init_vars
argument is to allow you to use custom variables in your conversation,illustrated below with stage
, first_message
, and second_message
.
For example:
1TelegramBot.startConversation(username, chat_id, function(username, message, chat_id) { 2 var obj = _.find(TelegramBot.conversations[chat_id], obj => obj.username == username); 3 console.log('Conversation Status: ' + obj); 4 switch(obj.stage) { 5 case 0: 6 TelegramBot.send('You have first responded with: ' + message + '\nWhat else do you want to say?', chat_id); 7 obj.first_message = message; 8 obj.stage++; 9 break; 10 11 case 1: 12 TelegramBot.send('You then said: ' + message, chat_id); 13 obj.second_message = message; 14 TelegramBot.endConversation(username, chat_id); 15 break; 16 } 17}, {stage: 0, first_message: "", second_message: ""} );
A full example of conversation handling is given below in the Examples section.
TelegramBot.endConversation(username, chat_id)
Used to end a conversation session.
TelegramBot.setCatchAllText(enabled, callback)
Allows you to set a method to capture all text messages that have not been otherwise registered with a trigger or an active conversation.
The boolean first argument, enabled
, allows you to register/de-register the catchAll.
The callback will receive 2 arguments: the username
and the entire Message object. No return value is needed - you will need to call your own TelegramBot.send
method if you wish to reply with a message.
Here is a basic example which just repeats everything the user has typed and formats it into Markdown:
1TelegramBot.setCatchAllText(true, function(username, message) { 2 TelegramBot.send("Markdown-flavored Message:\n" + message.text, message.chat.id, true); 3});
Note that the Telegram Bot API does not embrace user-formatted code blocks in `backticks`
A few examples
1if(Meteor.isServer) { 2 Meteor.startup(function() { 3 // set our token 4 TelegramBot.token = '123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11'; 5 TelegramBot.start(); // start the bot 6 // add a listener for '/test' 7 TelegramBot.addListener('/test', function(command) { 8 // command will contain the entire command in an array where command[0] is the command. 9 // In this case '/test'. Each argument will follow. 10 if(!command[1]) { // if no arguments 11 return false 12 // if you return false the bot wont answer 13 } 14 // command[1] will be the first argument, command[2] the second etc 15 // below the bot will reply with 'test: hi' if you sent him /test hi 16 return "test: " + command[1] 17 }); 18 }); 19}
1// You can also get the username via the second argument 2TelegramBot.addListener('/hi', function(command, username) { 3 return "hi @" + username 4})
Listing all commands:
1TelegramBot.addListener('/help', function(command) { 2 var msg = "I have the following commands loaded:\n"; 3 TelegramBot.triggers.text.forEach(function (post) { 4 msg = msg + "- " + post.command + "\n"; 5 }); 6 return msg; 7});
Example using other types than the default
1TelegramBot.addListener('incoming_document', function(c, u, o) { 2 TelegramBot.send('Got a file with ID ' + o.document.file_id, o.chat.id); 3 var file = TelegramBot.method('getFile', { 4 file_id: o.document.file_id 5 }).result.file_path; 6 // Don't do this in production because it will expose your Telegram Bot's API key 7 TelegramBot.send('Download the file at https://api.telegram.org/file/bot' + TelegramBot.token + '/' + file, o.chat.id); 8}, 'document');
Overriding listeners
You can do what you want in the callback for the listener really. For example call another method instead of sendMessage
1TelegramBot.addListener('/geo', function(command, username, original) { 2 TelegramBot.method('sendLocation',{ 3 chat_id: original.chat.id, 4 latitude: 59.329323, 5 longitude: 18.068581 6 }); 7});
Conversations
You can monitor all incoming chat messages from a user using conversations.
Below is a basic example showing how a Bot can ask for 3 responses and print them out.
The conversation is initiated by the user using /start
.
1TelegramBot.addListener('/start', function(command, username, messageraw) { 2 TelegramBot.startConversation(username, messageraw.chat.id, function(username, message, chat_id) { 3 var obj = _.find(TelegramBot.conversations[chat_id], obj => obj.username == username); 4 switch(obj.stage) { 5 case 0: 6 obj.personName = message; 7 TelegramBot.send('Cool. What\'s your height?', chat_id); 8 obj.stage++; 9 break; 10 11 case 1: 12 obj.personHeight = message; 13 // Sample markdown support - name will be bold 14 TelegramBot.send('Nice. What do you work as, *' + obj.personName + '*?', chat_id, true); 15 obj.stage++; 16 break; 17 18 case 2: 19 obj.personJob = message; 20 TelegramBot.send('Nice to meet you, ' + obj.personHeight + '-tall ' + obj.personJob + ' ' + obj.personName + '!', chat_id); 21 break; 22 } 23 console.log('Conversation Status: ' + obj); 24 }, {stage: 0, personName: "", personHeight: "", personJob: ""} ); 25 // The return in this listener will be the first prompt 26 return "Hey, what's your name?"; 27});
Changelogs
Version 1.2.1
- In line with Conversations support, added a Catch-all method for unhandled texts
TelegramBot.setCatchAllText()
Version 1.2.0
- Adds basic Conversations support
TelegramBot.startConversation()
TelegramBot.endConversation()
- Added check to prevent duplicate poll updates