Skip to content

Commit

Permalink
Minor improvements
Browse files Browse the repository at this point in the history
  • Loading branch information
Saluev committed Dec 26, 2023
1 parent 91485b6 commit 55c6a04
Show file tree
Hide file tree
Showing 5 changed files with 71 additions and 47 deletions.
1 change: 0 additions & 1 deletion suppgram/bridges/inmemory_telegram.py
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,6 @@ async def get_messages(
]

async def delete_messages(self, messages: List[TelegramMessage]):
print(messages, self.messages)
message_ids = {m.id for m in messages}
self.messages = [m for m in self.messages if m.id not in message_ids]

Expand Down
4 changes: 2 additions & 2 deletions suppgram/frontends/telegram/agent_frontend.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import asyncio
import json
import logging
from itertools import groupby
from typing import List, Iterable, Optional, Callable, Awaitable, Mapping
Expand Down Expand Up @@ -46,6 +45,7 @@
is_blocked_by_user,
make_pagination_keyboard,
paginate_texts,
decode_callback_data,
)
from suppgram.frontends.telegram.identification import (
make_agent_identification,
Expand Down Expand Up @@ -284,7 +284,7 @@ async def _handle_callback_query(self, update: Update, context: ContextTypes.DEF
return

agent = await self._backend.identify_agent(make_agent_identification(update.effective_user))
callback_data = json.loads(update.callback_query.data)
callback_data = decode_callback_data(update.callback_query.data)
action = callback_data.get("a")
if action is None:
return
Expand Down
22 changes: 14 additions & 8 deletions suppgram/frontends/telegram/customer_frontend.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import json
import logging
from typing import cast, List

Expand All @@ -25,6 +24,7 @@
)
from suppgram.frontends.telegram.app_manager import TelegramAppManager
from suppgram.frontends.telegram.callback_actions import CallbackActionKind
from suppgram.frontends.telegram.helpers import encode_callback_data, decode_callback_data
from suppgram.frontends.telegram.identification import (
make_customer_identification,
make_customer_diff,
Expand Down Expand Up @@ -103,11 +103,18 @@ async def _handle_callback_query(self, update: Update, context: ContextTypes.DEF
if not update.callback_query.data:
# No idea how to handle this update.
return
callback_data = json.loads(update.callback_query.data)
callback_data = decode_callback_data(update.callback_query.data)
action = callback_data["a"]
conversation = await self._backend.get_conversation(callback_data["c"])
conversation = await self._backend.identify_customer_conversation(
make_customer_identification(update.effective_user)
)
conversation_to_rate = await self._backend.get_conversation(callback_data["c"])
if action == CallbackActionKind.RATE:
await self._backend.rate_conversation(conversation, callback_data["r"])
if conversation.customer.id != conversation_to_rate.customer.id:
# Can't rate another person's conversation!
# Probably someone's playing with the callback query payloads.
return
await self._backend.rate_conversation(conversation_to_rate, callback_data["r"])
else:
logger.info(f"Customer frontend received unsupported callback action {action!r}")

Expand Down Expand Up @@ -206,8 +213,7 @@ async def _handle_conversation_rated(self, event: ConversationEvent):
def _make_rate_button(self, conversation: Conversation, rating: int) -> InlineKeyboardButton:
return InlineKeyboardButton(
text=self._texts.format_rating(rating),
callback_data=json.dumps(
{"a": CallbackActionKind.RATE, "c": conversation.id, "r": rating},
separators=(",", ":"),
), # TODO encrypt
callback_data=encode_callback_data(
{"a": CallbackActionKind.RATE, "c": conversation.id, "r": rating}
),
)
11 changes: 9 additions & 2 deletions suppgram/frontends/telegram/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,14 @@ def is_blocked_by_user(exc: TelegramError) -> bool:
return "bot was blocked by the user" in str(exc)


def encode_callback_data(doc: Any) -> str:
return json.dumps(doc, separators=(",", ":"))


def decode_callback_data(data: str) -> Any:
return json.loads(data)


def paginate_texts(
prefix: str,
texts: Iterable[str],
Expand Down Expand Up @@ -113,13 +121,12 @@ def _make_pagination_button(
) -> InlineKeyboardButton:
return InlineKeyboardButton(
text=text,
callback_data=json.dumps(
callback_data=encode_callback_data(
{
"a": CallbackActionKind.PAGE,
"c": message.chat.telegram_chat_id,
"m": message.telegram_message_id,
"p": page_idx,
},
separators=(",", ":"),
),
)
80 changes: 46 additions & 34 deletions suppgram/frontends/telegram/manager_frontend.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import asyncio
import json
import logging
from typing import Optional, Any, List

Expand Down Expand Up @@ -42,6 +41,8 @@
from suppgram.frontends.telegram.helpers import (
send_text_answer,
arrange_buttons,
encode_callback_data,
decode_callback_data,
)
from suppgram.frontends.telegram.identification import (
make_agent_identification,
Expand Down Expand Up @@ -118,6 +119,9 @@ def _make_handlers(self) -> List[BaseHandler]:
async def initialize(self):
await super().initialize()
await self._telegram_app.initialize()
await self._set_commands()

async def _set_commands(self):
await self._telegram_bot.set_my_commands(
[
BotCommand(
Expand Down Expand Up @@ -274,48 +278,28 @@ async def _update_new_conversation_notification(
all_tags: List[ConversationTag],
keyboard_only: bool = False,
):
assign_to_me_button = InlineKeyboardButton(
self._texts.telegram_assign_to_me_button_text,
callback_data=json.dumps(
{
"a": CallbackActionKind.ASSIGN_TO_ME,
"c": conversation.id,
},
separators=(",", ":"),
),
)
present_tag_ids = {tag.id for tag in conversation.tags}

assign_buttons = (
[[self._make_assign_to_me_button(conversation)]]
if conversation.state == ConversationState.NEW
else []
)
tag_buttons = [
InlineKeyboardButton(
self._texts.compose_remove_tag_button_text(tag)
if tag.id in present_tag_ids
else self._texts.compose_add_tag_button_text(tag),
callback_data=json.dumps(
{
"a": CallbackActionKind.REMOVE_CONVERSATION_TAG
if tag.id in present_tag_ids
else CallbackActionKind.ADD_CONVERSATION_TAG,
"c": conversation.id,
"t": tag.id,
},
separators=(",", ":"),
),
)
self._make_remove_tag_button(conversation, tag)
if tag.id in present_tag_ids
else self._make_add_tag_button(conversation, tag)
for tag in all_tags
]

inline_buttons = (
[[assign_to_me_button]] if conversation.state == ConversationState.NEW else []
)
inline_buttons.extend(arrange_buttons(tag_buttons))
inline_buttons = [*assign_buttons, *arrange_buttons(tag_buttons)]
inline_keyboard = InlineKeyboardMarkup(inline_buttons) if inline_buttons else None

if keyboard_only:
try:
await self._telegram_bot.edit_message_reply_markup(
message.chat.telegram_chat_id,
message.telegram_message_id,
reply_markup=InlineKeyboardMarkup(inline_buttons) if inline_buttons else None,
reply_markup=inline_keyboard,
)
return
except BadRequest as exc:
Expand All @@ -329,12 +313,40 @@ async def _update_new_conversation_notification(
message.chat.telegram_chat_id,
message.telegram_message_id,
parse_mode=text.parse_mode,
reply_markup=InlineKeyboardMarkup(inline_buttons) if inline_buttons else None,
reply_markup=inline_keyboard,
)
except BadRequest as exc:
if "Message is not modified" not in str(exc):
raise

def _make_assign_to_me_button(self, conversation: Conversation) -> InlineKeyboardButton:
return InlineKeyboardButton(
self._texts.telegram_assign_to_me_button_text,
callback_data=encode_callback_data(
{"a": CallbackActionKind.ASSIGN_TO_ME, "c": conversation.id}
),
)

def _make_add_tag_button(
self, conversation: Conversation, tag: ConversationTag
) -> InlineKeyboardButton:
return InlineKeyboardButton(
text=self._texts.compose_add_tag_button_text(tag),
callback_data=encode_callback_data(
{"a": CallbackActionKind.ADD_CONVERSATION_TAG, "c": conversation.id, "t": tag.id}
),
)

def _make_remove_tag_button(
self, conversation: Conversation, tag: ConversationTag
) -> InlineKeyboardButton:
return InlineKeyboardButton(
text=self._texts.compose_remove_tag_button_text(tag),
callback_data=encode_callback_data(
{"a": CallbackActionKind.REMOVE_CONVERSATION_TAG, "c": conversation.id, "t": tag.id}
),
)

async def _handle_start_command(self, update: Update, context: ContextTypes.DEFAULT_TYPE):
assert (
update.effective_chat
Expand Down Expand Up @@ -386,7 +398,7 @@ async def _handle_callback_query(self, update: Update, context: ContextTypes.DEF
# No idea how to handle this update.
return
await self._create_or_update_agent(update.effective_chat, update.effective_user)
callback_data = json.loads(update.callback_query.data)
callback_data = decode_callback_data(update.callback_query.data)
action = callback_data["a"]
if action == CallbackActionKind.ASSIGN_TO_ME:
conversation_id = callback_data["c"]
Expand Down

0 comments on commit 55c6a04

Please sign in to comment.