package main import ( "math" "time" "github.com/go-errors/errors" tele "gopkg.in/telebot.v3" ) func isFromAdmin(sender *tele.User) bool { if sender == nil { return false } _, ok := config.adminUidLookup[sender.ID] return ok } func initBot() (*tele.Bot, error) { pref := tele.Settings{ Token: config.TGBotToken, Poller: &tele.LongPoller{Timeout: 15 * time.Second}, } b, err := tele.NewBot(pref) if err != nil { return nil, errors.Wrap(err, 0) } b.Use(logMiddleware) // command routing b.Handle("/start", handleStartCmd) b.Handle("/me", handleUserInfoCmd) b.Handle("/chat", handleChatInfoCmd) b.Handle("/year_progress", handleYearProgressCmd) b.Handle("/xr", handleExchangeRateCmd) b.Handle("/tr", handleTranslateCmd) for _, tbtn := range translateBtns { b.Handle(tbtn, handleTranslateBtn) } b.Handle("/kanji", handleKanjiCmd) b.Handle(tele.OnText, handleGeneralMessage) b.Handle(tele.OnSticker, handleGeneralMessage) // admin required adminGrp := b.Group() adminGrp.Use(adminMiddleware) adminGrp.Handle("/traffic", handleTrafficCmd) adminGrp.Handle(&trafficBtnDays, handleTrafficBtnDays) adminGrp.Handle(&trafficBtnMonths, handleTrafficBtnMonths) adminGrp.Handle("/dig", handleDigCmd) return b, nil } func adminMiddleware(next tele.HandlerFunc) tele.HandlerFunc { return func(c tele.Context) error { u := c.Sender() if u == nil { if cb := c.Callback(); cb != nil { u = cb.Sender } } if !isFromAdmin(u) { return nil } return next(c) } } func logMiddleware(next tele.HandlerFunc) tele.HandlerFunc { return func(c tele.Context) error { upd := c.Update() defer func() { logger.Debugw("Log middleware", "update", upd) }() return next(c) } } func drawBar(progress float64, length int) string { barChars := []rune("ยท-=") if length <= 0 { return "" } step := 1 / float64(length) buf := make([]rune, length+2) buf[0], buf[length+1] = '[', ']' for i := 0; i < length; i++ { fill := (progress - float64(i)*step) / step fill = math.Min(math.Max(fill, 0), 1) idx := int(math.Round(fill * float64(len(barChars)-1))) buf[i+1] = barChars[idx] } return string(buf) } func handleGeneralMessage(c tele.Context) error { if thread := matchAssistantConversation(c.Bot().Me, c.Message()); thread != nil { return handleAssistantConversation(c, thread) } return nil } func stickerFromID(id string) *tele.Sticker { return &tele.Sticker{ File: tele.File{ FileID: id, }, } } func setTyping(c tele.Context) chan error { resultCh := make(chan error, 1) go func() { defer close(resultCh) resultCh <- c.Bot().Notify(c.Chat(), tele.Typing) }() return resultCh }