From 2245bd617cceb276d56a2d65d8fa0c4a0eb9100f Mon Sep 17 00:00:00 2001 From: Pietro Albini Date: Mon, 16 Nov 2015 19:52:53 +0100 Subject: [PATCH 1/2] Add support for channels --- botogram/__init__.py | 2 +- botogram/bot.py | 8 ++++++++ botogram/objects/mixins.py | 10 ++++++++-- 3 files changed, 17 insertions(+), 3 deletions(-) diff --git a/botogram/__init__.py b/botogram/__init__.py index 11e8e73..288de01 100644 --- a/botogram/__init__.py +++ b/botogram/__init__.py @@ -7,7 +7,7 @@ """ # flake8: noqa -from .bot import Bot, create +from .bot import Bot, create, channel from .frozenbot import FrozenBotError from .components import Component from .decorators import pass_bot, pass_shared, help_message_for diff --git a/botogram/bot.py b/botogram/bot.py index 874fc73..9247869 100644 --- a/botogram/bot.py +++ b/botogram/bot.py @@ -212,3 +212,11 @@ def create(api_key, *args, **kwargs): """Create a new bot""" conn = api.TelegramAPI(api_key) return Bot(conn, *args, **kwargs) + + +def channel(name, api_key): + """Get a representation of a channel""" + conn = api.TelegramAPI(api_key) + + obj = objects.Chat({"id": 0, "type": "channel", "username": name}, conn) + return obj diff --git a/botogram/objects/mixins.py b/botogram/objects/mixins.py index 8124ab6..dd311ae 100644 --- a/botogram/objects/mixins.py +++ b/botogram/objects/mixins.py @@ -36,8 +36,11 @@ def send(self, message, preview=True, reply_to=None, syntax=None, elif syntax not in ("plain", "markdown"): raise ValueError("Invalid syntax type: %s") + # Get the correct chat_id + chat_id = self.username if self.type == "channel" else self.id + # Build API call arguments - args = {"chat_id": self.id, "text": message, + args = {"chat_id": chat_id, "text": message, "disable_web_page_preview": not preview} if reply_to is not None: args["reply_to_message_id"] = reply_to @@ -55,8 +58,11 @@ def send_photo(self, path, caption=None, reply_to=None, extra=None): if hasattr(reply_to, "message_id"): reply_to = reply_to.message_id + # Get the correct chat_id + chat_id = self.username if self.type == "channel" else self.id + # Build API call arguments - args = {"chat_id": self.id} + args = {"chat_id": chat_id} if caption is not None: args["caption"] = caption if reply_to is not None: From 4f2f49512f025ae0a9b2a4608436a90b4610adf2 Mon Sep 17 00:00:00 2001 From: Pietro Albini Date: Sat, 21 Nov 2015 14:31:23 +0100 Subject: [PATCH 2/2] Add documentation about channels --- docs/api/channels.rst | 24 ++++++++++++ docs/api/index.rst | 1 + docs/channels.rst | 91 +++++++++++++++++++++++++++++++++++++++++++ docs/index.rst | 1 + 4 files changed, 117 insertions(+) create mode 100644 docs/api/channels.rst create mode 100644 docs/channels.rst diff --git a/docs/api/channels.rst b/docs/api/channels.rst new file mode 100644 index 0000000..ec1682d --- /dev/null +++ b/docs/api/channels.rst @@ -0,0 +1,24 @@ +.. Copyright (c) 2015 Pietro Albini + Released under the MIT license + +.. _api-channels: + +~~~~~~~~~~~~ +Channels API +~~~~~~~~~~~~ + +The Channels API provides a lightweight way to interact with channels. If you +just want to send messages to a channel, it's better if you use this. + + +.. py:function:: botogram.channel(name, api_key) + + Create a new :py:class:`~botogram.Chat` object which points to the channel. + You need to provide the channel name, prefixed with ``@``, and your bot's + API key. Please refer to the :ref:`channels-preparation ` + section if you don't know how to get it. + + :param str name: The channel name. + :param str api_key: Your bot's API key. + :return: The corresponding Chat object. + :rtype: botogram.Chat diff --git a/docs/api/index.rst b/docs/api/index.rst index 09594cb..6ddb31d 100644 --- a/docs/api/index.rst +++ b/docs/api/index.rst @@ -16,5 +16,6 @@ the development will be made trying to not break anything. utility bot + channels components telegram diff --git a/docs/channels.rst b/docs/channels.rst new file mode 100644 index 0000000..786344a --- /dev/null +++ b/docs/channels.rst @@ -0,0 +1,91 @@ +.. Copyright (c) 2015 Pietro Albini + Released under the MIT license + +.. _channels: + +~~~~~~~~~~~~~~~~~~~~~ +Working with channels +~~~~~~~~~~~~~~~~~~~~~ + +Telegram Channels provides a way to broadcast a message to multiple users. You +can manually send messages to them with your preferred Telegram client, but +sometimes you would want to send them with a script, or from a bot. + +With botogram you can easily do that, without even the need to run the bot. + +.. _channels-preparation: + +=========== +Preparation +=========== + +In order to start working with channels, you need to get a bot's API key. If +you already have a bot you can skip this step. First of all you need to contact +the `@botfather`_ Telegram account, and then send to it the ``/newbot`` +command. After you provide all the information he needs, you will get an API +key, which looks like this fake one:: + + 123456789:ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghi + +The final step is to add your bot as an administrator of the channel. Open your +favourite Telegram client, and go to the administrators' section of your +channel. From it you should add your bot, and then you're ready. + +.. _chanels-standalone: + +========================= +Manage without a full bot +========================= + +Because a bot's initialization is quite an heavy process, you can use a +lightweight API to just interact with channels. First of all you should import +botogram, and then call the :py:func:`botogram.channel` function to get a +channel object: + +.. code-block:: python + + import botogram + + chan = botogram.channel("@my_channel", "YOUR_API_KEY") + +You need to replace ``@my_channel`` with your channel's public name, and +``YOUR_API_KEY`` with the key you got before. Then you can use all the methods +of the :py:class:`~botogram.Chat` object with the instance you got. For +example, if you want to send a text message you should do: + +.. code-block:: python + :emphasize-lines: 2 + + chan = botogram.channel("@my_channel", "YOUR_API_KEY") + chan.send("Hello world") + +.. _channels-bot: + +========================= +Manage from a running bot +========================= + +If you want to control a channel from your bot, you can use all the methods +which sends messages with the channel name as the user ID. For example, if you +want to forward all the messages your bot receives to the ``@my_channel`` +channel, you can do something like this: + +.. code-block:: python + + @bot.process_message + def forward_messages(chat, message): + message.forward_to("@my_channel") + +If instead you want to announce to the ``@my_channel`` channel when someone +cites botogram in a chat, you can do this: + +.. code-block:: python + + @bot.message_contains("botogram") + @botogram.pass_bot + def we_are_famous(bot, chat, message): + user = "Someone" + if message.from_.username is not None: + user = message.from_.username + + bot.send("@my_channel", "%s mentioned botogram!" % user) diff --git a/docs/index.rst b/docs/index.rst index fbb8c11..9ea78cb 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -38,6 +38,7 @@ Introduction to botogram install tutorial/index + channels =============== Advanced topics