mirror of
https://github.com/c9s/bbgo.git
synced 2024-11-23 15:25:14 +00:00
interact: add Slack interaction
This commit is contained in:
parent
5ad918e166
commit
abee20acbf
|
@ -128,7 +128,7 @@ func main() {
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
interact.SetMessenger(&interact.Telegram{
|
interact.AddMessenger(&interact.Telegram{
|
||||||
Private: true,
|
Private: true,
|
||||||
Bot: b,
|
Bot: b,
|
||||||
})
|
})
|
||||||
|
|
2
go.mod
2
go.mod
|
@ -43,7 +43,7 @@ require (
|
||||||
github.com/robfig/cron/v3 v3.0.0
|
github.com/robfig/cron/v3 v3.0.0
|
||||||
github.com/shopspring/decimal v1.2.0 // indirect
|
github.com/shopspring/decimal v1.2.0 // indirect
|
||||||
github.com/sirupsen/logrus v1.8.1
|
github.com/sirupsen/logrus v1.8.1
|
||||||
github.com/slack-go/slack v0.6.6-0.20200602212211-b04b8521281b
|
github.com/slack-go/slack v0.10.1
|
||||||
github.com/spf13/afero v1.5.1 // indirect
|
github.com/spf13/afero v1.5.1 // indirect
|
||||||
github.com/spf13/cast v1.3.1 // indirect
|
github.com/spf13/cast v1.3.1 // indirect
|
||||||
github.com/spf13/cobra v1.1.1
|
github.com/spf13/cobra v1.1.1
|
||||||
|
|
2
go.sum
2
go.sum
|
@ -415,6 +415,8 @@ github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE
|
||||||
github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
|
github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
|
||||||
github.com/slack-go/slack v0.6.6-0.20200602212211-b04b8521281b h1:4NIpokK7Rg/k6lSzNQzvGLphpHtfAAaLw9AWHxHQn0w=
|
github.com/slack-go/slack v0.6.6-0.20200602212211-b04b8521281b h1:4NIpokK7Rg/k6lSzNQzvGLphpHtfAAaLw9AWHxHQn0w=
|
||||||
github.com/slack-go/slack v0.6.6-0.20200602212211-b04b8521281b/go.mod h1:FGqNzJBmxIsZURAxh2a8D21AnOVvvXZvGligs4npPUM=
|
github.com/slack-go/slack v0.6.6-0.20200602212211-b04b8521281b/go.mod h1:FGqNzJBmxIsZURAxh2a8D21AnOVvvXZvGligs4npPUM=
|
||||||
|
github.com/slack-go/slack v0.10.1 h1:BGbxa0kMsGEvLOEoZmYs8T1wWfoZXwmQFBb6FgYCXUA=
|
||||||
|
github.com/slack-go/slack v0.10.1/go.mod h1:wWL//kk0ho+FcQXcBTmEafUI5dz4qz5f4mMk8oIkioQ=
|
||||||
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM=
|
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM=
|
||||||
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
|
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
|
||||||
github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s=
|
github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s=
|
||||||
|
|
|
@ -6,6 +6,7 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"image/png"
|
"image/png"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
|
stdlog "log"
|
||||||
"math/rand"
|
"math/rand"
|
||||||
"os"
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
|
@ -16,6 +17,7 @@ import (
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
"github.com/pquerna/otp"
|
"github.com/pquerna/otp"
|
||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
|
"github.com/slack-go/slack"
|
||||||
"github.com/spf13/viper"
|
"github.com/spf13/viper"
|
||||||
"gopkg.in/tucnak/telebot.v2"
|
"gopkg.in/tucnak/telebot.v2"
|
||||||
|
|
||||||
|
@ -575,7 +577,7 @@ func (environ *Environment) ConfigureNotificationSystem(userConfig *Config) erro
|
||||||
// setup slack
|
// setup slack
|
||||||
slackToken := viper.GetString("slack-token")
|
slackToken := viper.GetString("slack-token")
|
||||||
if len(slackToken) > 0 && userConfig.Notifications != nil {
|
if len(slackToken) > 0 && userConfig.Notifications != nil {
|
||||||
environ.setupSlack(userConfig, slackToken)
|
environ.setupSlack(userConfig, slackToken, persistence)
|
||||||
}
|
}
|
||||||
|
|
||||||
// check if telegram bot token is defined
|
// check if telegram bot token is defined
|
||||||
|
@ -672,18 +674,65 @@ func (environ *Environment) getAuthStore(persistence service.PersistenceService)
|
||||||
return persistence.NewStore("bbgo", "auth", id)
|
return persistence.NewStore("bbgo", "auth", id)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (environ *Environment) setupSlack(userConfig *Config, slackToken string) {
|
func (environ *Environment) setupSlack(userConfig *Config, slackToken string, persistence service.PersistenceService) {
|
||||||
if conf := userConfig.Notifications.Slack; conf != nil {
|
|
||||||
if conf.ErrorChannel != "" {
|
conf := userConfig.Notifications.Slack
|
||||||
log.Debugf("found slack configured, setting up log hook...")
|
if conf == nil {
|
||||||
log.AddHook(slacklog.NewLogHook(slackToken, conf.ErrorChannel))
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if !strings.HasPrefix(slackToken, "xoxb-") {
|
||||||
|
log.Error("SLACK_BOT_TOKEN must have the prefix \"xoxb-\".")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// app-level token (for specific api)
|
||||||
|
slackAppToken := viper.GetString("slack-app-token")
|
||||||
|
if !strings.HasPrefix(slackAppToken, "xapp-") {
|
||||||
|
log.Errorf("SLACK_APP_TOKEN must have the prefix \"xapp-\".")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if conf.ErrorChannel != "" {
|
||||||
|
log.Debugf("found slack configured, setting up log hook...")
|
||||||
|
log.AddHook(slacklog.NewLogHook(slackToken, conf.ErrorChannel))
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Debugf("adding slack notifier with default channel: %s", conf.DefaultChannel)
|
||||||
|
|
||||||
|
var client = slack.New(slackToken,
|
||||||
|
slack.OptionDebug(true),
|
||||||
|
slack.OptionLog(stdlog.New(os.Stdout, "api: ", stdlog.Lshortfile|stdlog.LstdFlags)),
|
||||||
|
slack.OptionAppLevelToken(slackAppToken))
|
||||||
|
|
||||||
|
var notifier = slacknotifier.New(client, conf.DefaultChannel)
|
||||||
|
environ.AddNotifier(notifier)
|
||||||
|
|
||||||
|
// allocate a store, so that we can save the chatID for the owner
|
||||||
|
var messenger = interact.NewSlack(client)
|
||||||
|
|
||||||
|
var sessions = interact.SlackSessionMap{}
|
||||||
|
var sessionStore = persistence.NewStore("bbgo", "slack")
|
||||||
|
if err := sessionStore.Load(&sessions); err != nil {
|
||||||
|
log.WithError(err).Errorf("sessions load error")
|
||||||
|
} else {
|
||||||
|
for _, session := range sessions {
|
||||||
|
if session.IsAuthorized() {
|
||||||
|
// notifier.AddChat(session.Chat)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Debugf("adding slack notifier with default channel: %s", conf.DefaultChannel)
|
// you must restore the session after the notifier updates
|
||||||
|
// messenger.RestoreSessions(sessions)
|
||||||
var notifier = slacknotifier.New(slackToken, conf.DefaultChannel)
|
|
||||||
environ.AddNotifier(notifier)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
messenger.OnAuthorized(func(userSession *interact.SlackSession) {
|
||||||
|
if userSession.IsAuthorized() {
|
||||||
|
// notifier.AddChat(userSession.Chat)
|
||||||
|
}
|
||||||
|
|
||||||
|
})
|
||||||
|
interact.AddMessenger(messenger)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (environ *Environment) setupTelegram(userConfig *Config, telegramBotToken string, persistence service.PersistenceService) error {
|
func (environ *Environment) setupTelegram(userConfig *Config, telegramBotToken string, persistence service.PersistenceService) error {
|
||||||
|
@ -712,10 +761,7 @@ func (environ *Environment) setupTelegram(userConfig *Config, telegramBotToken s
|
||||||
environ.Notifiability.AddNotifier(notifier)
|
environ.Notifiability.AddNotifier(notifier)
|
||||||
|
|
||||||
// allocate a store, so that we can save the chatID for the owner
|
// allocate a store, so that we can save the chatID for the owner
|
||||||
var messenger = &interact.Telegram{
|
var messenger = interact.NewTelegram(bot)
|
||||||
Bot: bot,
|
|
||||||
Private: true,
|
|
||||||
}
|
|
||||||
|
|
||||||
var sessions = interact.TelegramSessionMap{}
|
var sessions = interact.TelegramSessionMap{}
|
||||||
var sessionStore = persistence.NewStore("bbgo", "telegram", telegramID)
|
var sessionStore = persistence.NewStore("bbgo", "telegram", telegramID)
|
||||||
|
@ -745,7 +791,7 @@ func (environ *Environment) setupTelegram(userConfig *Config, telegramBotToken s
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
interact.SetMessenger(messenger)
|
interact.AddMessenger(messenger)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,8 +8,8 @@ func Default() *Interact {
|
||||||
return defaultInteraction
|
return defaultInteraction
|
||||||
}
|
}
|
||||||
|
|
||||||
func SetMessenger(messenger Messenger) {
|
func AddMessenger(messenger Messenger) {
|
||||||
defaultInteraction.SetMessenger(messenger)
|
defaultInteraction.AddMessenger(messenger)
|
||||||
}
|
}
|
||||||
|
|
||||||
func AddCustomInteraction(custom CustomInteraction) {
|
func AddCustomInteraction(custom CustomInteraction) {
|
||||||
|
|
|
@ -50,7 +50,7 @@ type Interact struct {
|
||||||
|
|
||||||
customInteractions []CustomInteraction
|
customInteractions []CustomInteraction
|
||||||
|
|
||||||
messenger Messenger
|
messengers []Messenger
|
||||||
}
|
}
|
||||||
|
|
||||||
func New() *Interact {
|
func New() *Interact {
|
||||||
|
@ -172,12 +172,12 @@ func (it *Interact) runCommand(session Session, command string, args []string, c
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (it *Interact) SetMessenger(messenger Messenger) {
|
func (it *Interact) AddMessenger(messenger Messenger) {
|
||||||
// pass Responder function
|
// pass Responder function
|
||||||
messenger.SetTextMessageResponder(func(session Session, message string, reply Reply, ctxObjects ...interface{}) error {
|
messenger.SetTextMessageResponder(func(session Session, message string, reply Reply, ctxObjects ...interface{}) error {
|
||||||
return it.handleResponse(session, message, append(ctxObjects, reply)...)
|
return it.handleResponse(session, message, append(ctxObjects, reply)...)
|
||||||
})
|
})
|
||||||
it.messenger = messenger
|
it.messengers = append(it.messengers, messenger)
|
||||||
}
|
}
|
||||||
|
|
||||||
// builtin initializes the built-in commands
|
// builtin initializes the built-in commands
|
||||||
|
@ -222,21 +222,24 @@ func (it *Interact) registerCommands(commands map[string]*Command) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// register commands to the service
|
// register commands to the service
|
||||||
if it.messenger == nil {
|
if len(it.messengers) == 0 {
|
||||||
return fmt.Errorf("messenger is not set")
|
return fmt.Errorf("messenger is not set")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// commandName is used in the closure, we need to copy the variable
|
||||||
commandName := n
|
commandName := n
|
||||||
it.messenger.AddCommand(cmd, func(session Session, message string, reply Reply, ctxObjects ...interface{}) error {
|
for _, messenger := range it.messengers {
|
||||||
args := parseCommand(message)
|
messenger.AddCommand(cmd, func(session Session, message string, reply Reply, ctxObjects ...interface{}) error {
|
||||||
return it.runCommand(session, commandName, args, append(ctxObjects, reply)...)
|
args := parseCommand(message)
|
||||||
})
|
return it.runCommand(session, commandName, args, append(ctxObjects, reply)...)
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (it *Interact) Start(ctx context.Context) error {
|
func (it *Interact) Start(ctx context.Context) error {
|
||||||
if it.messenger == nil {
|
if len(it.messengers) == 0 {
|
||||||
log.Warn("messenger is not set, skip initializing")
|
log.Warn("messenger is not set, skip initializing")
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -256,6 +259,8 @@ func (it *Interact) Start(ctx context.Context) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: use go routine and context
|
// TODO: use go routine and context
|
||||||
it.messenger.Start(ctx)
|
for _, m := range it.messengers {
|
||||||
|
m.Start(ctx)
|
||||||
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -105,7 +105,7 @@ func TestCustomInteraction(t *testing.T) {
|
||||||
telegram := &Telegram{
|
telegram := &Telegram{
|
||||||
Bot: b,
|
Bot: b,
|
||||||
}
|
}
|
||||||
globalInteraction.SetMessenger(telegram)
|
globalInteraction.AddMessenger(telegram)
|
||||||
|
|
||||||
testInteraction := &TestInteraction{}
|
testInteraction := &TestInteraction{}
|
||||||
testInteraction.Commands(globalInteraction)
|
testInteraction.Commands(globalInteraction)
|
||||||
|
|
164
pkg/interact/slack.go
Normal file
164
pkg/interact/slack.go
Normal file
|
@ -0,0 +1,164 @@
|
||||||
|
package interact
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"log"
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"github.com/sirupsen/logrus"
|
||||||
|
"github.com/slack-go/slack"
|
||||||
|
"github.com/slack-go/slack/slackevents"
|
||||||
|
"github.com/slack-go/slack/socketmode"
|
||||||
|
)
|
||||||
|
|
||||||
|
type SlackSession struct {
|
||||||
|
BaseSession
|
||||||
|
}
|
||||||
|
|
||||||
|
type SlackSessionMap map[int64]*SlackSession
|
||||||
|
|
||||||
|
//go:generate callbackgen -type Slack
|
||||||
|
type Slack struct {
|
||||||
|
client *slack.Client
|
||||||
|
socket *socketmode.Client
|
||||||
|
|
||||||
|
sessions SlackSessionMap
|
||||||
|
|
||||||
|
commands []*Command
|
||||||
|
|
||||||
|
// textMessageResponder is used for interact to register its message handler
|
||||||
|
textMessageResponder Responder
|
||||||
|
|
||||||
|
authorizedCallbacks []func(userSession *SlackSession)
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewSlack(client *slack.Client) *Slack {
|
||||||
|
socket := socketmode.New(
|
||||||
|
client,
|
||||||
|
socketmode.OptionDebug(true),
|
||||||
|
socketmode.OptionLog(
|
||||||
|
log.New(os.Stdout, "socketmode: ",
|
||||||
|
log.Lshortfile|log.LstdFlags)),
|
||||||
|
)
|
||||||
|
|
||||||
|
return &Slack{
|
||||||
|
client: client,
|
||||||
|
socket: socket,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Slack) SetTextMessageResponder(responder Responder) {
|
||||||
|
s.textMessageResponder = responder
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Slack) AddCommand(command *Command, responder Responder) {
|
||||||
|
s.commands = append(s.commands, command)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Slack) listen() {
|
||||||
|
for evt := range s.socket.Events {
|
||||||
|
switch evt.Type {
|
||||||
|
case socketmode.EventTypeConnecting:
|
||||||
|
fmt.Println("Connecting to Slack with Socket Mode...")
|
||||||
|
case socketmode.EventTypeConnectionError:
|
||||||
|
fmt.Println("Connection failed. Retrying later...")
|
||||||
|
case socketmode.EventTypeConnected:
|
||||||
|
fmt.Println("Connected to Slack with Socket Mode.")
|
||||||
|
case socketmode.EventTypeEventsAPI:
|
||||||
|
eventsAPIEvent, ok := evt.Data.(slackevents.EventsAPIEvent)
|
||||||
|
if !ok {
|
||||||
|
fmt.Printf("Ignored %+v\n", evt)
|
||||||
|
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Printf("Event received: %+v\n", eventsAPIEvent)
|
||||||
|
|
||||||
|
s.socket.Ack(*evt.Request)
|
||||||
|
|
||||||
|
switch eventsAPIEvent.Type {
|
||||||
|
case slackevents.CallbackEvent:
|
||||||
|
innerEvent := eventsAPIEvent.InnerEvent
|
||||||
|
switch ev := innerEvent.Data.(type) {
|
||||||
|
case *slackevents.AppMentionEvent:
|
||||||
|
_, _, err := s.client.PostMessage(ev.Channel, slack.MsgOptionText("Yes, hello.", false))
|
||||||
|
if err != nil {
|
||||||
|
fmt.Printf("failed posting message: %v", err)
|
||||||
|
}
|
||||||
|
case *slackevents.MemberJoinedChannelEvent:
|
||||||
|
fmt.Printf("user %q joined to channel %q", ev.User, ev.Channel)
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
s.socket.Debugf("unsupported Events API event received")
|
||||||
|
}
|
||||||
|
case socketmode.EventTypeInteractive:
|
||||||
|
callback, ok := evt.Data.(slack.InteractionCallback)
|
||||||
|
if !ok {
|
||||||
|
fmt.Printf("Ignored %+v\n", evt)
|
||||||
|
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Printf("Interaction received: %+v\n", callback)
|
||||||
|
|
||||||
|
var payload interface{}
|
||||||
|
|
||||||
|
switch callback.Type {
|
||||||
|
case slack.InteractionTypeBlockActions:
|
||||||
|
// See https://api.slack.com/apis/connections/socket-implement#button
|
||||||
|
|
||||||
|
s.socket.Debugf("button clicked!")
|
||||||
|
case slack.InteractionTypeShortcut:
|
||||||
|
case slack.InteractionTypeViewSubmission:
|
||||||
|
// See https://api.slack.com/apis/connections/socket-implement#modal
|
||||||
|
case slack.InteractionTypeDialogSubmission:
|
||||||
|
default:
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
s.socket.Ack(*evt.Request, payload)
|
||||||
|
case socketmode.EventTypeSlashCommand:
|
||||||
|
cmd, ok := evt.Data.(slack.SlashCommand)
|
||||||
|
if !ok {
|
||||||
|
fmt.Printf("Ignored %+v\n", evt)
|
||||||
|
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
s.socket.Debugf("Slash command received: %+v", cmd)
|
||||||
|
|
||||||
|
payload := map[string]interface{}{
|
||||||
|
"blocks": []slack.Block{
|
||||||
|
slack.NewSectionBlock(
|
||||||
|
&slack.TextBlockObject{
|
||||||
|
Type: slack.MarkdownType,
|
||||||
|
Text: "foo",
|
||||||
|
},
|
||||||
|
nil,
|
||||||
|
slack.NewAccessory(
|
||||||
|
slack.NewButtonBlockElement(
|
||||||
|
"",
|
||||||
|
"somevalue",
|
||||||
|
&slack.TextBlockObject{
|
||||||
|
Type: slack.PlainTextType,
|
||||||
|
Text: "bar",
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
}}
|
||||||
|
|
||||||
|
s.socket.Ack(*evt.Request, payload)
|
||||||
|
default:
|
||||||
|
fmt.Fprintf(os.Stderr, "Unexpected event type received: %s\n", evt.Type)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Slack) Start(ctx context.Context) {
|
||||||
|
go s.listen()
|
||||||
|
if err := s.socket.Run() ; err != nil {
|
||||||
|
logrus.WithError(err).Errorf("slack socketmode error")
|
||||||
|
}
|
||||||
|
}
|
|
@ -96,7 +96,7 @@ type Telegram struct {
|
||||||
|
|
||||||
authorizing bool
|
authorizing bool
|
||||||
|
|
||||||
sessions map[int64]*TelegramSession
|
sessions TelegramSessionMap
|
||||||
|
|
||||||
// textMessageResponder is used for interact to register its message handler
|
// textMessageResponder is used for interact to register its message handler
|
||||||
textMessageResponder Responder
|
textMessageResponder Responder
|
||||||
|
@ -106,6 +106,14 @@ type Telegram struct {
|
||||||
authorizedCallbacks []func(s *TelegramSession)
|
authorizedCallbacks []func(s *TelegramSession)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func NewTelegram(bot *telebot.Bot) *Telegram {
|
||||||
|
return &Telegram{
|
||||||
|
Bot: bot,
|
||||||
|
Private: true,
|
||||||
|
sessions: make(map[int64]*TelegramSession),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (tm *Telegram) SetTextMessageResponder(textMessageResponder Responder) {
|
func (tm *Telegram) SetTextMessageResponder(textMessageResponder Responder) {
|
||||||
tm.textMessageResponder = textMessageResponder
|
tm.textMessageResponder = textMessageResponder
|
||||||
}
|
}
|
||||||
|
@ -213,6 +221,10 @@ func (tm *Telegram) RestoreSessions(sessions TelegramSessionMap) {
|
||||||
log.Infof("[telegram] restoring telegram %d sessions", len(sessions))
|
log.Infof("[telegram] restoring telegram %d sessions", len(sessions))
|
||||||
tm.sessions = sessions
|
tm.sessions = sessions
|
||||||
for _, session := range sessions {
|
for _, session := range sessions {
|
||||||
|
if session.Chat == nil || session.User == nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
if session.IsAuthorized() {
|
if session.IsAuthorized() {
|
||||||
if _, err := tm.Bot.Send(session.Chat, fmt.Sprintf("Hi %s, I'm back. Your telegram session is restored.", session.User.Username)); err != nil {
|
if _, err := tm.Bot.Send(session.Chat, fmt.Sprintf("Hi %s, I'm back. Your telegram session is restored.", session.User.Username)); err != nil {
|
||||||
log.WithError(err).Error("[telegram] can not send telegram message")
|
log.WithError(err).Error("[telegram] can not send telegram message")
|
||||||
|
|
|
@ -33,10 +33,8 @@ type Notifier struct {
|
||||||
|
|
||||||
type NotifyOption func(notifier *Notifier)
|
type NotifyOption func(notifier *Notifier)
|
||||||
|
|
||||||
func New(token, channel string, options ...NotifyOption) *Notifier {
|
func New(client *slack.Client, channel string, options ...NotifyOption) *Notifier {
|
||||||
// var client = slack.New(token, slack.OptionDebug(true))
|
// var client = slack.New(token, slack.OptionDebug(true))
|
||||||
var client = slack.New(token)
|
|
||||||
|
|
||||||
notifier := &Notifier{
|
notifier := &Notifier{
|
||||||
channel: channel,
|
channel: channel,
|
||||||
client: client,
|
client: client,
|
||||||
|
|
Loading…
Reference in New Issue
Block a user