Skip to content

Commit

Permalink
feat(auto delete): Added auto delete for Bot messages in group
Browse files Browse the repository at this point in the history
  • Loading branch information
Nickelza committed May 5, 2024
1 parent a866614 commit a0d3493
Show file tree
Hide file tree
Showing 16 changed files with 339 additions and 28 deletions.
2 changes: 2 additions & 0 deletions environment/env.example
Original file line number Diff line number Diff line change
Expand Up @@ -359,3 +359,5 @@ PLUNDER_COOLDOWN_DURATION=
PLUNDER_REPAY_MULTIPLIER=

IMPEL_DOWN_BAIL_PER_MINUTE=

AUTO_DELETE_DURATION_VALUES=
5 changes: 5 additions & 0 deletions resources/Environment.py
Original file line number Diff line number Diff line change
Expand Up @@ -1026,3 +1026,8 @@ def __str__(self) -> str:

# How much is each remaining minute of the sentence for bail in Impel Down. Default: 100k
IMPEL_DOWN_BAIL_PER_MINUTE = Environment("IMPEL_DOWN_BAIL_PER_MINUTE", default_value="100000")

# Values in minute for auto delete. Default: 1|2|5|15|30|60|120|180|360
AUTO_DELETE_DURATION_VALUES = Environment(
"AUTO_DELETE_DURATION_VALUES", default_value="1|2|5|15|30|60|120|180|360"
)
9 changes: 8 additions & 1 deletion resources/phrases.py
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,7 @@ def surround_with_arrows(text: str) -> str:
TEXT_YOU = "You"
TEXT_STOLE = "stole"
TEXT_OWE = "[owe]({})"
TEXT_NEVER = "Never"

TEXT_DAY = "day"
TEXT_DAYS = "days"
Expand Down Expand Up @@ -362,7 +363,8 @@ def surround_with_arrows(text: str) -> str:
PVT_KEY_SHOW_ALL = "Back to list"

GRP_KEY_DEVIL_FRUIT_BUY = Emoji.MONEY + " Buy"
GRP_KEY_FEATURES = "Features"
GRP_KEY_SETTINGS_FEATURES = "Features"
GRP_KEY_SETTINGS_AUTO_DELETE = "Auto delete"
GRP_TXT_FEATURES = "{}Which Bounty System features would you like to enable in this {}?"
GRP_KEY_PREDICTION_BET_IN_PRIVATE_CHAT = "Bet in private chat"
GRP_KEY_PREDICTION_VIEW_IN_PRIVATE_CHAT = "View in private chat"
Expand Down Expand Up @@ -2152,3 +2154,8 @@ def surround_with_arrows(text: str) -> str:
" prize!_"
)
DAILY_REWARD_PRIZE_CONFIRM_BELLY = "Belly amount: ฿*{}*"

