2019-05-31 00:18:41 +01:00
|
|
|
package telegram
|
|
|
|
|
|
|
|
import (
|
|
|
|
"errors"
|
|
|
|
"strings"
|
|
|
|
"sync"
|
|
|
|
|
|
|
|
"github.com/forestgiant/sliceutil"
|
2020-01-30 14:39:00 +03:00
|
|
|
"github.com/micro/go-micro/v2/agent/input"
|
2020-03-11 20:55:39 +03:00
|
|
|
"github.com/micro/go-micro/v2/logger"
|
2019-12-03 22:59:44 +03:00
|
|
|
tgbotapi "gopkg.in/telegram-bot-api.v4"
|
2019-05-31 00:18:41 +01:00
|
|
|
)
|
|
|
|
|
|
|
|
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()
|
|
|
|
|
2019-12-03 15:25:58 +08:00
|
|
|
select {
|
|
|
|
case <-tc.exit:
|
|
|
|
return
|
2019-05-31 00:18:41 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
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
|
2020-03-11 20:55:39 +03:00
|
|
|
if logger.V(logger.ErrorLevel, logger.DefaultLogger) {
|
|
|
|
logger.Error("[telegram][Send] error:", err)
|
|
|
|
}
|
2019-05-31 00:18:41 +01:00
|
|
|
msgConfig.Text = "This bot couldn't send the response (Internal error)"
|
|
|
|
tc.input.api.Send(msgConfig)
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|