package notificationimp import ( "encoding/json" "io" "net/http" "github.com/tech/sendico/notification/internal/server/notificationimp/telegram" tnotifications "github.com/tech/sendico/pkg/messaging/notifications/telegram" "github.com/tech/sendico/pkg/model" "github.com/tech/sendico/pkg/mservice" "go.uber.org/zap" ) const telegramWebhookMaxBody = 1 << 20 func (a *NotificationAPI) handleTelegramWebhook(w http.ResponseWriter, r *http.Request) { if a == nil { w.WriteHeader(http.StatusNoContent) return } if a.producer == nil { if a.logger != nil { a.logger.Warn("Telegram webhook ignored: messaging producer is not configured") } w.WriteHeader(http.StatusServiceUnavailable) return } var update telegram.Update dec := json.NewDecoder(io.LimitReader(r.Body, telegramWebhookMaxBody)) if err := dec.Decode(&update); err != nil { if a.logger != nil { a.logger.Warn("Failed to decode telegram webhook update", zap.Error(err)) } w.WriteHeader(http.StatusBadRequest) return } if a.logger != nil { fields := []zap.Field{ zap.Int64("update_id", update.UpdateID), zap.Bool("has_message", update.Message != nil), } if update.Message != nil { fields = append(fields, zap.Int64("message_id", update.Message.MessageID), zap.Int64("chat_id", update.Message.Chat.ID), zap.Int("text_length", len(update.Message.Text)), ) if update.Message.From != nil { fields = append(fields, zap.Int64("from_user_id", update.Message.From.ID)) } if update.Message.ReplyToMessage != nil { fields = append(fields, zap.Int64("reply_to_message_id", update.Message.ReplyToMessage.MessageID)) } } a.logger.Info("Telegram webhook update received", fields...) } payload := &model.TelegramWebhookUpdate{ UpdateID: update.UpdateID, } if update.Message != nil { payload.Message = update.Message.ToModel() } env := tnotifications.TelegramUpdate(string(mservice.Notifications), payload) if err := a.producer.SendMessage(env); err != nil { if a.logger != nil { a.logger.Warn("Failed to publish telegram webhook update", zap.Error(err), zap.Int64("update_id", update.UpdateID)) } w.WriteHeader(http.StatusServiceUnavailable) return } w.WriteHeader(http.StatusOK) }