add HTML parsing to message, and NtfyHost config

This commit is contained in:
Astra 2026-02-27 07:39:21 +00:00
parent 4f6f70afad
commit b9c485e76d

63
bot.go
View file

@ -7,7 +7,6 @@ import (
"fmt" "fmt"
"log" "log"
"math" "math"
"math/rand"
"net/http" "net/http"
"os" "os"
"regexp" "regexp"
@ -16,6 +15,8 @@ import (
"github.com/gotd/td/session" "github.com/gotd/td/session"
"github.com/gotd/td/telegram" "github.com/gotd/td/telegram"
"github.com/gotd/td/telegram/auth" "github.com/gotd/td/telegram/auth"
"github.com/gotd/td/telegram/message"
"github.com/gotd/td/telegram/message/html"
"github.com/gotd/td/telegram/updates" "github.com/gotd/td/telegram/updates"
"github.com/gotd/td/tg" "github.com/gotd/td/tg"
"golang.org/x/term" "golang.org/x/term"
@ -33,6 +34,7 @@ type Config struct {
APIHash string `yaml:"api_hash"` APIHash string `yaml:"api_hash"`
MonitoredChat int64 `yaml:"monitored_chat"` MonitoredChat int64 `yaml:"monitored_chat"`
AlertChat int64 `yaml:"alert_chat"` AlertChat int64 `yaml:"alert_chat"`
NtfyHost string `json:"ntfy_host"`
NtfyToken string `yaml:"ntfy_token"` NtfyToken string `yaml:"ntfy_token"`
NtfyTopic string `yaml:"ntfy_topic"` NtfyTopic string `yaml:"ntfy_topic"`
SessionPath string `yaml:"session_path"` SessionPath string `yaml:"session_path"`
@ -49,6 +51,7 @@ func loadConfig(path string) (*Config, error) {
api_hash: "" api_hash: ""
monitored_chat: 0 monitored_chat: 0
alert_chat: 0 alert_chat: 0
ntfy_host: "https://ntfy.sh/"
ntfy_token: "" ntfy_token: ""
ntfy_topic: "" ntfy_topic: ""
session_path: "antiscam.session" session_path: "antiscam.session"
@ -192,8 +195,32 @@ func escapeMarkdown(text string) string {
return result.String() return result.String()
} }
func notify(message, topic, title string, priority int, token string) { func escapeHTML(text string) string {
url := "https://ntfy.zio.sh/" + topic var result strings.Builder
for _, r := range text {
switch r {
case '&':
result.WriteString("&")
case '<':
result.WriteString("&lt;")
case '>':
result.WriteString("&gt;")
case '"':
result.WriteString("&quot;")
case '\'':
result.WriteString("&#39;")
default:
result.WriteRune(r)
}
}
return result.String()
}
func notify(message, host, topic, title string, priority int, token string) {
if !strings.HasSuffix(host, "/") {
host = host + "/"
}
url := host + topic
req, err := http.NewRequest("POST", url, bytes.NewBufferString(message)) req, err := http.NewRequest("POST", url, bytes.NewBufferString(message))
if err != nil { if err != nil {
log.Printf("notify: creating request: %v", err) log.Printf("notify: creating request: %v", err)
@ -390,21 +417,29 @@ func handleNewMessage(ctx context.Context, api *tg.Client, alertPeer *tg.InputPe
// Get supergroup name // Get supergroup name
chatName := channel.Title chatName := channel.Title
// Build and send alert message // Build alert message with HTML formatting for markdown v2
matchMessage := fmt.Sprintf("🚨 Matched\n**Score**: %.2f\n**Chat**: %s (ID: %d)\n**User**: %s (%s) (ID: %d)\n", matchMessageHTML := fmt.Sprintf("🚨 Matched\n<b>Score</b>: %.2f\n<b>Chat</b>: %s (ID: %d)\n<b>User</b>: %s (%s) (ID: %d)\n",
result.score, escapeMarkdown(chatName), chatID, escapeMarkdown(displayName+" ("+username+")"), username, senderID) result.score, escapeHTML(chatName), chatID, escapeHTML(displayName+" ("+username+")"), username, senderID)
// Send ntfy notification if config set // Send ntfy notification if config set (use plain text for ntfy)
if cfg.NtfyToken != "" || cfg.NtfyTopic != "" { if cfg.NtfyToken != "" || cfg.NtfyTopic != "" {
notify(matchMessage, cfg.NtfyTopic, fmt.Sprintf("Scam Alert: %s", chatName), 5, cfg.NtfyToken) plainMessage := fmt.Sprintf("🚨 Matched\nScore: %.2f\nChat: %s (ID: %d)\nUser: %s (%s) (ID: %d)\n",
result.score, chatName, chatID, displayName+" ("+username+")", username, senderID)
notify(plainMessage, cfg.NtfyHost, cfg.NtfyTopic, fmt.Sprintf("Scam Alert: %s", chatName), 5, cfg.NtfyToken)
} }
// Send alert message to alert chat // Create a resolver for user mentions (not needed for this message, but required by html.String)
_, err = api.MessagesSendMessage(ctx, &tg.MessagesSendMessageRequest{ userResolver := func(id int64) (tg.InputUserClass, error) {
Peer: alertPeer, return &tg.InputUserFromMessage{
Message: matchMessage, Peer: alertPeer,
RandomID: rand.Int63(), MsgID: 0,
}) UserID: id,
}, nil
}
// Send alert message to alert chat using StyledText with HTML
sender := message.NewSender(api)
_, err = sender.To(alertPeer).StyledText(ctx, html.String(userResolver, matchMessageHTML))
if err != nil { if err != nil {
log.Printf("Failed to send alert message: %v", err) log.Printf("Failed to send alert message: %v", err)
} }