add notify for chat

This commit is contained in:
harold 2025-02-08 11:41:20 +05:00
parent e32ac46898
commit 9e2dcaee53
10 changed files with 129 additions and 10 deletions

View File

@ -26,6 +26,7 @@ CREATE TABLE tg_messages (
CREATE TABLE successed (
id BIGSERIAL PRIMARY KEY UNIQUE,
user_id BIGINT NOT NULL REFERENCES users(id) ON DELETE CASCADE,
chat_id BIGINT NOT NULL REFERENCES tgchats(id) ON DELETE CASCADE,
reason TEXT NOT NULL,
chat_id UUID NOT NULL REFERENCES tgchats(slice_id) ON DELETE CASCADE,
created_at TIMESTAMP DEFAULT NOW() NOT NULL
);

View File

@ -1,8 +1,17 @@
from sqlalchemy.orm import Mapped, mapped_column
from typing import TYPE_CHECKING
from sqlalchemy.orm import Mapped, relationship
from src.core.database import Base
if TYPE_CHECKING:
from src.core.database import TgMessage
class TgChat(Base):
chat_type: Mapped[str]
title: Mapped[str]
message_relationship: Mapped[list["TgMessage"]] = relationship(
backref="tgchat_relationship",
)

View File

@ -1,10 +1,15 @@
from datetime import datetime
from typing import TYPE_CHECKING
from uuid import UUID
from sqlalchemy import ForeignKey, func
from sqlalchemy.orm import Mapped, mapped_column
from sqlalchemy.orm import Mapped, mapped_column, relationship
from src.core.database import Base
if TYPE_CHECKING:
from src.core.database import User, TgChat
class Success(Base):
__tablename__ = 'successed'
@ -16,10 +21,18 @@ class Success(Base):
user_id: Mapped[str] = mapped_column(
ForeignKey('users.id', ondelete='CASCADE'),
)
chat_id: Mapped[int] = mapped_column(
ForeignKey('tgchats.id', ondelete='CASCADE'),
slice_id: Mapped[UUID] = mapped_column(
ForeignKey('tgchats.slice_id', ondelete='CASCADE'),
)
reason: Mapped[str]
created_at: Mapped[datetime] = mapped_column(
default=datetime.utcnow,
server_default=func.now()
)
user_relationship: Mapped["User"] = relationship(
backref="success_relationship"
)
chat_relationship: Mapped["TgChat"] = relationship(
backref="success_relationship"
)

View File

@ -5,6 +5,7 @@ from src.core.common.constants import PydanticEnvPrefixEnum, EnvFileLocation, En
from src.core.settings.database import DatabaseSettings
from src.core.settings.gemini import GeminiSettings
from src.core.settings.groq import GroqSettings
from src.core.settings.notify import NotifySettings
from src.core.settings.rabbitmq import RabbitmqSettings
from src.core.settings.redis import RedisSettings
@ -23,6 +24,8 @@ class Settings(BaseSettings):
POSTGRES: DatabaseSettings
NOTIFY: NotifySettings = NotifySettings()
GROQ: GroqSettings
GEMINI: GeminiSettings
REDIS: RedisSettings

View File

@ -0,0 +1,5 @@
from pydantic import BaseModel
class NotifySettings(BaseModel):
CHAT_ID: int = -4781950241

View File

@ -2,13 +2,17 @@ import uuid
from pyrogram.types.user_and_chats import User as PyroUser, Chat as PyroChat
from src.core.database import TgChat, User
from src.core.database import TgChat, User, TgMessage
from src.core.database.successes import Success
from src.core.rabbitmq.connect import message_handler_publisher
from src.core.redis_helper.redis_connect import redis_client
from src.core.settings.base import settings
from src.core.tg_service.constants import MESSAGE_CHANG_SIZE
from src.core.tg_service.schemas import UserFromMessageSchema, MessagesForSendToWorkersSchema, MessageFromChatSchema
from src.core.database.connect import db_helper
from src.core.tg_service import crud as tg_crud
from src.core.tg_service.utils import create_and_format_message
from src.main import app
async def check_user_exists(
@ -88,4 +92,21 @@ async def check_chunk_state_and_publish(
data[chat_id].append(message_schema)
async def notify_for_success(
messages: list[TgMessage],
chat: TgChat,
success_reason: Success,
user_model: User,
) -> None:
message = create_and_format_message(
messages=messages,
reason=success_reason.reason,
user_model=user_model,
chat=chat,
)
await app.send_message(
chat_id=settings.NOTIFY.CHAT_ID,
message=message,
parse_mode="Markdown",
)

View File

@ -1,6 +1,9 @@
from pyrogram.types import Message
from pyrogram.enums import ChatType
from src.core.database import TgMessage, User, TgChat
def check_message_condition(
message: Message,
) -> bool:
@ -11,3 +14,28 @@ def check_message_condition(
)
return all(conditions)
def create_and_format_message(
messages: list[TgMessage],
reason: str,
chat: TgChat,
user_model: User,
) -> str:
if user_model.username:
user_link = f"{user_model.username}](tg://user?id={user_model.id})"
else:
user_link = f"ID: {user_model.id}"
messages_text = "\n".join(
f"{msg.message_time.isoformat()}: {msg.text}\n" for msg in messages
)
chat_link = f"https://t.me/c/{str(chat.id)[4:]}" if str(chat.id).startswith(
"-100") else f"https://t.me/{chat.id}"
return f"""🔥 *Найдена успешка!*
👤 *Пользователь:* {user_link}
🐩 *Чат*: [{chat.title}]({chat_link})
📌 *Причина:* {reason}
📝 *Диалог:* {messages_text}
"""

View File

@ -1,6 +1,10 @@
from sqlalchemy import insert
from uuid import UUID
from sqlalchemy import insert, select
from sqlalchemy.orm import selectinload, joinedload
from sqlalchemy.ext.asyncio import AsyncSession
from src.core.database import TgMessage, TgChat
from src.core.workers.schemas import ResponseFromGeminiSchema
from src.core.database.successes import Success
@ -19,3 +23,21 @@ async def bulk_create_success_reasons(
)
await session.execute(stmt)
await session.commit()
async def get_messages_by_slice_id(
session: AsyncSession,
slice_id: UUID
) -> Success:
stmt = (
select(Success)
.options(
joinedload(Success.user_relationship),
joinedload(Success.chat_relationship)
.selectinload(TgChat.message_relationship)
)
.where(Success.slice_id == slice_id)
)
return await session.scalar(stmt)

View File

@ -4,6 +4,7 @@ from sqlalchemy.ext.asyncio import AsyncSession
from faststream import Depends
from src.core.tg_service.service import notify_for_success
from src.core.workers.schemas import ResponseFromGeminiSchema
from src.core.database.connect import db_helper
from src.core.rabbitmq.connect import success_gemini_subscriber
@ -20,5 +21,21 @@ async def create_success_record(
session=session,
)
for success_message in message.success:
success_mod_with_relation = await workers_crud.get_messages_by_slice_id(
session=session,
slice_id=success_message.slice_id,
)
await notify_for_success(
messages=success_mod_with_relation.chat_relationship.message_relationship,
chat=success_mod_with_relation.chat_relationship,
user_model=success_mod_with_relation.user_relationship,
success_reason=success_mod_with_relation,,
)

View File

@ -1,9 +1,9 @@
from pydantic import BaseModel, PositiveInt, NegativeInt
from pydantic import BaseModel, PositiveInt, NegativeInt, UUID4
class SuccessChatFromAiSchema(BaseModel):
user_id: PositiveInt | None
chat_id: NegativeInt | None
slice_id: UUID4 | None
reason: str | None