package main import ( "encoding/json" "fmt" "io" "log" "os" "strconv" "strings" "time" "github.com/gocolly/colly" tb "gopkg.in/tucnak/telebot.v2" ) const ( dbFile = "quotes.json" ) // Quote represent a quote of the flim type Quote struct { Quote string `json:"quote"` Page string `json:"page"` ThumbURL string `json:"thumb_url"` } // VideoURL get url of the video func (q *Quote) VideoURL() string { return fmt.Sprintf( "https://george-abitbol.fr/%s", q.Page, ) } func main() { args := os.Args if len(args) > 1 && strings.Compare(args[1], "--update") == 0 { fmt.Println("Updating quotes") Update() return } var quotes []Quote // Load quote database file, err := os.Open(dbFile) if err != nil { log.Fatalf("Could not open quote file: %s\n", err) return } defer file.Close() bytes, err := io.ReadAll(file) if err != nil { log.Fatalf("Could not read quote file: %s\n", err) return } if err = json.Unmarshal(bytes, "es); err != nil { log.Fatalf("Could not Unmarshal quote file: %s\n", err) return } // Index quote database index, err := indexQuotes(quotes) if err != nil { log.Fatalf("Could not index quotes: %s\n", err) return } // Load telegram bot b, err := tb.NewBot(tb.Settings{ Token: os.Getenv("TELEGRAM_TOKEN"), Poller: &tb.LongPoller{Timeout: 10 * time.Second}, }) if err != nil { log.Fatalf("Could not connect to telegram: %s\n", err) return } // Add bot capabilities // Cite command b.Handle("/cite", func(m *tb.Message) { quotes, err := index.Search(m.Text) if err != nil || len(quotes) == 0 { b.Send(m.Chat, "Pas de citation trouvée") return } b.Send(m.Chat, fmt.Sprintf("%s\n\n%s", quotes[0].Quote, quotes[0].VideoURL())) }) // Search feature b.Handle(tb.OnQuery, func(q *tb.Query) { quotes, err := index.Search(q.Text) if err != nil { log.Println("Pas de fichier de citations trouvé") return } results := make(tb.Results, len(quotes)) for i, quote := range quotes { url := quote.VideoURL() thumb := quote.ThumbURL log.Printf("{%s, %s}\n", url, thumb) results[i] = &tb.VideoResult{ URL: url, MIME: "text/html", ThumbURL: thumb, Title: quote.Quote, } results[i].SetContent( &tb.InputTextMessageContent{ Text: fmt.Sprintf( "%s\n\n%s", quote.Quote, url, ), ParseMode: tb.ModeHTML, DisablePreview: false, }, ) results[i].SetResultID(strconv.Itoa(i)) } err = b.Answer(q, &tb.QueryResponse{ Results: results, SwitchPMParameter: "Ajoute moi", CacheTime: 0, // One minut }) if err != nil { log.Println(err) } }) // Start bot log.Println("Bot started") b.Start() } // Update get a fresh list of quotes from george-abitbol.fr func Update() error { var videos []Quote c := colly.NewCollector( colly.AllowedDomains("george-abitbol.fr"), ) // Find and visit all links c.OnHTML("div.thumb", func(e *colly.HTMLElement) { videos = append( videos, Quote{ Quote: e.ChildAttr("img", "alt"), ThumbURL: e.ChildAttr("img", "data-original"), Page: e.ChildAttr("a", "href"), }, ) }) c.Visit("http://george-abitbol.fr") file, err := os.Create(dbFile) if err != nil { return fmt.Errorf("could not create quotes files: %w", err) } defer file.Close() bytes, err := json.Marshal(&videos) if err != nil { return fmt.Errorf("could not marshal quotes: %w", err) } file.Write(bytes) return nil }