Skip to content

Commit 5fd83b3

Browse files
Daniel Pérez FernándezDaniel Pérez Fernández
authored andcommitted
feat: Support for sendPaidMedia
1 parent 531a15e commit 5fd83b3

File tree

1 file changed

+115
-0
lines changed

1 file changed

+115
-0
lines changed

src/telegram.js

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -405,6 +405,79 @@ class TelegramBot extends EventEmitter {
405405
}, null];
406406
}
407407

408+
409+
/**
410+
* Format multiple files to be uploaded; handles file paths, streams, and buffers
411+
* @param {String} type
412+
* @param {Array} files Array of file data objects
413+
* @param {Object} fileOptions File options
414+
* @param {String} [fileOptions.filename] File name
415+
* @param {String} [fileOptions.contentType] Content type (i.e. MIME)
416+
* @return {Object} formatted
417+
* @return {Object} formatted.formData Form data object with all files
418+
* @return {Array} formatted.fileIds Array of fileIds for non-file data
419+
* @throws Error if Buffer file type is not supported.
420+
* @see https://npmjs.com/package/file-type
421+
* @private
422+
*/
423+
_formatSendMultipleData(type, files, fileOptions = {}) {
424+
const formData = {};
425+
const fileIds = {};
426+
427+
files.forEach((file, index) => {
428+
let filedata = file.media || file.data;
429+
let filename = file.filename || fileOptions.filename;
430+
let contentType = file.contentType || fileOptions.contentType;
431+
432+
if (filedata instanceof stream.Stream) {
433+
if (!filename && filedata.path) {
434+
const url = URL.parse(path.basename(filedata.path.toString()), true);
435+
if (url.pathname) {
436+
filename = qs.unescape(url.pathname);
437+
}
438+
}
439+
} else if (Buffer.isBuffer(filedata)) {
440+
filename = `filename_${index}`;
441+
442+
if (!contentType) {
443+
const filetype = fileType(filedata);
444+
445+
if (filetype) {
446+
contentType = filetype.mime;
447+
const ext = filetype.ext;
448+
449+
if (ext) {
450+
filename = `${filename}.${ext}`;
451+
}
452+
} else {
453+
throw new errors.FatalError('Unsupported Buffer file-type');
454+
}
455+
}
456+
} else if (fs.existsSync(filedata)) {
457+
filedata = fs.createReadStream(filedata);
458+
459+
if (!filename) {
460+
filename = path.basename(filedata.path);
461+
}
462+
} else {
463+
fileIds[index] = filedata;
464+
return;
465+
}
466+
467+
filename = filename || `filename_${index}`;
468+
contentType = contentType || 'application/octet-stream';
469+
470+
formData[`${type}_${index}`] = {
471+
value: filedata,
472+
options: {
473+
filename,
474+
contentType,
475+
},
476+
};
477+
});
478+
479+
return { formData, fileIds };
480+
}
408481
/**
409482
* Start polling.
410483
* Rejects returned promise if a WebHook is being used by this instance.
@@ -1247,6 +1320,48 @@ class TelegramBot extends EventEmitter {
12471320
return this._request('sendVideoNote', opts);
12481321
}
12491322

1323+
/**
1324+
* Use this method to send paid media.
1325+
* @param {Number|String} chatId Unique identifier for the target chat or username of the target channel (in the format `@channelusername`)
1326+
* @param {Number} starCount The number of Telegram Stars that must be paid to buy access to the media; 1-10000
1327+
* @param {String|stream.Stream|Buffer} media A file path or Stream.
1328+
* @param {Object} [options] Additional Telegram query options
1329+
* @return {Promise} On success, the sent [Message](https://core.telegram.org/bots/api#message) object is returned
1330+
* @see https://core.telegram.org/bots/api#sendpaidmedia
1331+
*/
1332+
sendPaidMedia(chatId, starCount, media, options = {}) {
1333+
const opts = {
1334+
qs: options
1335+
};
1336+
1337+
opts.qs.chat_id = chatId;
1338+
opts.qs.star_count = starCount;
1339+
1340+
try {
1341+
const inputPaidMedia = [];
1342+
opts.formData = {};
1343+
1344+
const { formData, fileIds } = this._formatSendMultipleData('media', media);
1345+
1346+
opts.formData = formData;
1347+
1348+
inputPaidMedia.push(...media.map((item, index) => {
1349+
if (fileIds[index]) {
1350+
item.media = fileIds[index];
1351+
} else {
1352+
item.media = `attach://media_${index}`;
1353+
}
1354+
return item;
1355+
}));
1356+
1357+
opts.qs.media = stringify(inputPaidMedia);
1358+
} catch (ex) {
1359+
return Promise.reject(ex);
1360+
}
1361+
1362+
return this._request('sendPaidMedia', opts);
1363+
}
1364+
12501365
/**
12511366
* Use this method to send a group of photos or videos as an album.
12521367
*

0 commit comments

Comments
 (0)