Files
tgex-backend/tg_bot/bot/forward_system_event.go
Artem Tsyrulnikov 7f6527652b refactor
2026-01-20 14:05:38 +03:00

197 lines
5.4 KiB
Go

package bot
import (
"context"
"fmt"
"github.com/NicoNex/echotron/v3"
"github.com/rs/zerolog/log"
)
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")
}
}
}
}