Thumbnail

rani/matterbridge.git

Clone URL: https://git.buni.party/rani/matterbridge.git

commit 56c5d6fb98127cc3311a68a1212ab18608f073f1 Author: Wim <wim@42.be> Date: Sun Sep 04 20:03:07 2016 +0000 Add Gitter support diff --git a/bridge/bridge.go b/bridge/bridge.go index 5754ca9..047370b 100644 --- a/bridge/bridge.go +++ b/bridge/bridge.go @@ -36 +37 @@ package bridge  import (   //"fmt"   "github.com/42wim/matterbridge/bridge/config" + "github.com/42wim/matterbridge/bridge/gitter"   "github.com/42wim/matterbridge/bridge/irc"   "github.com/42wim/matterbridge/bridge/mattermost"   "github.com/42wim/matterbridge/bridge/xmpp" @@ -386 +399 @@ func NewBridge(cfg *config.Config) error {   if cfg.Xmpp.Enable {   b.Bridges = append(b.Bridges, bxmpp.New(cfg, c))   } + if cfg.Gitter.Enable { + b.Bridges = append(b.Bridges, bgitter.New(cfg, c)) + }   if len(b.Bridges) < 2 {   log.Fatalf("only %d sections enabled. Need at least 2 sections enabled (eg [IRC] and [mattermost]", len(b.Bridges))   } @@ -676 +717 @@ func (b *Bridge) mapChannels() error {   m["irc"] = val.IRC   m["mattermost"] = val.Mattermost   m["xmpp"] = val.Xmpp + m["gitter"] = val.Gitter   b.Channels = append(b.Channels, m)   }   return nil @@ -767 +818 @@ func (b *Bridge) mapIgnores() {   m := make(map[string][]string)   m["irc"] = strings.Fields(b.Config.IRC.IgnoreNicks)   m["mattermost"] = strings.Fields(b.Config.Mattermost.IgnoreNicks) - m["xmpp"] = strings.Fields(b.Config.Mattermost.IgnoreNicks) + m["xmpp"] = strings.Fields(b.Config.Xmpp.IgnoreNicks) + m["gitter"] = strings.Fields(b.Config.Gitter.IgnoreNicks)   b.ignoreNicks = m  }   @@ -1266 +1328 @@ func (b *Bridge) modifyMessage(msg *config.Message, dest string) {   switch dest {   case "irc":   setNickFormat(msg, b.Config.IRC.RemoteNickFormat) + case "gitter": + setNickFormat(msg, b.Config.Gitter.RemoteNickFormat)   case "xmpp":   setNickFormat(msg, b.Config.Xmpp.RemoteNickFormat)   case "mattermost": diff --git a/bridge/config/config.go b/bridge/config/config.go index 03836b6..cd353fc 100644 --- a/bridge/config/config.go +++ b/bridge/config/config.go @@ -286 +2814 @@ type Config struct {   IgnoreNicks string   Enable bool   } + Gitter struct { + Enable bool + IgnoreNicks string + Nick string + RemoteNickFormat string + Token string + } +   Mattermost struct {   URL string   ShowJoinPart bool @@ -486 +567 @@ type Config struct {   Enable bool   }   Xmpp struct { + IgnoreNicks string   Jid string   Password string   Server string @@ -606 +697 @@ type Config struct {   IRC string   Mattermost string   Xmpp string + Gitter string   }   General struct {   GiphyAPIKey string diff --git a/bridge/gitter/gitter.go b/bridge/gitter/gitter.go new file mode 100644 index 0000000..1d1b0a5 --- /dev/null +++ b/bridge/gitter/gitter.go @@ -00 +1110 @@ +package bgitter + +import ( + "github.com/42wim/matterbridge/bridge/config" + log "github.com/Sirupsen/logrus" + "github.com/sromku/go-gitter" + "strings" +) + +type Bgitter struct { + c *gitter.Gitter + *config.Config + Remote chan config.Message + Rooms []gitter.Room +} + +type Message struct { + Text string + Channel string + Username string +} + +var flog *log.Entry + +func init() { + flog = log.WithFields(log.Fields{"module": "gitter"}) +} + +func New(config *config.Config, c chan config.Message) *Bgitter { + b := &Bgitter{} + b.Config = config + b.Remote = c + return b +} + +func (b *Bgitter) Connect() error { + var err error + flog.Info("Trying Gitter connection") + b.c = gitter.New(b.Config.Gitter.Token) + _, err = b.c.GetUser() + if err != nil { + flog.Debugf("%#v", err) + return err + } + flog.Info("Connection succeeded") + b.setupChannels() + go b.handleGitter() + return nil +} + +func (b *Bgitter) Name() string { + return "gitter" +} + +func (b *Bgitter) Send(msg config.Message) error { + roomID := b.getRoomID(msg.Channel) + if roomID == "" { + flog.Errorf("Could not find roomID for %v", msg.Channel) + return nil + } + // add ZWSP because gitter echoes our own messages + return b.c.SendMessage(roomID, msg.Username+msg.Text+" ​") +} + +func (b *Bgitter) getRoomID(channel string) string { + for _, v := range b.Rooms { + if v.URI == channel { + return v.ID + } + } + return "" +} + +func (b *Bgitter) handleGitter() { + for _, val := range b.Config.Channel { + room := val.Gitter + roomID := b.getRoomID(room) + if roomID == "" { + continue + } + stream := b.c.Stream(roomID) + go b.c.Listen(stream) + + go func(stream *gitter.Stream, room string) { + for { + event := <-stream.Event + switch ev := event.Data.(type) { + case *gitter.MessageReceived: + // check for ZWSP to see if it's not an echo + if !strings.HasSuffix(ev.Message.Text, "​") { + b.Remote <- config.Message{Username: ev.Message.From.Username, Text: ev.Message.Text, Channel: room, Origin: "gitter"} + } + case *gitter.GitterConnectionClosed: + flog.Errorf("connection with gitter closed for room %s", room) + } + } + }(stream, room) + } +} + +func (b *Bgitter) setupChannels() { + b.Rooms, _ = b.c.GetRooms() + for _, val := range b.Config.Channel { + flog.Infof("Joining %s as %s", val.Gitter, b.Gitter.Nick) + _, err := b.c.JoinRoom(val.Gitter) + if err != nil { + log.Errorf("Joining %s failed", val.Gitter) + } + } +}