Skip to content
Branch: master
Find file Copy path
Find file Copy path
4 contributors

Users who have contributed to this file

@GochoMugo @kamikazechaser @preco21 @Coac
261 lines (203 sloc) 8.55 KB



TelegramBot is an EventEmitter that emits the following events:

  1. message: Received a new incoming Message of any kind
  2. Depending on the properties of the Message, one of these events may ALSO be emitted: text, audio, document, photo, sticker, video, voice, contact, location, new_chat_members, left_chat_member, new_chat_title, new_chat_photo, delete_chat_photo, group_chat_created, game, pinned_message, poll, migrate_from_chat_id, migrate_to_chat_id, channel_chat_created, supergroup_chat_created, successful_payment, invoice, video_note
  3. Arguments: message (Message), metadata ({ type?:string })
  4. new_chat_participant, left_chat_participant are deprecated
  5. callback_query: Received a new incoming Callback Query
  6. inline_query: Received a new incoming Inline Query
  7. chosen_inline_result: Received result of an inline query i.e. ChosenInlineResult
  8. channel_post: Received a new incoming channel post of any kind
  9. edited_message: Received a new version of a message that is known to the bot and was edited
  10. edited_message_text
  11. edited_message_caption
  12. edited_channel_post: Received a new version of a channel post that is known to the bot and was edited
  13. edited_channel_post_text
  14. edited_channel_post_caption
  15. shipping_query: Received a new incoming shipping query
  16. pre_checkout_query: Received a new incoming pre-checkout query
  17. poll: Received a new incoming poll
  18. polling_error: Error occurred during polling. See polling errors.
  19. webhook_error: Error occurred handling a webhook request. See webhook errors.
  20. error: Unexpected error occurred, usually fatal!

Tip: Its much better to listen a specific event rather than on message in order to stay safe from the content.

Tip: Bot must be enabled on inline mode for receive some messages.


Telegram only supports HTTPS connections to WebHooks. Therefore, in order to set a WebHook, you will need a SSL certificate. Since August 29, 2015 Telegram supports self-signed ones, thus, you can generate them:

# Our private cert will be key.pem, keep this file private
$ openssl genrsa -out key.pem 2048

# Our public certificate will be crt.pem
$ openssl req -new -sha256 -key key.pem -out crt.pem

Once they are generated, the crt.pem should be uploaded, when setting up your webhook. For example,

bot.setWebHook('', {
  certificate: 'path/to/crt.pem', // Path to your crt.pem

Note: If you encounter an error, like Error: error:0906D06C:PEM routines:PEM_read_bio:no start line, you may want to proceed to this issue for more information.

Sending files

The library makes it easy to get started sending files. By default, you may provide a file-path and the library will handle reading it for you. For example,

bot.sendAudio(chatId, 'path/to/audio.mp3');

You may also pass in a Readable Stream from which data will be piped. For example,

const stream = fs.createReadStream('path/to/audio.mp3');
bot.sendAudio(chatId, stream);

You may also pass in a Buffer containing the contents of your file. For example,

const buffer = fs.readFileSync('path/to/audio.mp3'); // sync! that's sad! :-( Just making a point!
bot.sendAudio(chatId, buffer);

If you already have a File ID, you earlier retrieved from Telegram, you may pass it in, for example:

const fileId = getFileIdSomehow();
bot.sendAudio(chatId, fileId);

Some API methods, such as SendPhoto, allow passing a HTTP URL, that the Telegram servers will use to download the file. For example,

const url = '';
bot.sendPhoto(chatId, url);

If you wish to explicitly specify the filename or MIME type, you may pass an additional argument as file options, like so:

const fileOptions = {
  // Explicitly specify the file name.
  filename: 'customfilename',
  // Explicitly specify the MIME type.
  contentType: 'audio/mpeg',
bot.sendAudio(chatId, data, {}, fileOptions);

NOTE: You MUST provide an empty object ({}) in place of Additional Telegram query options, if you have no query options to specify. For example,

// 'fileOptions' will be taken as additional Telegram query options!!!
bot.sendAudio(chatId, data, fileOptions);

bot.sendAudio(chatId, data, {}, fileOptions);

File Options (metadata)

When sending files, the library automatically resolves the filename and contentType properties. For now, this has to be manually activated using environment variable NTBA_FIX_350.

In order of highest-to-lowest precedence in searching for a value, when resolving the filename:

(fileOptions is the Object argument passed to the method. The "file" argument passed to the method can be a Stream, Buffer or filepath.)

  1. Is fileOptions.filename explictly defined?
  2. Does Stream#path exist?
  3. Is filepath provided?
  4. Default to "filename"

And the contentType:

  1. Is fileOptions.contentType explictly-defined?
  2. Does Stream#path exist?
  3. Try detecting file-type from the Buffer
  4. Is filepath provided?
  5. Is fileOptions.filename explicitly defined?
  6. Default to "application/octet-stream"

Performance Issue

To support providing file-paths to methods that send files involves performing a file operation, i.e. fs.existsSync(), that checks for the existence of the file at the provided path. While the cost of this operation might be negligible in most use cases, if you want to squeeze the best performance out of this library, you may wish to disable this behavior.

This will mean that you will NOT be able to pass in file-paths. You will have to use Streams or Buffers to provide the file contents.

Disabling this behavior:

const bot = new TelegramBot(token, {
  filepath: false,

Error handling

Every Error object we pass back has the properties:

  • code (String):
    • value is EFATAL if error was fatal e.g. network error
    • value is EPARSE if response body could not be parsed
    • value is ETELEGRAM if error was returned from Telegram servers
  • response (http.IncomingMessage):
    • available if error.code is not EFATAL
  • response.body (String|Object): Error response from Telegram
    • type is String if error.code is EPARSE
    • type is Object if error.code is ETELEGRAM

For example, sending message to a non-existent user:

bot.sendMessage(nonExistentUserId, 'text').catch((error) => {
  console.log(error.code);  // => 'ETELEGRAM'
  console.log(error.response.body); // => { ok: false, error_code: 400, description: 'Bad Request: chat not found' }

Polling errors

An error may occur during polling. It is up to you to handle it as you see fit. You may decide to crash your bot after a maximum number of polling errors occurring. It is all up to you.

By default, the polling error is just logged to stderr, if you do not handle this event yourself.

Listen on the 'polling_error' event. For example,

bot.on('polling_error', (error) => {
  console.log(error.code);  // => 'EFATAL'

WebHook errors

Just like with polling errors, you decide on how to handle it. By default, the error is logged to stderr.

Listen on the 'webhook_error' event. For example,

bot.on('webhook_error', (error) => {
  console.log(error.code);  // => 'EPARSE'
You can’t perform that action at this time.