How to send telegram mediaGroup with caption/text

Question:

I’m currently using python-telegram-bot and basically what I want to achieve with it is to send telegram messages like this:

telegram post with 3 photos and caption

So the message consists of 2+ photos/videos with text message underneath.

What I’ve already tried:

  1. sending message with send_message method, and including photo URLs, but it only shows 1 picture which is under the text

  2. sending media group using send_media_group, but this method has no caption parameter as send_photo.

Asked By: marzique

||

Answers:

You should use sendMediaGroup, where you can specify media field with an array of photo/video objects but the trick is to set caption property only for the first element of an array. In this case telegram will show that caption below the media content.

If you’ll specify captions for more than one element telegram will show them only when you click on photo preview for each photo separately.

Answered By: SleepWalker

send_media_group works but the caption has to be added when creating the media_group and to the first image only. Let’s say we have three images img0.png, img1.png and img2.png, we add them to the media_group using InputMediaPhoto with the parameter caption equal to the text we want to send only for the first image, otherwise we set caption equal to ''.

import telegram
from telegram import InputMediaPhoto

TOKEN = '' # token to access the HTTP API of your bot created with @BotFather
CHANNEL_ID = '' # id of your channel, for example @durov
bot = telegram.Bot(token = TOKEN)
media_group = []
text = 'some caption for album'
for num in range(3):
    media_group.append(InputMediaPhoto(open('img%d.png' % num, 'rb'), 
                                       caption = text if num == 0 else ''))
bot.send_media_group(chat_id = CHANNEL_ID, media = media_group)

enter image description here

Answered By: sound wave

Here is a vanilla Python implementation using requests:

SEND_MEDIA_GROUP = f'https://api.telegram.org/bot{token}/sendMediaGroup'

def send_media_group(chat_id, images, caption=None, reply_to_message_id=None):
        """
        Use this method to send an album of photos. On success, an array of Messages that were sent is returned.
        :param chat_id: chat id
        :param images: list of PIL images to send
        :param caption: caption of image
        :param reply_to_message_id: If the message is a reply, ID of the original message
        :return: response with the sent message
        """
        files = {}
        media = []
        for i, img in enumerate(images):
            with BytesIO() as output:
                img.save(output, format='PNG')
                output.seek(0)
                name = f'photo{i}'
                files[name] = output.read()
                # a list of InputMediaPhoto. attach refers to the name of the file in the files dict
                media.append(dict(type='photo', media=f'attach://{name}'))
        media[0]['caption'] = caption
        return requests.post(SEND_MEDIA_GROUP, data={'chat_id': chat_id, 'media': json.dumps(media), 'reply_to_message_id': reply_to_message_id }, files=files)
Answered By: Aray Karjauv