skip to Main Content

I’m aware I can use this

client.send_file(receiver, '/path/to/photo.jpg')

to send an image, but how can I attach a caption to the image?

2

Answers


  1. According to the documentation just pass the value of the caption with a keyword argument like so client.send_file(chat, '/my/photos/me.jpg', caption="It's me!"). You can read the documentation here

    Login or Signup to reply.
  2. While this question on how to send an image with caption to Telegram using Telethon was already answered concisely by @matthew-barlowe, (which I used to come to my own solution, thank you), I felt that it would be helpful to include a more comprehensive example using Telethon v3’s new async API.

    The code is documented and type hinted so it should provide it’s own explanation. In the interest of keeping the example brief, capturing of exceptions is excluded.

    
        import logging
        from random import uniform
        from time import sleep
        from typing import Dict, List, Union
        
        from telethon.sync import TelegramClient
        
        
        logging.basicConfig(
            format="[%(levelname) 5s/%(asctime)s] %(name)s: %(message)s", level=logging.WARNING
        )
        
        # you should use dotenv module to extract credentials from the environment or .env file; 'pip install python-dotenv'
        # do not store credentials in the file in production or git commit, this is only included for example purposes
        SESSION_NAME = "sqlite-session"
        TG_API_ID = 1234567890
        TG_API_HASH = "*****"
        CHANNEL_NAME = "yourchannelname"
        CHANNEL_DISPLAY_NAME = "Your Channel Name"
        CHANNEL_URL = "https://t.me/your-channel-name"
        
        # define client
        client = TelegramClient(SESSION_NAME, TG_API_ID, TG_API_HASH)
        
        
        def create_message(data: Dict) -> str:
            """Formats a dictionary as a Telegram message.
            :param data: Dict: A dictionary containing 'title', 'subtitle', 'text', 'url' and
                'image_path' keys to be formatted as a message.
            :return: str: A string including Markup to be sent as a message to a Telegram channel.
            """
        
            # generate message
            message = ""
            if data.get("title", None):
                message += f'**{data["title"]}**n'
            message += f'{data["subtitle"]}n' if data.get("subtitle", None) else ""
            if data.get("url", None):
                message += data["url"]
            message += "nn"
            message += f"[{CHANNEL_DISPLAY_NAME}]({CHANNEL_URL})"
            return message
        
        
        async def channel_broadcast(
            messages: Union[Dict, List[Dict]],
            channel: str,
            min_wait: float = 25.0,
            max_wait: float = 120.0
        ) -> None:
            """ Broadcasts a message to the specified Telegram channel. There will be a humanized wait in between postings.
            :param messages: Union[Dict, List[Dict, ...]]: A dictionary or list of dicts containing 'title', 'subtitle',
                'text', 'url' and 'image_path' keys to be formatted as a message.
            :param channel: str: The name of the channel messages are to be broadcast to. You must have permission to
                broadcast to this channel. See setup in telethon docs.
            :param min_wait: float: Minimum wait between messages.
            :param max_wait: float: Maximum wait between messages.
            :return: None
            """
        
            # ensure list
            messages = [messages] if isinstance(messages, dict) else messages
        
            for item in messages:
        
                # generate a properly formatted message using markup and available fields
                message = create_message(item)
        
                # connect previously defined client
                async with client:
                    await client.connect()
        
                    # send message if image is included
                    if item.get("image_path", None):
                        await client.send_file(
                            channel, item["image_path"], caption=message, link_preview=True
                        )
        
                    # send message without image
                    else:
                        await client.send_message(channel, message, link_preview=True)
        
                # short blocking wait for multiple messages
                # non-blocking waits are not in scope of this example
                if len(messages) > 1:
                    sleep(uniform(min_wait, max_wait))
        
        
        # you can provide a single dict or list of dicts
        messages = [
            {
                "title": "First Message",
                "subtitle": "This is the first message.",
                "text": "This is a paragraph of text. The main idea of the message will be included here.",
                "url": "https://test.com",
                "image_path": "/path/to/a/local/image.png",
            },
            {
                "title": "Second Message",
                "subtitle": None,
                "text": "This is a paragraph of text. The main idea of the message will be included here.",
                "url": None,
            },
        ]
        
        # send all messages with a humanized wait between messages
        with client:
            client.loop.run_until_complete(
                channel_broadcast(
                    messages, CHANNEL_NAME
                )
            )
    
    '''
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search