feat: sending and receiving messages with files, editing text messages
This commit is contained in:
111
services/chat.py
111
services/chat.py
@@ -1,14 +1,15 @@
|
||||
from uuid import UUID
|
||||
|
||||
import requests
|
||||
from aiohttp import ClientConnectorError
|
||||
from fastapi import HTTPException, UploadFile
|
||||
from sqlalchemy import select
|
||||
from sqlalchemy.orm import joinedload
|
||||
from starlette.responses import StreamingResponse
|
||||
|
||||
from backend.config import CHAT_CONNECTOR_API_KEY
|
||||
from backend.config import CHAT_CONNECTOR_API_KEY, CHAT_TELEGRAM_BOT_TOKEN
|
||||
from external.chat.chat_client import ChatClient
|
||||
from external.chat.schemas import ExternalCreateGroupRequest, ExternalCreateTopicRequest
|
||||
from external.chat.schemas import *
|
||||
from external.kafka.services.producer_service import ProducerService
|
||||
from models import Message, Chat, MessageStatus, TgGroup, Client, Card
|
||||
from models import Message, Chat, MessageStatus, TgGroup, Client, Card, MessageFile
|
||||
from schemas.chat import *
|
||||
from services.base import BaseService
|
||||
|
||||
@@ -161,10 +162,10 @@ class ChatService(BaseService):
|
||||
messages = (await self.session.scalars(stmt)).all()
|
||||
return GetMessagesResponse(messages=messages)
|
||||
|
||||
async def send_message(self, request: SendMessageRequest) -> SendMessageResponse:
|
||||
async def send_message(self, request: SendTextMessageRequest) -> SendTextMessageResponse:
|
||||
chat: Optional[Chat] = await self.session.get(Chat, request.message.chat_id)
|
||||
if not chat:
|
||||
return SendMessageResponse(ok=False, message=f'Чат с ID: {request.message.chat_id} не найден')
|
||||
return SendTextMessageResponse(ok=False, message=f'Чат с ID: {request.message.chat_id} не найден')
|
||||
|
||||
message = Message(
|
||||
text=request.message.text,
|
||||
@@ -182,7 +183,67 @@ class ChatService(BaseService):
|
||||
message.id,
|
||||
)
|
||||
|
||||
return SendMessageResponse(ok=ok, message=message)
|
||||
return SendTextMessageResponse(ok=ok, message=message)
|
||||
|
||||
async def repeat_sending_message(
|
||||
self,
|
||||
request: RepeatSendingTextMessageRequest,
|
||||
) -> RepeatSendingTextMessageResponse:
|
||||
message: Optional[Message] = await self._get_message_by_id(request.message.id)
|
||||
if not message:
|
||||
return RepeatSendingTextMessageResponse(ok=False, message=f'Сообщение с ID: {request.message.id} не найдено')
|
||||
|
||||
ok, msg = await ProducerService.send_message_to_connector(
|
||||
request.message.text,
|
||||
message.chat.tg_group_id,
|
||||
message.chat.tg_topic_id,
|
||||
message.id,
|
||||
)
|
||||
|
||||
if ok:
|
||||
message.status = MessageStatus.sending
|
||||
await self.session.commit()
|
||||
|
||||
return RepeatSendingTextMessageResponse(ok=ok, message=msg)
|
||||
|
||||
async def send_messages_with_files(
|
||||
self,
|
||||
files: list[UploadFile],
|
||||
chat_id: int,
|
||||
caption: str,
|
||||
) -> LoadMessagesResponse:
|
||||
chat: Optional[Chat] = await self.session.get(Chat, chat_id)
|
||||
if not chat:
|
||||
return SendTextMessageResponse(ok=False, message=f'Чат с ID: {chat_id} не найден')
|
||||
|
||||
chat_client = ChatClient(api_key=CHAT_CONNECTOR_API_KEY)
|
||||
response = await chat_client.send_messages_with_files(
|
||||
str(chat.tg_group_id),
|
||||
chat.tg_topic_id,
|
||||
caption,
|
||||
files
|
||||
)
|
||||
|
||||
last_message = None
|
||||
for file_schema in response.files:
|
||||
file = MessageFile(**file_schema.model_dump())
|
||||
self.session.add(file)
|
||||
|
||||
message = Message(
|
||||
text='',
|
||||
created_at=datetime.now(),
|
||||
chat_id=chat_id,
|
||||
status=MessageStatus.success,
|
||||
file=file,
|
||||
)
|
||||
last_message = message
|
||||
self.session.add(message)
|
||||
|
||||
if last_message:
|
||||
last_message.text = caption
|
||||
await self.session.commit()
|
||||
|
||||
return LoadMessagesResponse(ok=response.ok, message=response.message)
|
||||
|
||||
async def _get_message_by_id(self, message_id: int) -> Optional[Message]:
|
||||
stmt = (
|
||||
@@ -203,7 +264,35 @@ class ChatService(BaseService):
|
||||
message.chat.tg_group_id,
|
||||
)
|
||||
|
||||
message.is_deleted = True
|
||||
await self.session.commit()
|
||||
|
||||
return DeleteMessageResponse(ok=ok, message=msg)
|
||||
|
||||
async def edit_message(self, request: EditMessageRequest) -> EditMessageResponse:
|
||||
message: Optional[Message] = await self._get_message_by_id(request.message.id)
|
||||
if not message:
|
||||
return EditMessageResponse(ok=False, message=f'Сообщение с ID: {request.message.id} не найдено')
|
||||
|
||||
ok, msg = await ProducerService.send_message_editing_to_connector(
|
||||
message.id,
|
||||
message.tg_message_id,
|
||||
message.chat.tg_group_id,
|
||||
request.message.text,
|
||||
)
|
||||
|
||||
return EditMessageResponse(ok=ok, message=msg)
|
||||
|
||||
async def get_tg_file(self, file_id: int) -> StreamingResponse:
|
||||
file: Optional[MessageFile] = await self.session.get(MessageFile, file_id)
|
||||
if not file:
|
||||
raise HTTPException(status_code=404, detail=f'Файл с ID {file_id} не найден')
|
||||
|
||||
url: str = f'https://api.telegram.org/file/bot{CHAT_TELEGRAM_BOT_TOKEN}/{file.file_path}'
|
||||
print(f'URL = {url}')
|
||||
|
||||
response = requests.get(url, stream=True)
|
||||
|
||||
if response.status_code != 200:
|
||||
raise HTTPException(status_code=response.status_code, detail="Error fetching file")
|
||||
|
||||
content_type = response.headers.get("Content-Type", "application/octet-stream")
|
||||
|
||||
return StreamingResponse(response.iter_content(chunk_size=8192), media_type=content_type)
|
||||
|
||||
Reference in New Issue
Block a user