MVP системы отложенных сообщений
This commit is contained in:
@@ -288,6 +288,8 @@ class MainBot(AnyBots):
|
||||
|
||||
self.MakeBackups.start()
|
||||
self.CheckDataBases.start()
|
||||
else:
|
||||
self.SendingDeferredMessages.start()
|
||||
|
||||
async def BotOff(self):
|
||||
if self.task_start:
|
||||
@@ -303,6 +305,25 @@ class MainBot(AnyBots):
|
||||
print(f"{datetime.datetime.now().strftime('%H:%M:%S %d-%m-%Y')}:: Соединение с дискордом разорвано")
|
||||
await self.BotOff()
|
||||
|
||||
@tasks.loop(seconds=60)
|
||||
async def SendingDeferredMessages(self):
|
||||
try:
|
||||
async with self.DataBaseManager.session() as session:
|
||||
async with session.begin():
|
||||
stmt = self.DataBaseManager.select(self.DataBaseManager.model_classes['scheduled_messages']).where(
|
||||
self.DataBaseManager.model_classes['scheduled_messages'].timestamp - datetime.datetime.now().timestamp() <= 0
|
||||
).with_for_update()
|
||||
messages = (await session.execute(stmt)).scalars().all()
|
||||
|
||||
for message in messages:
|
||||
webhook = await self.fetch_webhook(message.webhook_id)
|
||||
await webhook.send(await message.parse_message(self))
|
||||
|
||||
await session.delete(message)
|
||||
|
||||
except Exception as error:
|
||||
print(f"{datetime.datetime.now().strftime('%H:%M:%S %d-%m-%Y')}:: err SendingDeferredMessages: {error}")
|
||||
|
||||
@tasks.loop(seconds=60)
|
||||
async def CheckDataBases(self):
|
||||
try:
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import re
|
||||
import disnake
|
||||
from disnake.ext import commands
|
||||
from disnake.ext import tasks
|
||||
@@ -208,3 +209,39 @@ class AdminModule(commands.Cog):
|
||||
session.add(user_role)
|
||||
await ctx.send(embed = self.client.SuccessEmbed(description = f'Пользователю <@{userid}> успешно назначена роль <@&{roleid}>. \n```diff\n- Эта функция не выдаёт роли автоматически, поэтому требуется выдача вручную.```', colour = 0xff9900))
|
||||
return 0
|
||||
|
||||
@commands.slash_command(name="запланировать_сообщение", description="Позволяет запланировать отправку анонсов и других сообщений")
|
||||
async def schedule_message(self, ctx: disnake.AppCmdInter,
|
||||
message_id: str = commands.Param(description="Укажите id сообщения, которое будет отложено", name="сообщение"),
|
||||
webhook_link: str = commands.Param(description="Укажите ссылку на вебхук, от которого будет отправлено сообщение(по умолчанию от лица бота)", name="вебхук", default=None),
|
||||
timestamp: int = commands.Param(description="Временная метка для отправки сообщения", name="таймстамп", default=None)):
|
||||
|
||||
await ctx.response.defer()
|
||||
|
||||
def extract_webhook_id(webhook_url: str) -> int | None:
|
||||
pattern = r"^https:\/\/(?:canary\.|ptb\.)?discord(?:app)?\.com\/api\/webhooks\/(\d+)\/[\w\-]+$"
|
||||
match = re.match(pattern, webhook_url)
|
||||
if match:
|
||||
return int(match.group(1))
|
||||
return None
|
||||
|
||||
if webhook_link is None:
|
||||
webhook_id = None
|
||||
else:
|
||||
webhook_id = extract_webhook_id(webhook_link)
|
||||
if webhook_id is None:
|
||||
await ctx.edit_original_response(embed = self.client.ErrEmbed(description = f'Некорректная ссылка'))
|
||||
return 1
|
||||
|
||||
async with self.DataBaseManager.session() as session:
|
||||
async with session.begin():
|
||||
if not (await self.DataBaseManager.model_classes['staff_users'].is_admin_or_moder_by_id(ctx.author.id, self.DataBaseManager, session, is_admin=True, is_moder=False)):
|
||||
await ctx.edit_original_response(embed = self.client.ErrEmbed(description = f'У вас недостаточно полномочий, чтобы оставлять отложенные сообщения.'))
|
||||
return 1
|
||||
else:
|
||||
scheduled_message_model = self.DataBaseManager.model_classes['scheduled_messages']
|
||||
message = scheduled_message_model(source_channel_id=ctx.channel.id, source_message_id=int(message_id), webhook_id=webhook_id, timestamp=timestamp)
|
||||
session.add(message)
|
||||
|
||||
await ctx.edit_original_response(embed = self.client.SuccessEmbed(description = f'Успешно! Текст сообщения:\n {await message.parse_message(self.client)}', colour = 0xff9900))
|
||||
return 0
|
||||
|
||||
@@ -152,7 +152,7 @@ class StaffUser(Base):
|
||||
return await self.__class__.is_admin_or_moder_by_id(self.id, DBManager, session)
|
||||
|
||||
@staticmethod
|
||||
async def is_admin_or_moder_by_id(member_id, DBManager, session):
|
||||
async def is_admin_or_moder_by_id(member_id, DBManager, session, *, is_admin=True, is_moder=True):
|
||||
staff_branches_model = DBManager.model_classes['staff_branches']
|
||||
staff_users_roles_model = DBManager.model_classes['staff_users_roles']
|
||||
|
||||
@@ -162,8 +162,8 @@ class StaffUser(Base):
|
||||
.where(
|
||||
DBManager.and_(
|
||||
DBManager.or_(
|
||||
staff_branches_model.is_admin == True,
|
||||
staff_branches_model.is_moder == True,
|
||||
(staff_branches_model.is_admin == True) if is_admin else False,
|
||||
(staff_branches_model.is_moder == True) if is_moder else False,
|
||||
),
|
||||
staff_users_roles_model.user_id == member_id
|
||||
)
|
||||
@@ -233,10 +233,18 @@ class AllowedDomain(Base):
|
||||
|
||||
class ScheduledMessage(Base):
|
||||
__tablename__ = "scheduled_messages"
|
||||
message_id: Mapped[discord_identificator_pk]
|
||||
webhook_id: Mapped[discord_identificator]
|
||||
timestamp: Mapped[float | None] = mapped_column(Float)
|
||||
source_message_id: Mapped[discord_identificator_pk]
|
||||
source_channel_id: Mapped[discord_identificator]
|
||||
webhook_id: Mapped[int | None] = mapped_column(BigInteger, nullable=True, index=True)
|
||||
timestamp: Mapped[float | None] = mapped_column(Float, nullable=True, index=True)
|
||||
|
||||
async def parse_message(self, client):
|
||||
krekchat = await client.fetch_guild(client.krekchat.id)
|
||||
source_channel = await krekchat.fetch_channel(self.source_channel_id)
|
||||
source_message = await source_channel.fetch_message(self.source_message_id)
|
||||
|
||||
content = source_message.content
|
||||
return content
|
||||
|
||||
all_data = {
|
||||
'base': Base
|
||||
|
||||
Reference in New Issue
Block a user