summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWim <wim@42.be>2016-07-14 00:23:50 +0200
committerWim <wim@42.be>2016-08-14 22:40:26 +0200
commit1f72ca4c4ecb5ab3ef831b8e70c74909f5720fb8 (patch)
tree3240335d69700fe216c1a966a8cbb09703f2f08c
parent46faad8b57c7c02e2ec158fe7462f751ba63c3be (diff)
downloadmatterbridge-msglm-1f72ca4c4ecb5ab3ef831b8e70c74909f5720fb8.tar.gz
matterbridge-msglm-1f72ca4c4ecb5ab3ef831b8e70c74909f5720fb8.tar.bz2
matterbridge-msglm-1f72ca4c4ecb5ab3ef831b8e70c74909f5720fb8.zip
Add initial XMPP support
-rw-r--r--bridge/bridge.go167
-rw-r--r--bridge/config.go10
-rw-r--r--matterbridge.conf.sample30
3 files changed, 182 insertions, 25 deletions
diff --git a/bridge/bridge.go b/bridge/bridge.go
index 034aed6f..76654c40 100644
--- a/bridge/bridge.go
+++ b/bridge/bridge.go
@@ -5,6 +5,7 @@ import (
"github.com/42wim/matterbridge/matterclient"
"github.com/42wim/matterbridge/matterhook"
log "github.com/Sirupsen/logrus"
+ "github.com/mattn/go-xmpp"
"github.com/peterhellberg/giphy"
ircm "github.com/sorcix/irc"
"github.com/thoj/go-ircevent"
@@ -26,6 +27,10 @@ type MMapi struct {
mmIgnoreNicks []string
}
+type MMxmpp struct {
+ xc *xmpp.Client
+ xmppMap map[string]string
+}
type MMirc struct {
i *irc.Connection
ircNick string
@@ -44,13 +49,15 @@ type Bridge struct {
MMhook
MMapi
MMirc
+ MMxmpp
*Config
kind string
}
type FancyLog struct {
- irc *log.Entry
- mm *log.Entry
+ irc *log.Entry
+ mm *log.Entry
+ xmpp *log.Entry
}
var flog FancyLog
@@ -60,6 +67,7 @@ const Legacy = "legacy"
func initFLog() {
flog.irc = log.WithFields(log.Fields{"module": "irc"})
flog.mm = log.WithFields(log.Fields{"module": "mattermost"})
+ flog.xmpp = log.WithFields(log.Fields{"module": "xmpp"})
}
func NewBridge(name string, config *Config, kind string) *Bridge {
@@ -67,16 +75,26 @@ func NewBridge(name string, config *Config, kind string) *Bridge {
b := &Bridge{}
b.Config = config
b.kind = kind
- b.ircNick = b.Config.IRC.Nick
- b.ircMap = make(map[string]string)
b.mmMap = make(map[string]string)
- b.MMirc.names = make(map[string][]string)
- b.ircIgnoreNicks = strings.Fields(b.Config.IRC.IgnoreNicks)
- b.mmIgnoreNicks = strings.Fields(b.Config.Mattermost.IgnoreNicks)
- for _, val := range b.Config.Channel {
- b.ircMap[val.IRC] = val.Mattermost
- b.mmMap[val.Mattermost] = val.IRC
+ if b.Config.General.Irc {
+ b.ircNick = b.Config.IRC.Nick
+ b.ircMap = make(map[string]string)
+ b.MMirc.names = make(map[string][]string)
+ b.ircIgnoreNicks = strings.Fields(b.Config.IRC.IgnoreNicks)
+ b.mmIgnoreNicks = strings.Fields(b.Config.Mattermost.IgnoreNicks)
+ for _, val := range b.Config.Channel {
+ b.ircMap[val.IRC] = val.Mattermost
+ b.mmMap[val.Mattermost] = val.IRC
+ }
+ }
+ if b.Config.General.Xmpp {
+ b.xmppMap = make(map[string]string)
+ for _, val := range b.Config.Channel {
+ b.xmppMap[val.Xmpp] = val.Mattermost
+ b.mmMap[val.Mattermost] = val.Xmpp
+ }
}
+
if kind == Legacy {
b.mh = matterhook.New(b.Config.Mattermost.URL,
matterhook.Config{InsecureSkipVerify: b.Config.Mattermost.SkipTLSVerify,
@@ -98,9 +116,25 @@ func NewBridge(name string, config *Config, kind string) *Bridge {
}
go b.mc.WsReceiver()
}
- flog.irc.Info("Trying IRC connection")
- b.i = b.createIRC(name)
- flog.irc.Info("Connection succeeded")
+
+ if b.Config.General.Irc {
+ flog.irc.Info("Trying IRC connection")
+ b.i = b.createIRC(name)
+ flog.irc.Info("Connection succeeded")
+ }
+ if b.Config.General.Xmpp {
+ var err error
+ flog.xmpp.Info("Trying XMPP connection")
+ b.xc, err = b.createXMPP()
+ if err != nil {
+ flog.xmpp.Debugf("%#v", err)
+ panic("xmpp failure")
+ }
+ flog.xmpp.Info("Connection succeeded")
+ b.setupChannels()
+ go b.handleXmpp()
+ }
+
go b.handleMatter()
return b
}
@@ -123,6 +157,25 @@ func (b *Bridge) createIRC(name string) *irc.Connection {
return i
}
+func (b *Bridge) createXMPP() (*xmpp.Client, error) {
+ options := xmpp.Options{
+ Host: b.Config.Xmpp.Server,
+ User: b.Config.Xmpp.Jid,
+ Password: b.Config.Xmpp.Password,
+ NoTLS: true,
+ StartTLS: true,
+ Debug: true,
+ Session: true,
+ Status: "",
+ StatusMessage: "",
+ Resource: "",
+ InsecureAllowUnencryptedAuth: false,
+ }
+ var err error
+ b.xc, err = options.NewClient()
+ return b.xc, err
+}
+
func (b *Bridge) handleNewConnection(event *irc.Event) {
flog.irc.Info("Registering callbacks")
i := b.i
@@ -147,11 +200,19 @@ func (b *Bridge) handleNewConnection(event *irc.Event) {
}
func (b *Bridge) setupChannels() {
- i := b.i
- for _, val := range b.Config.Channel {
- flog.irc.Infof("Joining %s as %s", val.IRC, b.ircNick)
- i.Join(val.IRC)
+ if b.Config.General.Irc {
+ for _, val := range b.Config.Channel {
+ flog.irc.Infof("Joining %s as %s", val.IRC, b.ircNick)
+ b.i.Join(val.IRC)
+ }
}
+ if b.Config.General.Xmpp {
+ for _, val := range b.Config.Channel {
+ flog.xmpp.Infof("Joining %s as %s", val.Xmpp, b.Xmpp.Nick)
+ b.xc.JoinMUCNoHistory(val.Xmpp+"@"+b.Xmpp.Muc, b.Xmpp.Nick)
+ }
+ }
+
}
func (b *Bridge) handleIrcBotCommand(event *irc.Event) bool {
@@ -340,9 +401,11 @@ func (b *Bridge) handleMatter() {
if b.ignoreMessage(message.Username, message.Text, "mattermost") {
continue
}
- username = message.Username + ": "
- if b.Config.IRC.RemoteNickFormat != "" {
- username = strings.Replace(b.Config.IRC.RemoteNickFormat, "{NICK}", message.Username, -1)
+ if b.Config.General.Irc {
+ username = message.Username + ": "
+ if b.Config.IRC.RemoteNickFormat != "" {
+ username = strings.Replace(b.Config.IRC.RemoteNickFormat, "{NICK}", message.Username, -1)
+ }
}
cmds := strings.Fields(message.Text)
// empty message
@@ -353,17 +416,27 @@ func (b *Bridge) handleMatter() {
switch cmd {
case "!users":
flog.mm.Info("Received !users from ", message.Username)
- b.i.SendRaw("NAMES " + b.getIRCChannel(message.Channel))
+ if b.Config.General.Irc {
+ b.i.SendRaw("NAMES " + b.getIRCChannel(message.Channel))
+ }
continue
case "!gif":
message.Text = b.giphyRandom(strings.Fields(strings.Replace(message.Text, "!gif ", "", 1)))
- b.Send(b.ircNick, message.Text, b.getIRCChannel(message.Channel))
+ if b.Config.General.Irc {
+ b.Send(b.ircNick, message.Text, b.getIRCChannel(message.Channel))
+ }
continue
}
texts := strings.Split(message.Text, "\n")
for _, text := range texts {
flog.mm.Debug("Sending message from " + message.Username + " to " + message.Channel)
- b.i.Privmsg(b.getIRCChannel(message.Channel), username+text)
+ if b.Config.General.Irc {
+ b.i.Privmsg(b.getIRCChannel(message.Channel), username+text)
+ }
+ if b.Config.General.Xmpp {
+ b.xc.Send(xmpp.Chat{Type: "groupchat", Remote: "testje@c.sw.be", Text: username + text})
+
+ }
}
}
}
@@ -380,8 +453,14 @@ func (b *Bridge) giphyRandom(query []string) string {
return res.Data.FixedHeightDownsampledURL
}
-func (b *Bridge) getMMChannel(ircChannel string) string {
- mmChannel := b.ircMap[ircChannel]
+func (b *Bridge) getMMChannel(channel string) string {
+ var mmChannel string
+ if b.Config.General.Irc {
+ mmChannel = b.ircMap[channel]
+ }
+ if b.Config.General.Xmpp {
+ mmChannel = b.xmppMap[channel]
+ }
if b.kind == Legacy {
return mmChannel
}
@@ -405,3 +484,41 @@ func (b *Bridge) ignoreMessage(nick string, message string, protocol string) boo
}
return false
}
+
+func (b *Bridge) xmppKeepAlive() {
+ go func() {
+ ticker := time.NewTicker(90 * time.Second)
+ for {
+ select {
+ case <-ticker.C:
+ b.xc.Send(xmpp.Chat{})
+ }
+ }
+ }()
+}
+
+func (b *Bridge) handleXmpp() error {
+ for {
+ m, err := b.xc.Recv()
+ if err != nil {
+ return err
+ }
+ switch v := m.(type) {
+ case xmpp.Chat:
+ var channel, nick string
+ if v.Type == "groupchat" {
+ s := strings.Split(v.Remote, "@")
+ if len(s) == 2 {
+ channel = s[0]
+ }
+ s = strings.Split(s[1], "/")
+ if len(s) == 2 {
+ nick = s[1]
+ }
+ b.Send(nick, v.Text, b.getMMChannel(channel))
+ }
+ case xmpp.Presence:
+ // do nothing
+ }
+ }
+}
diff --git a/bridge/config.go b/bridge/config.go
index 3750a1a0..274d4261 100644
--- a/bridge/config.go
+++ b/bridge/config.go
@@ -38,12 +38,22 @@ type Config struct {
IgnoreNicks string
NoTLS bool
}
+ Xmpp struct {
+ Jid string
+ Password string
+ Server string
+ Muc string
+ Nick string
+ }
Channel map[string]*struct {
IRC string
Mattermost string
+ Xmpp string
}
General struct {
GiphyAPIKey string
+ Xmpp bool
+ Irc bool
}
}
diff --git a/matterbridge.conf.sample b/matterbridge.conf.sample
index 55746539..a8afc48c 100644
--- a/matterbridge.conf.sample
+++ b/matterbridge.conf.sample
@@ -42,6 +42,31 @@ RemoteNickFormat="{NICK}: "
IgnoreNicks="ircspammer1 ircspammer2"
###################################################################
+#XMPP section
+###################################################################
+[XMPP]
+#xmpp server to connect to.
+#REQUIRED
+Server="jabber.example.com:5222"
+
+#Jid
+#REQUIRED
+Jid="user@example.com"
+
+#Password
+#REQUIRED
+Password="yourpass"
+
+#MUC
+#REQUIRED
+Muc="conference.jabber.example.com"
+
+#Your nick in the rooms
+#REQUIRED
+Nick="xmppbot"
+
+
+###################################################################
#mattermost section
###################################################################
@@ -146,3 +171,8 @@ mattermost="testing"
#request your API key on https://github.com/giphy/GiphyAPI. This is a public beta key.
#OPTIONAL
GiphyApiKey="dc6zaTOxFJmzC"
+
+#Choose only one protocol to bridge, do not set both to true!
+#REQUIRED
+Irc=true
+Xmpp=false