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

Change telegram library to pytelegrambotapi #6889

Merged
merged 9 commits into from
Dec 11, 2020
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
1 change: 1 addition & 0 deletions changelog/6814.improvement.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Replace use of ``python-telegram-bot`` package with ``pyTelegramBotAPI``
43 changes: 43 additions & 0 deletions docs/user-guide/connectors/telegram.rst
Original file line number Diff line number Diff line change
Expand Up @@ -44,3 +44,46 @@ you need to supply a ``credentials.yml`` with the following content:
access_token: "490161424:AAGlRxinBRtKGb21_rlOEMtDFZMXBl6EC0o"
verify: "your_bot"
webhook_url: "https://your_url.com/webhooks/telegram/webhook"

Supported Response Attachments
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

In addition to standard ``text:`` responses, this channel also supports the following components from the `Telegram API <https://core.telegram.org/bots/api/#message>`_:

- ``button`` arguments:
- button_type: inline | vertical | reply
- ``custom`` arguments:
- photo
- audio
- document
- sticker
- video
- video_note
- animation
- voice
- media
- latitude, longitude (location)
- latitude, longitude, title, address (venue)
- phone_number
- game_short_name
- action

Examples:

.. code-block:: yaml

utter_ask_transfer_form_confirm:
- buttons:
- payload: /affirm
title: Yes
- payload: /deny
title: No, cancel the transaction
button_type: vertical
text: Would you like to transfer {currency}{amount_of_money} to {PERSON}?
image: "https://i.imgur.com/nGF1K8f.jpg"

.. code-block:: yaml

- text: Here's my giraffe sticker!
custom:
sticker: "https://github.com/TelegramBots/book/raw/master/src/docs/sticker-fred.webp"
19 changes: 19 additions & 0 deletions poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,6 @@ coloredlogs = "^10.0"
"ruamel.yaml" = "^0.16"
scikit-learn = "^0.22"
slackclient = "^2.0.0"
python-telegram-bot = ">=11.1,<13.0"
twilio = "~6.26"
webexteamssdk = ">=1.1.1,<1.4.0"
mattermostwrapper = "~2.2"
Expand Down Expand Up @@ -124,6 +123,7 @@ kafka-python = "^1.4"
ujson = ">=1.35,<3.0"
oauth2client = "4.1.3"
regex = "~2020.6"
pyTelegramBotAPI = "^3.7.3"

[tool.poetry.dev-dependencies]
pytest-cov = "^2.8.1"
Expand Down
46 changes: 25 additions & 21 deletions rasa/core/channels/telegram.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
from sanic import Blueprint, response
from sanic.request import Request
from sanic.response import HTTPResponse
from telegram import (
Bot,
from telebot import TeleBot
from telebot.types import (
InlineKeyboardButton,
Update,
InlineKeyboardMarkup,
Expand All @@ -19,9 +19,10 @@
logger = logging.getLogger(__name__)


class TelegramOutput(Bot, OutputChannel):
class TelegramOutput(TeleBot, OutputChannel):
"""Output channel for Telegram"""

# skipcq: PYL-W0236
rgstephens marked this conversation as resolved.
Show resolved Hide resolved
@classmethod
def name(cls) -> Text:
return "telegram"
Expand Down Expand Up @@ -59,31 +60,33 @@ async def send_text_with_buttons(
:button_type reply: reply keyboard
"""
if button_type == "inline":
reply_markup = InlineKeyboardMarkup()
button_list = [
[
InlineKeyboardButton(s["title"], callback_data=s["payload"])
for s in buttons
]
InlineKeyboardButton(s["title"], callback_data=s["payload"])
for s in buttons
]
reply_markup = InlineKeyboardMarkup(button_list)
reply_markup.row(*button_list)

elif button_type == "vertical":
button_list = [
[InlineKeyboardButton(s["title"], callback_data=s["payload"])]
reply_markup = InlineKeyboardMarkup()
[
reply_markup.row(
InlineKeyboardButton(s["title"], callback_data=s["payload"])
)
for s in buttons
]
reply_markup = InlineKeyboardMarkup(button_list)

elif button_type == "reply":
button_list = []
for bttn in buttons:
if isinstance(bttn, list):
button_list.append([KeyboardButton(s["title"]) for s in bttn])
else:
button_list.append([KeyboardButton(bttn["title"])])
reply_markup = ReplyKeyboardMarkup(
button_list, resize_keyboard=True, one_time_keyboard=True
resize_keyboard=False, one_time_keyboard=True
rgstephens marked this conversation as resolved.
Show resolved Hide resolved
)
# drop button_type from button_list
button_list = [b for b in buttons if b.get("title")]
for idx, button in enumerate(buttons):
if isinstance(button, list):
reply_markup.add(KeyboardButton(s["title"]) for s in button)
else:
reply_markup.add(KeyboardButton(button["title"]))
else:
logger.error(
"Trying to send text with buttons for unknown "
Expand Down Expand Up @@ -202,11 +205,12 @@ async def set_webhook(_: Request) -> HTTPResponse:
async def message(request: Request) -> Any:
if request.method == "POST":

if not out_channel.get_me()["username"] == self.verify:
request_dict = request.json
update = Update.de_json(request_dict)
rgstephens marked this conversation as resolved.
Show resolved Hide resolved
if not out_channel.get_me().username == self.verify:
logger.debug("Invalid access token, check it matches Telegram")
return response.text("failed")

update = Update.de_json(request.json, out_channel)
if self._is_button(update):
msg = update.callback_query.message
text = update.callback_query.data
Expand Down Expand Up @@ -265,6 +269,6 @@ async def message(request: Request) -> Any:

def get_output_channel(self) -> TelegramOutput:
channel = TelegramOutput(self.access_token)
channel.setWebhook(self.webhook_url)
channel.set_webhook(url=self.webhook_url)

return channel
2 changes: 1 addition & 1 deletion tests/core/test_channels.py
Original file line number Diff line number Diff line change
Expand Up @@ -302,7 +302,7 @@ def test_rocketchat_channel():
# USED FOR DOCS - don't rename without changing in the docs
@pytest.mark.filterwarnings("ignore:unclosed file.*:ResourceWarning")
# telegram channel will try to set a webhook, so we need to mock the api
@patch.object(TelegramOutput, "setWebhook", noop)
@patch.object(TelegramOutput, "set_webhook", noop)
def test_telegram_channel():
# START DOC INCLUDE
from rasa.core.channels.telegram import TelegramInput
Expand Down