github.com/annwntech/go-micro/v2@v2.9.5/agent/input/telegram/conn.go (about) 1 package telegram 2 3 import ( 4 "errors" 5 "strings" 6 "sync" 7 8 "github.com/forestgiant/sliceutil" 9 "github.com/annwntech/go-micro/v2/agent/input" 10 "github.com/annwntech/go-micro/v2/logger" 11 tgbotapi "gopkg.in/telegram-bot-api.v4" 12 ) 13 14 type telegramConn struct { 15 input *telegramInput 16 17 recv <-chan tgbotapi.Update 18 exit chan bool 19 20 syncCond *sync.Cond 21 mutex sync.Mutex 22 } 23 24 func newConn(input *telegramInput) (*telegramConn, error) { 25 conn := &telegramConn{ 26 input: input, 27 } 28 29 conn.syncCond = sync.NewCond(&conn.mutex) 30 31 go conn.run() 32 33 return conn, nil 34 } 35 36 func (tc *telegramConn) run() { 37 u := tgbotapi.NewUpdate(0) 38 u.Timeout = 60 39 updates, err := tc.input.api.GetUpdatesChan(u) 40 if err != nil { 41 return 42 } 43 44 tc.recv = updates 45 tc.syncCond.Signal() 46 47 select { 48 case <-tc.exit: 49 return 50 } 51 } 52 53 func (tc *telegramConn) Close() error { 54 return nil 55 } 56 57 func (tc *telegramConn) Recv(event *input.Event) error { 58 if event == nil { 59 return errors.New("event cannot be nil") 60 } 61 62 for { 63 if tc.recv == nil { 64 tc.mutex.Lock() 65 tc.syncCond.Wait() 66 } 67 68 update := <-tc.recv 69 70 if update.Message == nil || (len(tc.input.whitelist) > 0 && !sliceutil.Contains(tc.input.whitelist, update.Message.From.UserName)) { 71 continue 72 } 73 74 if event.Meta == nil { 75 event.Meta = make(map[string]interface{}) 76 } 77 78 event.Type = input.TextEvent 79 event.From = update.Message.From.UserName 80 event.To = tc.input.api.Self.UserName 81 event.Data = []byte(update.Message.Text) 82 event.Meta["chatId"] = update.Message.Chat.ID 83 event.Meta["chatType"] = update.Message.Chat.Type 84 event.Meta["messageId"] = update.Message.MessageID 85 86 return nil 87 } 88 } 89 90 func (tc *telegramConn) Send(event *input.Event) error { 91 messageText := strings.TrimSpace(string(event.Data)) 92 93 chatId := event.Meta["chatId"].(int64) 94 chatType := ChatType(event.Meta["chatType"].(string)) 95 96 msgConfig := tgbotapi.NewMessage(chatId, messageText) 97 msgConfig.ParseMode = tgbotapi.ModeHTML 98 99 if sliceutil.Contains([]ChatType{Group, Supergroup}, chatType) { 100 msgConfig.ReplyToMessageID = event.Meta["messageId"].(int) 101 } 102 103 _, err := tc.input.api.Send(msgConfig) 104 105 if err != nil { 106 // probably it could be because of nested HTML tags -- telegram doesn't allow nested tags 107 if logger.V(logger.ErrorLevel, logger.DefaultLogger) { 108 logger.Error("[telegram][Send] error:", err) 109 } 110 msgConfig.Text = "This bot couldn't send the response (Internal error)" 111 tc.input.api.Send(msgConfig) 112 } 113 114 return nil 115 }