package main import ( "encoding/json" "fmt" "log" "reflect" "strings" "time" "github.com/boltdb/bolt" tgbotapi "github.com/go-telegram-bot-api/telegram-bot-api/v5" "golang.org/x/net/html" ) func in_array(val interface{}, array interface{}) (exists bool) { exists = false switch reflect.TypeOf(array).Kind() { case reflect.Slice: s := reflect.ValueOf(array) for i := 0; i < s.Len(); i++ { if reflect.DeepEqual(val, s.Index(i).Interface()) == true { exists = true return } } } return } func NormalizeHTMLforTelegram(s string) (out string) { tags := []string{"br", "img", "b", "strong", "i", "em", "code", "s", "strike", "del", "u", "pre"} domDocTest := html.NewTokenizer(strings.NewReader(s)) previousStartTokenTest := domDocTest.Token() flagendtag := false for { tt := domDocTest.Next() if len(out) > 2500 { if e := in_array(previousStartTokenTest.Data, tags) && previousStartTokenTest.Data != "img" && previousStartTokenTest.Data != "br" && !flagendtag; e { out += fmt.Sprintf(" ...", previousStartTokenTest.Data) } else { out += " ..." } return } switch { case tt == html.ErrorToken: return case tt == html.StartTagToken: previousStartTokenTest = domDocTest.Token() if e := in_array(previousStartTokenTest.Data, tags); e { switch { case previousStartTokenTest.Data == "br": out += "\n" case previousStartTokenTest.Data == "img" && previousStartTokenTest.Attr[0].Key == "src": out += fmt.Sprintf("%s ", previousStartTokenTest.Attr[0].Val) // case previousStartTokenTest.Data == "a" && previousStartTokenTest.Attr[0].Key == "href": // out += fmt.Sprintf(" %s ", previousStartTokenTest.Attr[0].Val) default: out += fmt.Sprintf(" <%s>", previousStartTokenTest.Data) } flagendtag = false } case tt == html.EndTagToken: t := domDocTest.Token() if e := in_array(t.Data, tags); e { // switch { // case t.Data == "a": // out += " " // default: out += fmt.Sprintf(" ", t.Data) // } flagendtag = true } case tt == html.SelfClosingTagToken: t := domDocTest.Token() if e := in_array(t.Data, tags); e { if t.Data == "br" { out += "\n" } } case tt == html.TextToken: if previousStartTokenTest.Data == "script" { continue } TxtContent := strings.TrimSpace(html.UnescapeString(string(domDocTest.Text()))) if len(TxtContent) > 0 { out += html.EscapeString(TxtContent) } } } } func SendAndWriteToDB(send SendItems, dbpath string, rssname string, token string, chatid int64, debug bool) error { db, err := bolt.Open(dbpath, 0600, nil) if err != nil { log.Fatal(err) } defer db.Close() for i := len(send.ItemList) - 1; i >= 0; i-- { v := send.ItemList[i] log.Printf("Send to telegram post: %s", v.Title) bot, err := tgbotapi.NewBotAPI(token) if err != nil { log.Panic(err) } bot.Debug = debug s := "" + rssname + "\n\n" + "" + string(v.Title) + "\n\n" + NormalizeHTMLforTelegram(html.UnescapeString(string(v.Description))) + "\n\n" + v.Link msg := tgbotapi.NewMessage(chatid, s) msg.ParseMode = "Html" _, err = bot.Send(msg) if err != nil { log.Panic(err) } duration := time.Duration(10) * time.Second time.Sleep(duration) db.Update(func(tx *bolt.Tx) error { b, err := tx.CreateBucketIfNotExists([]byte(rssname)) if err != nil { return err } encoded, err := json.Marshal(v) if err != nil { return err } err = b.Put([]byte(v.Link), encoded) if err != nil { return err } return nil }) } return nil }