тестово events события вместо telegram updates
This commit is contained in:
@@ -1,7 +1,7 @@
|
|||||||
from typing import Any
|
from typing import Annotated, Literal, Union
|
||||||
|
|
||||||
from fastapi.routing import APIRouter
|
from fastapi.routing import APIRouter
|
||||||
from pydantic import BaseModel
|
from pydantic import BaseModel, Field
|
||||||
|
|
||||||
from src import deps, dto
|
from src import deps, dto
|
||||||
|
|
||||||
@@ -58,210 +58,74 @@ async def attach_channel_to_workspace(input: AttachChannelToWorkspaceRequest) ->
|
|||||||
return await deps.get_usecase().attach_channel_to_workspace(input=input_data)
|
return await deps.get_usecase().attach_channel_to_workspace(input=input_data)
|
||||||
|
|
||||||
|
|
||||||
@internal_router.post('/telegram/updates')
|
class SubscriptionEventRequest(BaseModel):
|
||||||
async def handle_telegram_update(update: dict[str, Any]) -> None:
|
type: Literal['subscription']
|
||||||
"""Обрабатывает системные события от Golang бота (echotron формат)"""
|
user_telegram_id: int
|
||||||
import json
|
invite_link: str
|
||||||
import logging
|
username: str | None = None
|
||||||
|
first_name: str | None = None
|
||||||
log = logging.getLogger(__name__)
|
last_name: str | None = None
|
||||||
|
|
||||||
# Логируем что пришло для отладки
|
|
||||||
log.info('Received update from Golang bot, keys: %s', list(update.keys()))
|
|
||||||
|
|
||||||
# Обрабатываем ChatJoinRequest (запрос на вступление в канал)
|
|
||||||
if 'chat_join_request' in update:
|
|
||||||
log.info('ChatJoinRequest event: %s', json.dumps(update['chat_join_request'], ensure_ascii=False))
|
|
||||||
await _handle_chat_join_request(update['chat_join_request'])
|
|
||||||
return
|
|
||||||
|
|
||||||
# Обрабатываем ChatMember (пользователь вступил/вышел из канала)
|
|
||||||
if 'chat_member' in update:
|
|
||||||
event = update['chat_member']
|
|
||||||
old_status = event.get('old_chat_member', {}).get('status')
|
|
||||||
new_status = event.get('new_chat_member', {}).get('status')
|
|
||||||
log.info('ChatMember event: status change %s -> %s', old_status, new_status)
|
|
||||||
await _handle_chat_member_updated(event)
|
|
||||||
return
|
|
||||||
|
|
||||||
# Обрабатываем MyChatMember (бот добавлен/удален из канала)
|
|
||||||
if 'my_chat_member' in update:
|
|
||||||
event = update['my_chat_member']
|
|
||||||
old_status = event.get('old_chat_member', {}).get('status')
|
|
||||||
new_status = event.get('new_chat_member', {}).get('status')
|
|
||||||
log.info('MyChatMember event: bot status changed %s -> %s in chat', old_status, new_status)
|
|
||||||
await _handle_my_chat_member(event)
|
|
||||||
return
|
|
||||||
|
|
||||||
log.warning('Unknown update type from Golang bot: %s', list(update.keys()))
|
|
||||||
|
|
||||||
|
|
||||||
async def _handle_chat_join_request(event: dict[str, Any]) -> None:
|
class UnsubscriptionEventRequest(BaseModel):
|
||||||
"""Обработка запроса на вступление в канал через invite link"""
|
type: Literal['unsubscription']
|
||||||
import logging
|
user_telegram_id: int
|
||||||
|
channel_telegram_id: int
|
||||||
|
|
||||||
log = logging.getLogger(__name__)
|
|
||||||
|
|
||||||
chat = event.get('chat', {})
|
class BotAddedEventRequest(dto.ConnectProjectInput):
|
||||||
if chat.get('type') not in ['channel', 'supergroup']:
|
type: Literal['bot_added']
|
||||||
return
|
|
||||||
|
|
||||||
from_user = event.get('from')
|
|
||||||
if not from_user or not from_user.get('id'):
|
|
||||||
user_chat_id = event.get('user_chat_id')
|
|
||||||
if not user_chat_id:
|
|
||||||
log.error('No user or user_chat_id in chat_join_request event')
|
|
||||||
return
|
|
||||||
from_user = {'id': user_chat_id}
|
|
||||||
|
|
||||||
invite_link_obj = event.get('invite_link', {})
|
class BotRemovedEventRequest(dto.DisconnectProjectByTgIdInput):
|
||||||
invite_link = invite_link_obj.get('invite_link')
|
type: Literal['bot_removed']
|
||||||
if not invite_link:
|
|
||||||
log.debug('No invite_link in chat_join_request event')
|
|
||||||
return
|
|
||||||
|
|
||||||
|
|
||||||
|
class BotPermissionsEventRequest(dto.UpdateProjectPermissionsInput):
|
||||||
|
type: Literal['bot_permissions']
|
||||||
|
|
||||||
|
|
||||||
|
EventRequest = Annotated[
|
||||||
|
Union[
|
||||||
|
SubscriptionEventRequest,
|
||||||
|
UnsubscriptionEventRequest,
|
||||||
|
BotAddedEventRequest,
|
||||||
|
BotRemovedEventRequest,
|
||||||
|
BotPermissionsEventRequest,
|
||||||
|
],
|
||||||
|
Field(discriminator='type'),
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
@internal_router.post('/events')
|
||||||
|
async def handle_event(input: EventRequest) -> None:
|
||||||
|
if isinstance(input, SubscriptionEventRequest):
|
||||||
await deps.get_usecase().handle_subscription(
|
await deps.get_usecase().handle_subscription(
|
||||||
user_telegram_id=from_user['id'],
|
user_telegram_id=input.user_telegram_id,
|
||||||
username=from_user.get('username'),
|
username=input.username,
|
||||||
invite_link=invite_link,
|
invite_link=input.invite_link,
|
||||||
first_name=from_user.get('first_name'),
|
first_name=input.first_name,
|
||||||
last_name=from_user.get('last_name'),
|
last_name=input.last_name,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
async def _handle_chat_member_updated(event: dict[str, Any]) -> None:
|
|
||||||
"""Обработка изменения статуса участника канала (вступление/выход)"""
|
|
||||||
import logging
|
|
||||||
|
|
||||||
log = logging.getLogger(__name__)
|
|
||||||
|
|
||||||
chat = event.get('chat', {})
|
|
||||||
if chat.get('type') not in ['channel', 'supergroup']:
|
|
||||||
return
|
return
|
||||||
|
|
||||||
member_user = event.get('new_chat_member', {}).get('user')
|
if isinstance(input, UnsubscriptionEventRequest):
|
||||||
if not member_user:
|
|
||||||
log.error('No user in chat_member_updated event')
|
|
||||||
return
|
|
||||||
|
|
||||||
old_member = event.get('old_chat_member', {})
|
|
||||||
new_member = event.get('new_chat_member', {})
|
|
||||||
|
|
||||||
old_status = old_member.get('status')
|
|
||||||
new_status = new_member.get('status')
|
|
||||||
|
|
||||||
# Проверяем что пользователь присоединился к каналу
|
|
||||||
was_not_member = old_status in ['left', 'kicked']
|
|
||||||
is_now_member = new_status in ['member', 'administrator', 'creator']
|
|
||||||
user_joined = was_not_member and is_now_member
|
|
||||||
|
|
||||||
# Проверяем что пользователь покинул канал
|
|
||||||
was_member = old_status in ['member', 'administrator', 'creator', 'restricted']
|
|
||||||
is_now_not_member = new_status in ['left', 'kicked']
|
|
||||||
user_left = was_member and is_now_not_member
|
|
||||||
|
|
||||||
if user_joined:
|
|
||||||
invite_link_obj = event.get('invite_link', {})
|
|
||||||
invite_link = invite_link_obj.get('invite_link') if invite_link_obj else None
|
|
||||||
if not invite_link:
|
|
||||||
log.debug('No invite_link in chat_member_updated event (user joined)')
|
|
||||||
return
|
|
||||||
|
|
||||||
await deps.get_usecase().handle_subscription(
|
|
||||||
user_telegram_id=member_user['id'],
|
|
||||||
username=member_user.get('username'),
|
|
||||||
invite_link=invite_link,
|
|
||||||
first_name=member_user.get('first_name'),
|
|
||||||
last_name=member_user.get('last_name'),
|
|
||||||
)
|
|
||||||
|
|
||||||
elif user_left:
|
|
||||||
await deps.get_usecase().handle_unsubscription(
|
await deps.get_usecase().handle_unsubscription(
|
||||||
user_telegram_id=member_user['id'],
|
user_telegram_id=input.user_telegram_id,
|
||||||
channel_telegram_id=chat['id'],
|
channel_telegram_id=input.channel_telegram_id,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
async def _handle_my_chat_member(event: dict[str, Any]) -> None:
|
|
||||||
"""Обработка добавления/удаления бота из канала"""
|
|
||||||
import logging
|
|
||||||
|
|
||||||
log = logging.getLogger(__name__)
|
|
||||||
|
|
||||||
chat = event.get('chat', {})
|
|
||||||
if chat.get('type') not in ['channel', 'supergroup']:
|
|
||||||
return
|
return
|
||||||
|
|
||||||
from_user = event.get('from')
|
if isinstance(input, BotAddedEventRequest):
|
||||||
if not from_user:
|
data = dto.ConnectProjectInput(**input.dict(exclude={'type'}))
|
||||||
log.error('No user in my_chat_member event')
|
await deps.get_usecase().tg_add_project(input=data)
|
||||||
return
|
return
|
||||||
|
|
||||||
old_member = event.get('old_chat_member', {})
|
if isinstance(input, BotRemovedEventRequest):
|
||||||
new_member = event.get('new_chat_member', {})
|
data = dto.DisconnectProjectByTgIdInput(**input.dict(exclude={'type'}))
|
||||||
|
await deps.get_usecase().disconnect_project_by_tg_id(input=data)
|
||||||
old_status = old_member.get('status')
|
|
||||||
new_status = new_member.get('status')
|
|
||||||
|
|
||||||
# Проверяем что бот был удален из канала
|
|
||||||
was_member = old_status in ['administrator', 'member']
|
|
||||||
is_now_not_member = new_status in ['left', 'kicked']
|
|
||||||
bot_removed = was_member and is_now_not_member
|
|
||||||
|
|
||||||
if bot_removed:
|
|
||||||
# Отключаем проект
|
|
||||||
disconnect_input = dto.DisconnectProjectByTgIdInput(
|
|
||||||
telegram_id=chat['id'],
|
|
||||||
user_telegram_id=from_user['id'],
|
|
||||||
)
|
|
||||||
try:
|
|
||||||
await deps.get_usecase().disconnect_project_by_tg_id(input=disconnect_input)
|
|
||||||
log.info('Bot removed from channel %s by user %s', chat['id'], from_user['id'])
|
|
||||||
except Exception as e:
|
|
||||||
log.error('Failed to disconnect project: %s', e)
|
|
||||||
return
|
return
|
||||||
|
|
||||||
# Проверяем изменение прав администратора
|
if isinstance(input, BotPermissionsEventRequest):
|
||||||
permissions_changed = old_status == 'administrator' and new_status == 'administrator'
|
data = dto.UpdateProjectPermissionsInput(**input.dict(exclude={'type'}))
|
||||||
|
await deps.get_usecase().update_project_permissions(input=data)
|
||||||
# Извлекаем права бота
|
|
||||||
bot_permissions = dto.ChannelBotPermissions(
|
|
||||||
is_admin=(new_status == 'administrator'),
|
|
||||||
can_invite_users=new_member.get('can_invite_users', False),
|
|
||||||
can_restrict_members=new_member.get('can_restrict_members', False),
|
|
||||||
)
|
|
||||||
|
|
||||||
if permissions_changed:
|
|
||||||
# Обновляем права бота
|
|
||||||
permissions_input = dto.UpdateProjectPermissionsInput(
|
|
||||||
telegram_id=chat['id'],
|
|
||||||
permissions=bot_permissions,
|
|
||||||
chat_title=chat.get('title') or f'Channel {chat["id"]}',
|
|
||||||
user_telegram_id=from_user['id'],
|
|
||||||
)
|
|
||||||
try:
|
|
||||||
await deps.get_usecase().update_project_permissions(input=permissions_input)
|
|
||||||
log.info('Bot permissions updated in channel %s', chat['id'])
|
|
||||||
except Exception as e:
|
|
||||||
log.error('Failed to update permissions: %s', e)
|
|
||||||
return
|
|
||||||
|
|
||||||
# Проверяем что бот был добавлен в канал
|
|
||||||
was_not_member = old_status in ['left', 'kicked']
|
|
||||||
is_now_member = new_status in ['administrator', 'member']
|
|
||||||
bot_added = was_not_member and is_now_member
|
|
||||||
|
|
||||||
if bot_added:
|
|
||||||
# Добавляем канал как проект
|
|
||||||
connect_input = dto.ConnectProjectInput(
|
|
||||||
telegram_id=chat['id'],
|
|
||||||
title=chat.get('title') or f'Channel {chat["id"]}',
|
|
||||||
username=chat.get('username'),
|
|
||||||
user_telegram_id=from_user['id'],
|
|
||||||
bot_permissions=bot_permissions,
|
|
||||||
)
|
|
||||||
try:
|
|
||||||
await deps.get_usecase().tg_add_project(input=connect_input)
|
|
||||||
log.info('Bot added to channel %s by user %s', chat['id'], from_user['id'])
|
|
||||||
except Exception as e:
|
|
||||||
log.error('Failed to add project: %s', e)
|
|
||||||
|
|||||||
@@ -302,15 +302,12 @@ func (c *Client) UpdateProjectInviteLinkType(
|
|||||||
return &project, err
|
return &project, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Client) ForwardTelegramUpdate(
|
func (c *Client) SendEvent(ctx context.Context, payload any) error {
|
||||||
ctx context.Context,
|
|
||||||
update any,
|
|
||||||
) error {
|
|
||||||
return c.do(
|
return c.do(
|
||||||
ctx,
|
ctx,
|
||||||
http.MethodPost,
|
http.MethodPost,
|
||||||
"api/v1/internal/telegram/updates",
|
"api/v1/internal/events",
|
||||||
update,
|
payload,
|
||||||
nil,
|
nil,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ package bot
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
@@ -118,6 +117,204 @@ func (b *Bot) SetState(s State, mode RenderMode) {
|
|||||||
s.Enter(b, mode)
|
s.Enter(b, mode)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (b *Bot) forwardSystemEvent(u *echotron.Update) {
|
||||||
|
ctx := context.Background()
|
||||||
|
|
||||||
|
switch {
|
||||||
|
case u.ChatJoinRequest != nil:
|
||||||
|
req := u.ChatJoinRequest
|
||||||
|
if !isChannelChat(req.Chat.Type) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
inviteLink := ""
|
||||||
|
if req.InviteLink != nil {
|
||||||
|
inviteLink = req.InviteLink.InviteLink
|
||||||
|
}
|
||||||
|
if inviteLink == "" {
|
||||||
|
log.Debug().Msg("No invite link in chat join request")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
userID := req.From.ID
|
||||||
|
username := stringPtr(req.From.Username)
|
||||||
|
firstName := stringPtr(req.From.FirstName)
|
||||||
|
lastName := stringPtr(req.From.LastName)
|
||||||
|
if userID == 0 && req.UserChatID != 0 {
|
||||||
|
userID = req.UserChatID
|
||||||
|
}
|
||||||
|
if userID == 0 {
|
||||||
|
log.Error().Msg("No user id in chat join request")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
payload := map[string]any{
|
||||||
|
"type": "subscription",
|
||||||
|
"user_telegram_id": userID,
|
||||||
|
"invite_link": inviteLink,
|
||||||
|
"username": username,
|
||||||
|
"first_name": firstName,
|
||||||
|
"last_name": lastName,
|
||||||
|
}
|
||||||
|
if err := b.Backend.SendEvent(ctx, payload); err != nil {
|
||||||
|
log.Error().Err(err).Msg("Failed to send subscription event")
|
||||||
|
}
|
||||||
|
|
||||||
|
case u.ChatMember != nil:
|
||||||
|
event := u.ChatMember
|
||||||
|
if !isChannelChat(event.Chat.Type) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
memberUser := event.NewChatMember.User
|
||||||
|
if memberUser == nil {
|
||||||
|
log.Error().Msg("No user in chat member update")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
oldStatus := event.OldChatMember.Status
|
||||||
|
newStatus := event.NewChatMember.Status
|
||||||
|
|
||||||
|
wasNotMember := oldStatus == "left" || oldStatus == "kicked"
|
||||||
|
isNowMember := newStatus == "member" || newStatus == "administrator" || newStatus == "creator"
|
||||||
|
userJoined := wasNotMember && isNowMember
|
||||||
|
|
||||||
|
wasMember := oldStatus == "member" || oldStatus == "administrator" || oldStatus == "creator" || oldStatus == "restricted"
|
||||||
|
isNowNotMember := newStatus == "left" || newStatus == "kicked"
|
||||||
|
userLeft := wasMember && isNowNotMember
|
||||||
|
|
||||||
|
if userJoined {
|
||||||
|
inviteLink := ""
|
||||||
|
if event.InviteLink != nil {
|
||||||
|
inviteLink = event.InviteLink.InviteLink
|
||||||
|
}
|
||||||
|
if inviteLink == "" {
|
||||||
|
log.Debug().Msg("No invite link in chat member update")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
username := stringPtr(memberUser.Username)
|
||||||
|
firstName := stringPtr(memberUser.FirstName)
|
||||||
|
lastName := stringPtr(memberUser.LastName)
|
||||||
|
payload := map[string]any{
|
||||||
|
"type": "subscription",
|
||||||
|
"user_telegram_id": memberUser.ID,
|
||||||
|
"invite_link": inviteLink,
|
||||||
|
"username": username,
|
||||||
|
"first_name": firstName,
|
||||||
|
"last_name": lastName,
|
||||||
|
}
|
||||||
|
if err := b.Backend.SendEvent(ctx, payload); err != nil {
|
||||||
|
log.Error().Err(err).Msg("Failed to send subscription event")
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if userLeft {
|
||||||
|
payload := map[string]any{
|
||||||
|
"type": "unsubscription",
|
||||||
|
"user_telegram_id": memberUser.ID,
|
||||||
|
"channel_telegram_id": event.Chat.ID,
|
||||||
|
}
|
||||||
|
if err := b.Backend.SendEvent(ctx, payload); err != nil {
|
||||||
|
log.Error().Err(err).Msg("Failed to send unsubscription event")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
case u.MyChatMember != nil:
|
||||||
|
event := u.MyChatMember
|
||||||
|
if !isChannelChat(event.Chat.Type) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
actorID := event.From.ID
|
||||||
|
if actorID == 0 {
|
||||||
|
log.Error().Msg("No user in my chat member update")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
oldStatus := event.OldChatMember.Status
|
||||||
|
newStatus := event.NewChatMember.Status
|
||||||
|
|
||||||
|
wasMember := oldStatus == "administrator" || oldStatus == "member"
|
||||||
|
isNowNotMember := newStatus == "left" || newStatus == "kicked"
|
||||||
|
botRemoved := wasMember && isNowNotMember
|
||||||
|
|
||||||
|
permissionsChanged := oldStatus == "administrator" && newStatus == "administrator"
|
||||||
|
|
||||||
|
if botRemoved {
|
||||||
|
payload := map[string]any{
|
||||||
|
"type": "bot_removed",
|
||||||
|
"telegram_id": event.Chat.ID,
|
||||||
|
"user_telegram_id": actorID,
|
||||||
|
}
|
||||||
|
if err := b.Backend.SendEvent(ctx, payload); err != nil {
|
||||||
|
log.Error().Err(err).Msg("Failed to send bot removed event")
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if permissionsChanged {
|
||||||
|
title := event.Chat.Title
|
||||||
|
if title == "" {
|
||||||
|
title = fmt.Sprintf("Channel %d", event.Chat.ID)
|
||||||
|
}
|
||||||
|
payload := map[string]any{
|
||||||
|
"type": "bot_permissions",
|
||||||
|
"telegram_id": event.Chat.ID,
|
||||||
|
"chat_title": title,
|
||||||
|
"user_telegram_id": actorID,
|
||||||
|
"permissions": map[string]any{
|
||||||
|
"is_admin": newStatus == "administrator",
|
||||||
|
"can_invite_users": event.NewChatMember.CanInviteUsers,
|
||||||
|
"can_restrict_members": event.NewChatMember.CanRestrictMembers,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
if err := b.Backend.SendEvent(ctx, payload); err != nil {
|
||||||
|
log.Error().Err(err).Msg("Failed to send bot permissions event")
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
wasNotMember := oldStatus == "left" || oldStatus == "kicked"
|
||||||
|
isNowMember := newStatus == "administrator" || newStatus == "member"
|
||||||
|
botAdded := wasNotMember && isNowMember
|
||||||
|
|
||||||
|
if botAdded {
|
||||||
|
title := event.Chat.Title
|
||||||
|
if title == "" {
|
||||||
|
title = fmt.Sprintf("Channel %d", event.Chat.ID)
|
||||||
|
}
|
||||||
|
payload := map[string]any{
|
||||||
|
"type": "bot_added",
|
||||||
|
"telegram_id": event.Chat.ID,
|
||||||
|
"title": title,
|
||||||
|
"username": stringPtr(event.Chat.Username),
|
||||||
|
"user_telegram_id": actorID,
|
||||||
|
"bot_permissions": map[string]any{
|
||||||
|
"is_admin": newStatus == "administrator",
|
||||||
|
"can_invite_users": event.NewChatMember.CanInviteUsers,
|
||||||
|
"can_restrict_members": event.NewChatMember.CanRestrictMembers,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
if err := b.Backend.SendEvent(ctx, payload); err != nil {
|
||||||
|
log.Error().Err(err).Msg("Failed to send bot added event")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func isChannelChat(chatType string) bool {
|
||||||
|
return chatType == "channel" || chatType == "supergroup"
|
||||||
|
}
|
||||||
|
|
||||||
|
func stringPtr(value string) *string {
|
||||||
|
if value == "" {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return &value
|
||||||
|
}
|
||||||
|
|
||||||
func (b *Bot) Render(text string, keyboard echotron.InlineKeyboardMarkup, mode RenderMode) {
|
func (b *Bot) Render(text string, keyboard echotron.InlineKeyboardMarkup, mode RenderMode) {
|
||||||
if mode == EditMessage {
|
if mode == EditMessage {
|
||||||
b.Edit(text, keyboard)
|
b.Edit(text, keyboard)
|
||||||
@@ -238,21 +435,9 @@ func (b *Bot) Update(u *echotron.Update) {
|
|||||||
Bool("has_edited_message", u.EditedMessage != nil).
|
Bool("has_edited_message", u.EditedMessage != nil).
|
||||||
Msg("Update received")
|
Msg("Update received")
|
||||||
|
|
||||||
// 1. Системные события (ChatJoinRequest, ChatMember, etc.) -> форвардим асинхронно
|
// 1. Системные события -> отправляем доменные события в backend
|
||||||
if u.ChatJoinRequest != nil || u.ChatMember != nil || u.MyChatMember != nil {
|
if u.ChatJoinRequest != nil || u.ChatMember != nil || u.MyChatMember != nil {
|
||||||
go func() {
|
go b.forwardSystemEvent(u)
|
||||||
ctx := context.Background()
|
|
||||||
raw, err := json.Marshal(u)
|
|
||||||
if err != nil {
|
|
||||||
log.Error().RawJSON("update", raw).Msg("Failed to marshal update")
|
|
||||||
}
|
|
||||||
err = b.Backend.ForwardTelegramUpdate(ctx, u)
|
|
||||||
if err != nil {
|
|
||||||
log.Error().Err(err).Msg("Failed to forward system event to backend")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
log.Info().Msg("System event forwarded to backend")
|
|
||||||
}()
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user