Bump version to 1.1.1: Fix Telegram webhook handling and chat_id saving
All checks were successful
Build and Push Docker Image / build-and-push (push) Successful in 1m33s
All checks were successful
Build and Push Docker Image / build-and-push (push) Successful in 1m33s
- Fix TelegramUpdate struct to handle message and edited_message properly - Fix chat_id saving for messages without text - Add comprehensive logging for webhook registration - Improve error handling and diagnostics
This commit is contained in:
63
.env.bak
Normal file
63
.env.bak
Normal file
@@ -0,0 +1,63 @@
|
||||
# ============================================
|
||||
# Единый файл конфигурации для всех проектов
|
||||
# Backend и Play-Life-Web
|
||||
# ============================================
|
||||
|
||||
# ============================================
|
||||
# Database Configuration
|
||||
# ============================================
|
||||
DB_HOST=localhost
|
||||
DB_PORT=5432
|
||||
DB_USER=playeng
|
||||
DB_PASSWORD=playeng
|
||||
DB_NAME=playeng
|
||||
|
||||
# ============================================
|
||||
# Backend Server Configuration
|
||||
# ============================================
|
||||
# Порт для backend сервера (по умолчанию: 8080)
|
||||
# В production всегда используется порт 8080 внутри контейнера
|
||||
PORT=8080
|
||||
|
||||
# ============================================
|
||||
# Play Life Web Configuration
|
||||
# ============================================
|
||||
# Порт для frontend приложения play-life-web
|
||||
WEB_PORT=3001
|
||||
|
||||
# ============================================
|
||||
# Telegram Bot Configuration (optional)
|
||||
# ============================================
|
||||
# Get token from @BotFather in Telegram: https://t.me/botfather
|
||||
# To get chat ID: send a message to your bot, then visit: https://api.telegram.org/bot<YOUR_BOT_TOKEN>/getUpdates
|
||||
# Look for "chat":{"id":123456789} - that number is your chat ID
|
||||
TELEGRAM_BOT_TOKEN=your_telegram_bot_token_here
|
||||
TELEGRAM_CHAT_ID=123456789
|
||||
# Base URL для автоматической настройки webhook
|
||||
# Примеры:
|
||||
# - Для production с HTTPS: https://your-domain.com
|
||||
# - Для локальной разработки с ngrok: https://abc123.ngrok.io
|
||||
# - Для прямого доступа на нестандартном порту: http://your-server:8080
|
||||
# Webhook будет настроен автоматически при старте сервера на: <TELEGRAM_WEBHOOK_BASE_URL>/webhook/telegram
|
||||
# Если не указан, webhook нужно настраивать вручную
|
||||
TELEGRAM_WEBHOOK_BASE_URL=https://your-domain.com
|
||||
|
||||
# ============================================
|
||||
# Todoist Webhook Configuration (optional)
|
||||
# ============================================
|
||||
# Секрет для проверки подлинности webhook от Todoist
|
||||
# Если задан, все запросы должны содержать заголовок X-Todoist-Webhook-Secret с этим значением
|
||||
# Оставьте пустым, если не хотите использовать проверку секрета
|
||||
TODOIST_WEBHOOK_SECRET=
|
||||
|
||||
# ============================================
|
||||
# Scheduler Configuration
|
||||
# ============================================
|
||||
# Часовой пояс для планировщика задач (например: Europe/Moscow, America/New_York, UTC)
|
||||
# Используется для:
|
||||
# - Автоматической фиксации целей на неделю каждый понедельник в 6:00
|
||||
# - Отправки ежедневного отчёта в 23:59
|
||||
# ВАЖНО: Укажите правильный часовой пояс, иначе задачи будут срабатывать в UTC!
|
||||
# Список доступных часовых поясов: https://en.wikipedia.org/wiki/List_of_tz_database_time_zones
|
||||
TIMEZONE=Europe/Moscow
|
||||
|
||||
@@ -182,8 +182,9 @@ type TelegramWebhook struct {
|
||||
|
||||
// TelegramUpdate - структура для Telegram webhook (обычно это Update объект)
|
||||
type TelegramUpdate struct {
|
||||
UpdateID int `json:"update_id"`
|
||||
Message TelegramMessage `json:"message"`
|
||||
UpdateID int `json:"update_id"`
|
||||
Message *TelegramMessage `json:"message,omitempty"`
|
||||
EditedMessage *TelegramMessage `json:"edited_message,omitempty"`
|
||||
}
|
||||
|
||||
type App struct {
|
||||
@@ -2374,20 +2375,22 @@ func main() {
|
||||
}
|
||||
|
||||
// Пытаемся настроить webhook автоматически при старте, если есть base URL и bot token в БД
|
||||
// Это опционально - основная регистрация происходит при сохранении токена через UI
|
||||
webhookBaseURL := getEnv("WEBHOOK_BASE_URL", "")
|
||||
if webhookBaseURL != "" {
|
||||
integration, err := app.getTelegramIntegration()
|
||||
if err == nil && integration.BotToken != nil && *integration.BotToken != "" {
|
||||
webhookURL := strings.TrimRight(webhookBaseURL, "/") + "/webhook/telegram"
|
||||
log.Printf("Attempting to setup Telegram webhook at startup. WEBHOOK_BASE_URL='%s'", webhookBaseURL)
|
||||
if err := setupTelegramWebhook(*integration.BotToken, webhookURL); err != nil {
|
||||
log.Printf("Warning: Failed to setup Telegram webhook at startup: %v. Webhook will be configured when user saves bot token.", err)
|
||||
} else {
|
||||
log.Printf("Telegram webhook configured successfully at startup: %s", webhookURL)
|
||||
log.Printf("SUCCESS: Telegram webhook configured successfully at startup: %s", webhookURL)
|
||||
}
|
||||
} else {
|
||||
log.Printf("Telegram bot token not found in database. Webhook will be configured when user saves bot token.")
|
||||
}
|
||||
} else {
|
||||
log.Printf("WEBHOOK_BASE_URL not set. Webhook will be configured when user saves bot token.")
|
||||
}
|
||||
|
||||
// Инициализируем БД для play-life проекта
|
||||
@@ -2469,6 +2472,7 @@ func getMapKeys(m map[string]interface{}) []string {
|
||||
// setupTelegramWebhook настраивает webhook для Telegram бота
|
||||
func setupTelegramWebhook(botToken, webhookURL string) error {
|
||||
apiURL := fmt.Sprintf("https://api.telegram.org/bot%s/setWebhook", botToken)
|
||||
log.Printf("Setting up Telegram webhook: apiURL=%s, webhookURL=%s", apiURL, webhookURL)
|
||||
|
||||
payload := map[string]string{
|
||||
"url": webhookURL,
|
||||
@@ -2486,12 +2490,15 @@ func setupTelegramWebhook(botToken, webhookURL string) error {
|
||||
|
||||
resp, err := client.Post(apiURL, "application/json", bytes.NewBuffer(jsonData))
|
||||
if err != nil {
|
||||
log.Printf("ERROR: Failed to send webhook setup request: %v", err)
|
||||
return fmt.Errorf("failed to send webhook setup request: %w", err)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
bodyBytes, _ := io.ReadAll(resp.Body)
|
||||
log.Printf("Telegram API response: status=%d, body=%s", resp.StatusCode, string(bodyBytes))
|
||||
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
bodyBytes, _ := io.ReadAll(resp.Body)
|
||||
return fmt.Errorf("telegram API returned status %d: %s", resp.StatusCode, string(bodyBytes))
|
||||
}
|
||||
|
||||
@@ -4100,24 +4107,51 @@ func (a *App) telegramWebhookHandler(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
// Сохраняем chat_id при первом сообщении
|
||||
if update.Message.Chat.ID != 0 {
|
||||
chatIDStr := strconv.FormatInt(update.Message.Chat.ID, 10)
|
||||
// Определяем, какое сообщение использовать (message или edited_message)
|
||||
var message *TelegramMessage
|
||||
if update.Message != nil {
|
||||
message = update.Message
|
||||
log.Printf("Telegram webhook received: update_id=%d, message type=message", update.UpdateID)
|
||||
} else if update.EditedMessage != nil {
|
||||
message = update.EditedMessage
|
||||
log.Printf("Telegram webhook received: update_id=%d, message type=edited_message", update.UpdateID)
|
||||
} else {
|
||||
log.Printf("Telegram webhook received: update_id=%d, but no message or edited_message found", update.UpdateID)
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
json.NewEncoder(w).Encode(map[string]string{
|
||||
"message": "No message found in update",
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
log.Printf("Telegram webhook: message present, chat_id=%d", message.Chat.ID)
|
||||
|
||||
// Сохраняем chat_id при первом сообщении (даже если нет текста)
|
||||
if message.Chat.ID != 0 {
|
||||
chatIDStr := strconv.FormatInt(message.Chat.ID, 10)
|
||||
log.Printf("Processing chat_id: %s", chatIDStr)
|
||||
integration, err := a.getTelegramIntegration()
|
||||
if err == nil {
|
||||
if err != nil {
|
||||
log.Printf("Error getting telegram integration: %v", err)
|
||||
} else {
|
||||
// Сохраняем chat_id, если его еще нет
|
||||
if integration.ChatID == nil || *integration.ChatID == "" {
|
||||
log.Printf("Attempting to save chat_id: %s", chatIDStr)
|
||||
if err := a.saveTelegramChatID(chatIDStr); err != nil {
|
||||
log.Printf("Warning: Failed to save chat_id: %v", err)
|
||||
} else {
|
||||
log.Printf("Saved chat_id from first message: %s", chatIDStr)
|
||||
log.Printf("Successfully saved chat_id from first message: %s", chatIDStr)
|
||||
}
|
||||
} else {
|
||||
log.Printf("Chat_id already exists in database: %s", *integration.ChatID)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
log.Printf("Warning: message.Chat.ID is 0, cannot save chat_id")
|
||||
}
|
||||
|
||||
// Проверяем, что есть message
|
||||
if update.Message.Text == "" {
|
||||
// Проверяем, что есть текст в сообщении
|
||||
if message.Text == "" {
|
||||
log.Printf("Telegram webhook: no text in message")
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
json.NewEncoder(w).Encode(map[string]string{
|
||||
@@ -4126,8 +4160,8 @@ func (a *App) telegramWebhookHandler(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
fullText := update.Message.Text
|
||||
entities := update.Message.Entities
|
||||
fullText := message.Text
|
||||
entities := message.Entities
|
||||
if entities == nil {
|
||||
entities = []TelegramEntity{}
|
||||
}
|
||||
@@ -4278,16 +4312,18 @@ func (a *App) updateTelegramIntegrationHandler(w http.ResponseWriter, r *http.Re
|
||||
|
||||
// Настраиваем webhook автоматически при сохранении токена
|
||||
webhookBaseURL := getEnv("WEBHOOK_BASE_URL", "")
|
||||
log.Printf("Attempting to setup Telegram webhook. WEBHOOK_BASE_URL='%s'", webhookBaseURL)
|
||||
if webhookBaseURL != "" {
|
||||
webhookURL := strings.TrimRight(webhookBaseURL, "/") + "/webhook/telegram"
|
||||
log.Printf("Setting up Telegram webhook: URL=%s", webhookURL)
|
||||
if err := setupTelegramWebhook(req.BotToken, webhookURL); err != nil {
|
||||
log.Printf("Warning: Failed to setup Telegram webhook: %v", err)
|
||||
log.Printf("ERROR: Failed to setup Telegram webhook: %v", err)
|
||||
// Не возвращаем ошибку, так как токен уже сохранен
|
||||
} else {
|
||||
log.Printf("Telegram webhook configured successfully: %s", webhookURL)
|
||||
log.Printf("SUCCESS: Telegram webhook configured successfully: %s", webhookURL)
|
||||
}
|
||||
} else {
|
||||
log.Printf("Warning: WEBHOOK_BASE_URL not set. Webhook will not be configured automatically.")
|
||||
log.Printf("WARNING: WEBHOOK_BASE_URL not set. Webhook will not be configured automatically.")
|
||||
}
|
||||
|
||||
integration, err := a.getTelegramIntegration()
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "play-life-web",
|
||||
"version": "1.1.0",
|
||||
"version": "1.1.1",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
|
||||
Reference in New Issue
Block a user