1 | # Usage
|
2 |
|
3 | * [Events](#events)
|
4 | * [WebHooks](#webhooks)
|
5 | * [Sending files](#sending-files)
|
6 | * [Error handling](#error-handling)
|
7 |
|
8 | <a name="events"></a>
|
9 | ## Events
|
10 |
|
11 | *TelegramBot* is an [EventEmitter](https://nodejs.org/api/events.html#events_class_eventemitter)
|
12 | that emits the following events:
|
13 |
|
14 | 1. `message`: Received a new incoming [Message][message] of any kind
|
15 | 1. Depending on the properties of the [Message][message], one of these
|
16 | events may **ALSO** be emitted: `text`, `audio`, `document`, `photo`,
|
17 | `sticker`, `video`, `voice`, `contact`, `location`,
|
18 | `new_chat_members`, `left_chat_member`, `new_chat_title`,
|
19 | `new_chat_photo`, `delete_chat_photo`, `group_chat_created`,
|
20 | `game`, `pinned_message`, `poll`, `dice`, `migrate_from_chat_id`, `migrate_to_chat_id`,
|
21 | `channel_chat_created`, `supergroup_chat_created`,
|
22 | `successful_payment`, `invoice`, `video_note`
|
23 | 1. **Arguments**: `message` ([Message][message]), `metadata` (`{ type?:string }`)
|
24 | 1. `new_chat_participant`, `left_chat_participant` are **deprecated**
|
25 | 1. `callback_query`: Received a new incoming [Callback Query][callback-query]
|
26 | 1. `inline_query`: Received a new incoming [Inline Query][inline-query]
|
27 | 1. `chosen_inline_result`: Received result of an inline query i.e. [ChosenInlineResult][chosen-inline-result]
|
28 | 1. `channel_post`: Received a new incoming channel post of any kind
|
29 | 1. `edited_message`: Received a new version of a message that is known to the bot and was edited
|
30 | 1. `edited_message_text`
|
31 | 1. `edited_message_caption`
|
32 | 1. `edited_channel_post`: Received a new version of a channel post that is known to the bot and was edited
|
33 | 1. `edited_channel_post_text`
|
34 | 1. `edited_channel_post_caption`
|
35 | 1. `shipping_query`: Received a new incoming shipping query
|
36 | 1. `pre_checkout_query`: Received a new incoming pre-checkout query
|
37 | 1. `poll`: Received a new incoming poll
|
38 | 1. `polling_error`: Error occurred during polling. See [polling errors](#polling-errors).
|
39 | 1. `webhook_error`: Error occurred handling a webhook request. See [webhook errors](#webhook-errors).
|
40 | 1. `error`: Unexpected error occurred, usually fatal!
|
41 |
|
42 | **Tip:** Its much better to listen a specific event rather than on
|
43 | `message` in order to stay safe from the content.
|
44 |
|
45 | **Tip:** Bot must be enabled on [inline mode][inline-mode] for receive some
|
46 | messages.
|
47 |
|
48 | <a name="webhooks"></a>
|
49 | ## WebHooks
|
50 |
|
51 | Telegram only supports HTTPS connections to WebHooks.
|
52 | Therefore, in order to set a WebHook, you will need a SSL certificate.
|
53 | Since August 29, 2015 Telegram supports self-signed ones, thus, you can
|
54 | generate them:
|
55 |
|
56 | ```bash
|
57 | # Our private cert will be key.pem, keep this file private
|
58 | $ openssl genrsa -out key.pem 2048
|
59 |
|
60 | # Our public certificate will be crt.pem
|
61 | $ openssl req -new -sha256 -key key.pem -out crt.pem
|
62 | ```
|
63 |
|
64 | Once they are generated, the `crt.pem` should be uploaded, when setting up
|
65 | your webhook. For example,
|
66 |
|
67 | ```js
|
68 | bot.setWebHook('public-url.com', {
|
69 | certificate: 'path/to/crt.pem', // Path to your crt.pem
|
70 | });
|
71 | ```
|
72 |
|
73 | **Note:** If you encounter an error, like
|
74 | `Error: error:0906D06C:PEM routines:PEM_read_bio:no start line`,
|
75 | you may want to proceed to [this issue][issue-63] for more information.
|
76 |
|
77 | <a name="sending-files"></a>
|
78 | ## Sending files
|
79 |
|
80 | The library makes it easy to get started sending files. *By default*, you
|
81 | may provide a **file-path** and the library will handle reading it for you.
|
82 | For example,
|
83 |
|
84 | ```js
|
85 | bot.sendAudio(chatId, 'path/to/audio.mp3');
|
86 | ```
|
87 |
|
88 | You may also pass in a **Readable Stream** from which data will be piped.
|
89 | For example,
|
90 |
|
91 | ```js
|
92 | const stream = fs.createReadStream('path/to/audio.mp3');
|
93 | bot.sendAudio(chatId, stream);
|
94 | ```
|
95 |
|
96 | You may also pass in a **Buffer** containing the contents of your file.
|
97 | For example,
|
98 |
|
99 | ```js
|
100 | const buffer = fs.readFileSync('path/to/audio.mp3'); // sync! that's sad! :-( Just making a point!
|
101 | bot.sendAudio(chatId, buffer);
|
102 | ```
|
103 |
|
104 | If you already have a **File ID**, you earlier retrieved from Telegram,
|
105 | you may pass it in, for example:
|
106 |
|
107 | ```js
|
108 | const fileId = getFileIdSomehow();
|
109 | bot.sendAudio(chatId, fileId);
|
110 | ```
|
111 |
|
112 | Some API methods, such as *SendPhoto*, allow passing a **HTTP URL**, that
|
113 | the Telegram servers will use to download the file. For example,
|
114 |
|
115 | ```js
|
116 | const url = 'https://telegram.org/img/t_logo.png';
|
117 | bot.sendPhoto(chatId, url);
|
118 | ```
|
119 |
|
120 | If you wish to explicitly specify the filename or
|
121 | [MIME type](http://en.wikipedia.org/wiki/Internet_media_type),
|
122 | you may pass an additional argument as file options, like so:
|
123 |
|
124 | ```js
|
125 | const fileOptions = {
|
126 | // Explicitly specify the file name.
|
127 | filename: 'customfilename',
|
128 | // Explicitly specify the MIME type.
|
129 | contentType: 'audio/mpeg',
|
130 | };
|
131 | bot.sendAudio(chatId, data, {}, fileOptions);
|
132 | ```
|
133 |
|
134 | **NOTE:** You **MUST** provide an empty object (`{}`) in place of
|
135 | *Additional Telegram query options*, if you have **no** query options
|
136 | to specify. For example,
|
137 |
|
138 | ```js
|
139 | // WRONG!
|
140 | // 'fileOptions' will be taken as additional Telegram query options!!!
|
141 | bot.sendAudio(chatId, data, fileOptions);
|
142 |
|
143 | // RIGHT!
|
144 | bot.sendAudio(chatId, data, {}, fileOptions);
|
145 | ```
|
146 |
|
147 |
|
148 | <a name="sending-files-options"></a>
|
149 | ### File Options (metadata)
|
150 |
|
151 | When sending files, the library automatically resolves
|
152 | the `filename` and `contentType` properties.
|
153 | **For now, this has to be manually activated using environment
|
154 | variable `NTBA_FIX_350`.**
|
155 |
|
156 | In order of highest-to-lowest precedence in searching for
|
157 | a value, when resolving the `filename`:
|
158 |
|
159 | *(`fileOptions` is the Object argument passed to the method.
|
160 | The "file" argument passed to the method can be a `Stream`,
|
161 | `Buffer` or `filepath`.)*
|
162 |
|
163 | 1. Is `fileOptions.filename` explictly defined?
|
164 | 1. Does `Stream#path` exist?
|
165 | 1. Is `filepath` provided?
|
166 | 1. Default to `"filename"`
|
167 |
|
168 | And the `contentType`:
|
169 |
|
170 | 1. Is `fileOptions.contentType` explictly-defined?
|
171 | 1. Does `Stream#path` exist?
|
172 | 1. Try detecting file-type from the `Buffer`
|
173 | 1. Is `filepath` provided?
|
174 | 1. Is `fileOptions.filename` explicitly defined?
|
175 | 1. Default to `"application/octet-stream"`
|
176 |
|
177 | <a name="sending-files-performance"></a>
|
178 | ### Performance Issue
|
179 |
|
180 | To support providing file-paths to methods that send files involves
|
181 | performing a file operation, i.e. *fs.existsSync()*, that checks for
|
182 | the existence of the file at the provided path. While the cost of
|
183 | this operation *might* be negligible in most use cases, if you want
|
184 | to squeeze the best performance out of this library, you may wish to
|
185 | disable this behavior.
|
186 |
|
187 | This will mean that you will **NOT** be able to pass in file-paths.
|
188 | You will have to use Streams or Buffers to provide the file contents.
|
189 |
|
190 | Disabling this behavior:
|
191 |
|
192 | ```js
|
193 | const bot = new TelegramBot(token, {
|
194 | filepath: false,
|
195 | });
|
196 | ```
|
197 |
|
198 | <a name="error-handling"></a>
|
199 | ## Error handling
|
200 |
|
201 | Every `Error` object we pass back has the properties:
|
202 |
|
203 | * `code` (String):
|
204 | * value is `EFATAL` if error was fatal e.g. network error
|
205 | * value is `EPARSE` if response body could **not** be parsed
|
206 | * value is `ETELEGRAM` if error was returned from Telegram servers
|
207 | * `response` ([http.IncomingMessage](https://nodejs.org/api/http.html#http_class_http_incomingmessage)):
|
208 | * available if `error.code` is **not** `EFATAL`
|
209 | * `response.body` (String|Object): Error response from Telegram
|
210 | * type is `String` if `error.code` is `EPARSE`
|
211 | * type is `Object` if `error.code` is `ETELEGRAM`
|
212 |
|
213 | For example, sending message to a non-existent user:
|
214 |
|
215 | ```js
|
216 | bot.sendMessage(nonExistentUserId, 'text').catch((error) => {
|
217 | console.log(error.code); // => 'ETELEGRAM'
|
218 | console.log(error.response.body); // => { ok: false, error_code: 400, description: 'Bad Request: chat not found' }
|
219 | });
|
220 | ```
|
221 |
|
222 | <a name="polling-errors"></a>
|
223 | ## Polling errors
|
224 |
|
225 | An error may occur during polling. It is up to you to handle it
|
226 | as you see fit. You may decide to crash your bot after a maximum number
|
227 | of polling errors occurring. **It is all up to you.**
|
228 |
|
229 | By default, the polling error is just logged to stderr, if you do
|
230 | **not** handle this event yourself.
|
231 |
|
232 | Listen on the `'polling_error'` event. For example,
|
233 |
|
234 | ```js
|
235 | bot.on('polling_error', (error) => {
|
236 | console.log(error.code); // => 'EFATAL'
|
237 | });
|
238 | ```
|
239 |
|
240 | <a name="webhook-errors"></a>
|
241 | ## WebHook errors
|
242 |
|
243 | Just like with [polling errors](#polling-errors), you decide on how to
|
244 | handle it. By default, the error is logged to stderr.
|
245 |
|
246 | Listen on the `'webhook_error'` event. For example,
|
247 |
|
248 | ```js
|
249 | bot.on('webhook_error', (error) => {
|
250 | console.log(error.code); // => 'EPARSE'
|
251 | });
|
252 | ```
|
253 |
|
254 | [update]:https://core.telegram.org/bots/api#update
|
255 | [message]:https://core.telegram.org/bots/api#message
|
256 | [callback-query]:https://core.telegram.org/bots/api#callbackquery
|
257 | [inline-query]:https://core.telegram.org/bots/api#inlinequery
|
258 | [chosen-inline-result]:https://core.telegram.org/bots/api#choseninlineresult
|
259 | [inline-mode]:https://core.telegram.org/bots/api#inline-mode
|
260 | [issue-63]:https://github.com/yagop/node-telegram-bot-api/issues/63
|