2020-11-09 18:54:06 +00:00
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
2024-05-13 07:21:28 +00:00
|
|
|
"context"
|
|
|
|
"fmt"
|
2021-12-07 18:05:43 +00:00
|
|
|
"strconv"
|
2024-05-13 07:21:28 +00:00
|
|
|
"strings"
|
2020-11-09 18:54:06 +00:00
|
|
|
|
2024-05-13 07:21:28 +00:00
|
|
|
"github.com/carlmjohnson/requests"
|
2023-01-24 15:49:33 +00:00
|
|
|
"go.goblog.app/app/pkgs/builderpool"
|
2021-12-07 17:23:57 +00:00
|
|
|
)
|
2020-11-09 18:54:06 +00:00
|
|
|
|
2021-06-06 12:39:42 +00:00
|
|
|
func (a *goBlog) initTelegram() {
|
2023-12-27 10:37:58 +00:00
|
|
|
a.pPostHooks = append(a.pPostHooks, func(p *post) { a.tgPost(p, false) })
|
2022-03-31 14:18:49 +00:00
|
|
|
a.pUpdateHooks = append(a.pUpdateHooks, a.tgUpdate)
|
|
|
|
a.pDeleteHooks = append(a.pDeleteHooks, a.tgDelete)
|
2023-12-27 10:37:58 +00:00
|
|
|
a.pUndeleteHooks = append(a.pUndeleteHooks, func(p *post) { a.tgPost(p, true) })
|
2022-03-31 14:18:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func (tg *configTelegram) enabled() bool {
|
|
|
|
if tg == nil || !tg.Enabled || tg.BotToken == "" || tg.ChatID == "" {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
|
2024-05-13 07:21:28 +00:00
|
|
|
const (
|
|
|
|
telegramChatParam = "telegramchat"
|
|
|
|
telegramMsgParam = "telegrammsg"
|
|
|
|
)
|
|
|
|
|
2023-12-27 10:37:58 +00:00
|
|
|
func (a *goBlog) tgPost(p *post, silent bool) {
|
|
|
|
if tg := a.getBlogFromPost(p).Telegram; tg.enabled() && p.isPublicPublishedSectionPost() {
|
2024-05-13 07:21:28 +00:00
|
|
|
tgChat := p.firstParameter(telegramChatParam)
|
|
|
|
tgMsg := p.firstParameter(telegramMsgParam)
|
2023-12-27 10:37:58 +00:00
|
|
|
if tgChat != "" && tgMsg != "" {
|
|
|
|
// Already posted
|
|
|
|
return
|
|
|
|
}
|
|
|
|
// Generate HTML
|
2024-05-13 07:21:28 +00:00
|
|
|
html := tg.generateHTML(p.RenderedTitle, a.shortPostURL(p))
|
2023-12-27 10:37:58 +00:00
|
|
|
if html == "" {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
// Send message
|
2024-05-13 07:21:28 +00:00
|
|
|
chatId, msgId, err := a.sendTelegram(tg, html, "HTML", silent)
|
2023-12-27 10:37:58 +00:00
|
|
|
if err != nil {
|
|
|
|
a.error("Failed to send post to Telegram", "err", err)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
if chatId == 0 || msgId == 0 {
|
|
|
|
// Not sent
|
|
|
|
return
|
|
|
|
}
|
|
|
|
// Save chat and message id to post
|
2024-05-13 07:21:28 +00:00
|
|
|
if err := a.db.replacePostParam(p.Path, telegramChatParam, []string{strconv.FormatInt(chatId, 10)}); err != nil {
|
2023-12-27 10:37:58 +00:00
|
|
|
a.error("Failed to save Telegram chat id", "err", err)
|
|
|
|
}
|
2024-05-13 07:21:28 +00:00
|
|
|
if err := a.db.replacePostParam(p.Path, telegramMsgParam, []string{strconv.Itoa(msgId)}); err != nil {
|
2023-12-27 10:37:58 +00:00
|
|
|
a.error("Failed to save Telegram message id", "err", err)
|
2021-12-07 18:05:43 +00:00
|
|
|
}
|
2022-03-31 14:18:49 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (a *goBlog) tgUpdate(p *post) {
|
2022-12-14 15:03:54 +00:00
|
|
|
if tg := a.getBlogFromPost(p).Telegram; tg.enabled() {
|
2024-05-13 07:21:28 +00:00
|
|
|
tgChat := p.firstParameter(telegramChatParam)
|
|
|
|
tgMsg := p.firstParameter(telegramMsgParam)
|
2022-03-31 14:18:49 +00:00
|
|
|
if tgChat == "" || tgMsg == "" {
|
|
|
|
// Not send to Telegram
|
|
|
|
return
|
2021-06-14 19:34:29 +00:00
|
|
|
}
|
2022-03-31 14:18:49 +00:00
|
|
|
// Generate HTML
|
2024-05-13 07:21:28 +00:00
|
|
|
html := tg.generateHTML(p.RenderedTitle, a.shortPostURL(p))
|
2022-03-31 14:18:49 +00:00
|
|
|
if html == "" {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
// Send update
|
2024-05-13 07:21:28 +00:00
|
|
|
if err := a.updateTelegram(tg, tgChat, tgMsg, html, "HTML"); err != nil {
|
2023-12-27 10:37:58 +00:00
|
|
|
a.error("Failed to send update to Telegram", "err", err)
|
2022-03-31 14:18:49 +00:00
|
|
|
}
|
|
|
|
}
|
2020-11-17 21:10:13 +00:00
|
|
|
}
|
|
|
|
|
2022-03-31 14:18:49 +00:00
|
|
|
func (a *goBlog) tgDelete(p *post) {
|
2022-12-14 15:03:54 +00:00
|
|
|
if tg := a.getBlogFromPost(p).Telegram; tg.enabled() {
|
2024-05-13 07:21:28 +00:00
|
|
|
tgChat := p.firstParameter(telegramChatParam)
|
|
|
|
tgMsg := p.firstParameter(telegramMsgParam)
|
2022-03-31 14:18:49 +00:00
|
|
|
if tgChat == "" || tgMsg == "" {
|
|
|
|
// Not send to Telegram
|
|
|
|
return
|
|
|
|
}
|
|
|
|
// Delete message
|
2024-05-13 07:21:28 +00:00
|
|
|
if err := a.deleteTelegram(tg, tgChat, tgMsg); err != nil {
|
2023-12-27 10:37:58 +00:00
|
|
|
a.error("Failed to delete Telegram message", "err", err)
|
2022-03-31 14:18:49 +00:00
|
|
|
}
|
|
|
|
// Delete chat and message id from post
|
2024-05-13 07:21:28 +00:00
|
|
|
if err := a.db.replacePostParam(p.Path, telegramChatParam, []string{}); err != nil {
|
2023-12-27 10:37:58 +00:00
|
|
|
a.error("Failed to remove Telegram chat id", "err", err)
|
2022-03-31 14:18:49 +00:00
|
|
|
}
|
2024-05-13 07:21:28 +00:00
|
|
|
if err := a.db.replacePostParam(p.Path, telegramMsgParam, []string{}); err != nil {
|
2023-12-27 10:37:58 +00:00
|
|
|
a.error("Failed to remove Telegram message id", "err", err)
|
2022-03-31 14:18:49 +00:00
|
|
|
}
|
2021-06-14 19:34:29 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-05-13 07:21:28 +00:00
|
|
|
func (tg *configTelegram) generateHTML(title, shortURL string) string {
|
2021-06-14 19:34:29 +00:00
|
|
|
if !tg.enabled() {
|
|
|
|
return ""
|
2020-11-09 18:54:06 +00:00
|
|
|
}
|
2023-01-24 15:49:33 +00:00
|
|
|
message := builderpool.Get()
|
|
|
|
defer builderpool.Put(message)
|
2024-05-13 07:21:28 +00:00
|
|
|
tgReplacer := strings.NewReplacer("<", "<", ">", ">", "&", "&")
|
2021-06-06 12:39:42 +00:00
|
|
|
if title != "" {
|
2024-05-13 07:21:28 +00:00
|
|
|
tgReplacer.WriteString(message, title)
|
2020-11-09 18:54:06 +00:00
|
|
|
message.WriteString("\n\n")
|
|
|
|
}
|
2024-05-13 07:21:28 +00:00
|
|
|
message.WriteString("<a href=\"" + shortURL + "\">")
|
|
|
|
tgReplacer.WriteString(message, shortURL)
|
|
|
|
message.WriteString("</a>")
|
|
|
|
return message.String()
|
|
|
|
}
|
|
|
|
|
|
|
|
type telegramMessageResult struct {
|
|
|
|
OK bool `json:"ok"`
|
|
|
|
Description string `json:"description"`
|
|
|
|
Result struct {
|
|
|
|
Chat struct {
|
|
|
|
ID int64 `json:"id"`
|
|
|
|
} `json:"chat"`
|
|
|
|
MessageID int `json:"message_id"`
|
|
|
|
} `json:"result"`
|
2020-11-09 18:54:06 +00:00
|
|
|
}
|
|
|
|
|
2022-03-31 14:18:49 +00:00
|
|
|
func (a *goBlog) sendTelegram(tg *configTelegram, message, mode string, silent bool) (int64, int, error) {
|
2021-06-14 19:34:29 +00:00
|
|
|
if !tg.enabled() {
|
2021-12-07 18:05:43 +00:00
|
|
|
return 0, 0, nil
|
2021-02-08 19:33:48 +00:00
|
|
|
}
|
2024-05-13 07:21:28 +00:00
|
|
|
|
|
|
|
telegramURL := "https://api.telegram.org/bot" + tg.BotToken + "/sendMessage"
|
|
|
|
result := &telegramMessageResult{}
|
|
|
|
if err := requests.URL(telegramURL).Client(a.httpClient).
|
|
|
|
Param("chat_id", tg.ChatID).
|
|
|
|
Param("text", message).
|
|
|
|
Param("parse_mode", mode).
|
|
|
|
Param("disable_notification", strconv.FormatBool(silent)).
|
|
|
|
ToJSON(result).
|
|
|
|
Fetch(context.Background()); err != nil {
|
2021-12-07 18:05:43 +00:00
|
|
|
return 0, 0, err
|
2020-11-09 18:54:06 +00:00
|
|
|
}
|
2024-05-13 07:21:28 +00:00
|
|
|
|
|
|
|
if !result.OK {
|
|
|
|
return 0, 0, fmt.Errorf("error from Telegram API: %s", result.Description)
|
2021-12-07 18:05:43 +00:00
|
|
|
}
|
2024-05-13 07:21:28 +00:00
|
|
|
|
|
|
|
return result.Result.Chat.ID, result.Result.MessageID, nil
|
2021-12-07 18:05:43 +00:00
|
|
|
}
|
|
|
|
|
2024-05-13 07:21:28 +00:00
|
|
|
func (a *goBlog) updateTelegram(tg *configTelegram, chatID, messageID, message, mode string) error {
|
2021-12-07 18:05:43 +00:00
|
|
|
if !tg.enabled() {
|
|
|
|
return nil
|
|
|
|
}
|
2024-05-13 07:21:28 +00:00
|
|
|
|
|
|
|
telegramURL := "https://api.telegram.org/bot" + tg.BotToken + "/editMessageText"
|
|
|
|
result := &telegramMessageResult{}
|
|
|
|
if err := requests.URL(telegramURL).Client(a.httpClient).
|
|
|
|
Param("chat_id", chatID).
|
|
|
|
Param("message_id", messageID).
|
|
|
|
Param("text", message).
|
|
|
|
Param("parse_mode", mode).
|
|
|
|
ToJSON(result).
|
|
|
|
Fetch(context.Background()); err != nil {
|
2021-12-07 18:05:43 +00:00
|
|
|
return err
|
|
|
|
}
|
2024-05-13 07:21:28 +00:00
|
|
|
|
|
|
|
if !result.OK {
|
|
|
|
return fmt.Errorf("error from Telegram API: %s", result.Description)
|
2021-12-07 18:05:43 +00:00
|
|
|
}
|
2024-05-13 07:21:28 +00:00
|
|
|
|
|
|
|
return nil
|
2021-12-07 18:14:00 +00:00
|
|
|
}
|
|
|
|
|
2024-05-13 07:21:28 +00:00
|
|
|
func (a *goBlog) deleteTelegram(tg *configTelegram, chatID, messageID string) error {
|
2021-12-07 18:14:00 +00:00
|
|
|
if !tg.enabled() {
|
|
|
|
return nil
|
|
|
|
}
|
2024-05-13 07:21:28 +00:00
|
|
|
|
|
|
|
telegramURL := "https://api.telegram.org/bot" + tg.BotToken + "/deleteMessage"
|
|
|
|
result := &telegramMessageResult{}
|
|
|
|
if err := requests.URL(telegramURL).Client(a.httpClient).
|
|
|
|
Param("chat_id", chatID).
|
|
|
|
Param("message_id", messageID).
|
|
|
|
ToJSON(result).
|
|
|
|
Fetch(context.Background()); err != nil {
|
2021-12-07 18:14:00 +00:00
|
|
|
return err
|
|
|
|
}
|
2024-05-13 07:21:28 +00:00
|
|
|
|
|
|
|
if !result.OK {
|
|
|
|
return fmt.Errorf("error from Telegram API: %s", result.Description)
|
2021-12-07 18:14:00 +00:00
|
|
|
}
|
2024-05-13 07:21:28 +00:00
|
|
|
|
|
|
|
return nil
|
2020-11-09 18:54:06 +00:00
|
|
|
}
|