mirror of
https://github.com/cwinfo/matterbridge.git
synced 2025-06-27 14:39:24 +00:00
Compare commits
19 Commits
v0.16.0-rc
...
v0.16.1
Author | SHA1 | Date | |
---|---|---|---|
e99532fb89 | |||
4aa646f6b0 | |||
9dcd51fb80 | |||
6dee988b76 | |||
5af40db396 | |||
b3553bee7a | |||
ac19c94b9f | |||
845f7dc331 | |||
2adeae37e1 | |||
16eb12b2a0 | |||
8411f2aa32 | |||
e8acc49cbd | |||
4bed073c65 | |||
272735fb26 | |||
b75cf2c189 | |||
1aaa992250 | |||
6256c066f1 | |||
870b89a8f0 | |||
65ac96913c |
2
.github/ISSUE_TEMPLATE.md
vendored
2
.github/ISSUE_TEMPLATE.md
vendored
@ -1,3 +1,5 @@
|
||||
If you have a configuration problem, please first try to create a basic configuration following the instructions on [the wiki](https://github.com/42wim/matterbridge/wiki/How-to-create-your-config) before filing an issue.
|
||||
|
||||
Please answer the following questions.
|
||||
|
||||
### Which version of matterbridge are you using?
|
||||
|
34
.travis.yml
Normal file
34
.travis.yml
Normal file
@ -0,0 +1,34 @@
|
||||
language: go
|
||||
go:
|
||||
- 1.7.x
|
||||
- 1.8.x
|
||||
- tip
|
||||
install: true
|
||||
|
||||
matrix:
|
||||
# It's ok if our code fails on unstable development versions of Go.
|
||||
allow_failures:
|
||||
- go: tip
|
||||
# Don't wait for tip tests to finish. Mark the test run green if the
|
||||
# tests pass on the stable versions of Go.
|
||||
fast_finish: true
|
||||
|
||||
notifications:
|
||||
email: false
|
||||
|
||||
before_script:
|
||||
- GO_FILES=$(find . -iname '*.go' | grep -v /vendor/) # All the .go files, excluding vendor/
|
||||
- PKGS=$(go list ./... | grep -v /vendor/) # All the import paths, excluding vendor/
|
||||
# - go get github.com/golang/lint/golint # Linter
|
||||
- go get honnef.co/go/tools/cmd/megacheck # Badass static analyzer/linter
|
||||
|
||||
# Anything in before_script: that returns a nonzero exit code will
|
||||
# flunk the build and immediately stop. It's sorta like having
|
||||
# set -e enabled in bash.
|
||||
script:
|
||||
script:
|
||||
- test -z $(gofmt -s -l $GO_FILES) # Fail if a .go file hasn't been formatted with gofmt
|
||||
#- go test -v -race $PKGS # Run all the tests with the race detector enabled
|
||||
- go vet $PKGS # go vet is the official Go static analyzer
|
||||
- megacheck $PKGS # "go vet on steroids" + linter
|
||||
#- golint -set_exit_status $PKGS # one last linter
|
20
README.md
20
README.md
@ -1,5 +1,7 @@
|
||||
# matterbridge
|
||||
[](https://gitter.im/42wim/matterbridge) [](https://webchat.freenode.net/?channels=matterbridgechat) [](https://discord.gg/AkKPtrQ) [](https://riot.im/app/#/room/#matterbridge:matrix.org)
|
||||
Click on one of the badges below to join the chat
|
||||
|
||||
[](https://gitter.im/42wim/matterbridge) [](https://webchat.freenode.net/?channels=matterbridgechat) [](https://discord.gg/AkKPtrQ) [](https://riot.im/app/#/room/#matterbridge:matrix.org) [](https://join.slack.com/matterbridgechat/shared_invite/MjEwODMxNjU1NDMwLTE0OTk2MTU3NTMtMzZkZmRiNDZhOA)
|
||||
|
||||

|
||||
|
||||
@ -13,6 +15,7 @@ Has a REST API.
|
||||
* [Binaries](#binaries)
|
||||
* [Building](#building)
|
||||
* [Configuration](#configuration)
|
||||
* [Howto](https://github.com/42wim/matterbridge/wiki/How-to-create-your-config)
|
||||
* [Examples](#examples)
|
||||
* [Running](#running)
|
||||
* [Docker](#docker)
|
||||
@ -30,7 +33,7 @@ Has a REST API.
|
||||
|
||||
# Requirements
|
||||
Accounts to one of the supported bridges
|
||||
* [Mattermost](https://github.com/mattermost/platform/) 3.5.x - 3.10.x
|
||||
* [Mattermost](https://github.com/mattermost/platform/) 3.5.x - 3.10.x, 4.0.x
|
||||
* [IRC](http://www.mirc.com/servers.html)
|
||||
* [XMPP](https://jabber.org)
|
||||
* [Gitter](https://gitter.im)
|
||||
@ -45,8 +48,7 @@ Accounts to one of the supported bridges
|
||||
# Installing
|
||||
## Binaries
|
||||
Binaries can be found [here] (https://github.com/42wim/matterbridge/releases/)
|
||||
* Latest rc release (with steam support) [v0.16.0-rc2](https://github.com/42wim/matterbridge/releases/latest)
|
||||
* Latest stable release [v0.15.0](https://github.com/42wim/matterbridge/releases/tag/v0.15.0)
|
||||
* Latest stable release [v0.16.1](https://github.com/42wim/matterbridge/releases/tag/v0.16.1)
|
||||
|
||||
## Building
|
||||
Go 1.6+ is required. Make sure you have [Go](https://golang.org/doc/install) properly installed, including setting up your [GOPATH] (https://golang.org/doc/code.html#GOPATH)
|
||||
@ -64,12 +66,12 @@ matterbridge
|
||||
```
|
||||
|
||||
# Configuration
|
||||
* [matterbridge.toml.sample](https://github.com/42wim/matterbridge/blob/master/matterbridge.toml.sample) for documentation and an example.
|
||||
* [matterbridge.toml.simple](https://github.com/42wim/matterbridge/blob/master/matterbridge.toml.simple) for a simple example.
|
||||
|
||||
## Create a configuration.
|
||||
## Basic configuration
|
||||
See [howto](https://github.com/42wim/matterbridge/wiki/How-to-create-your-config) for a step by step walkthrough for creating your configuration.
|
||||
|
||||
## Advanced configuration
|
||||
* [matterbridge.toml.sample](https://github.com/42wim/matterbridge/blob/master/matterbridge.toml.sample) for documentation and an example.
|
||||
|
||||
## Examples
|
||||
### Bridge mattermost (off-topic) - irc (#testing)
|
||||
```
|
||||
@ -181,6 +183,6 @@ Matterbridge wouldn't exist without these libraries:
|
||||
* mattermost - https://github.com/mattermost/platform
|
||||
* matrix - https://github.com/matrix-org/gomatrix
|
||||
* slack - https://github.com/nlopes/slack
|
||||
* steam - https://github.com/Philipp15b/go-steam
|
||||
* telegram - https://github.com/go-telegram-bot-api/telegram-bot-api
|
||||
* xmpp - https://github.com/mattn/go-xmpp
|
||||
|
||||
|
@ -88,10 +88,7 @@ func New(cfg *config.Config, bridge *config.Bridge, c chan config.Message) *Brid
|
||||
|
||||
func (b *Bridge) JoinChannels() error {
|
||||
err := b.joinChannels(b.Channels, b.Joined)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
return err
|
||||
}
|
||||
|
||||
func (b *Bridge) joinChannels(channels map[string]config.ChannelInfo, exists map[string]bool) error {
|
||||
|
@ -209,7 +209,7 @@ func Deprecated(cfg Protocol, account string) bool {
|
||||
log.Printf("ERROR: %s BindAddress is deprecated, you need to change it to WebhookBindAddress.", account)
|
||||
} else if cfg.URL != "" {
|
||||
log.Printf("ERROR: %s URL is deprecated, you need to change it to WebhookURL.", account)
|
||||
} else if cfg.UseAPI == true {
|
||||
} else if cfg.UseAPI {
|
||||
log.Printf("ERROR: %s UseAPI is deprecated, it's enabled by default, please remove it from your config file.", account)
|
||||
} else {
|
||||
return false
|
||||
|
@ -153,33 +153,41 @@ func (b *bdiscord) messageCreate(s *discordgo.Session, m *discordgo.MessageCreat
|
||||
if b.Config.WebhookURL != "" && m.Author.Bot && m.Author.ID == b.webhookID {
|
||||
return
|
||||
}
|
||||
|
||||
if len(m.Attachments) > 0 {
|
||||
for _, attach := range m.Attachments {
|
||||
m.Content = m.Content + "\n" + attach.URL
|
||||
}
|
||||
}
|
||||
if m.Content == "" {
|
||||
return
|
||||
|
||||
var text string
|
||||
if m.Content != "" {
|
||||
flog.Debugf("Receiving message %#v", m.Message)
|
||||
if len(m.MentionRoles) > 0 {
|
||||
m.Message.Content = b.replaceRoleMentions(m.Message.Content)
|
||||
}
|
||||
m.Message.Content = b.stripCustomoji(m.Message.Content)
|
||||
m.Message.Content = b.replaceChannelMentions(m.Message.Content)
|
||||
text = m.ContentWithMentionsReplaced()
|
||||
}
|
||||
flog.Debugf("Receiving message %#v", m.Message)
|
||||
|
||||
channelName := b.getChannelName(m.ChannelID)
|
||||
if b.UseChannelID {
|
||||
channelName = "ID:" + m.ChannelID
|
||||
}
|
||||
username := b.getNick(m.Author)
|
||||
if len(m.MentionRoles) > 0 {
|
||||
m.Message.Content = b.replaceRoleMentions(m.Message.Content)
|
||||
}
|
||||
m.Message.Content = b.stripCustomoji(m.Message.Content)
|
||||
m.Message.Content = b.replaceChannelMentions(m.Message.Content)
|
||||
|
||||
text := m.ContentWithMentionsReplaced()
|
||||
if b.Config.ShowEmbeds && m.Message.Embeds != nil {
|
||||
for _, embed := range m.Message.Embeds {
|
||||
text = text + "embed: " + embed.Title + " - " + embed.Description + " - " + embed.URL + "\n"
|
||||
}
|
||||
}
|
||||
|
||||
// no empty messages
|
||||
if text == "" {
|
||||
return
|
||||
}
|
||||
|
||||
flog.Debugf("Sending message from %s on %s to gateway", m.Author.Username, b.Account)
|
||||
b.Remote <- config.Message{Username: username, Text: text, Channel: channelName,
|
||||
Account: b.Account, Avatar: "https://cdn.discordapp.com/avatars/" + m.Author.ID + "/" + m.Author.Avatar + ".jpg",
|
||||
|
@ -4,6 +4,7 @@ import (
|
||||
"strings"
|
||||
)
|
||||
|
||||
/*
|
||||
func tableformatter(nicks []string, nicksPerRow int, continued bool) string {
|
||||
result := "|IRC users"
|
||||
if continued {
|
||||
@ -29,6 +30,7 @@ func tableformatter(nicks []string, nicksPerRow int, continued bool) string {
|
||||
}
|
||||
return result
|
||||
}
|
||||
*/
|
||||
|
||||
func plainformatter(nicks []string, nicksPerRow int) string {
|
||||
return strings.Join(nicks, ", ") + " currently on IRC"
|
||||
|
@ -148,9 +148,9 @@ func (b *Birc) Send(msg config.Message) error {
|
||||
|
||||
func (b *Birc) doSend() {
|
||||
rate := time.Millisecond * time.Duration(b.Config.MessageDelay)
|
||||
throttle := time.Tick(rate)
|
||||
throttle := time.NewTicker(rate)
|
||||
for msg := range b.Local {
|
||||
<-throttle
|
||||
<-throttle.C
|
||||
b.i.Privmsg(msg.Channel, msg.Username+msg.Text)
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
package bmattermost
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"github.com/42wim/matterbridge/bridge/config"
|
||||
"github.com/42wim/matterbridge/matterclient"
|
||||
"github.com/42wim/matterbridge/matterhook"
|
||||
@ -12,9 +13,8 @@ type MMhook struct {
|
||||
}
|
||||
|
||||
type MMapi struct {
|
||||
mc *matterclient.MMClient
|
||||
mmMap map[string]string
|
||||
mmIgnoreNicks []string
|
||||
mc *matterclient.MMClient
|
||||
mmMap map[string]string
|
||||
}
|
||||
|
||||
type MMMessage struct {
|
||||
@ -29,7 +29,6 @@ type Bmattermost struct {
|
||||
MMapi
|
||||
Config *config.Protocol
|
||||
Remote chan config.Message
|
||||
name string
|
||||
TeamId string
|
||||
Account string
|
||||
}
|
||||
@ -55,33 +54,49 @@ func (b *Bmattermost) Command(cmd string) string {
|
||||
}
|
||||
|
||||
func (b *Bmattermost) Connect() error {
|
||||
if b.Config.WebhookURL != "" && b.Config.WebhookBindAddress != "" {
|
||||
flog.Info("Connecting using webhookurl and webhookbindaddress")
|
||||
b.mh = matterhook.New(b.Config.WebhookURL,
|
||||
matterhook.Config{InsecureSkipVerify: b.Config.SkipTLSVerify,
|
||||
BindAddress: b.Config.WebhookBindAddress})
|
||||
} else if b.Config.WebhookURL != "" {
|
||||
flog.Info("Connecting using webhookurl (for posting) and token")
|
||||
if b.Config.WebhookBindAddress != "" {
|
||||
if b.Config.WebhookURL != "" {
|
||||
flog.Info("Connecting using webhookurl (sending) and webhookbindaddress (receiving)")
|
||||
} else if b.Config.Login != "" {
|
||||
flog.Info("Connecting using login/password (sending)")
|
||||
err := b.apiLogin()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
flog.Info("Connecting using webhookbindaddress (receiving)")
|
||||
b.mh = matterhook.New(b.Config.WebhookURL,
|
||||
matterhook.Config{InsecureSkipVerify: b.Config.SkipTLSVerify,
|
||||
BindAddress: b.Config.WebhookBindAddress})
|
||||
}
|
||||
go b.handleMatter()
|
||||
return nil
|
||||
}
|
||||
if b.Config.WebhookURL != "" {
|
||||
flog.Info("Connecting using webhookurl (sending)")
|
||||
b.mh = matterhook.New(b.Config.WebhookURL,
|
||||
matterhook.Config{InsecureSkipVerify: b.Config.SkipTLSVerify,
|
||||
DisableServer: true})
|
||||
} else {
|
||||
flog.Info("Connecting using token")
|
||||
b.mc = matterclient.New(b.Config.Login, b.Config.Password,
|
||||
b.Config.Team, b.Config.Server)
|
||||
b.mc.SkipTLSVerify = b.Config.SkipTLSVerify
|
||||
b.mc.NoTLS = b.Config.NoTLS
|
||||
flog.Infof("Connecting %s (team: %s) on %s", b.Config.Login, b.Config.Team, b.Config.Server)
|
||||
err := b.mc.Login()
|
||||
if b.Config.Login != "" {
|
||||
flog.Info("Connecting using login/password (receiving)")
|
||||
err := b.apiLogin()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
go b.handleMatter()
|
||||
}
|
||||
return nil
|
||||
} else if b.Config.Login != "" {
|
||||
flog.Info("Connecting using login/password (sending and receiving)")
|
||||
err := b.apiLogin()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
flog.Info("Connection succeeded")
|
||||
b.TeamId = b.mc.GetTeamId()
|
||||
go b.mc.WsReceiver()
|
||||
go b.mc.StatusLoop()
|
||||
go b.handleMatter()
|
||||
}
|
||||
if b.Config.WebhookBindAddress == "" && b.Config.WebhookURL == "" && b.Config.Login == "" {
|
||||
return errors.New("No connection method found. See that you have WebhookBindAddress, WebhookURL or Login/Password/Server/Team configured.")
|
||||
}
|
||||
go b.handleMatter()
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -126,11 +141,11 @@ func (b *Bmattermost) Send(msg config.Message) error {
|
||||
|
||||
func (b *Bmattermost) handleMatter() {
|
||||
mchan := make(chan *MMMessage)
|
||||
if b.Config.WebhookBindAddress != "" && b.Config.WebhookURL != "" {
|
||||
if b.Config.WebhookBindAddress != "" {
|
||||
flog.Debugf("Choosing webhooks based receiving")
|
||||
go b.handleMatterHook(mchan)
|
||||
} else {
|
||||
flog.Debugf("Choosing login (api) based receiving")
|
||||
flog.Debugf("Choosing login/password based receiving")
|
||||
go b.handleMatterClient(mchan)
|
||||
}
|
||||
for message := range mchan {
|
||||
@ -166,7 +181,7 @@ func (b *Bmattermost) handleMatterClient(mchan chan *MMMessage) {
|
||||
m.Text = message.Text + b.Config.EditSuffix
|
||||
}
|
||||
if len(message.Post.FileIds) > 0 {
|
||||
for _, link := range b.mc.GetPublicLinks(message.Post.FileIds) {
|
||||
for _, link := range b.mc.GetFileLinks(message.Post.FileIds) {
|
||||
m.Text = m.Text + "\n" + link
|
||||
}
|
||||
}
|
||||
@ -187,3 +202,20 @@ func (b *Bmattermost) handleMatterHook(mchan chan *MMMessage) {
|
||||
mchan <- m
|
||||
}
|
||||
}
|
||||
|
||||
func (b *Bmattermost) apiLogin() error {
|
||||
b.mc = matterclient.New(b.Config.Login, b.Config.Password,
|
||||
b.Config.Team, b.Config.Server)
|
||||
b.mc.SkipTLSVerify = b.Config.SkipTLSVerify
|
||||
b.mc.NoTLS = b.Config.NoTLS
|
||||
flog.Infof("Connecting %s (team: %s) on %s", b.Config.Login, b.Config.Team, b.Config.Server)
|
||||
err := b.mc.Login()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
flog.Info("Connection succeeded")
|
||||
b.TeamId = b.mc.GetTeamId()
|
||||
go b.mc.WsReceiver()
|
||||
go b.mc.StatusLoop()
|
||||
return nil
|
||||
}
|
||||
|
@ -16,7 +16,6 @@ type Brocketchat struct {
|
||||
MMhook
|
||||
Config *config.Protocol
|
||||
Remote chan config.Message
|
||||
name string
|
||||
Account string
|
||||
}
|
||||
|
||||
|
@ -1,11 +1,13 @@
|
||||
package bslack
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/42wim/matterbridge/bridge/config"
|
||||
"github.com/42wim/matterbridge/matterhook"
|
||||
log "github.com/Sirupsen/logrus"
|
||||
"github.com/nlopes/slack"
|
||||
"html"
|
||||
"regexp"
|
||||
"strings"
|
||||
"time"
|
||||
@ -52,22 +54,52 @@ func (b *Bslack) Command(cmd string) string {
|
||||
}
|
||||
|
||||
func (b *Bslack) Connect() error {
|
||||
if b.Config.WebhookURL != "" && b.Config.WebhookBindAddress != "" {
|
||||
flog.Info("Connecting using webhookurl and webhookbindaddress")
|
||||
if b.Config.WebhookBindAddress != "" {
|
||||
if b.Config.WebhookURL != "" {
|
||||
flog.Info("Connecting using webhookurl (sending) and webhookbindaddress (receiving)")
|
||||
b.mh = matterhook.New(b.Config.WebhookURL,
|
||||
matterhook.Config{InsecureSkipVerify: b.Config.SkipTLSVerify,
|
||||
BindAddress: b.Config.WebhookBindAddress})
|
||||
} else if b.Config.Token != "" {
|
||||
flog.Info("Connecting using token (sending)")
|
||||
b.sc = slack.New(b.Config.Token)
|
||||
b.rtm = b.sc.NewRTM()
|
||||
go b.rtm.ManageConnection()
|
||||
flog.Info("Connecting using webhookbindaddress (receiving)")
|
||||
b.mh = matterhook.New(b.Config.WebhookURL,
|
||||
matterhook.Config{InsecureSkipVerify: b.Config.SkipTLSVerify,
|
||||
BindAddress: b.Config.WebhookBindAddress})
|
||||
} else {
|
||||
flog.Info("Connecting using webhookbindaddress (receiving)")
|
||||
b.mh = matterhook.New(b.Config.WebhookURL,
|
||||
matterhook.Config{InsecureSkipVerify: b.Config.SkipTLSVerify,
|
||||
BindAddress: b.Config.WebhookBindAddress})
|
||||
}
|
||||
go b.handleSlack()
|
||||
return nil
|
||||
}
|
||||
if b.Config.WebhookURL != "" {
|
||||
flog.Info("Connecting using webhookurl (sending)")
|
||||
b.mh = matterhook.New(b.Config.WebhookURL,
|
||||
matterhook.Config{BindAddress: b.Config.WebhookBindAddress})
|
||||
} else if b.Config.WebhookURL != "" {
|
||||
flog.Info("Connecting using webhookurl (for posting) and token")
|
||||
b.mh = matterhook.New(b.Config.WebhookURL,
|
||||
matterhook.Config{DisableServer: true})
|
||||
} else {
|
||||
flog.Info("Connecting using token")
|
||||
matterhook.Config{InsecureSkipVerify: b.Config.SkipTLSVerify,
|
||||
DisableServer: true})
|
||||
if b.Config.Token != "" {
|
||||
flog.Info("Connecting using token (receiving)")
|
||||
b.sc = slack.New(b.Config.Token)
|
||||
b.rtm = b.sc.NewRTM()
|
||||
go b.rtm.ManageConnection()
|
||||
go b.handleSlack()
|
||||
}
|
||||
} else if b.Config.Token != "" {
|
||||
flog.Info("Connecting using token (sending and receiving)")
|
||||
b.sc = slack.New(b.Config.Token)
|
||||
b.rtm = b.sc.NewRTM()
|
||||
go b.rtm.ManageConnection()
|
||||
go b.handleSlack()
|
||||
}
|
||||
if b.Config.WebhookBindAddress == "" && b.Config.WebhookURL == "" && b.Config.Token == "" {
|
||||
return errors.New("No connection method found. See that you have WebhookBindAddress, WebhookURL or Token configured.")
|
||||
}
|
||||
flog.Info("Connection succeeded")
|
||||
go b.handleSlack()
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -78,7 +110,7 @@ func (b *Bslack) Disconnect() error {
|
||||
|
||||
func (b *Bslack) JoinChannel(channel string) error {
|
||||
// we can only join channels using the API
|
||||
if b.Config.WebhookURL == "" || b.Config.WebhookBindAddress == "" {
|
||||
if b.Config.WebhookURL == "" && b.Config.WebhookBindAddress == "" {
|
||||
if strings.HasPrefix(b.Config.Token, "xoxb") {
|
||||
// TODO check if bot has already joined channel
|
||||
return nil
|
||||
@ -119,7 +151,7 @@ func (b *Bslack) Send(msg config.Message) error {
|
||||
return err
|
||||
}
|
||||
np := slack.NewPostMessageParameters()
|
||||
if b.Config.PrefixMessagesWithNick == true {
|
||||
if b.Config.PrefixMessagesWithNick {
|
||||
np.AsUser = true
|
||||
}
|
||||
np.Username = nick
|
||||
@ -175,7 +207,7 @@ func (b *Bslack) getChannelByID(ID string) (*slack.Channel, error) {
|
||||
|
||||
func (b *Bslack) handleSlack() {
|
||||
mchan := make(chan *MMMessage)
|
||||
if b.Config.WebhookBindAddress != "" && b.Config.WebhookURL != "" {
|
||||
if b.Config.WebhookBindAddress != "" {
|
||||
flog.Debugf("Choosing webhooks based receiving")
|
||||
go b.handleMatterHook(mchan)
|
||||
} else {
|
||||
@ -192,6 +224,7 @@ func (b *Bslack) handleSlack() {
|
||||
texts := strings.Split(message.Text, "\n")
|
||||
for _, text := range texts {
|
||||
text = b.replaceURL(text)
|
||||
text = html.UnescapeString(text)
|
||||
flog.Debugf("Sending message from %s on %s to gateway", message.Username, b.Account)
|
||||
b.Remote <- config.Message{Text: text, Username: message.Username, Channel: message.Channel, Account: b.Account, Avatar: b.getAvatar(message.Username), UserID: message.UserID}
|
||||
}
|
||||
@ -227,6 +260,15 @@ func (b *Bslack) handleSlackClient(mchan chan *MMMessage) {
|
||||
m.Text = ev.Text
|
||||
m.Raw = ev
|
||||
m.Text = b.replaceMention(m.Text)
|
||||
if ev.BotID != "" && user.Name == "" {
|
||||
bot, err := b.rtm.GetBotInfo(ev.BotID)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
if bot.Name != "" {
|
||||
m.Username = bot.Name
|
||||
}
|
||||
}
|
||||
mchan <- m
|
||||
}
|
||||
count++
|
||||
|
@ -136,7 +136,7 @@ func (b *Bsteam) handleEvents() {
|
||||
myLoginInfo.AuthCode = code
|
||||
}
|
||||
default:
|
||||
log.Errorf("LogOnFailedEvent: ", e.Result)
|
||||
log.Errorf("LogOnFailedEvent: %#v ", e.Result)
|
||||
// TODO: Handle EResult_InvalidLoginAuthCode
|
||||
return
|
||||
}
|
||||
|
44
changelog.md
44
changelog.md
@ -1,3 +1,47 @@
|
||||
# v0.16.1
|
||||
## New features
|
||||
* slack: also relay messages of other bots #213
|
||||
* mattermost: show also links if public links have not been enabled.
|
||||
|
||||
## Bugfix
|
||||
* mattermost, slack: fix connecting logic #216
|
||||
|
||||
# v0.16.0
|
||||
## Breaking Changes
|
||||
* URL,UseAPI,BindAddress is deprecated. Your config has to be updated.
|
||||
* URL => WebhookURL
|
||||
* BindAddress => WebhookBindAddress
|
||||
* UseAPI => removed
|
||||
This change allows you to specify a WebhookURL and a token (slack,discord), so that
|
||||
messages will be sent with the webhook, but received via the token (API)
|
||||
If you have not specified WebhookURL and WebhookBindAddress the API (login or token)
|
||||
will be used automatically. (no need for UseAPI)
|
||||
|
||||
## New features
|
||||
* mattermost: add support for mattermost 4.0
|
||||
* steam: New protocol support added (http://store.steampowered.com/)
|
||||
* discord: Support for embedded messages (sent by other bots)
|
||||
Shows title, description and URL of embedded messages (sent by other bots)
|
||||
To enable add ```ShowEmbeds=true``` to your discord config
|
||||
* discord: ```WebhookURL``` posting support added (thanks @saury07) #204
|
||||
Discord API does not allow to change the name of the user posting, but webhooks does.
|
||||
|
||||
## Changes
|
||||
* general: all :emoji: will be converted to unicode, providing consistent emojis across all bridges
|
||||
* telegram: Add ```UseInsecureURL``` option for telegram (default false)
|
||||
WARNING! If enabled this will relay GIF/stickers/documents and other attachments as URLs
|
||||
Those URLs will contain your bot-token. This may not be what you want.
|
||||
For now there is no secure way to relay GIF/stickers/documents without seeing your token.
|
||||
|
||||
## Bugfix
|
||||
* irc: detect charset and try to convert it to utf-8 before sending it to other bridges. #209 #210
|
||||
* slack: Remove label from URLs (slack). #205
|
||||
* slack: Relay <>& correctly to other bridges #215
|
||||
* steam: Fix channel id bug in steam (channels are off by 0x18000000000000)
|
||||
* general: various improvements
|
||||
* general: samechannelgateway now relays messages correct again #207
|
||||
|
||||
|
||||
# v0.16.0-rc2
|
||||
## Breaking Changes
|
||||
* URL,UseAPI,BindAddress is deprecated. Your config has to be updated.
|
||||
|
@ -5,6 +5,7 @@ import (
|
||||
"github.com/42wim/matterbridge/bridge"
|
||||
"github.com/42wim/matterbridge/bridge/config"
|
||||
log "github.com/Sirupsen/logrus"
|
||||
"github.com/peterhellberg/emojilib"
|
||||
// "github.com/davecgh/go-spew/spew"
|
||||
"regexp"
|
||||
"strings"
|
||||
@ -95,30 +96,28 @@ func (gw *Gateway) Start() error {
|
||||
}
|
||||
|
||||
func (gw *Gateway) handleReceive() {
|
||||
for {
|
||||
select {
|
||||
case msg := <-gw.Message:
|
||||
if msg.Event == config.EVENT_FAILURE {
|
||||
for _, br := range gw.Bridges {
|
||||
if msg.Account == br.Account {
|
||||
go gw.reconnectBridge(br)
|
||||
}
|
||||
for msg := range gw.Message {
|
||||
if msg.Event == config.EVENT_FAILURE {
|
||||
for _, br := range gw.Bridges {
|
||||
if msg.Account == br.Account {
|
||||
go gw.reconnectBridge(br)
|
||||
}
|
||||
}
|
||||
if msg.Event == config.EVENT_REJOIN_CHANNELS {
|
||||
for _, br := range gw.Bridges {
|
||||
if msg.Account == br.Account {
|
||||
br.Joined = make(map[string]bool)
|
||||
br.JoinChannels()
|
||||
}
|
||||
}
|
||||
if msg.Event == config.EVENT_REJOIN_CHANNELS {
|
||||
for _, br := range gw.Bridges {
|
||||
if msg.Account == br.Account {
|
||||
br.Joined = make(map[string]bool)
|
||||
br.JoinChannels()
|
||||
}
|
||||
continue
|
||||
}
|
||||
if !gw.ignoreMessage(&msg) {
|
||||
msg.Timestamp = time.Now()
|
||||
for _, br := range gw.Bridges {
|
||||
gw.handleMessage(msg, br)
|
||||
}
|
||||
continue
|
||||
}
|
||||
if !gw.ignoreMessage(&msg) {
|
||||
msg.Timestamp = time.Now()
|
||||
gw.modifyMessage(&msg)
|
||||
for _, br := range gw.Bridges {
|
||||
gw.handleMessage(msg, br)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -296,6 +295,11 @@ func (gw *Gateway) modifyAvatar(msg *config.Message, dest *bridge.Bridge) {
|
||||
}
|
||||
}
|
||||
|
||||
func (gw *Gateway) modifyMessage(msg *config.Message) {
|
||||
// replace :emoji: to unicode
|
||||
msg.Text = emojilib.Replace(msg.Text)
|
||||
}
|
||||
|
||||
func getChannelID(msg config.Message) string {
|
||||
return msg.Channel + msg.Account
|
||||
}
|
||||
@ -310,8 +314,8 @@ func (gw *Gateway) validGatewayDest(msg *config.Message, channel *config.Channel
|
||||
|
||||
// check if we are running a samechannelgateway.
|
||||
// if it is and the channel name matches it's ok, otherwise we shouldn't use this channel.
|
||||
for k, _ := range GIDmap {
|
||||
if channel.SameChannel[k] == true {
|
||||
for k := range GIDmap {
|
||||
if channel.SameChannel[k] {
|
||||
if msg.Channel == channel.Name {
|
||||
// add the gateway to our message
|
||||
msg.Gateway = k
|
||||
@ -322,8 +326,8 @@ func (gw *Gateway) validGatewayDest(msg *config.Message, channel *config.Channel
|
||||
}
|
||||
}
|
||||
// check if we are in the correct gateway
|
||||
for k, _ := range GIDmap {
|
||||
if channel.GID[k] == true {
|
||||
for k := range GIDmap {
|
||||
if channel.GID[k] {
|
||||
// add the gateway to our message
|
||||
msg.Gateway = k
|
||||
return true
|
||||
@ -333,8 +337,5 @@ func (gw *Gateway) validGatewayDest(msg *config.Message, channel *config.Channel
|
||||
}
|
||||
|
||||
func isApi(account string) bool {
|
||||
if strings.HasPrefix(account, "api.") {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
return strings.HasPrefix(account, "api.")
|
||||
}
|
||||
|
@ -99,10 +99,9 @@ func (c *Client) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
// Receive returns an incoming message from mattermost outgoing webhooks URL.
|
||||
func (c *Client) Receive() Message {
|
||||
for {
|
||||
select {
|
||||
case msg := <-c.In:
|
||||
return msg
|
||||
}
|
||||
var msg Message
|
||||
for msg = range c.In {
|
||||
return msg
|
||||
}
|
||||
return msg
|
||||
}
|
||||
|
@ -12,7 +12,7 @@ import (
|
||||
)
|
||||
|
||||
var (
|
||||
version = "0.16.0-rc2"
|
||||
version = "0.16.1"
|
||||
githash string
|
||||
)
|
||||
|
||||
|
@ -88,7 +88,7 @@ func (m *MMClient) SetLogLevel(level string) {
|
||||
func (m *MMClient) Login() error {
|
||||
// check if this is a first connect or a reconnection
|
||||
firstConnection := true
|
||||
if m.WsConnected == true {
|
||||
if m.WsConnected {
|
||||
firstConnection = false
|
||||
}
|
||||
m.WsConnected = false
|
||||
@ -149,7 +149,7 @@ func (m *MMClient) Login() error {
|
||||
return errors.New("invalid " + model.SESSION_COOKIE_TOKEN)
|
||||
}
|
||||
} else {
|
||||
myinfo, appErr = m.Client.Login(m.Credentials.Login, m.Credentials.Pass)
|
||||
_, appErr = m.Client.Login(m.Credentials.Login, m.Credentials.Pass)
|
||||
}
|
||||
if appErr != nil {
|
||||
d := b.Duration()
|
||||
@ -329,7 +329,6 @@ func (m *MMClient) parseActionPost(rmsg *Message) {
|
||||
}
|
||||
rmsg.Text = data.Message
|
||||
rmsg.Post = data
|
||||
return
|
||||
}
|
||||
|
||||
func (m *MMClient) UpdateUsers() error {
|
||||
@ -500,6 +499,25 @@ func (m *MMClient) GetPublicLinks(filenames []string) []string {
|
||||
return output
|
||||
}
|
||||
|
||||
func (m *MMClient) GetFileLinks(filenames []string) []string {
|
||||
uriScheme := "https://"
|
||||
if m.NoTLS {
|
||||
uriScheme = "http://"
|
||||
}
|
||||
|
||||
var output []string
|
||||
for _, f := range filenames {
|
||||
res, err := m.Client.GetPublicLink(f)
|
||||
if err != nil {
|
||||
// public links is probably disabled, create the link ourselves
|
||||
output = append(output, uriScheme+m.Credentials.Server+model.API_URL_SUFFIX_V3+"/files/"+f+"/get")
|
||||
continue
|
||||
}
|
||||
output = append(output, res)
|
||||
}
|
||||
return output
|
||||
}
|
||||
|
||||
func (m *MMClient) UpdateChannelHeader(channelId string, header string) {
|
||||
data := make(map[string]string)
|
||||
data["channel_id"] = channelId
|
||||
@ -516,7 +534,7 @@ func (m *MMClient) UpdateLastViewed(channelId string) {
|
||||
if m.mmVersion() >= 3.08 {
|
||||
view := model.ChannelView{ChannelId: channelId}
|
||||
res, _ := m.Client.ViewChannel(view)
|
||||
if res == false {
|
||||
if !res {
|
||||
m.log.Errorf("ChannelView update for %s failed", channelId)
|
||||
}
|
||||
return
|
||||
@ -664,13 +682,13 @@ func (m *MMClient) GetUsers() map[string]*model.User {
|
||||
func (m *MMClient) GetUser(userId string) *model.User {
|
||||
m.Lock()
|
||||
defer m.Unlock()
|
||||
u, ok := m.Users[userId]
|
||||
_, ok := m.Users[userId]
|
||||
if !ok {
|
||||
res, err := m.Client.GetProfilesByIds([]string{userId})
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
u = res.Data.(map[string]*model.User)[userId]
|
||||
u := res.Data.(map[string]*model.User)[userId]
|
||||
m.Users[userId] = u
|
||||
}
|
||||
return m.Users[userId]
|
||||
@ -833,7 +851,8 @@ func supportedVersion(version string) bool {
|
||||
strings.HasPrefix(version, "3.7.0") ||
|
||||
strings.HasPrefix(version, "3.8.0") ||
|
||||
strings.HasPrefix(version, "3.9.0") ||
|
||||
strings.HasPrefix(version, "3.10.0") {
|
||||
strings.HasPrefix(version, "3.10.0") ||
|
||||
strings.HasPrefix(version, "4.0") {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
|
@ -134,12 +134,11 @@ func (c *Client) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
// Receive returns an incoming message from mattermost outgoing webhooks URL.
|
||||
func (c *Client) Receive() IMessage {
|
||||
for {
|
||||
select {
|
||||
case msg := <-c.In:
|
||||
return msg
|
||||
}
|
||||
var msg IMessage
|
||||
for msg := range c.In {
|
||||
return msg
|
||||
}
|
||||
return msg
|
||||
}
|
||||
|
||||
// Send sends a msg to mattermost incoming webhooks URL.
|
||||
|
19
vendor/github.com/peterhellberg/emojilib/LICENSE
generated
vendored
Normal file
19
vendor/github.com/peterhellberg/emojilib/LICENSE
generated
vendored
Normal file
@ -0,0 +1,19 @@
|
||||
Copyright (c) 2015-2017 Peter Hellberg https://c7.se/
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the "Software"),
|
||||
to deal in the Software without restriction, including without limitation
|
||||
the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
and/or sell copies of the Software, and to permit persons to whom the
|
||||
Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included
|
||||
in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
|
||||
OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
88
vendor/github.com/peterhellberg/emojilib/emojilib.go
generated
vendored
Normal file
88
vendor/github.com/peterhellberg/emojilib/emojilib.go
generated
vendored
Normal file
@ -0,0 +1,88 @@
|
||||
/*
|
||||
|
||||
Package emojilib is a port of the Emoji keyword library to Go
|
||||
|
||||
Installation
|
||||
|
||||
Just go get the package:
|
||||
|
||||
go get -u github.com/peterhellberg/emojilib
|
||||
|
||||
Usage
|
||||
|
||||
A small usage example
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/peterhellberg/emojilib"
|
||||
)
|
||||
|
||||
func main() {
|
||||
fmt.Println(emojilib.ReplaceWithPadding("I :green_heart: You!"))
|
||||
}
|
||||
|
||||
*/
|
||||
package emojilib
|
||||
|
||||
import "errors"
|
||||
|
||||
//go:generate go run _generator/main.go
|
||||
|
||||
// Emojis contain emojis keyed on their name
|
||||
type Emojis map[string]Emoji
|
||||
|
||||
// Emoji contains the keywords, char and category for an emoji
|
||||
type Emoji struct {
|
||||
Keywords []string `json:"keywords"`
|
||||
Char string `json:"char"`
|
||||
Category string `json:"category"`
|
||||
}
|
||||
|
||||
// ErrUnknownEmoji is returned from Find if provided with a unknown emoji name
|
||||
var ErrUnknownEmoji = errors.New("unknown emoji")
|
||||
|
||||
// ErrUnknownKeyword is returned from Keyword if provided with a unknown keyword
|
||||
var ErrUnknownKeyword = errors.New("unknown keyword")
|
||||
|
||||
// Find returns an Emoji if provided with a known name
|
||||
func Find(n string) (Emoji, error) {
|
||||
if e, ok := emojis[n]; ok {
|
||||
return e, nil
|
||||
}
|
||||
|
||||
return Emoji{}, ErrUnknownEmoji
|
||||
}
|
||||
|
||||
// Keyword returns Emojis for the given keyword
|
||||
func Keyword(k string) ([]Emoji, error) {
|
||||
if names, ok := keywordLookup[k]; ok {
|
||||
es := []Emoji{}
|
||||
|
||||
for _, n := range names {
|
||||
es = append(es, emojis[n])
|
||||
}
|
||||
|
||||
return es, nil
|
||||
}
|
||||
|
||||
return []Emoji{}, ErrUnknownKeyword
|
||||
}
|
||||
|
||||
// All returns all the emojis
|
||||
func All() Emojis {
|
||||
return emojis
|
||||
}
|
||||
|
||||
// Replace takes a string and replaces all emoji names with their emoji character
|
||||
func Replace(s string) string {
|
||||
return emojiReplacer.Replace(s)
|
||||
}
|
||||
|
||||
// ReplaceWithPadding takes a string and replaces all emoji names with their
|
||||
// emoji character and a space in order to display better in terminals
|
||||
func ReplaceWithPadding(s string) string {
|
||||
return emojiPaddedReplacer.Replace(s)
|
||||
}
|
19620
vendor/github.com/peterhellberg/emojilib/generated.go
generated
vendored
Normal file
19620
vendor/github.com/peterhellberg/emojilib/generated.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
8
vendor/manifest
vendored
8
vendor/manifest
vendored
@ -416,6 +416,14 @@
|
||||
"branch": "master",
|
||||
"notests": true
|
||||
},
|
||||
{
|
||||
"importpath": "github.com/peterhellberg/emojilib",
|
||||
"repository": "https://github.com/peterhellberg/emojilib",
|
||||
"vcs": "git",
|
||||
"revision": "41920917e2710c9f0ec22d29db182f60e7ed9d11",
|
||||
"branch": "master",
|
||||
"notests": true
|
||||
},
|
||||
{
|
||||
"importpath": "github.com/peterhellberg/giphy",
|
||||
"repository": "https://github.com/peterhellberg/giphy",
|
||||
|
Reference in New Issue
Block a user