bbgo_origin/pkg/notifier/telegramnotifier/telegram.go

153 lines
2.9 KiB
Go
Raw Normal View History

2020-12-05 06:20:27 +00:00
package telegramnotifier
import (
"fmt"
2022-01-14 03:37:23 +00:00
"strconv"
"time"
"github.com/sirupsen/logrus"
2022-01-14 03:37:23 +00:00
"gopkg.in/tucnak/telebot.v2"
2020-12-11 07:58:05 +00:00
"github.com/c9s/bbgo/pkg/types"
2020-12-05 06:20:27 +00:00
)
var log = logrus.WithField("service", "telegram")
2020-12-05 06:20:27 +00:00
type Notifier struct {
bot *telebot.Bot
2022-01-14 03:37:23 +00:00
// Subscribers stores the Chat objects for broadcasting
Subscribers map[int64]time.Time `json:"chats"`
2022-01-14 03:37:23 +00:00
// Owner
// when owner and owner chat is not nil, notification will send to the owner chat
Owner *telebot.User `json:"owner"`
OwnerChat *telebot.Chat `json:"chat"`
broadcast bool
2020-12-05 06:20:27 +00:00
}
2021-10-15 08:10:25 +00:00
type Option func(notifier *Notifier)
func UseBroadcast() Option {
return func(notifier *Notifier) {
notifier.broadcast = true
}
}
2020-12-05 06:20:27 +00:00
// New
func New(bot *telebot.Bot, options ...Option) *Notifier {
notifier := &Notifier{ bot: bot }
for _, o := range options {
o(notifier)
}
2020-12-05 06:20:27 +00:00
return notifier
}
func (n *Notifier) Notify(obj interface{}, args ...interface{}) {
n.NotifyTo("", obj, args...)
2020-12-05 06:20:27 +00:00
}
func filterPlaintextMessages(args []interface{}) (texts []string, pureArgs []interface{}) {
2021-05-15 01:59:17 +00:00
var firstObjectOffset = -1
2020-12-11 07:58:05 +00:00
for idx, arg := range args {
switch a := arg.(type) {
case types.PlainText:
texts = append(texts, a.PlainText())
2021-05-15 01:59:17 +00:00
if firstObjectOffset == -1 {
firstObjectOffset = idx
2021-05-14 06:57:22 +00:00
}
2020-12-11 07:58:05 +00:00
case types.Stringer:
texts = append(texts, a.String())
2021-05-15 01:59:17 +00:00
if firstObjectOffset == -1 {
firstObjectOffset = idx
2021-05-14 06:57:22 +00:00
}
2020-12-11 07:58:05 +00:00
}
}
pureArgs = args
2021-05-15 01:59:17 +00:00
if firstObjectOffset > -1 {
pureArgs = args[:firstObjectOffset]
2020-12-05 06:20:27 +00:00
}
return texts, pureArgs
}
2020-12-05 06:20:27 +00:00
func (n *Notifier) NotifyTo(channel string, obj interface{}, args ...interface{}) {
var texts, pureArgs = filterPlaintextMessages(args)
var message string
switch a := obj.(type) {
case string:
message = fmt.Sprintf(a, pureArgs...)
2020-12-11 07:58:05 +00:00
case types.PlainText:
message = a.PlainText()
case types.Stringer:
message = a.String()
default:
log.Errorf("unsupported notification format: %T %+v", a, a)
}
if n.broadcast {
2022-01-14 03:37:23 +00:00
n.Broadcast(message)
for _, text := range texts {
2022-01-14 03:37:23 +00:00
n.Broadcast(text)
}
2022-01-14 03:37:23 +00:00
} else if n.OwnerChat != nil {
n.SendToOwner(message)
for _, text := range texts {
2022-01-14 03:37:23 +00:00
n.SendToOwner(text)
}
}
}
func (n *Notifier) AddSubscriber(m *telebot.Message) {
if n.Subscribers == nil {
n.Subscribers = make(map[int64]time.Time)
2022-01-14 03:37:23 +00:00
}
n.Subscribers[m.Chat.ID] = m.Time()
2022-01-14 03:37:23 +00:00
}
2022-01-14 03:38:38 +00:00
func (n *Notifier) SetOwner(owner *telebot.User, chat *telebot.Chat) {
n.Owner = owner
n.OwnerChat = chat
}
2022-01-14 03:37:23 +00:00
func (n *Notifier) SendToOwner(message string) {
if n.OwnerChat == nil {
return
}
if _, err := n.bot.Send(n.OwnerChat, message); err != nil {
2022-01-14 03:37:23 +00:00
log.WithError(err).Error("telegram send error")
}
}
func (n *Notifier) Broadcast(message string) {
if n.Subscribers == nil {
return
}
for chatID := range n.Subscribers {
chat, err := n.bot.ChatByID(strconv.FormatInt(chatID, 10))
2022-01-14 03:37:23 +00:00
if err != nil {
log.WithError(err).Error("can not get chat by ID")
continue
}
if _, err := n.bot.Send(chat, message); err != nil {
2022-01-14 03:37:23 +00:00
log.WithError(err).Error("failed to send message")
}
2020-12-11 07:58:05 +00:00
}
2020-12-05 06:20:27 +00:00
}