2
0
mirror of https://github.com/yagop/node-telegram-bot-api synced 2025-08-22 18:07:16 +00:00

src: Support file options, defaults in sending files

This commit is contained in:
GochoMugo 2017-11-16 20:27:17 +03:00
parent fb1f4344b3
commit d6083e4327
6 changed files with 275 additions and 80 deletions

View File

@ -1,2 +1,3 @@
bin bin
lib
*.md *.md

View File

@ -30,13 +30,13 @@ TelegramBot
* [.sendMessage(chatId, text, [options])](#TelegramBot+sendMessage) ⇒ <code>Promise</code> * [.sendMessage(chatId, text, [options])](#TelegramBot+sendMessage) ⇒ <code>Promise</code>
* [.answerInlineQuery(inlineQueryId, results, [options])](#TelegramBot+answerInlineQuery) ⇒ <code>Promise</code> * [.answerInlineQuery(inlineQueryId, results, [options])](#TelegramBot+answerInlineQuery) ⇒ <code>Promise</code>
* [.forwardMessage(chatId, fromChatId, messageId, [options])](#TelegramBot+forwardMessage) ⇒ <code>Promise</code> * [.forwardMessage(chatId, fromChatId, messageId, [options])](#TelegramBot+forwardMessage) ⇒ <code>Promise</code>
* [.sendPhoto(chatId, photo, [options])](#TelegramBot+sendPhoto) ⇒ <code>Promise</code> * [.sendPhoto(chatId, photo, [options], [fileOpts])](#TelegramBot+sendPhoto) ⇒ <code>Promise</code>
* [.sendAudio(chatId, audio, [options])](#TelegramBot+sendAudio) ⇒ <code>Promise</code> * [.sendAudio(chatId, audio, [options], [fileOpts])](#TelegramBot+sendAudio) ⇒ <code>Promise</code>
* [.sendDocument(chatId, doc, [options], [fileOpts])](#TelegramBot+sendDocument) ⇒ <code>Promise</code> * [.sendDocument(chatId, doc, [options], [fileOpts])](#TelegramBot+sendDocument) ⇒ <code>Promise</code>
* [.sendSticker(chatId, sticker, [options])](#TelegramBot+sendSticker) ⇒ <code>Promise</code> * [.sendSticker(chatId, sticker, [options])](#TelegramBot+sendSticker) ⇒ <code>Promise</code>
* [.sendVideo(chatId, video, [options])](#TelegramBot+sendVideo) ⇒ <code>Promise</code> * [.sendVideo(chatId, video, [options], [fileOpts])](#TelegramBot+sendVideo) ⇒ <code>Promise</code>
* [.sendVideoNote(chatId, videoNote, [options])](#TelegramBot+sendVideoNote) ⇒ <code>Promise</code> * [.sendVideoNote(chatId, videoNote, [options], [fileOpts])](#TelegramBot+sendVideoNote) ⇒ <code>Promise</code>
* [.sendVoice(chatId, voice, [options])](#TelegramBot+sendVoice) ⇒ <code>Promise</code> * [.sendVoice(chatId, voice, [options], [fileOpts])](#TelegramBot+sendVoice) ⇒ <code>Promise</code>
* [.sendChatAction(chatId, action, [options])](#TelegramBot+sendChatAction) ⇒ <code>Promise</code> * [.sendChatAction(chatId, action, [options])](#TelegramBot+sendChatAction) ⇒ <code>Promise</code>
* [.kickChatMember(chatId, userId, [options])](#TelegramBot+kickChatMember) ⇒ <code>Promise</code> * [.kickChatMember(chatId, userId, [options])](#TelegramBot+kickChatMember) ⇒ <code>Promise</code>
* [.unbanChatMember(chatId, userId, [options])](#TelegramBot+unbanChatMember) ⇒ <code>Promise</code> * [.unbanChatMember(chatId, userId, [options])](#TelegramBot+unbanChatMember) ⇒ <code>Promise</code>
@ -339,31 +339,41 @@ Forward messages of any kind.
<a name="TelegramBot+sendPhoto"></a> <a name="TelegramBot+sendPhoto"></a>
### telegramBot.sendPhoto(chatId, photo, [options]) ⇒ <code>Promise</code> ### telegramBot.sendPhoto(chatId, photo, [options], [fileOpts]) ⇒ <code>Promise</code>
Send photo Send photo
**Kind**: instance method of <code>[TelegramBot](#TelegramBot)</code> **Kind**: instance method of <code>[TelegramBot](#TelegramBot)</code>
**See**: https://core.telegram.org/bots/api#sendphoto **See**
- https://core.telegram.org/bots/api#sendphoto
- https://github.com/yagop/node-telegram-bot-api/blob/master/doc/usage.md#sending-files
| Param | Type | Description | | Param | Type | Description |
| --- | --- | --- | | --- | --- | --- |
| chatId | <code>Number</code> &#124; <code>String</code> | Unique identifier for the message recipient | | chatId | <code>Number</code> &#124; <code>String</code> | Unique identifier for the message recipient |
| photo | <code>String</code> &#124; <code>stream.Stream</code> &#124; <code>Buffer</code> | A file path or a Stream. Can also be a `file_id` previously uploaded | | photo | <code>String</code> &#124; <code>stream.Stream</code> &#124; <code>Buffer</code> | A file path or a Stream. Can also be a `file_id` previously uploaded |
| [options] | <code>Object</code> | Additional Telegram query options | | [options] | <code>Object</code> | Additional Telegram query options |
| [fileOpts] | <code>Object</code> | Optional file related meta-data |
<a name="TelegramBot+sendAudio"></a> <a name="TelegramBot+sendAudio"></a>
### telegramBot.sendAudio(chatId, audio, [options]) ⇒ <code>Promise</code> ### telegramBot.sendAudio(chatId, audio, [options], [fileOpts]) ⇒ <code>Promise</code>
Send audio Send audio
**Kind**: instance method of <code>[TelegramBot](#TelegramBot)</code> **Kind**: instance method of <code>[TelegramBot](#TelegramBot)</code>
**See**: https://core.telegram.org/bots/api#sendaudio **See**
- https://core.telegram.org/bots/api#sendaudio
- https://github.com/yagop/node-telegram-bot-api/blob/master/doc/usage.md#sending-files
| Param | Type | Description | | Param | Type | Description |
| --- | --- | --- | | --- | --- | --- |
| chatId | <code>Number</code> &#124; <code>String</code> | Unique identifier for the message recipient | | chatId | <code>Number</code> &#124; <code>String</code> | Unique identifier for the message recipient |
| audio | <code>String</code> &#124; <code>stream.Stream</code> &#124; <code>Buffer</code> | A file path, Stream or Buffer. Can also be a `file_id` previously uploaded. | | audio | <code>String</code> &#124; <code>stream.Stream</code> &#124; <code>Buffer</code> | A file path, Stream or Buffer. Can also be a `file_id` previously uploaded. |
| [options] | <code>Object</code> | Additional Telegram query options | | [options] | <code>Object</code> | Additional Telegram query options |
| [fileOpts] | <code>Object</code> | Optional file related meta-data |
<a name="TelegramBot+sendDocument"></a> <a name="TelegramBot+sendDocument"></a>
@ -371,7 +381,11 @@ Send audio
Send Document Send Document
**Kind**: instance method of <code>[TelegramBot](#TelegramBot)</code> **Kind**: instance method of <code>[TelegramBot](#TelegramBot)</code>
**See**: https://core.telegram.org/bots/api#sendDocument **See**
- https://core.telegram.org/bots/api#sendDocument
- https://github.com/yagop/node-telegram-bot-api/blob/master/doc/usage.md#sending-files
| Param | Type | Description | | Param | Type | Description |
| --- | --- | --- | | --- | --- | --- |
@ -396,46 +410,61 @@ Send .webp stickers.
<a name="TelegramBot+sendVideo"></a> <a name="TelegramBot+sendVideo"></a>
### telegramBot.sendVideo(chatId, video, [options]) ⇒ <code>Promise</code> ### telegramBot.sendVideo(chatId, video, [options], [fileOpts]) ⇒ <code>Promise</code>
Use this method to send video files, Telegram clients support mp4 videos (other formats may be sent as Document). Use this method to send video files, Telegram clients support mp4 videos (other formats may be sent as Document).
**Kind**: instance method of <code>[TelegramBot](#TelegramBot)</code> **Kind**: instance method of <code>[TelegramBot](#TelegramBot)</code>
**See**: https://core.telegram.org/bots/api#sendvideo **See**
- https://core.telegram.org/bots/api#sendvideo
- https://github.com/yagop/node-telegram-bot-api/blob/master/doc/usage.md#sending-files
| Param | Type | Description | | Param | Type | Description |
| --- | --- | --- | | --- | --- | --- |
| chatId | <code>Number</code> &#124; <code>String</code> | Unique identifier for the message recipient | | chatId | <code>Number</code> &#124; <code>String</code> | Unique identifier for the message recipient |
| video | <code>String</code> &#124; <code>stream.Stream</code> &#124; <code>Buffer</code> | A file path or Stream. Can also be a `file_id` previously uploaded. | | video | <code>String</code> &#124; <code>stream.Stream</code> &#124; <code>Buffer</code> | A file path or Stream. Can also be a `file_id` previously uploaded. |
| [options] | <code>Object</code> | Additional Telegram query options | | [options] | <code>Object</code> | Additional Telegram query options |
| [fileOpts] | <code>Object</code> | Optional file related meta-data |
<a name="TelegramBot+sendVideoNote"></a> <a name="TelegramBot+sendVideoNote"></a>
### telegramBot.sendVideoNote(chatId, videoNote, [options]) ⇒ <code>Promise</code> ### telegramBot.sendVideoNote(chatId, videoNote, [options], [fileOpts]) ⇒ <code>Promise</code>
Use this method to send rounded square videos of upto 1 minute long. Use this method to send rounded square videos of upto 1 minute long.
**Kind**: instance method of <code>[TelegramBot](#TelegramBot)</code> **Kind**: instance method of <code>[TelegramBot](#TelegramBot)</code>
**Info**: The length parameter is actually optional. However, the API (at time of writing) requires you to always provide it until it is fixed. **Info**: The length parameter is actually optional. However, the API (at time of writing) requires you to always provide it until it is fixed.
**See**: https://core.telegram.org/bots/api#sendvideonote **See**
- https://core.telegram.org/bots/api#sendvideonote
- https://github.com/yagop/node-telegram-bot-api/blob/master/doc/usage.md#sending-files
| Param | Type | Description | | Param | Type | Description |
| --- | --- | --- | | --- | --- | --- |
| chatId | <code>Number</code> &#124; <code>String</code> | Unique identifier for the message recipient | | chatId | <code>Number</code> &#124; <code>String</code> | Unique identifier for the message recipient |
| videoNote | <code>String</code> &#124; <code>stream.Stream</code> &#124; <code>Buffer</code> | A file path or Stream. Can also be a `file_id` previously uploaded. | | videoNote | <code>String</code> &#124; <code>stream.Stream</code> &#124; <code>Buffer</code> | A file path or Stream. Can also be a `file_id` previously uploaded. |
| [options] | <code>Object</code> | Additional Telegram query options | | [options] | <code>Object</code> | Additional Telegram query options |
| [fileOpts] | <code>Object</code> | Optional file related meta-data |
<a name="TelegramBot+sendVoice"></a> <a name="TelegramBot+sendVoice"></a>
### telegramBot.sendVoice(chatId, voice, [options]) ⇒ <code>Promise</code> ### telegramBot.sendVoice(chatId, voice, [options], [fileOpts]) ⇒ <code>Promise</code>
Send voice Send voice
**Kind**: instance method of <code>[TelegramBot](#TelegramBot)</code> **Kind**: instance method of <code>[TelegramBot](#TelegramBot)</code>
**See**: https://core.telegram.org/bots/api#sendvoice **See**
- https://core.telegram.org/bots/api#sendvoice
- https://github.com/yagop/node-telegram-bot-api/blob/master/doc/usage.md#sending-files
| Param | Type | Description | | Param | Type | Description |
| --- | --- | --- | | --- | --- | --- |
| chatId | <code>Number</code> &#124; <code>String</code> | Unique identifier for the message recipient | | chatId | <code>Number</code> &#124; <code>String</code> | Unique identifier for the message recipient |
| voice | <code>String</code> &#124; <code>stream.Stream</code> &#124; <code>Buffer</code> | A file path, Stream or Buffer. Can also be a `file_id` previously uploaded. | | voice | <code>String</code> &#124; <code>stream.Stream</code> &#124; <code>Buffer</code> | A file path, Stream or Buffer. Can also be a `file_id` previously uploaded. |
| [options] | <code>Object</code> | Additional Telegram query options | | [options] | <code>Object</code> | Additional Telegram query options |
| [fileOpts] | <code>Object</code> | Optional file related meta-data |
<a name="TelegramBot+sendChatAction"></a> <a name="TelegramBot+sendChatAction"></a>

View File

@ -115,6 +115,45 @@ const url = 'https://telegram.org/img/t_logo.png';
bot.sendPhoto(chatId, url); bot.sendPhoto(chatId, url);
``` ```
If you wish to explicitly specify the filename or
[MIME type](http://en.wikipedia.org/wiki/Internet_media_type),
you may pass the an additional argument as file options, like so:
```js
const fileOpts = {
// Explicitly specify the file name.
filename: 'customfilename',
// Explicitly specify the MIME type.
contentType: 'audio/mpeg'
};
bot.sendAudio(chatId, data, {}, fileOpts);
```
<a name="sending-files-metadata"></a>
### 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`:
1. Is `fileOptions.filename` explictly defined?
1. Does `Stream#path` exist?
1. Is `filepath` provided?
1. Default to `"filename"`
And the `contentType`:
1. Is `fileOptions.contentType` explictly-defined?
1. Does `Stream#path` exist?
1. Try detecting file-type from the `Buffer`
1. Is `filepath` provided?
1. Is `fileOptions.filename` explicitly defined?
1. Default to `"application/octet-stream`
<a name="sending-files-performance"></a> <a name="sending-files-performance"></a>
### Performance Issue ### Performance Issue

View File

@ -284,6 +284,9 @@ class TelegramBot extends EventEmitter {
* Format data to be uploaded; handles file paths, streams and buffers * Format data to be uploaded; handles file paths, streams and buffers
* @param {String} type * @param {String} type
* @param {String|stream.Stream|Buffer} data * @param {String|stream.Stream|Buffer} data
* @param {Object} fileOpts File options
* @param {String} [fileOpts.filename] File name
* @param {String} [fileOpts.contentType] Content type (i.e. MIME)
* @return {Array} formatted * @return {Array} formatted
* @return {Object} formatted[0] formData * @return {Object} formatted[0] formData
* @return {String} formatted[1] fileId * @return {String} formatted[1] fileId
@ -291,55 +294,68 @@ class TelegramBot extends EventEmitter {
* @see https://npmjs.com/package/file-type * @see https://npmjs.com/package/file-type
* @private * @private
*/ */
_formatSendData(type, data) { _formatSendData(type, data, fileOpts = {}) {
let formData; let filedata = data;
let fileName; let filename = fileOpts.filename;
let fileId; let contentType = fileOpts.contentType;
if (data instanceof stream.Stream) { if (data instanceof stream.Stream) {
// Will be 'null' if could not be parsed. Default to 'filename'. if (!filename && data.path) {
// For example, 'data.path' === '/?id=123' from 'request("https://example.com/?id=123")' // Will be 'null' if could not be parsed.
fileName = URL.parse(path.basename(data.path.toString())).pathname || 'filename'; // For example, 'data.path' === '/?id=123' from 'request("https://example.com/?id=123")'
formData = {}; const url = URL.parse(path.basename(data.path.toString()));
formData[type] = { filename = qs.unescape(url.pathname);
value: data,
options: {
filename: qs.unescape(fileName),
contentType: mime.lookup(fileName)
}
};
} else if (Buffer.isBuffer(data)) {
const filetype = fileType(data);
if (!filetype) {
throw new errors.FatalError('Unsupported Buffer file type');
} }
formData = {}; } else if (Buffer.isBuffer(data)) {
formData[type] = { if (!filename && !process.env.NTBA_FIX_350) {
value: data, deprecate('Buffers will have their filenames default to "filename" instead of "data".');
options: { filename = 'data';
filename: `data.${filetype.ext}`, }
contentType: filetype.mime if (!contentType) {
const filetype = fileType(data);
if (filetype) {
contentType = filetype.mime;
const ext = filetype.ext;
if (ext && !process.env.NTBA_FIX_350) {
filename = `${filename}.${ext}`;
}
} else if (!process.env.NTBA_FIX_350) {
deprecate('An error will no longer be thrown if file-type of buffer could not be detected.');
throw new errors.FatalError('Unsupported Buffer file-type');
} }
}; }
} else if (!this.options.filepath) { } else if (data) {
/** if (this.options.filepath && fs.existsSync(data)) {
* When the constructor option 'filepath' is set to filedata = fs.createReadStream(data);
* 'false', we do not support passing file-paths. if (!filename) {
*/ filename = path.basename(data);
fileId = data;
} else if (fs.existsSync(data)) {
fileName = path.basename(data);
formData = {};
formData[type] = {
value: fs.createReadStream(data),
options: {
filename: fileName,
contentType: mime.lookup(fileName)
} }
}; } else {
return [null, data];
}
} else { } else {
fileId = data; return [null, data];
} }
return [formData, fileId];
filename = filename || 'filename';
contentType = contentType || mime.lookup(filename);
if (process.env.NTBA_FIX_350) {
contentType = contentType || 'application/octet-stream';
} else {
deprecate('In the future, content-type of files you send will default to "application/octet-stream".');
}
// TODO: Add missing file extension.
return [{
[type]: {
value: filedata,
options: {
filename,
contentType,
},
},
}, null];
} }
/** /**
@ -685,16 +701,18 @@ class TelegramBot extends EventEmitter {
* @param {String|stream.Stream|Buffer} photo A file path or a Stream. Can * @param {String|stream.Stream|Buffer} photo A file path or a Stream. Can
* also be a `file_id` previously uploaded * also be a `file_id` previously uploaded
* @param {Object} [options] Additional Telegram query options * @param {Object} [options] Additional Telegram query options
* @param {Object} [fileOpts] Optional file related meta-data
* @return {Promise} * @return {Promise}
* @see https://core.telegram.org/bots/api#sendphoto * @see https://core.telegram.org/bots/api#sendphoto
* @see https://github.com/yagop/node-telegram-bot-api/blob/master/doc/usage.md#sending-files
*/ */
sendPhoto(chatId, photo, options = {}) { sendPhoto(chatId, photo, options = {}, fileOpts = {}) {
const opts = { const opts = {
qs: options, qs: options,
}; };
opts.qs.chat_id = chatId; opts.qs.chat_id = chatId;
try { try {
const sendData = this._formatSendData('photo', photo); const sendData = this._formatSendData('photo', photo, fileOpts);
opts.formData = sendData[0]; opts.formData = sendData[0];
opts.qs.photo = sendData[1]; opts.qs.photo = sendData[1];
} catch (ex) { } catch (ex) {
@ -709,16 +727,18 @@ class TelegramBot extends EventEmitter {
* @param {String|stream.Stream|Buffer} audio A file path, Stream or Buffer. * @param {String|stream.Stream|Buffer} audio A file path, Stream or Buffer.
* Can also be a `file_id` previously uploaded. * Can also be a `file_id` previously uploaded.
* @param {Object} [options] Additional Telegram query options * @param {Object} [options] Additional Telegram query options
* @param {Object} [fileOpts] Optional file related meta-data
* @return {Promise} * @return {Promise}
* @see https://core.telegram.org/bots/api#sendaudio * @see https://core.telegram.org/bots/api#sendaudio
* @see https://github.com/yagop/node-telegram-bot-api/blob/master/doc/usage.md#sending-files
*/ */
sendAudio(chatId, audio, options = {}) { sendAudio(chatId, audio, options = {}, fileOpts = {}) {
const opts = { const opts = {
qs: options qs: options
}; };
opts.qs.chat_id = chatId; opts.qs.chat_id = chatId;
try { try {
const sendData = this._formatSendData('audio', audio); const sendData = this._formatSendData('audio', audio, fileOpts);
opts.formData = sendData[0]; opts.formData = sendData[0];
opts.qs.audio = sendData[1]; opts.qs.audio = sendData[1];
} catch (ex) { } catch (ex) {
@ -736,6 +756,7 @@ class TelegramBot extends EventEmitter {
* @param {Object} [fileOpts] Optional file related meta-data * @param {Object} [fileOpts] Optional file related meta-data
* @return {Promise} * @return {Promise}
* @see https://core.telegram.org/bots/api#sendDocument * @see https://core.telegram.org/bots/api#sendDocument
* @see https://github.com/yagop/node-telegram-bot-api/blob/master/doc/usage.md#sending-files
*/ */
sendDocument(chatId, doc, options = {}, fileOpts = {}) { sendDocument(chatId, doc, options = {}, fileOpts = {}) {
const opts = { const opts = {
@ -743,15 +764,12 @@ class TelegramBot extends EventEmitter {
}; };
opts.qs.chat_id = chatId; opts.qs.chat_id = chatId;
try { try {
const sendData = this._formatSendData('document', doc); const sendData = this._formatSendData('document', doc, fileOpts);
opts.formData = sendData[0]; opts.formData = sendData[0];
opts.qs.document = sendData[1]; opts.qs.document = sendData[1];
} catch (ex) { } catch (ex) {
return Promise.reject(ex); return Promise.reject(ex);
} }
if (opts.formData && Object.keys(fileOpts).length) {
opts.formData.document.options = fileOpts;
}
return this._request('sendDocument', opts); return this._request('sendDocument', opts);
} }
@ -785,16 +803,18 @@ class TelegramBot extends EventEmitter {
* @param {String|stream.Stream|Buffer} video A file path or Stream. * @param {String|stream.Stream|Buffer} video A file path or Stream.
* Can also be a `file_id` previously uploaded. * Can also be a `file_id` previously uploaded.
* @param {Object} [options] Additional Telegram query options * @param {Object} [options] Additional Telegram query options
* @param {Object} [fileOpts] Optional file related meta-data
* @return {Promise} * @return {Promise}
* @see https://core.telegram.org/bots/api#sendvideo * @see https://core.telegram.org/bots/api#sendvideo
* @see https://github.com/yagop/node-telegram-bot-api/blob/master/doc/usage.md#sending-files
*/ */
sendVideo(chatId, video, options = {}) { sendVideo(chatId, video, options = {}, fileOpts = {}) {
const opts = { const opts = {
qs: options qs: options
}; };
opts.qs.chat_id = chatId; opts.qs.chat_id = chatId;
try { try {
const sendData = this._formatSendData('video', video); const sendData = this._formatSendData('video', video, fileOpts);
opts.formData = sendData[0]; opts.formData = sendData[0];
opts.qs.video = sendData[1]; opts.qs.video = sendData[1];
} catch (ex) { } catch (ex) {
@ -809,17 +829,19 @@ class TelegramBot extends EventEmitter {
* @param {String|stream.Stream|Buffer} videoNote A file path or Stream. * @param {String|stream.Stream|Buffer} videoNote A file path or Stream.
* Can also be a `file_id` previously uploaded. * Can also be a `file_id` previously uploaded.
* @param {Object} [options] Additional Telegram query options * @param {Object} [options] Additional Telegram query options
* @param {Object} [fileOpts] Optional file related meta-data
* @return {Promise} * @return {Promise}
* @info The length parameter is actually optional. However, the API (at time of writing) requires you to always provide it until it is fixed. * @info The length parameter is actually optional. However, the API (at time of writing) requires you to always provide it until it is fixed.
* @see https://core.telegram.org/bots/api#sendvideonote * @see https://core.telegram.org/bots/api#sendvideonote
* @see https://github.com/yagop/node-telegram-bot-api/blob/master/doc/usage.md#sending-files
*/ */
sendVideoNote(chatId, videoNote, options = {}) { sendVideoNote(chatId, videoNote, options = {}, fileOpts = {}) {
const opts = { const opts = {
qs: options qs: options
}; };
opts.qs.chat_id = chatId; opts.qs.chat_id = chatId;
try { try {
const sendData = this._formatSendData('video_note', videoNote); const sendData = this._formatSendData('video_note', videoNote, fileOpts);
opts.formData = sendData[0]; opts.formData = sendData[0];
opts.qs.video_note = sendData[1]; opts.qs.video_note = sendData[1];
} catch (ex) { } catch (ex) {
@ -834,16 +856,18 @@ class TelegramBot extends EventEmitter {
* @param {String|stream.Stream|Buffer} voice A file path, Stream or Buffer. * @param {String|stream.Stream|Buffer} voice A file path, Stream or Buffer.
* Can also be a `file_id` previously uploaded. * Can also be a `file_id` previously uploaded.
* @param {Object} [options] Additional Telegram query options * @param {Object} [options] Additional Telegram query options
* @param {Object} [fileOpts] Optional file related meta-data
* @return {Promise} * @return {Promise}
* @see https://core.telegram.org/bots/api#sendvoice * @see https://core.telegram.org/bots/api#sendvoice
* @see https://github.com/yagop/node-telegram-bot-api/blob/master/doc/usage.md#sending-files
*/ */
sendVoice(chatId, voice, options = {}) { sendVoice(chatId, voice, options = {}, fileOpts = {}) {
const opts = { const opts = {
qs: options qs: options
}; };
opts.qs.chat_id = chatId; opts.qs.chat_id = chatId;
try { try {
const sendData = this._formatSendData('voice', voice); const sendData = this._formatSendData('voice', voice, fileOpts);
opts.formData = sendData[0]; opts.formData = sendData[0];
opts.qs.voice = sendData[1]; opts.qs.voice = sendData[1];
} catch (ex) { } catch (ex) {

View File

@ -630,13 +630,6 @@ describe('TelegramBot', function telegramSuite() {
assert.ok(is.object(resp.document)); assert.ok(is.object(resp.document));
}); });
}); });
it('should send a document with custom file options', function test() {
const document = fs.createReadStream(`${__dirname}/data/photo.gif`);
const fileOpts = { filename: 'customfilename.gif' };
return bot.sendDocument(USERID, document, {}, fileOpts).then(resp => {
assert.equal(resp.document.file_name, fileOpts.filename);
});
});
}); });
describe('#sendSticker', function sendStickerSuite() { describe('#sendSticker', function sendStickerSuite() {

109
test/test.sendfile.js Normal file
View File

@ -0,0 +1,109 @@
const assert = require('assert');
const fs = require('fs');
const path = require('path');
const TelegramBot = require('..');
const paths = {
audio: path.join(__dirname, "data/audio.mp3"),
};
// TODO:Enable all other tests
describe.only('sending files', function sendfileSuite() {
const bot = new TelegramBot("token");
before(function beforeSuite() {
process.env.NTBA_FIX_350 = 1;
});
after(function afterSuite() {
delete process.env.NTBA_FIX_350;
});
describe('using fileOptions', function sendfileOptionsSuite() {
const type = 'file';
const stream = fs.createReadStream(paths.audio);
const nonPathStream = fs.createReadStream(paths.audio);
const buffer = fs.readFileSync(paths.audio);
const nonDetectableBuffer = fs.readFileSync(__filename);
const filepath = paths.audio;
const fileId = 'fileId';
const files = [stream, nonPathStream, buffer, nonDetectableBuffer, filepath];
delete nonPathStream.path;
describe('filename', function filenameSuite() {
it('(1) fileOptions.filename', function test() {
const filename = 'custom-filename';
files.forEach((file) => {
const [{ [type]: data }] = bot._formatSendData(type, file, { filename });
assert.equal(data.options.filename, filename);
});
});
it('(2) Stream#path', function test() {
if (!stream.path) {
return this.skip('Stream#path unsupported');
}
const [{ [type]: data }] = bot._formatSendData(type, stream);
assert.equal(data.options.filename, path.basename(paths.audio));
});
it('(3) filepath', function test() {
const [{ [type]: data }] = bot._formatSendData(type, filepath);
assert.equal(data.options.filename, path.basename(paths.audio));
});
it('(4) final default', function test() {
[nonPathStream, buffer, nonDetectableBuffer].forEach((file) => {
const [{ [type]: data }] = bot._formatSendData(type, file);
assert.equal(data.options.filename, 'filename');
});
});
});
describe('contentType', function contentTypeSuite() {
it('(1) fileOpts.contentType', function test() {
const contentType = 'application/custom-type';
files.forEach((file) => {
const [{ [type]: data }] = bot._formatSendData(type, file, { contentType });
assert.equal(data.options.contentType, contentType);
});
});
it('(2) Stream#path', function test() {
if (!stream.path) {
return this.skip('Stream#path unsupported');
}
const [{ [type]: data }] = bot._formatSendData(type, stream);
assert.equal(data.options.contentType, 'audio/mpeg');
});
it('(3) Buffer file-type', function test() {
const [{ [type]: data }] = bot._formatSendData(type, buffer);
assert.equal(data.options.contentType, 'audio/mpeg');
});
it('(4) filepath', function test() {
const [{ [type]: data }] = bot._formatSendData(type, filepath);
assert.equal(data.options.contentType, 'audio/mpeg');
});
it('(5) fileOptions.filename', function test() {
[nonPathStream, nonDetectableBuffer].forEach((file) => {
const [{ [type]: data }] = bot._formatSendData(type, file, {
filename: 'image.gif',
});
assert.equal(data.options.contentType, 'image/gif');
});
});
it('(6) Final default', function test() {
[nonPathStream, nonDetectableBuffer].forEach((file) => {
const [{ [type]: data }] = bot._formatSendData(type, file);
assert.equal(data.options.contentType, 'application/octet-stream');
});
});
});
});
});