From e76dbdbcbc42a3cf63ad49cae2d24b30b98229c6 Mon Sep 17 00:00:00 2001 From: spatade Date: Tue, 10 Oct 2023 15:19:49 +0530 Subject: [PATCH 1/2] telegram buttons --- kairon/chat/converters/channels/telegram.py | 23 +++++++++++++++++++ kairon/chat/handlers/channels/telegram.py | 5 ++++ metadata/message_template.yml | 1 + .../channel_data/channel_data.json | 7 +++++- tests/unit_test/utility_test.py | 18 +++++++++++++++ 5 files changed, 53 insertions(+), 1 deletion(-) diff --git a/kairon/chat/converters/channels/telegram.py b/kairon/chat/converters/channels/telegram.py index 1271bf4c5..9b5b83d72 100644 --- a/kairon/chat/converters/channels/telegram.py +++ b/kairon/chat/converters/channels/telegram.py @@ -34,6 +34,27 @@ def link_transformer(self, message): except Exception as ex: raise Exception(f" Error in TelegramResponseConverter::link_transformer {str(ex)}") + def button_transformer(self, message): + try: + jsoniterator = ElementTransformerOps.json_generator(message) + reply_markup = {} + inline_keyboard = [] + reply_markup.update({"inline_keyboard": inline_keyboard}) + inline_keyboard_array = [] + for item in jsoniterator: + if item.get("type") == ElementTypes.BUTTON.value: + title = ElementTransformerOps.json_generator(item.get("children")) + for titletext in title: + button_text = titletext.get("text") + btn_body = {} + btn_body.update({"text": button_text}) + btn_body.update({"callback_data": item.get("value")}) + inline_keyboard_array.append(btn_body) + inline_keyboard.append(inline_keyboard_array) + return reply_markup + except Exception as ex: + raise Exception(f"Exception in TelegramResponseConverter::button_transfomer: {str(ex)}") + async def messageConverter(self, message): try: if self.message_type == ElementTypes.IMAGE.value: @@ -42,5 +63,7 @@ async def messageConverter(self, message): return self.link_transformer(message) elif self.message_type == ElementTypes.VIDEO.value: return super().video_transformer(message) + elif self.message_type == ElementTypes.BUTTON.value: + return self.button_transformer(message) except Exception as ex: raise Exception(f"Error in TelegramResponseConverter::messageConverter {str(ex)}") diff --git a/kairon/chat/handlers/channels/telegram.py b/kairon/chat/handlers/channels/telegram.py index 0669f7ee8..15615e78f 100644 --- a/kairon/chat/handlers/channels/telegram.py +++ b/kairon/chat/handlers/channels/telegram.py @@ -25,6 +25,8 @@ from kairon.chat.agent_processor import AgentProcessor from kairon import Utility from kairon.chat.converters.channels.response_factory import ConverterFactory +from kairon.chat.converters.channels.responseconverter import ElementTransformerOps +import json logger = logging.getLogger(__name__) @@ -159,6 +161,9 @@ async def send_custom_json( del response["text"] api_call = getattr(self, send_functions[("text",)]) api_call(recipient_id, *response_list, **response) + elif ops_type in ["button"]: + body_default = ElementTransformerOps.getChannelConfig(ChannelTypes.TELEGRAM.value, "body_message") + self.send_message(recipient_id, text=body_default, reply_markup=json.dumps(response)) else: self.send_message(recipient_id, str(json_message)) except Exception as ap: diff --git a/metadata/message_template.yml b/metadata/message_template.yml index 4b97be8f5..335e81bc4 100644 --- a/metadata/message_template.yml +++ b/metadata/message_template.yml @@ -122,6 +122,7 @@ telegram: "disable_notification":false, "reply_to_message_id":0}' video: '{"text":""}' + body_message: 'Please select from quick buttons:' msteams: body_message: "Please select from quick buttons:" diff --git a/tests/testing_data/channel_data/channel_data.json b/tests/testing_data/channel_data/channel_data.json index 582cef603..fbdb56800 100644 --- a/tests/testing_data/channel_data/channel_data.json +++ b/tests/testing_data/channel_data/channel_data.json @@ -457,5 +457,10 @@ ], "button": "Submit Option" } - } + }, + "telegram_button_op_one": {"inline_keyboard": [[{"text": "One", "callback_data": "single button is clicked"}]]}, + "telegram_button_op_multi": {"inline_keyboard": [[{"text": "Veg", "callback_data": "Vegetables only"}, + {"text": "Non-veg", "callback_data": "fish food served"}, + {"text": "Desert", "callback_data": "Only Desert food"}]]} + } \ No newline at end of file diff --git a/tests/unit_test/utility_test.py b/tests/unit_test/utility_test.py index 1f34d7ac5..e8a001e9f 100644 --- a/tests/unit_test/utility_test.py +++ b/tests/unit_test/utility_test.py @@ -2747,3 +2747,21 @@ def test_is_picklable_for_mongo_failure(self): assert not Utility.is_picklable_for_mongo({"requests": requests}) assert not Utility.is_picklable_for_mongo({"utility": Utility}) assert not Utility.is_picklable_for_mongo({"is_picklable_for_mongo": Utility.is_picklable_for_mongo}) + + def test_button_transformer_telegram_single_button(self): + json_data = json.load(open("tests/testing_data/channel_data/channel_data.json")) + input_json = json_data.get("button_one") + from kairon.chat.converters.channels.telegram import TelegramResponseConverter + telegram = TelegramResponseConverter("button", "telegram") + response = telegram.button_transformer(input_json) + expected_output = json_data.get("telegram_button_op_one") + assert expected_output == response + + def test_button_transformer_telegram_multi_buttons(self): + json_data = json.load(open("tests/testing_data/channel_data/channel_data.json")) + input_json = json_data.get("button_three") + from kairon.chat.converters.channels.telegram import TelegramResponseConverter + telegram = TelegramResponseConverter("button", "telegram") + response = telegram.button_transformer(input_json) + expected_output = json_data.get("telegram_button_op_multi") + assert expected_output == response \ No newline at end of file From d0f8fc66d1a7d6a7bf5ee38a0957387f178719e0 Mon Sep 17 00:00:00 2001 From: spatade Date: Tue, 10 Oct 2023 17:24:44 +0530 Subject: [PATCH 2/2] Code coverage issue --- .../channel_data/channel_data.json | 4 +++- tests/unit_test/utility_test.py | 21 ++++++++++++++++--- 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/tests/testing_data/channel_data/channel_data.json b/tests/testing_data/channel_data/channel_data.json index fbdb56800..1e7cfd240 100644 --- a/tests/testing_data/channel_data/channel_data.json +++ b/tests/testing_data/channel_data/channel_data.json @@ -461,6 +461,8 @@ "telegram_button_op_one": {"inline_keyboard": [[{"text": "One", "callback_data": "single button is clicked"}]]}, "telegram_button_op_multi": {"inline_keyboard": [[{"text": "Veg", "callback_data": "Vegetables only"}, {"text": "Non-veg", "callback_data": "fish food served"}, - {"text": "Desert", "callback_data": "Only Desert food"}]]} + {"text": "Desert", "callback_data": "Only Desert food"}]]}, + "button_one_exception": [{"type":"button","value":"single button is clicked","id":"5"}, + {"type":"paragraph","children":[{"text":""}]}] } \ No newline at end of file diff --git a/tests/unit_test/utility_test.py b/tests/unit_test/utility_test.py index e8a001e9f..acb8fcb9b 100644 --- a/tests/unit_test/utility_test.py +++ b/tests/unit_test/utility_test.py @@ -41,6 +41,7 @@ from kairon.shared.models import TemplateType from kairon.shared.utils import Utility, MailUtility from kairon.shared.verification.email import QuickEmailVerification +from kairon.chat.converters.channels.telegram import TelegramResponseConverter class TestUtility: @@ -2751,7 +2752,6 @@ def test_is_picklable_for_mongo_failure(self): def test_button_transformer_telegram_single_button(self): json_data = json.load(open("tests/testing_data/channel_data/channel_data.json")) input_json = json_data.get("button_one") - from kairon.chat.converters.channels.telegram import TelegramResponseConverter telegram = TelegramResponseConverter("button", "telegram") response = telegram.button_transformer(input_json) expected_output = json_data.get("telegram_button_op_one") @@ -2760,8 +2760,23 @@ def test_button_transformer_telegram_single_button(self): def test_button_transformer_telegram_multi_buttons(self): json_data = json.load(open("tests/testing_data/channel_data/channel_data.json")) input_json = json_data.get("button_three") - from kairon.chat.converters.channels.telegram import TelegramResponseConverter telegram = TelegramResponseConverter("button", "telegram") response = telegram.button_transformer(input_json) expected_output = json_data.get("telegram_button_op_multi") - assert expected_output == response \ No newline at end of file + assert expected_output == response + + @pytest.mark.asyncio + async def test_button_transformer_telegram_messageConverter(self): + json_data = json.load(open("tests/testing_data/channel_data/channel_data.json")) + input_json = json_data.get("button_three") + telegram = ConverterFactory.getConcreteInstance("button", "telegram") + response = await telegram.messageConverter(input_json) + expected_output = json_data.get("telegram_button_op_multi") + assert expected_output == response + + def test_button_transformer_telegram_exception(self): + json_data = json.load(open("tests/testing_data/channel_data/channel_data.json")) + input_json = json_data.get("button_one_exception") + telegram = TelegramResponseConverter("button", "telegram") + with pytest.raises(Exception): + telegram.button_transformer(input_json)