platypush/platypush/plugins/chat/telegram.py
2020-01-01 20:59:22 +01:00

968 lines
46 KiB
Python

import datetime
import os
from threading import RLock
from typing import Optional, Union
# noinspection PyPackageRequirements
from telegram.ext import Updater
# noinspection PyPackageRequirements
from telegram.message import Message as TelegramMessage
# noinspection PyPackageRequirements
from telegram.user import User as TelegramUser
from platypush.message.response.chat.telegram import TelegramMessageResponse, TelegramFileResponse, \
TelegramChatResponse, TelegramUserResponse, TelegramUsersResponse
from platypush.plugins import Plugin, action
class Resource:
def __init__(self, file_id: Optional[int] = None, url: Optional[str] = None, path: Optional[str] = None):
assert file_id or url or path, 'You need to specify either file_id, url or path'
self.file_id = file_id
self.url = url
self.path = path
self._file = None
def __enter__(self):
if self.path:
self._file = open(os.path.abspath(os.path.expanduser(self.path)), 'rb')
return self._file
return self.file_id or self.url
def __exit__(self, exc_type, exc_val, exc_tb):
if self._file:
self._file.close()
class ChatTelegramPlugin(Plugin):
"""
Plugin to programmatically send Telegram messages through a Telegram bot. In order to send messages to contacts,
groups or channels you'll first need to register a bot. To do so:
1. Open a Telegram conversation with the `@BotFather <https://telegram.me/BotFather>`_.
2. Send ``/start`` followed by ``/newbot``. Choose a display name and a username for your bot.
3. Copy the provided API token in the configuration of this plugin.
4. Open a conversation with your newly created bot.
Requires:
* **python-telegram-bot** (``pip install python-telegram-bot``)
"""
def __init__(self, api_token: str, **kwargs):
"""
:param api_token: API token as returned by the `@BotFather <https://telegram.me/BotFather>`_
"""
super().__init__(**kwargs)
self._api_token = api_token
self._telegram_lock = RLock()
self._telegram: Optional[Updater] = None
def get_telegram(self) -> Updater:
with self._telegram_lock:
if self._telegram:
return self._telegram
self._telegram = Updater(self._api_token, use_context=True)
return self._telegram
@staticmethod
def parse_msg(msg: TelegramMessage) -> TelegramMessageResponse:
return TelegramMessageResponse(
message_id=msg.message_id,
chat_id=msg.chat_id,
chat_username=msg.chat.username,
chat_firstname=msg.chat.first_name,
chat_lastname=msg.chat.last_name,
from_user_id=msg.from_user.id if msg.from_user else None,
from_username=msg.from_user.username if msg.from_user else None,
from_firstname=msg.from_user.first_name if msg.from_user else None,
from_lastname=msg.from_user.last_name if msg.from_user else None,
text=msg.text,
caption=msg.caption,
creation_date=msg.date,
edit_date=msg.edit_date,
forward_date=msg.forward_date,
forward_from_message_id=msg.forward_from_message_id,
photo_file_id=msg.photo[0].file_id if msg.photo else None,
photo_file_size=msg.photo[0].file_size if msg.photo else None,
photo_width=msg.photo[0].width if msg.photo else None,
photo_height=msg.photo[0].height if msg.photo else None,
document_file_id=msg.document.file_id if msg.document else None,
document_file_name=msg.document.file_name if msg.document else None,
document_file_size=msg.document.file_size if msg.document else None,
document_mime_type=msg.document.mime_type if msg.document else None,
audio_file_id=msg.audio.file_id if msg.audio else None,
audio_file_size=msg.audio.file_size if msg.audio else None,
audio_performer=msg.audio.performer if msg.audio else None,
audio_title=msg.audio.title if msg.audio else None,
audio_duration=msg.audio.duration if msg.audio else None,
audio_mime_type=msg.audio.mime_type if msg.audio else None,
video_file_id=msg.video.file_id if msg.video else None,
video_file_size=msg.video.file_size if msg.video else None,
video_duration=msg.video.duration if msg.video else None,
video_width=msg.video.width if msg.video else None,
video_height=msg.video.height if msg.video else None,
video_mime_type=msg.video.mime_type if msg.video else None,
location_latitude=msg.location.latitude if msg.location else None,
location_longitude=msg.location.longitude if msg.location else None,
contact_phone_number=msg.contact.phone_number if msg.contact else None,
contact_first_name=msg.contact.first_name if msg.contact else None,
contact_last_name=msg.contact.last_name if msg.contact else None,
contact_user_id=msg.contact.user_id if msg.contact else None,
contact_vcard=msg.contact.vcard if msg.contact else None,
link=msg.link,
media_group_id=msg.media_group_id
)
@staticmethod
def parse_user(user: TelegramUser) -> TelegramUserResponse:
return TelegramUserResponse(
user_id=user.id,
username=user.username,
is_bot=user.is_bot,
first_name=user.first_name,
last_name=user.last_name,
language_code=user.language_code,
link=user.link
)
@action
def send_message(self, chat_id: Union[str, int], text: str, parse_mode: Optional[str] = None,
disable_web_page_preview: bool = False, disable_notification: bool = False,
reply_to_message_id: Optional[int] = None) -> TelegramMessageResponse:
"""
Send a message to a chat.
:param chat_id: Chat ID. Can be either a numerical ID or a unique identifier in the format ``@channelname``.
In order to get your own Telegram chat_id open a conversation with
`@IDBot <https://telegram.me/IDBot>`_ and type ``/start`` followed by ``/getid``. Similar procedures
also exist to get a group or channel chat_id - just Google for "Telegram get channel/group chat_id".
:param text: Text to be sent.
:param parse_mode: Set to 'Markdown' or 'HTML' to send either Markdown or HTML content.
:param disable_web_page_preview: If True then web previews for URLs will be disabled.
:param disable_notification: If True then no notification will be sent to the users.
:param reply_to_message_id: If set then the message will be sent as a response to the specified message.
"""
telegram = self.get_telegram()
msg = telegram.bot.send_message(chat_id=chat_id,
text=text,
parse_mode=parse_mode,
disable_web_page_preview=disable_web_page_preview,
disable_notification=disable_notification,
reply_to_message_id=reply_to_message_id)
return self.parse_msg(msg)
@action
def send_photo(self, chat_id: Union[str, int],
file_id: Optional[int] = None,
url: Optional[str] = None,
path: Optional[str] = None,
caption: Optional[str] = None,
parse_mode: Optional[str] = None,
disable_notification: bool = False,
reply_to_message_id: Optional[int] = None,
timeout: int = 20) -> TelegramMessageResponse:
"""
Send a picture to a chat.
:param chat_id: Chat ID. Can be either a numerical ID or a unique identifier in the format ``@channelname``.
In order to get your own Telegram chat_id open a conversation with
`@IDBot <https://telegram.me/IDBot>`_ and type ``/start`` followed by ``/getid``. Similar procedures
also exist to get a group or channel chat_id - just Google for "Telegram get channel/group chat_id".
:param file_id: Set it if the file already exists on Telegram servers and has a file_id.
Note that you'll have to specify either ``file_id``, ``url`` or ``path``.
:param url: Set it if you want to send a file from a remote URL.
Note that you'll have to specify either ``file_id``, ``url`` or ``path``.
:param path: Set it if you want to send a file from the local filesystem.
Note that you'll have to specify either ``file_id``, ``url`` or ``path``.
:param caption: Optional caption for the picture.
:param parse_mode: Set to 'Markdown' or 'HTML' to send either Markdown or HTML content.
:param disable_notification: If True then no notification will be sent to the users.
:param reply_to_message_id: If set then the message will be sent as a response to the specified message.
:param timeout: Upload timeout (default: 20 seconds)
"""
telegram = self.get_telegram()
with Resource(file_id=file_id, url=url, path=path) as resource:
msg = telegram.bot.send_photo(chat_id=chat_id,
photo=resource,
caption=caption,
disable_notification=disable_notification,
reply_to_message_id=reply_to_message_id,
timeout=timeout, parse_mode=parse_mode)
return self.parse_msg(msg)
@action
def send_audio(self, chat_id: Union[str, int],
file_id: Optional[int] = None,
url: Optional[str] = None,
path: Optional[str] = None,
caption: Optional[str] = None,
performer: Optional[str] = None,
title: Optional[str] = None,
duration: Optional[float] = None,
parse_mode: Optional[str] = None,
disable_notification: bool = False,
reply_to_message_id: Optional[int] = None,
timeout: int = 20) -> TelegramMessageResponse:
"""
Send audio to a chat.
:param chat_id: Chat ID. Can be either a numerical ID or a unique identifier in the format ``@channelname``.
In order to get your own Telegram chat_id open a conversation with
`@IDBot <https://telegram.me/IDBot>`_ and type ``/start`` followed by ``/getid``. Similar procedures
also exist to get a group or channel chat_id - just Google for "Telegram get channel/group chat_id".
:param file_id: Set it if the file already exists on Telegram servers and has a file_id.
Note that you'll have to specify either ``file_id``, ``url`` or ``path``.
:param url: Set it if you want to send a file from a remote URL.
Note that you'll have to specify either ``file_id``, ``url`` or ``path``.
:param path: Set it if you want to send a file from the local filesystem.
Note that you'll have to specify either ``file_id``, ``url`` or ``path``.
:param caption: Optional caption for the picture.
:param performer: Optional audio performer.
:param title: Optional audio title.
:param duration: Duration of the audio in seconds.
:param parse_mode: Set to 'Markdown' or 'HTML' to send either Markdown or HTML content.
:param disable_notification: If True then no notification will be sent to the users.
:param reply_to_message_id: If set then the message will be sent as a response to the specified message.
:param timeout: Upload timeout (default: 20 seconds)
"""
telegram = self.get_telegram()
with Resource(file_id=file_id, url=url, path=path) as resource:
msg = telegram.bot.send_audio(chat_id=chat_id,
audio=resource,
caption=caption,
disable_notification=disable_notification,
performer=performer,
title=title,
duration=duration,
reply_to_message_id=reply_to_message_id,
timeout=timeout,
parse_mode=parse_mode)
return self.parse_msg(msg)
@action
def send_document(self, chat_id: Union[str, int],
file_id: Optional[int] = None,
url: Optional[str] = None,
path: Optional[str] = None,
filename: Optional[str] = None,
caption: Optional[str] = None,
parse_mode: Optional[str] = None,
disable_notification: bool = False,
reply_to_message_id: Optional[int] = None,
timeout: int = 20) -> TelegramMessageResponse:
"""
Send a document to a chat.
:param chat_id: Chat ID. Can be either a numerical ID or a unique identifier in the format ``@channelname``.
In order to get your own Telegram chat_id open a conversation with
`@IDBot <https://telegram.me/IDBot>`_ and type ``/start`` followed by ``/getid``. Similar procedures
also exist to get a group or channel chat_id - just Google for "Telegram get channel/group chat_id".
:param file_id: Set it if the file already exists on Telegram servers and has a file_id.
Note that you'll have to specify either ``file_id``, ``url`` or ``path``.
:param url: Set it if you want to send a file from a remote URL.
Note that you'll have to specify either ``file_id``, ``url`` or ``path``.
:param path: Set it if you want to send a file from the local filesystem.
Note that you'll have to specify either ``file_id``, ``url`` or ``path``.
:param filename: Name of the file as it will be shown in Telegram.
:param caption: Optional caption for the picture.
:param parse_mode: Set to 'Markdown' or 'HTML' to send either Markdown or HTML content.
:param disable_notification: If True then no notification will be sent to the users.
:param reply_to_message_id: If set then the message will be sent as a response to the specified message.
:param timeout: Upload timeout (default: 20 seconds)
"""
telegram = self.get_telegram()
with Resource(file_id=file_id, url=url, path=path) as resource:
msg = telegram.bot.send_document(chat_id=chat_id,
document=resource,
filename=filename,
caption=caption,
disable_notification=disable_notification,
reply_to_message_id=reply_to_message_id,
timeout=timeout,
parse_mode=parse_mode)
return self.parse_msg(msg)
@action
def send_video(self, chat_id: Union[str, int],
file_id: Optional[int] = None,
url: Optional[str] = None,
path: Optional[str] = None,
duration: Optional[int] = None,
caption: Optional[str] = None,
width: Optional[int] = None,
height: Optional[int] = None,
parse_mode: Optional[str] = None,
disable_notification: bool = False,
reply_to_message_id: Optional[int] = None,
timeout: int = 20) -> TelegramMessageResponse:
"""
Send a video to a chat.
:param chat_id: Chat ID. Can be either a numerical ID or a unique identifier in the format ``@channelname``.
In order to get your own Telegram chat_id open a conversation with
`@IDBot <https://telegram.me/IDBot>`_ and type ``/start`` followed by ``/getid``. Similar procedures
also exist to get a group or channel chat_id - just Google for "Telegram get channel/group chat_id".
:param file_id: Set it if the file already exists on Telegram servers and has a file_id.
Note that you'll have to specify either ``file_id``, ``url`` or ``path``.
:param url: Set it if you want to send a file from a remote URL.
Note that you'll have to specify either ``file_id``, ``url`` or ``path``.
:param path: Set it if you want to send a file from the local filesystem.
Note that you'll have to specify either ``file_id``, ``url`` or ``path``.
:param duration: Duration in seconds.
:param caption: Optional caption for the picture.
:param width: Video width.
:param height: Video height.
:param parse_mode: Set to 'Markdown' or 'HTML' to send either Markdown or HTML content.
:param disable_notification: If True then no notification will be sent to the users.
:param reply_to_message_id: If set then the message will be sent as a response to the specified message.
:param timeout: Upload timeout (default: 20 seconds)
"""
telegram = self.get_telegram()
with Resource(file_id=file_id, url=url, path=path) as resource:
msg = telegram.bot.send_video(chat_id=chat_id,
video=resource,
duration=duration,
caption=caption,
width=width,
height=height,
disable_notification=disable_notification,
reply_to_message_id=reply_to_message_id,
timeout=timeout,
parse_mode=parse_mode)
return self.parse_msg(msg)
@action
def send_animation(self, chat_id: Union[str, int],
file_id: Optional[int] = None,
url: Optional[str] = None,
path: Optional[str] = None,
duration: Optional[int] = None,
caption: Optional[str] = None,
width: Optional[int] = None,
height: Optional[int] = None,
parse_mode: Optional[str] = None,
disable_notification: bool = False,
reply_to_message_id: Optional[int] = None,
timeout: int = 20) -> TelegramMessageResponse:
"""
Send an animation (GIF or H.264/MPEG-4 AVC video without sound) to a chat.
:param chat_id: Chat ID. Can be either a numerical ID or a unique identifier in the format ``@channelname``.
In order to get your own Telegram chat_id open a conversation with
`@IDBot <https://telegram.me/IDBot>`_ and type ``/start`` followed by ``/getid``. Similar procedures
also exist to get a group or channel chat_id - just Google for "Telegram get channel/group chat_id".
:param file_id: Set it if the file already exists on Telegram servers and has a file_id.
Note that you'll have to specify either ``file_id``, ``url`` or ``path``.
:param url: Set it if you want to send a file from a remote URL.
Note that you'll have to specify either ``file_id``, ``url`` or ``path``.
:param path: Set it if you want to send a file from the local filesystem.
Note that you'll have to specify either ``file_id``, ``url`` or ``path``.
:param duration: Duration in seconds.
:param caption: Optional caption for the picture.
:param width: Video width.
:param height: Video height.
:param parse_mode: Set to 'Markdown' or 'HTML' to send either Markdown or HTML content.
:param disable_notification: If True then no notification will be sent to the users.
:param reply_to_message_id: If set then the message will be sent as a response to the specified message.
:param timeout: Upload timeout (default: 20 seconds)
"""
telegram = self.get_telegram()
with Resource(file_id=file_id, url=url, path=path) as resource:
msg = telegram.bot.send_animation(chat_id=chat_id,
animation=resource,
duration=duration,
caption=caption,
width=width,
height=height,
disable_notification=disable_notification,
reply_to_message_id=reply_to_message_id,
timeout=timeout,
parse_mode=parse_mode)
return self.parse_msg(msg)
@action
def send_voice(self, chat_id: Union[str, int],
file_id: Optional[int] = None,
url: Optional[str] = None,
path: Optional[str] = None,
caption: Optional[str] = None,
duration: Optional[float] = None,
parse_mode: Optional[str] = None,
disable_notification: bool = False,
reply_to_message_id: Optional[int] = None,
timeout: int = 20) -> TelegramMessageResponse:
"""
Send audio to a chat as a voice file. For this to work, your audio must be in an .ogg file encoded with OPUS
(other formats may be sent as Audio or Document).
:param chat_id: Chat ID. Can be either a numerical ID or a unique identifier in the format ``@channelname``.
In order to get your own Telegram chat_id open a conversation with
`@IDBot <https://telegram.me/IDBot>`_ and type ``/start`` followed by ``/getid``. Similar procedures
also exist to get a group or channel chat_id - just Google for "Telegram get channel/group chat_id".
:param file_id: Set it if the file already exists on Telegram servers and has a file_id.
Note that you'll have to specify either ``file_id``, ``url`` or ``path``.
:param url: Set it if you want to send a file from a remote URL.
Note that you'll have to specify either ``file_id``, ``url`` or ``path``.
:param path: Set it if you want to send a file from the local filesystem.
Note that you'll have to specify either ``file_id``, ``url`` or ``path``.
:param caption: Optional caption for the picture.
:param duration: Duration of the voice in seconds.
:param parse_mode: Set to 'Markdown' or 'HTML' to send either Markdown or HTML content.
:param disable_notification: If True then no notification will be sent to the users.
:param reply_to_message_id: If set then the message will be sent as a response to the specified message.
:param timeout: Upload timeout (default: 20 seconds)
"""
telegram = self.get_telegram()
with Resource(file_id=file_id, url=url, path=path) as resource:
msg = telegram.bot.send_voice(chat_id=chat_id,
voice=resource,
caption=caption,
disable_notification=disable_notification,
duration=duration,
reply_to_message_id=reply_to_message_id,
timeout=timeout, parse_mode=parse_mode)
return self.parse_msg(msg)
@action
def send_video_note(self, chat_id: Union[str, int],
file_id: Optional[int] = None,
url: Optional[str] = None,
path: Optional[str] = None,
duration: Optional[int] = None,
disable_notification: bool = False,
reply_to_message_id: Optional[int] = None,
timeout: int = 20) -> TelegramMessageResponse:
"""
Send a video note to a chat. As of v.4.0, Telegram clients support rounded square mp4 videos of up to
1 minute long.
:param chat_id: Chat ID. Can be either a numerical ID or a unique identifier in the format ``@channelname``.
In order to get your own Telegram chat_id open a conversation with
`@IDBot <https://telegram.me/IDBot>`_ and type ``/start`` followed by ``/getid``. Similar procedures
also exist to get a group or channel chat_id - just Google for "Telegram get channel/group chat_id".
:param file_id: Set it if the file already exists on Telegram servers and has a file_id.
Note that you'll have to specify either ``file_id``, ``url`` or ``path``.
:param url: Set it if you want to send a file from a remote URL.
Note that you'll have to specify either ``file_id``, ``url`` or ``path``.
:param path: Set it if you want to send a file from the local filesystem.
Note that you'll have to specify either ``file_id``, ``url`` or ``path``.
:param duration: Duration in seconds.
:param disable_notification: If True then no notification will be sent to the users.
:param reply_to_message_id: If set then the message will be sent as a response to the specified message.
:param timeout: Upload timeout (default: 20 seconds)
"""
telegram = self.get_telegram()
with Resource(file_id=file_id, url=url, path=path) as resource:
msg = telegram.bot.send_video_note(chat_id=chat_id,
video=resource,
duration=duration,
disable_notification=disable_notification,
reply_to_message_id=reply_to_message_id,
timeout=timeout)
return self.parse_msg(msg)
@action
def send_location(self, chat_id: Union[str, int],
latitude: float,
longitude: float,
disable_notification: bool = False,
reply_to_message_id: Optional[int] = None,
timeout: int = 20) -> TelegramMessageResponse:
"""
Send a location to a chat.
:param chat_id: Chat ID. Can be either a numerical ID or a unique identifier in the format ``@channelname``.
In order to get your own Telegram chat_id open a conversation with
`@IDBot <https://telegram.me/IDBot>`_ and type ``/start`` followed by ``/getid``. Similar procedures
also exist to get a group or channel chat_id - just Google for "Telegram get channel/group chat_id".
:param latitude: Latitude
:param longitude: Longitude
:param disable_notification: If True then no notification will be sent to the users.
:param reply_to_message_id: If set then the message will be sent as a response to the specified message.
:param timeout: Upload timeout (default: 20 seconds)
"""
telegram = self.get_telegram()
msg = telegram.bot.send_location(chat_id=chat_id,
latitude=latitude,
longitude=longitude,
disable_notification=disable_notification,
reply_to_message_id=reply_to_message_id,
timeout=timeout)
return self.parse_msg(msg)
@action
def send_venue(self, chat_id: Union[str, int],
latitude: float,
longitude: float,
title: str,
address: str,
foursquare_id: Optional[str] = None,
foursquare_type: Optional[str] = None,
disable_notification: bool = False,
reply_to_message_id: Optional[int] = None,
timeout: int = 20) -> TelegramMessageResponse:
"""
Send the address of a venue to a chat.
:param chat_id: Chat ID. Can be either a numerical ID or a unique identifier in the format ``@channelname``.
In order to get your own Telegram chat_id open a conversation with
`@IDBot <https://telegram.me/IDBot>`_ and type ``/start`` followed by ``/getid``. Similar procedures
also exist to get a group or channel chat_id - just Google for "Telegram get channel/group chat_id".
:param latitude: Latitude
:param longitude: Longitude
:param title: Venue name.
:param address: Venue address.
:param foursquare_id: Foursquare ID.
:param foursquare_type: Foursquare type.
:param disable_notification: If True then no notification will be sent to the users.
:param reply_to_message_id: If set then the message will be sent as a response to the specified message.
:param timeout: Upload timeout (default: 20 seconds)
"""
telegram = self.get_telegram()
msg = telegram.bot.send_venue(chat_id=chat_id,
latitude=latitude,
longitude=longitude,
title=title,
address=address,
foursquare_id=foursquare_id,
foursquare_type=foursquare_type,
disable_notification=disable_notification,
reply_to_message_id=reply_to_message_id,
timeout=timeout)
return self.parse_msg(msg)
@action
def send_contact(self, chat_id: Union[str, int],
phone_number: str,
first_name: str,
last_name: Optional[str] = None,
vcard: Optional[str] = None,
disable_notification: bool = False,
reply_to_message_id: Optional[int] = None,
timeout: int = 20) -> TelegramMessageResponse:
"""
Send a contact to a chat.
:param chat_id: Chat ID. Can be either a numerical ID or a unique identifier in the format ``@channelname``.
In order to get your own Telegram chat_id open a conversation with
`@IDBot <https://telegram.me/IDBot>`_ and type ``/start`` followed by ``/getid``. Similar procedures
also exist to get a group or channel chat_id - just Google for "Telegram get channel/group chat_id".
:param phone_number: Phone number.
:param first_name: First name.
:param last_name: Last name.
:param vcard: Additional contact info in vCard format (0-2048 bytes).
:param disable_notification: If True then no notification will be sent to the users.
:param reply_to_message_id: If set then the message will be sent as a response to the specified message.
:param timeout: Upload timeout (default: 20 seconds)
"""
telegram = self.get_telegram()
msg = telegram.bot.send_contact(chat_id=chat_id,
phone_number=phone_number,
first_name=first_name,
last_name=last_name,
vcard=vcard,
disable_notification=disable_notification,
reply_to_message_id=reply_to_message_id,
timeout=timeout)
return self.parse_msg(msg)
@action
def get_file(self, file_id: str, timeout: int = 20) -> TelegramFileResponse:
"""
Get the info and URL of an uploaded file by file_id.
:param file_id: File ID.
:param timeout: Upload timeout (default: 20 seconds).
"""
telegram = self.get_telegram()
file = telegram.bot.get_file(file_id, timeout=timeout)
return TelegramFileResponse(file_id=file.file_id, file_path=file.file_path, file_size=file.file_size)
@action
def get_chat(self, chat_id: Union[int, str], timeout: int = 20) -> TelegramChatResponse:
"""
Get the info about a Telegram chat.
:param chat_id: Chat ID.
:param timeout: Upload timeout (default: 20 seconds).
"""
telegram = self.get_telegram()
chat = telegram.bot.get_chat(chat_id, timeout=timeout)
return TelegramChatResponse(chat_id=chat.id,
link=chat.link,
username=chat.username,
invite_link=chat.invite_link,
title=chat.title,
description=chat.description,
type=chat.type,
first_name=chat.first_name,
last_name=chat.last_name)
@action
def get_chat_user(self, chat_id: Union[int, str], user_id: int, timeout: int = 20) -> TelegramUserResponse:
"""
Get the info about a user connected to a chat.
:param chat_id: Chat ID.
:param user_id: User ID.
:param timeout: Upload timeout (default: 20 seconds).
"""
telegram = self.get_telegram()
user = telegram.bot.get_chat_member(chat_id, user_id, timeout=timeout)
return TelegramUserResponse(user_id=user.user.id,
link=user.user.link,
username=user.user.username,
first_name=user.user.first_name,
last_name=user.user.last_name,
is_bot=user.user.is_bot,
language_code=user.user.language_code)
@action
def get_chat_administrators(self, chat_id: Union[int, str], timeout: int = 20) -> TelegramUsersResponse:
"""
Get the list of the administrators of a chat.
:param chat_id: Chat ID.
:param timeout: Upload timeout (default: 20 seconds).
"""
telegram = self.get_telegram()
admins = telegram.bot.get_chat_administrators(chat_id, timeout=timeout)
return TelegramUsersResponse([
TelegramUserResponse(
user_id=user.user.id,
link=user.user.link,
username=user.user.username,
first_name=user.user.first_name,
last_name=user.user.last_name,
is_bot=user.user.is_bot,
language_code=user.user.language_code,
) for user in admins
])
@action
def get_chat_members_count(self, chat_id: Union[int, str], timeout: int = 20) -> int:
"""
Get the number of users in a chat.
:param chat_id: Chat ID.
:param timeout: Upload timeout (default: 20 seconds).
"""
telegram = self.get_telegram()
return telegram.bot.get_chat_members_count(chat_id, timeout=timeout)
@action
def kick_chat_member(self, chat_id: Union[str, int],
user_id: int,
until_date: Optional[datetime.datetime] = None,
timeout: int = 20):
"""
Kick a user from a chat.
:param chat_id: Chat ID. Can be either a numerical ID or a unique identifier in the format ``@channelname``.
In order to get your own Telegram chat_id open a conversation with
`@IDBot <https://telegram.me/IDBot>`_ and type ``/start`` followed by ``/getid``. Similar procedures
also exist to get a group or channel chat_id - just Google for "Telegram get channel/group chat_id".
:param user_id: Unique user ID.
:param until_date: End date for the ban.
:param timeout: Request timeout (default: 20 seconds)
"""
telegram = self.get_telegram()
telegram.bot.kick_chat_member(
chat_id=chat_id,
user_id=user_id,
until_date=until_date,
timeout=timeout)
@action
def unban_chat_member(self, chat_id: Union[str, int],
user_id: int,
timeout: int = 20):
"""
Lift the ban from a chat member.
:param chat_id: Chat ID. Can be either a numerical ID or a unique identifier in the format ``@channelname``.
In order to get your own Telegram chat_id open a conversation with
`@IDBot <https://telegram.me/IDBot>`_ and type ``/start`` followed by ``/getid``. Similar procedures
also exist to get a group or channel chat_id - just Google for "Telegram get channel/group chat_id".
:param user_id: Unique user ID.
:param timeout: Request timeout (default: 20 seconds)
"""
telegram = self.get_telegram()
telegram.bot.unban_chat_member(
chat_id=chat_id,
user_id=user_id,
timeout=timeout)
@action
def promote_chat_member(self, chat_id: Union[str, int],
user_id: int,
can_change_info: Optional[bool] = None,
can_post_messages: Optional[bool] = None,
can_edit_messages: Optional[bool] = None,
can_delete_messages: Optional[bool] = None,
can_invite_users: Optional[bool] = None,
can_restrict_members: Optional[bool] = None,
can_promote_members: Optional[bool] = None,
can_pin_messages: Optional[bool] = None,
timeout: int = 20):
"""
Promote or demote a member.
:param chat_id: Chat ID. Can be either a numerical ID or a unique identifier in the format ``@channelname``.
In order to get your own Telegram chat_id open a conversation with
`@IDBot <https://telegram.me/IDBot>`_ and type ``/start`` followed by ``/getid``. Similar procedures
also exist to get a group or channel chat_id - just Google for "Telegram get channel/group chat_id".
:param user_id: Unique user ID.
:param can_change_info: Pass True if the user can change channel info.
:param can_post_messages: Pass True if the user can post messages.
:param can_edit_messages: Pass True if the user can edit messages.
:param can_delete_messages: Pass True if the user can delete messages.
:param can_invite_users: Pass True if the user can invite other users to the channel/group.
:param can_restrict_members: Pass True if the user can restrict the permissions of other users.
:param can_promote_members: Pass True if the user can promote mebmers.
:param can_pin_messages: Pass True if the user can pin messages.
:param timeout: Request timeout (default: 20 seconds)
"""
telegram = self.get_telegram()
telegram.bot.promote_chat_member(
chat_id=chat_id,
user_id=user_id,
can_change_info=can_change_info,
can_post_messages=can_post_messages,
can_edit_messages=can_edit_messages,
can_delete_messages=can_delete_messages,
can_invite_users=can_invite_users,
can_restrict_members=can_restrict_members,
can_promote_members=can_promote_members,
can_pin_messages=can_pin_messages,
timeout=timeout)
@action
def set_chat_title(self, chat_id: Union[str, int],
title: str,
timeout: int = 20):
"""
Set the title of a channel/group.
:param chat_id: Chat ID. Can be either a numerical ID or a unique identifier in the format ``@channelname``.
In order to get your own Telegram chat_id open a conversation with
`@IDBot <https://telegram.me/IDBot>`_ and type ``/start`` followed by ``/getid``. Similar procedures
also exist to get a group or channel chat_id - just Google for "Telegram get channel/group chat_id".
:param title: New chat title.
:param timeout: Request timeout (default: 20 seconds)
"""
telegram = self.get_telegram()
telegram.bot.set_chat_title(
chat_id=chat_id,
description=title,
timeout=timeout)
@action
def set_chat_description(self, chat_id: Union[str, int],
description: str,
timeout: int = 20):
"""
Set the description of a channel/group.
:param chat_id: Chat ID. Can be either a numerical ID or a unique identifier in the format ``@channelname``.
In order to get your own Telegram chat_id open a conversation with
`@IDBot <https://telegram.me/IDBot>`_ and type ``/start`` followed by ``/getid``. Similar procedures
also exist to get a group or channel chat_id - just Google for "Telegram get channel/group chat_id".
:param description: New chat description.
:param timeout: Request timeout (default: 20 seconds)
"""
telegram = self.get_telegram()
telegram.bot.set_chat_description(
chat_id=chat_id,
description=description,
timeout=timeout)
@action
def set_chat_photo(self, chat_id: Union[str, int],
path: str,
timeout: int = 20):
"""
Set the photo of a channel/group.
:param chat_id: Chat ID. Can be either a numerical ID or a unique identifier in the format ``@channelname``.
In order to get your own Telegram chat_id open a conversation with
`@IDBot <https://telegram.me/IDBot>`_ and type ``/start`` followed by ``/getid``. Similar procedures
also exist to get a group or channel chat_id - just Google for "Telegram get channel/group chat_id".
:param path: Path of the new image.
:param timeout: Request timeout (default: 20 seconds)
"""
telegram = self.get_telegram()
with Resource(path=path) as resource:
telegram.bot.set_chat_photo(
chat_id=chat_id,
photo=resource,
timeout=timeout)
@action
def delete_chat_photo(self, chat_id: Union[str, int],
timeout: int = 20):
"""
Delete the photo of a channel/group.
:param chat_id: Chat ID. Can be either a numerical ID or a unique identifier in the format ``@channelname``.
In order to get your own Telegram chat_id open a conversation with
`@IDBot <https://telegram.me/IDBot>`_ and type ``/start`` followed by ``/getid``. Similar procedures
also exist to get a group or channel chat_id - just Google for "Telegram get channel/group chat_id".
:param timeout: Request timeout (default: 20 seconds)
"""
telegram = self.get_telegram()
telegram.bot.delete_chat_photo(
chat_id=chat_id,
timeout=timeout)
@action
def pin_chat_message(self, chat_id: Union[str, int],
message_id: int,
disable_notification: Optional[bool] = None,
timeout: int = 20):
"""
Pin a message in a chat.
:param chat_id: Chat ID. Can be either a numerical ID or a unique identifier in the format ``@channelname``.
In order to get your own Telegram chat_id open a conversation with
`@IDBot <https://telegram.me/IDBot>`_ and type ``/start`` followed by ``/getid``. Similar procedures
also exist to get a group or channel chat_id - just Google for "Telegram get channel/group chat_id".
:param message_id: Message ID.
:param disable_notification: If True then no notification will be sent to the users.
:param timeout: Request timeout (default: 20 seconds)
"""
telegram = self.get_telegram()
telegram.bot.pin_chat_message(
chat_id=chat_id,
message_id=message_id,
disable_notification=disable_notification,
timeout=timeout)
@action
def unpin_chat_message(self, chat_id: Union[str, int],
timeout: int = 20):
"""
Unpin the message of a chat.
:param chat_id: Chat ID. Can be either a numerical ID or a unique identifier in the format ``@channelname``.
In order to get your own Telegram chat_id open a conversation with
`@IDBot <https://telegram.me/IDBot>`_ and type ``/start`` followed by ``/getid``. Similar procedures
also exist to get a group or channel chat_id - just Google for "Telegram get channel/group chat_id".
:param timeout: Request timeout (default: 20 seconds)
"""
telegram = self.get_telegram()
telegram.bot.unpin_chat_message(
chat_id=chat_id,
timeout=timeout)
@action
def leave_chat(self, chat_id: Union[str, int],
timeout: int = 20):
"""
Leave a chat.
:param chat_id: Chat ID. Can be either a numerical ID or a unique identifier in the format ``@channelname``.
In order to get your own Telegram chat_id open a conversation with
`@IDBot <https://telegram.me/IDBot>`_ and type ``/start`` followed by ``/getid``. Similar procedures
also exist to get a group or channel chat_id - just Google for "Telegram get channel/group chat_id".
:param timeout: Request timeout (default: 20 seconds)
"""
telegram = self.get_telegram()
telegram.bot.leave_chat(
chat_id=chat_id,
timeout=timeout)
# vim:sw=4:ts=4:et: