如何在 python 中使用 Telethon 发送带标题的图像?
How can I send an image with a caption using Telethon in python?
我知道我可以使用这个
client.send_file(receiver, '/path/to/photo.jpg')
要发送图片,但如何为图片附加标题?
根据文档,只需使用关键字参数传递标题的值,例如 client.send_file(chat, '/my/photos/me.jpg', caption="It's me!")
。您可以阅读文档 here
虽然这个关于如何使用 Telethon 将带标题的图像发送到 Telegram 的问题已经由 @matthew-barlowe 简洁地回答了(我曾经使用自己的解决方案,谢谢),但我觉得使用 Telethon v3 的新异步 API.
包含一个更全面的示例会很有帮助
代码已记录并提供类型提示,因此它应该提供自己的解释。为了保持示例简洁,排除了异常捕获。
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 += "\n\n"
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
)
)
'''
我知道我可以使用这个
client.send_file(receiver, '/path/to/photo.jpg')
要发送图片,但如何为图片附加标题?
根据文档,只需使用关键字参数传递标题的值,例如 client.send_file(chat, '/my/photos/me.jpg', caption="It's me!")
。您可以阅读文档 here
虽然这个关于如何使用 Telethon 将带标题的图像发送到 Telegram 的问题已经由 @matthew-barlowe 简洁地回答了(我曾经使用自己的解决方案,谢谢),但我觉得使用 Telethon v3 的新异步 API.
包含一个更全面的示例会很有帮助代码已记录并提供类型提示,因此它应该提供自己的解释。为了保持示例简洁,排除了异常捕获。
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 += "\n\n"
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
)
)
'''