Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for channels #12

Merged
merged 2 commits into from
Nov 21, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion botogram/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
8 changes: 8 additions & 0 deletions botogram/bot.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
10 changes: 8 additions & 2 deletions botogram/objects/mixins.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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:
Expand Down
24 changes: 24 additions & 0 deletions docs/api/channels.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
.. Copyright (c) 2015 Pietro Albini <[email protected]>
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 <preparations>`
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
1 change: 1 addition & 0 deletions docs/api/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,6 @@ the development will be made trying to not break anything.

utility
bot
channels
components
telegram
91 changes: 91 additions & 0 deletions docs/channels.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
.. Copyright (c) 2015 Pietro Albini <[email protected]>
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)
1 change: 1 addition & 0 deletions docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ Introduction to botogram

install
tutorial/index
channels

===============
Advanced topics
Expand Down