AUTO_DELETE_SET = (
"After how many minutes should the Bot's messages be deleted from the chat?"
"\n\nCurrent setting: *{}*"
)
10 changes: 8 additions & 2 deletions src/chat/group/group_chat_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@
manage as manage_screen_prediction_bet_status,
)
from src.chat.group.screens.screen_settings import manage as manage_screen_settings
from src.chat.group.screens.screen_settings_auto_delete import (
manage as manage_screen_settings_auto_delete,
)
from src.chat.group.screens.screen_settings_features import manage as manage_screen_features
from src.chat.group.screens.screen_silence import manage as manage_screen_silence
from src.chat.group.screens.screen_silence_end import manage as manage_screen_silence_end
Expand Down Expand Up @@ -95,7 +98,7 @@ async def manage(
if added_to_group:
group.is_active = True
group.save()
command = Command.GRP_FEATURES
command = Command.GRP_SETTINGS_FEATURES

# Insert or update user, with message count
try:
Expand Down Expand Up @@ -211,7 +214,7 @@ async def dispatch_screens(
update, context, user, inbound_keyboard, target_user, command, group_chat
)

case Screen.GRP_FEATURES: # Features
case Screen.GRP_SETTINGS_FEATURES: # Features
await manage_screen_features(
update, context, inbound_keyboard, group_chat, added_to_group
)
Expand All @@ -238,6 +241,9 @@ async def dispatch_screens(
case Screen.GRP_SETTINGS: # Settings
await manage_screen_settings(update, context)

case Screen.GRP_SETTINGS_AUTO_DELETE: # Auto delete
await manage_screen_settings_auto_delete(update, context, inbound_keyboard, group_chat)

case _: # Unknown screen
if update.callback_query is not None:
raise GroupChatException(GroupChatError.UNRECOGNIZED_SCREEN)
Expand Down
6 changes: 5 additions & 1 deletion src/chat/group/screens/screen_settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,10 @@ async def manage(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
"""

inline_keyboard: list[list[Keyboard]] = [
[Keyboard(phrases.GRP_KEY_FEATURES, screen=Screen.GRP_FEATURES)],
# Features
[Keyboard(phrases.GRP_KEY_SETTINGS_FEATURES, screen=Screen.GRP_SETTINGS_FEATURES)],
# Auto delete
[Keyboard(phrases.GRP_KEY_SETTINGS_AUTO_DELETE, screen=Screen.GRP_SETTINGS_AUTO_DELETE)],
]

await full_message_send(
Expand All @@ -26,4 +29,5 @@ async def manage(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
keyboard=inline_keyboard,
add_delete_button=True,
use_close_delete=True,
should_auto_delete=False,
)
66 changes: 66 additions & 0 deletions src/chat/group/screens/screen_settings_auto_delete.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
from telegram import Update
from telegram.ext import ContextTypes

import resources.Environment as Env
import resources.phrases as phrases
from src.model.GroupChat import GroupChat
from src.model.enums.Emoji import Emoji
from src.model.enums.ReservedKeyboardKeys import ReservedKeyboardKeys
from src.model.pojo.Keyboard import Keyboard
from src.service.list_service import get_options_keyboard
from src.service.message_service import full_message_send


async def manage(
update: Update,
context: ContextTypes.DEFAULT_TYPE,
inbound_keyboard: Keyboard,
group_chat: GroupChat,
) -> None:
"""
Manage the auto delete screen
:param update: The update object
:param context: The context object
:param inbound_keyboard: The inbound keyboard
:param group_chat: The group chat
:return: None
"""

if ReservedKeyboardKeys.DEFAULT_PRIMARY_KEY in inbound_keyboard.info:
duration = inbound_keyboard.get(ReservedKeyboardKeys.DEFAULT_PRIMARY_KEY)
group_chat.auto_delete_duration = duration
group_chat.save()

current_value = group_chat.auto_delete_duration
# Create numeric keyboard with all possible values
numeric_keyboard: list[list[Keyboard]] = get_options_keyboard(
inbound_info=inbound_keyboard.info,
values=Env.AUTO_DELETE_DURATION_VALUES.get_list(),
current_selected=current_value,
)

# Add "Never" option as first option
numeric_keyboard.insert(
0,
[
Keyboard(
(Emoji.RADIO_BUTTON if current_value is None else "") + phrases.TEXT_NEVER,
info={ReservedKeyboardKeys.DEFAULT_PRIMARY_KEY: None},
inbound_info=inbound_keyboard.info,
)
],
)

ot_text = phrases.AUTO_DELETE_SET.format(
phrases.TEXT_NEVER if current_value is None else current_value
)
await full_message_send(
context,
ot_text,
update=update,
keyboard=numeric_keyboard,
add_delete_button=True,
use_close_delete=True,
inbound_keyboard=inbound_keyboard,
should_auto_delete=False,
)
9 changes: 7 additions & 2 deletions src/chat/group/screens/screen_settings_features.py
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ async def manage(
add_delete_button=True,
use_close_delete=True,
inbound_keyboard=inbound_keyboard,
should_auto_delete=False,
)


Expand Down Expand Up @@ -138,7 +139,9 @@ def get_features_keyboard(group_chat: GroupChat) -> list[list[Keyboard]]:
ReservedKeyboardKeys.TOGGLE: not is_enabled_feature,
}
button: Keyboard = Keyboard(
f"{emoji} {feature.get_description()}", info=button_info, screen=Screen.GRP_FEATURES
f"{emoji} {feature.get_description()}",
info=button_info,
screen=Screen.GRP_SETTINGS_FEATURES,
)

# If feature is pinnable, add button in a new row with the pin toggle button
Expand All @@ -153,7 +156,9 @@ def get_features_keyboard(group_chat: GroupChat) -> list[list[Keyboard]]:
FeaturesReservedKeys.PIN_TOGGLE: not is_enabled_pin,
}
pin_toggle: Keyboard = Keyboard(
f"{is_enabled_emoji} {Emoji.PIN}", info=pin_button_info, screen=Screen.GRP_FEATURES
f"{is_enabled_emoji} {Emoji.PIN}",
info=pin_button_info,
screen=Screen.GRP_SETTINGS_FEATURES,
)

# Relative feature button and pin button in the same new row
Expand Down
27 changes: 9 additions & 18 deletions src/chat/private/screens/screen_crew_davy_back_fight_request.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
from telegram.error import TelegramError
from telegram.ext import ContextTypes

import constants as c
import resources.Environment as Env
import resources.phrases as phrases
from src.chat.private.screens.screen_crew_davy_back_fight_request_received import accept
Expand All @@ -24,6 +23,7 @@
convert_minutes_to_duration,
datetime_is_before,
)
from src.service.list_service import get_options_keyboard
from src.service.message_service import full_message_send, get_yes_no_keyboard, get_deeplink


Expand Down Expand Up @@ -249,23 +249,14 @@ async def edit_options(
raise ValueError()

# Create numeric keyboard with all possible values
numeric_keyboard: list[list[Keyboard]] = []
line_keyboard: list[Keyboard] = []
for i in range(minimum, maximum + 1):
line_keyboard.append(
Keyboard(
str(i),
info={key: i},
inbound_info=inbound_keyboard.info,
exclude_key_from_inbound_info=[ReservedKeyboardKeys.SCREEN_STEP_NO_INPUT],
)
)
if len(line_keyboard) == c.STANDARD_LIST_KEYBOARD_ROW_SIZE:
numeric_keyboard.append(line_keyboard)
line_keyboard = []

if len(line_keyboard) > 0:
numeric_keyboard.append(line_keyboard)
numeric_keyboard: list[list[Keyboard]] = get_options_keyboard(
primary_key=key,
inbound_info=inbound_keyboard.info,
exclude_key_from_inbound_info=[ReservedKeyboardKeys.SCREEN_STEP_NO_INPUT],
generate_numbers=True,
start_number=minimum,
end_number=maximum,
)

user.private_screen_stay = True
await full_message_send(
Expand Down
1 change: 1 addition & 0 deletions src/model/GroupChat.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ class GroupChat(BaseModel):
last_error_message = CharField(null=True)
is_active = BooleanField(default=True)
is_muted = BooleanField(default=False)
auto_delete_duration = IntegerField(null=True) # In minutes

# Backref
enabled_features = None
Expand Down
26 changes: 26 additions & 0 deletions src/model/GroupChatAutoDelete.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import datetime

from peewee import *

from src.model.BaseModel import BaseModel
from src.model.GroupChat import GroupChat


class GroupChatAutoDelete(BaseModel):
"""
Group Chat Auto Delete class
"""

id: int | PrimaryKeyField = PrimaryKeyField()
group_chat: GroupChat | ForeignKeyField = ForeignKeyField(
GroupChat, backref="auto_delete", on_delete="CASCADE"
)
message_id: int | IntegerField = IntegerField()
date: datetime.datetime | DateTimeField = DateTimeField(default=datetime.datetime.now)
delete_date: datetime.datetime | DateTimeField = DateTimeField()

class Meta:
db_table = "group_chat_auto_delete"


GroupChatAutoDelete.create_table()
4 changes: 2 additions & 2 deletions src/model/enums/Command.py
Original file line number Diff line number Diff line change
Expand Up @@ -348,9 +348,9 @@ def __eq__(self, other):
)
COMMANDS.append(GRP_SETTINGS)

GRP_FEATURES = Command(
GRP_SETTINGS_FEATURES = Command(
CommandName.EMPTY,
Screen.GRP_FEATURES,
Screen.GRP_SETTINGS_FEATURES,
allow_while_arrested=True,
only_by_chat_admin=True,
answer_callback=True,
Expand Down
3 changes: 2 additions & 1 deletion src/model/enums/Screen.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,14 @@ class Screen(StrEnum):
GRP_SPEAK = "G17"
GRP_BOUNTY_GIFT = "G18"
GRP_DEVIL_FRUIT_COLLECT = "G19" # Deprecated
GRP_FEATURES = "G20"
GRP_SETTINGS_FEATURES = "G20"
GRP_DEVIL_FRUIT_SELL = "G21"
GRP_BOUNTY_LOAN = "G22"
GRP_PLUNDER = "G23"
GRP_DAILY_REWARD = "G24"
GRP_DAILY_REWARD_PRIZE = "G25"
GRP_SETTINGS = "G26"
GRP_SETTINGS_AUTO_DELETE = "G27"

PVT_START = "P1"
PVT_SETTINGS = "P2"
Expand Down
4 changes: 4 additions & 0 deletions src/service/generic_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
from src.model.DavyBackFight import DavyBackFight
from src.service.crew_service import end_all_conscription
from src.service.davy_back_fight_service import start_all as start_dbf, end_all as end_dbf
from src.service.group_service import auto_delete


async def run_minute_tasks(context: ContextTypes.DEFAULT_TYPE) -> None:
Expand All @@ -23,3 +24,6 @@ async def run_minute_tasks(context: ContextTypes.DEFAULT_TYPE) -> None:

# End all Crew conscription
context.application.create_task(end_all_conscription(context))

# Auto delete messages
context.application.create_task(auto_delete(context))
37 changes: 37 additions & 0 deletions src/service/group_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
from src.model.BaseModel import BaseModel
from src.model.Group import Group
from src.model.GroupChat import GroupChat
from src.model.GroupChatAutoDelete import GroupChatAutoDelete
from src.model.GroupChatDisabledFeature import GroupChatDisabledFeature
from src.model.GroupChatEnabledFeaturePin import GroupChatEnabledFeaturePin
from src.model.GroupChatFeaturePinMessage import GroupChatFeaturePinMessage
Expand Down Expand Up @@ -323,3 +324,39 @@ def save_group_chat_error(group_chat: GroupChat, error: str) -> None:
group.last_error_date = datetime.now()
group.last_error_message = error
group.save()


async def auto_delete(context: ContextTypes.DEFAULT_TYPE) -> None:
"""
Auto delete messages
:param context: The context
"""

# Get maximum 20 messages to auto delete
auto_deletes: list[GroupChatAutoDelete] = (
GroupChatAutoDelete.select()
.where(GroupChatAutoDelete.delete_date < datetime.now())
.limit(20)
)

for auto_delete_item in auto_deletes:
context.application.create_task(auto_delete_process(context, auto_delete_item))


async def auto_delete_process(
context: ContextTypes.DEFAULT_TYPE, auto_delete_item: GroupChatAutoDelete
) -> None:
"""
Auto delete process
:param context: The context
:param auto_delete_item: The message
"""

group_chat: GroupChat = auto_delete_item.group_chat
group: Group = group_chat.group
try:
await context.bot.delete_message(group.tg_group_id, auto_delete_item.message_id)
except TelegramError as te:
save_group_chat_error(group_chat, str(te))

auto_delete_item.delete_instance()
Loading

0 comments on commit a0d3493

Please sign in to comment.