114 lines
		
	
	
		
			2.3 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			114 lines
		
	
	
		
			2.3 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| package telegram
 | |
| 
 | |
| import (
 | |
| 	"errors"
 | |
| 	"strings"
 | |
| 	"sync"
 | |
| 
 | |
| 	"github.com/forestgiant/sliceutil"
 | |
| 	"github.com/micro/go-micro/v2/agent/input"
 | |
| 	"github.com/micro/go-micro/v2/util/log"
 | |
| 	tgbotapi "gopkg.in/telegram-bot-api.v4"
 | |
| )
 | |
| 
 | |
| type telegramConn struct {
 | |
| 	input *telegramInput
 | |
| 
 | |
| 	recv <-chan tgbotapi.Update
 | |
| 	exit chan bool
 | |
| 
 | |
| 	syncCond *sync.Cond
 | |
| 	mutex    sync.Mutex
 | |
| }
 | |
| 
 | |
| func newConn(input *telegramInput) (*telegramConn, error) {
 | |
| 	conn := &telegramConn{
 | |
| 		input: input,
 | |
| 	}
 | |
| 
 | |
| 	conn.syncCond = sync.NewCond(&conn.mutex)
 | |
| 
 | |
| 	go conn.run()
 | |
| 
 | |
| 	return conn, nil
 | |
| }
 | |
| 
 | |
| func (tc *telegramConn) run() {
 | |
| 	u := tgbotapi.NewUpdate(0)
 | |
| 	u.Timeout = 60
 | |
| 	updates, err := tc.input.api.GetUpdatesChan(u)
 | |
| 	if err != nil {
 | |
| 		return
 | |
| 	}
 | |
| 
 | |
| 	tc.recv = updates
 | |
| 	tc.syncCond.Signal()
 | |
| 
 | |
| 	select {
 | |
| 	case <-tc.exit:
 | |
| 		return
 | |
| 	}
 | |
| }
 | |
| 
 | |
| func (tc *telegramConn) Close() error {
 | |
| 	return nil
 | |
| }
 | |
| 
 | |
| func (tc *telegramConn) Recv(event *input.Event) error {
 | |
| 	if event == nil {
 | |
| 		return errors.New("event cannot be nil")
 | |
| 	}
 | |
| 
 | |
| 	for {
 | |
| 		if tc.recv == nil {
 | |
| 			tc.mutex.Lock()
 | |
| 			tc.syncCond.Wait()
 | |
| 		}
 | |
| 
 | |
| 		update := <-tc.recv
 | |
| 
 | |
| 		if update.Message == nil || (len(tc.input.whitelist) > 0 && !sliceutil.Contains(tc.input.whitelist, update.Message.From.UserName)) {
 | |
| 			continue
 | |
| 		}
 | |
| 
 | |
| 		if event.Meta == nil {
 | |
| 			event.Meta = make(map[string]interface{})
 | |
| 		}
 | |
| 
 | |
| 		event.Type = input.TextEvent
 | |
| 		event.From = update.Message.From.UserName
 | |
| 		event.To = tc.input.api.Self.UserName
 | |
| 		event.Data = []byte(update.Message.Text)
 | |
| 		event.Meta["chatId"] = update.Message.Chat.ID
 | |
| 		event.Meta["chatType"] = update.Message.Chat.Type
 | |
| 		event.Meta["messageId"] = update.Message.MessageID
 | |
| 
 | |
| 		return nil
 | |
| 	}
 | |
| }
 | |
| 
 | |
| func (tc *telegramConn) Send(event *input.Event) error {
 | |
| 	messageText := strings.TrimSpace(string(event.Data))
 | |
| 
 | |
| 	chatId := event.Meta["chatId"].(int64)
 | |
| 	chatType := ChatType(event.Meta["chatType"].(string))
 | |
| 
 | |
| 	msgConfig := tgbotapi.NewMessage(chatId, messageText)
 | |
| 	msgConfig.ParseMode = tgbotapi.ModeHTML
 | |
| 
 | |
| 	if sliceutil.Contains([]ChatType{Group, Supergroup}, chatType) {
 | |
| 		msgConfig.ReplyToMessageID = event.Meta["messageId"].(int)
 | |
| 	}
 | |
| 
 | |
| 	_, err := tc.input.api.Send(msgConfig)
 | |
| 
 | |
| 	if err != nil {
 | |
| 		// probably it could be because of nested HTML tags -- telegram doesn't allow nested tags
 | |
| 		log.Log("[telegram][Send] error:", err)
 | |
| 		msgConfig.Text = "This bot couldn't send the response (Internal error)"
 | |
| 		tc.input.api.Send(msgConfig)
 | |
| 	}
 | |
| 
 | |
| 	return nil
 | |
| }
 |