-
Notifications
You must be signed in to change notification settings - Fork 10
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Showing
6 changed files
with
245 additions
and
49 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,38 +1,33 @@ | ||
module github.com/svenwiltink/go-musicbot | ||
|
||
require ( | ||
github.com/BurntSushi/toml v0.3.1 // indirect | ||
github.com/ChannelMeter/iso8601duration v0.0.0-20150204201828-8da3af7a2a61 | ||
github.com/DexterLB/mpvipc v0.0.0-20180427115922-c65680788f71 | ||
github.com/Masterminds/semver v1.4.2 // indirect | ||
github.com/Masterminds/vcs v1.12.0 // indirect | ||
github.com/armon/go-radix v1.0.0 // indirect | ||
github.com/boltdb/bolt v1.3.1 // indirect | ||
github.com/blang/semver v3.5.1+incompatible // indirect | ||
github.com/channelmeter/iso8601duration v0.0.0-20150204201828-8da3af7a2a61 // indirect | ||
github.com/davecgh/go-spew v1.1.1 // indirect | ||
github.com/fluffle/goirc v0.0.0-20180216210456-fc1dfa1ceb88 | ||
github.com/golang/dep v0.5.0 // indirect | ||
github.com/golang/lint v0.0.0-20181217174547-8f45f776aaf1 // indirect | ||
github.com/golang/mock v1.1.1 // indirect | ||
github.com/golang/protobuf v1.2.0 // indirect | ||
github.com/gorilla/websocket v1.3.0 // indirect | ||
github.com/jmank88/nuts v0.3.0 // indirect | ||
github.com/mitchellh/gox v0.4.0 // indirect | ||
github.com/mitchellh/iochan v1.0.0 // indirect | ||
github.com/nightlyone/lockfile v0.0.0-20180618180623-0ad87eef1443 // indirect | ||
github.com/gorilla/websocket v1.3.0 | ||
github.com/mattermost/mattermost-server v5.6.2+incompatible | ||
github.com/nicksnyder/go-i18n v1.10.0 // indirect | ||
github.com/pborman/uuid v1.2.0 // indirect | ||
github.com/pelletier/go-toml v1.2.0 // indirect | ||
github.com/pkg/errors v0.8.1 // indirect | ||
github.com/pmezard/go-difflib v1.0.0 // indirect | ||
github.com/sdboyer/constext v0.0.0-20170321163424-836a14457353 // indirect | ||
github.com/stretchr/testify v1.2.2 | ||
github.com/svenwiltink/ddpgo v0.0.0-20180824111114-cbfd6602d7b7 // indirect | ||
github.com/svenwiltink/rocketchatgo v0.0.0-20180824111422-519bc8c4b617 | ||
github.com/svenwiltink/youtube-dl v0.0.0-20180530195755-08954d006d6a | ||
github.com/vansante/go-event-emitter v0.0.0-20180601122726-d1e9ab59df60 | ||
golang.org/x/lint v0.0.0-20181217174547-8f45f776aaf1 // indirect | ||
go.uber.org/atomic v1.3.2 // indirect | ||
go.uber.org/multierr v1.1.0 // indirect | ||
go.uber.org/zap v1.9.1 // indirect | ||
golang.org/x/crypto v0.0.0-20190103213133-ff983b9c42bc // indirect | ||
golang.org/x/net v0.0.0-20180824045131-faa378e6dbae // indirect | ||
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4 // indirect | ||
golang.org/x/tools v0.0.0-20190108222858-421f03a57a64 // indirect | ||
google.golang.org/api v0.0.0-20180824000442-943e5aafc110 | ||
gopkg.in/natefinch/lumberjack.v2 v2.0.0 // indirect | ||
gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce // indirect | ||
gopkg.in/yaml.v2 v2.2.2 // indirect | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,189 @@ | ||
package mattermost | ||
|
||
import ( | ||
"fmt" | ||
"github.com/gorilla/websocket" | ||
mattermost "github.com/mattermost/mattermost-server/model" | ||
"github.com/svenwiltink/go-musicbot/pkg/bot" | ||
"log" | ||
"strings" | ||
"time" | ||
) | ||
|
||
type MessageProvider struct { | ||
Config *bot.Config | ||
MessageChannel chan bot.Message | ||
|
||
team *mattermost.Team | ||
channel *mattermost.Channel | ||
|
||
client *mattermost.Client4 | ||
websocketClient *mattermost.WebSocketClient | ||
} | ||
|
||
func (provider *MessageProvider) Start() error { | ||
|
||
protocol := "http://" | ||
if provider.Config.Mattermost.Ssl { | ||
protocol = "https://" | ||
} | ||
|
||
provider.client = mattermost.NewAPIv4Client(protocol + provider.Config.Mattermost.Server) | ||
provider.client.SetOAuthToken(provider.Config.Mattermost.PrivateAccessToken) | ||
|
||
team, response := provider.client.GetTeamByName(provider.Config.Mattermost.Teamname, "") | ||
if response.Error != nil { | ||
return fmt.Errorf("unable to get team by name %s: %+v", provider.Config.Mattermost.Teamname, response.Error) | ||
} | ||
|
||
provider.team = team | ||
|
||
channel, response := provider.client.GetChannelByName(provider.Config.Mattermost.Channel, team.Id, "") | ||
if response.Error != nil { | ||
return fmt.Errorf("unable to get channel by name %s: %+v", provider.Config.Mattermost.Teamname, response.Error) | ||
} | ||
|
||
provider.channel = channel | ||
|
||
err := provider.connect() | ||
if err != nil { | ||
return err | ||
} | ||
|
||
go provider.pingLoop() | ||
go provider.startReadLoop() | ||
|
||
return nil | ||
} | ||
|
||
func (provider *MessageProvider) SendReplyToMessage(message bot.Message, reply string) error { | ||
post := &mattermost.Post{ | ||
ChannelId: message.Target, | ||
Message: reply, | ||
} | ||
|
||
_, response := provider.client.CreatePost(post) | ||
if response.Error != nil { | ||
log.Printf("unable to post message %+v: %+v", post, response) | ||
return fmt.Errorf("unable to post message %+v: %+v", post, response) | ||
} | ||
|
||
return nil | ||
} | ||
|
||
func (provider *MessageProvider) BroadcastMessage(message string) error { | ||
post := &mattermost.Post{ | ||
ChannelId: provider.channel.Id, | ||
Message: message, | ||
} | ||
|
||
_, response := provider.client.CreatePost(post) | ||
if response.Error != nil { | ||
log.Printf("unable to post message %+v: %+v", post, response) | ||
return fmt.Errorf("unable to post message %+v: %+v", post, response) | ||
} | ||
|
||
return nil | ||
} | ||
|
||
func (provider *MessageProvider) GetMessageChannel() chan bot.Message { | ||
return provider.MessageChannel | ||
} | ||
|
||
func (provider *MessageProvider) connect() error { | ||
|
||
protocol := "ws://" | ||
if provider.Config.Mattermost.Ssl { | ||
protocol = "wss://" | ||
} | ||
|
||
connection, appErr := mattermost.NewWebSocketClient(protocol+provider.Config.Mattermost.Server, provider.Config.Mattermost.PrivateAccessToken) | ||
if appErr != nil { | ||
return fmt.Errorf("unable to connect to mattermost websocker: %+v", appErr) | ||
} | ||
|
||
provider.websocketClient = connection | ||
|
||
connection.Listen() | ||
|
||
return nil | ||
} | ||
|
||
func (provider *MessageProvider) startReadLoop() { | ||
log.Println("starting mattermost read loop") | ||
for { | ||
for event := range provider.websocketClient.EventChannel { | ||
if event.Event == mattermost.WEBSOCKET_EVENT_POSTED { | ||
|
||
postData, exists := event.Data["post"] | ||
if !exists { | ||
log.Printf("invalid postdata from event %+v", event) | ||
continue | ||
} | ||
|
||
var jsonString string | ||
|
||
switch t := postData.(type) { | ||
case string: | ||
jsonString = postData.(string) | ||
default: | ||
log.Printf("invalid data type %s for event %+v", t, event) | ||
continue | ||
} | ||
|
||
post := mattermost.PostFromJson(strings.NewReader(jsonString)) | ||
provider.handleMessage(post) | ||
} | ||
} | ||
log.Println("mattermost eventchannel closed. Probably disconnected D:") | ||
} | ||
|
||
} | ||
|
||
func (provider *MessageProvider) handleMessage(post *mattermost.Post) { | ||
channel, response := provider.client.GetChannel(post.ChannelId, "") | ||
if response.Error != nil { | ||
log.Printf("unable to get channel by id %s: %+v", post.ChannelId, response) | ||
return | ||
} | ||
|
||
// ignore all messaged not from the channel or direct | ||
if channel.Name != provider.Config.Mattermost.Channel && channel.Type != mattermost.CHANNEL_DIRECT { | ||
log.Printf("ignoring message from channel %s", channel.Name) | ||
} | ||
|
||
author, response := provider.client.GetUser(post.UserId, "") | ||
if response.Error != nil { | ||
log.Printf("unable to get user by id %s: %+v", post.ChannelId, response) | ||
return | ||
} | ||
|
||
msg := bot.Message{ | ||
Target: post.ChannelId, | ||
Message: post.Message, | ||
IsPrivate: channel.Type == mattermost.CHANNEL_DIRECT, | ||
Sender: bot.Sender{ | ||
Name: author.Username, | ||
NickName: author.Nickname, | ||
}, | ||
} | ||
|
||
provider.MessageChannel <- msg | ||
} | ||
|
||
func (provider *MessageProvider) pingLoop() { | ||
ticker := time.NewTicker(10 * time.Second) | ||
for range ticker.C { | ||
err := provider.websocketClient.Conn.WriteMessage(websocket.PingMessage, []byte{}) | ||
if err != nil { | ||
log.Printf("unable to ping: %+v", err) | ||
} | ||
} | ||
} | ||
|
||
func New(config *bot.Config) *MessageProvider { | ||
return &MessageProvider{ | ||
MessageChannel: make(chan bot.Message), | ||
Config: config, | ||
} | ||
} |