Skip to content

Instantly share code, notes, and snippets.

@volodalexey
Last active February 25, 2023 10:48
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save volodalexey/0af785e7aaf8d4f8d8a365639736f4dd to your computer and use it in GitHub Desktop.
Save volodalexey/0af785e7aaf8d4f8d8a365639736f4dd to your computer and use it in GitHub Desktop.
Telegram Bot API - sendPhoto example with NodeJS

Example of sendPhoto method with pure NodeJS without third-party modules.

const fs = require('fs');
const https = require('https');

const chat_id = '...123...'; // telegram chat id
const botToken = '...aaa...'; // telegram bot token

const imageBuffer = fs.readFileSync('./image.jpg');

const boundary = '----WebKitFormBoundarydxxXNCrBx4FFWOWa';
const contentType = `multipart/form-data; boundary=${boundary}`;

const dataBefore =
  `--${boundary}\r\n` +
  `Content-Disposition: form-data; name="chat_id"\r\n` +
  `\r\n${chat_id}\r\n` +
  `--${boundary}\r\n` +
  `Content-Disposition: form-data; name="photo"; filename="photo.jpg"\r\n` +
  `Content-Type: image/jpeg\r\n` +
  `\r\n`;

const dataAfter = `\r\n` + `--${boundary}--\r\n`;

const resultBuffer = Buffer.concat(
  [Buffer.from(dataBefore), imageBuffer, Buffer.from(dataAfter)],
  Buffer.byteLength(dataBefore) + imageBuffer.length + Buffer.byteLength(dataAfter),
);

https
  .request({
    hostname: 'api.telegram.org',
    port: 443,
    path: `/bot${tbotToken}/sendPhoto`,
    method: 'POST',
    headers: {
      'Content-Type': contentType,
      // no need to specify content-length, if Buffer body data is created correctly
    }
  }, (res) => {
    const chunks = [];
    res.on('data', (chunk) => chunks.push(chunk));
    res.on('end', () => {
      if (res.statusCode === 200) {
        const resText = Buffer.concat(chunks).toString('utf8');
        if (resText && res.headers['content-type']) {
          if (res.headers['content-type'].includes('application/json')) {
            try {
              const objResponse = JSON.parse(resText);
              console.log(objResponse)
            } catch (err) {
              console.error(err);
            }
          } else {
            console.error('Unsupported response content type');
          }
        } else {
          console.error(`Empty response ${res.statusCode} ${res.statusMessage} ${res.headers['content-type']}`);
        }
      } else {
        console.error(`${res.statusCode} ${res.statusMessage} ${res.headers['content-type']} ${resText}`);
    }
  });
})
  .on('error', console.error)
  .end(resultBuffer);
@volodalexey
Copy link
Author

Concat buffers

function concat(bufferList, totalLength) {
  const target = Buffer.allocUnsafe(totalLength)
  let offset = 0;
  for(const buffer of bufferList) {
    target.set(buffer, offset)
    offset += buffer.length
  }

  return target
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment