matterbridge/vendor/github.com/nlopes/slack/rtm.go

135 lines
4.3 KiB
Go
Raw Normal View History

2016-09-05 14:34:37 +00:00
package slack
import (
2017-07-16 12:29:46 +00:00
"context"
"encoding/json"
2016-09-05 14:34:37 +00:00
"net/url"
2018-08-09 22:38:19 +00:00
"sync"
2017-07-16 12:29:46 +00:00
"time"
2018-08-09 22:38:19 +00:00
"github.com/gorilla/websocket"
)
const (
websocketDefaultTimeout = 10 * time.Second
defaultPingInterval = 30 * time.Second
)
const (
rtmEventTypeAck = ""
rtmEventTypeHello = "hello"
rtmEventTypeGoodbye = "goodbye"
rtmEventTypePong = "pong"
rtmEventTypeDesktopNotification = "desktop_notification"
2016-09-05 14:34:37 +00:00
)
2017-07-16 12:29:46 +00:00
// StartRTM calls the "rtm.start" endpoint and returns the provided URL and the full Info block.
2016-09-05 14:34:37 +00:00
//
2017-07-16 12:29:46 +00:00
// To have a fully managed Websocket connection, use `NewRTM`, and call `ManageConnection()` on it.
2016-09-05 14:34:37 +00:00
func (api *Client) StartRTM() (info *Info, websocketURL string, err error) {
2018-08-09 22:38:19 +00:00
ctx, cancel := context.WithTimeout(context.Background(), websocketDefaultTimeout)
defer cancel()
return api.StartRTMContext(ctx)
2017-07-16 12:29:46 +00:00
}
// StartRTMContext calls the "rtm.start" endpoint and returns the provided URL and the full Info block with a custom context.
//
// To have a fully managed Websocket connection, use `NewRTM`, and call `ManageConnection()` on it.
func (api *Client) StartRTMContext(ctx context.Context) (info *Info, websocketURL string, err error) {
2016-09-05 14:34:37 +00:00
response := &infoResponseFull{}
2018-12-01 18:55:35 +00:00
err = postSlackMethod(ctx, api.httpclient, "rtm.start", url.Values{"token": {api.token}}, response, api)
2017-07-16 12:29:46 +00:00
if err != nil {
2018-08-09 22:38:19 +00:00
return nil, "", err
2017-07-16 12:29:46 +00:00
}
2018-08-09 22:38:19 +00:00
2017-07-16 12:29:46 +00:00
api.Debugln("Using URL:", response.Info.URL)
2018-08-09 22:38:19 +00:00
return &response.Info, response.Info.URL, response.Err()
2017-07-16 12:29:46 +00:00
}
// ConnectRTM calls the "rtm.connect" endpoint and returns the provided URL and the compact Info block.
//
// To have a fully managed Websocket connection, use `NewRTM`, and call `ManageConnection()` on it.
func (api *Client) ConnectRTM() (info *Info, websocketURL string, err error) {
2018-08-09 22:38:19 +00:00
ctx, cancel := context.WithTimeout(context.Background(), websocketDefaultTimeout)
defer cancel()
return api.ConnectRTMContext(ctx)
2017-07-16 12:29:46 +00:00
}
2018-08-09 22:38:19 +00:00
// ConnectRTMContext calls the "rtm.connect" endpoint and returns the
// provided URL and the compact Info block with a custom context.
2017-07-16 12:29:46 +00:00
//
// To have a fully managed Websocket connection, use `NewRTM`, and call `ManageConnection()` on it.
func (api *Client) ConnectRTMContext(ctx context.Context) (info *Info, websocketURL string, err error) {
response := &infoResponseFull{}
2018-12-01 18:55:35 +00:00
err = postSlackMethod(ctx, api.httpclient, "rtm.connect", url.Values{"token": {api.token}}, response, api)
2016-09-05 14:34:37 +00:00
if err != nil {
2018-08-09 22:38:19 +00:00
api.Debugf("Failed to connect to RTM: %s", err)
return nil, "", err
2016-09-05 14:34:37 +00:00
}
2018-08-09 22:38:19 +00:00
2016-09-05 14:34:37 +00:00
api.Debugln("Using URL:", response.Info.URL)
2018-08-09 22:38:19 +00:00
return &response.Info, response.Info.URL, response.Err()
2016-09-05 14:34:37 +00:00
}
2018-08-09 22:38:19 +00:00
// RTMOption options for the managed RTM.
type RTMOption func(*RTM)
// RTMOptionUseStart as of 11th July 2017 you should prefer setting this to false, see:
// https://api.slack.com/changelog/2017-04-start-using-rtm-connect-and-stop-using-rtm-start
func RTMOptionUseStart(b bool) RTMOption {
return func(rtm *RTM) {
rtm.useRTMStart = b
}
}
// RTMOptionDialer takes a gorilla websocket Dialer and uses it as the
// Dialer when opening the websocket for the RTM connection.
func RTMOptionDialer(d *websocket.Dialer) RTMOption {
return func(rtm *RTM) {
rtm.dialer = d
}
}
// RTMOptionPingInterval determines how often to deliver a ping message to slack.
func RTMOptionPingInterval(d time.Duration) RTMOption {
return func(rtm *RTM) {
rtm.pingInterval = d
rtm.resetDeadman()
}
2017-07-16 12:29:46 +00:00
}
2018-12-01 18:55:35 +00:00
// RTMOptionConnParams installs parameters to embed into the connection URL.
func RTMOptionConnParams(connParams url.Values) RTMOption {
return func(rtm *RTM) {
rtm.connParams = connParams
}
}
2018-08-09 22:38:19 +00:00
// NewRTM returns a RTM, which provides a fully managed connection to
2017-07-16 12:29:46 +00:00
// Slack's websocket-based Real-Time Messaging protocol.
2018-08-09 22:38:19 +00:00
func (api *Client) NewRTM(options ...RTMOption) *RTM {
2017-07-16 12:29:46 +00:00
result := &RTM{
Client: *api,
2018-12-01 18:55:35 +00:00
wasIntentional: true,
isConnected: false,
2017-07-16 12:29:46 +00:00
IncomingEvents: make(chan RTMEvent, 50),
outgoingMessages: make(chan OutgoingMessage, 20),
2018-08-09 22:38:19 +00:00
pingInterval: defaultPingInterval,
pingDeadman: time.NewTimer(deadmanDuration(defaultPingInterval)),
2017-07-16 12:29:46 +00:00
killChannel: make(chan bool),
2018-08-09 22:38:19 +00:00
disconnected: make(chan struct{}, 1),
2017-07-16 12:29:46 +00:00
forcePing: make(chan bool),
rawEvents: make(chan json.RawMessage),
idGen: NewSafeID(1),
2018-08-09 22:38:19 +00:00
mu: &sync.Mutex{},
2017-07-16 12:29:46 +00:00
}
2018-08-09 22:38:19 +00:00
for _, opt := range options {
opt(result)
2017-07-16 12:29:46 +00:00
}
return result
2016-09-05 14:34:37 +00:00
}