From 194d8698cedd8d7649ebec82e2f0c0f811037254 Mon Sep 17 00:00:00 2001 From: Jan-Lukas Else Date: Tue, 7 Dec 2021 19:05:43 +0100 Subject: [PATCH] Update Telegram message on post update --- notifications.go | 2 +- telegram.go | 105 +++++++++++++++++++++++++++++++++++++++++++---- telegram_test.go | 5 ++- 3 files changed, 100 insertions(+), 12 deletions(-) diff --git a/notifications.go b/notifications.go index 4f95afe..6900614 100644 --- a/notifications.go +++ b/notifications.go @@ -31,7 +31,7 @@ func (a *goBlog) sendNotification(text string) { log.Println("Failed to save notification:", err.Error()) } if an := a.cfg.Notifications; an != nil { - _, err := a.send(an.Telegram, n.Text, "") + _, _, err := a.send(an.Telegram, n.Text, "") if err != nil { log.Println("Failed to send Telegram notification:", err.Error()) } diff --git a/telegram.go b/telegram.go index e08af3c..256967e 100644 --- a/telegram.go +++ b/telegram.go @@ -2,8 +2,10 @@ package main import ( "bytes" + "errors" "log" "net/url" + "strconv" tgbotapi "github.com/go-telegram-bot-api/telegram-bot-api/v5" ) @@ -11,10 +13,61 @@ import ( func (a *goBlog) initTelegram() { a.pPostHooks = append(a.pPostHooks, func(p *post) { if tg := a.cfg.Blogs[p.Blog].Telegram; tg.enabled() && p.isPublishedSectionPost() { - if html := tg.generateHTML(p.RenderedTitle, a.fullPostURL(p), a.shortPostURL(p)); html != "" { - if _, err := a.send(tg, html, "HTML"); err != nil { - log.Printf("Failed to send post to Telegram: %v", err) - } + // Generate HTML + html := tg.generateHTML(p.RenderedTitle, a.fullPostURL(p), a.shortPostURL(p)) + if html == "" { + return + } + // Send message + chatId, msgId, err := a.send(tg, html, tgbotapi.ModeHTML) + if err != nil { + log.Printf("Failed to send post to Telegram: %v", err) + return + } + if chatId == 0 || msgId == 0 { + // Not sent + return + } + // Save chat and message id to post + err = a.db.replacePostParam(p.Path, "telegramchat", []string{strconv.FormatInt(chatId, 10)}) + if err != nil { + log.Printf("Failed to save Telegram chat id: %v", err) + } + err = a.db.replacePostParam(p.Path, "telegrammsg", []string{strconv.Itoa(msgId)}) + if err != nil { + log.Printf("Failed to save Telegram message id: %v", err) + } + } + }) + a.pUpdateHooks = append(a.pUpdateHooks, func(p *post) { + if tg := a.cfg.Blogs[p.Blog].Telegram; tg.enabled() && p.isPublishedSectionPost() { + tgChat := p.firstParameter("telegramchat") + tgMsg := p.firstParameter("telegrammsg") + if tgChat == "" || tgMsg == "" { + // Not send to Telegram + return + } + // Parse tgChat to int64 + chatId, err := strconv.ParseInt(tgChat, 10, 64) + if err != nil { + log.Printf("Failed to parse Telegram chat ID: %v", err) + return + } + // Parse tgMsg to int + messageId, err := strconv.Atoi(tgMsg) + if err != nil { + log.Printf("Failed to parse Telegram message ID: %v", err) + return + } + // Generate HTML + html := tg.generateHTML(p.RenderedTitle, a.fullPostURL(p), a.shortPostURL(p)) + if html == "" { + return + } + // Send update + err = a.sendUpdate(tg, chatId, messageId, html, "HTML") + if err != nil { + log.Printf("Failed to send update to Telegram: %v", err) } } }) @@ -48,13 +101,13 @@ func (tg *configTelegram) generateHTML(title, fullURL, shortURL string) string { return message.String() } -func (a *goBlog) send(tg *configTelegram, message, mode string) (int, error) { +func (a *goBlog) send(tg *configTelegram, message, mode string) (int64, int, error) { if !tg.enabled() { - return 0, nil + return 0, 0, nil } bot, err := tgbotapi.NewBotAPIWithClient(tg.BotToken, tgbotapi.APIEndpoint, a.httpClient) if err != nil { - return 0, err + return 0, 0, err } msg := tgbotapi.MessageConfig{ BaseChat: tgbotapi.BaseChat{ @@ -65,7 +118,41 @@ func (a *goBlog) send(tg *configTelegram, message, mode string) (int, error) { } res, err := bot.Send(msg) if err != nil { - return 0, err + return 0, 0, err } - return res.MessageID, nil + return res.Chat.ID, res.MessageID, nil +} + +func (a *goBlog) sendUpdate(tg *configTelegram, chatId int64, messageId int, message, mode string) error { + if !tg.enabled() { + return nil + } + bot, err := tgbotapi.NewBotAPIWithClient(tg.BotToken, tgbotapi.APIEndpoint, a.httpClient) + if err != nil { + return err + } + chat, err := bot.GetChat(tgbotapi.ChatInfoConfig{ + ChatConfig: tgbotapi.ChatConfig{ + SuperGroupUsername: tg.ChatID, + }, + }) + if err != nil { + return err + } + if chat.ID != chatId { + return errors.New("chat id mismatch") + } + msg := tgbotapi.EditMessageTextConfig{ + BaseEdit: tgbotapi.BaseEdit{ + ChatID: chatId, + MessageID: messageId, + }, + Text: message, + ParseMode: mode, + } + _, err = bot.Send(msg) + if err != nil { + return err + } + return nil } diff --git a/telegram_test.go b/telegram_test.go index a723a19..6bbb67a 100644 --- a/telegram_test.go +++ b/telegram_test.go @@ -82,7 +82,7 @@ func Test_configTelegram_send(t *testing.T) { return } rw.WriteHeader(http.StatusOK) - rw.Write([]byte(`{"ok":true,"result":{"message_id":123,"from":{"id":123456789,"is_bot":true,"first_name":"Test","username":"testbot"},"chat":{"id":123456789,"first_name":"Test","username":"testbot"},"date":1564181818,"text":"Message"}}`)) + rw.Write([]byte(`{"ok":true,"result":{"message_id":123,"from":{"id":123456789,"is_bot":true,"first_name":"Test","username":"testbot"},"chat":{"id":789,"first_name":"Test","username":"testbot"},"date":1564181818,"text":"Message"}}`)) })) tg := &configTelegram{ @@ -95,10 +95,11 @@ func Test_configTelegram_send(t *testing.T) { httpClient: fakeClient.Client, } - msgId, err := app.send(tg, "Message", "HTML") + chatId, msgId, err := app.send(tg, "Message", "HTML") require.Nil(t, err) assert.Equal(t, 123, msgId) + assert.Equal(t, int64(789), chatId) assert.NotNil(t, fakeClient.req) assert.Equal(t, http.MethodPost, fakeClient.req.Method)