forked from lug/matterbridge
		
	Compare commits
	
		
			14 Commits
		
	
	
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					4f406b2ce6 | ||
| 
						 | 
					e564c555d7 | ||
| 
						 | 
					f7ec9af9e8 | ||
| 
						 | 
					4d93a774ce | ||
| 
						 | 
					2595dd30bf | ||
| 
						 | 
					9190365289 | ||
| 
						 | 
					57794b3b9f | ||
| 
						 | 
					3c36f651be | ||
| 
						 | 
					8e6ddadba2 | ||
| 
						 | 
					8a87a71927 | ||
| 
						 | 
					0047e6f523 | ||
| 
						 | 
					7183095a28 | ||
| 
						 | 
					13c90893c7 | ||
| 
						 | 
					976fbcd07f | 
							
								
								
									
										84
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										84
									
								
								README.md
									
									
									
									
									
								
							@@ -9,20 +9,20 @@ Letting people be where they want to be.<br />
 | 
			
		||||
 | 
			
		||||
   <sup>
 | 
			
		||||
 | 
			
		||||
[Discord][mb-discord] |
 | 
			
		||||
[Gitter][mb-gitter] |
 | 
			
		||||
[IRC][mb-irc] |
 | 
			
		||||
[Discord][mb-discord] |
 | 
			
		||||
[Keybase][mb-keybase] |
 | 
			
		||||
[Matrix][mb-matrix] |
 | 
			
		||||
[Slack][mb-slack] |
 | 
			
		||||
[Mattermost][mb-mattermost] |
 | 
			
		||||
[MSTeams][mb-msteams] |
 | 
			
		||||
[Rocket.Chat][mb-rocketchat] |
 | 
			
		||||
[XMPP][mb-xmpp] |
 | 
			
		||||
[Slack][mb-slack] |
 | 
			
		||||
[Telegram][mb-telegram] |
 | 
			
		||||
[Twitch][mb-twitch] |
 | 
			
		||||
[WhatsApp][mb-whatsapp] |
 | 
			
		||||
[XMPP][mb-xmpp] |
 | 
			
		||||
[Zulip][mb-zulip] |
 | 
			
		||||
[Telegram][mb-telegram] |
 | 
			
		||||
[Keybase][mb-keybase] |
 | 
			
		||||
[MSTeams][mb-msteams] |
 | 
			
		||||
And more...
 | 
			
		||||
</sup>
 | 
			
		||||
 | 
			
		||||
@@ -87,29 +87,29 @@ And more...
 | 
			
		||||
 | 
			
		||||
### Natively supported
 | 
			
		||||
 | 
			
		||||
- [Mattermost](https://github.com/mattermost/mattermost-server/) 4.x, 5.x
 | 
			
		||||
- [IRC](http://www.mirc.com/servers.html)
 | 
			
		||||
- [XMPP](https://xmpp.org)
 | 
			
		||||
- [Gitter](https://gitter.im)
 | 
			
		||||
- [Slack](https://slack.com)
 | 
			
		||||
- [Discord](https://discordapp.com)
 | 
			
		||||
- [Telegram](https://telegram.org)
 | 
			
		||||
- [Rocket.chat](https://rocket.chat)
 | 
			
		||||
- [Matrix](https://matrix.org)
 | 
			
		||||
- [Microsoft Teams](https://teams.microsoft.com)
 | 
			
		||||
- [Steam](https://store.steampowered.com/)
 | 
			
		||||
- [Twitch](https://twitch.tv)
 | 
			
		||||
- [Ssh-chat](https://github.com/shazow/ssh-chat)
 | 
			
		||||
- [WhatsApp](https://www.whatsapp.com/)
 | 
			
		||||
- [Zulip](https://zulipchat.com)
 | 
			
		||||
- [Gitter](https://gitter.im)
 | 
			
		||||
- [IRC](http://www.mirc.com/servers.html)
 | 
			
		||||
- [Keybase](https://keybase.io)
 | 
			
		||||
- [Matrix](https://matrix.org)
 | 
			
		||||
- [Mattermost](https://github.com/mattermost/mattermost-server/) 4.x, 5.x
 | 
			
		||||
- [Microsoft Teams](https://teams.microsoft.com)
 | 
			
		||||
- [Rocket.chat](https://rocket.chat)
 | 
			
		||||
- [Slack](https://slack.com)
 | 
			
		||||
- [Ssh-chat](https://github.com/shazow/ssh-chat)
 | 
			
		||||
- [Steam](https://store.steampowered.com/)
 | 
			
		||||
- [Telegram](https://telegram.org)
 | 
			
		||||
- [Twitch](https://twitch.tv)
 | 
			
		||||
- [WhatsApp](https://www.whatsapp.com/)
 | 
			
		||||
- [XMPP](https://xmpp.org)
 | 
			
		||||
- [Zulip](https://zulipchat.com)
 | 
			
		||||
 | 
			
		||||
### 3rd party via matterbridge api
 | 
			
		||||
 | 
			
		||||
- [Discourse](https://github.com/DeclanHoare/matterbabble)
 | 
			
		||||
- [Facebook messenger](https://github.com/VictorNine/fbridge)
 | 
			
		||||
- [Minecraft](https://github.com/elytra/MatterLink)
 | 
			
		||||
- [Reddit](https://github.com/bonehurtingjuice/mattereddit)
 | 
			
		||||
- [Facebook messenger](https://github.com/VictorNine/fbridge)
 | 
			
		||||
- [Discourse](https://github.com/DeclanHoare/matterbabble)
 | 
			
		||||
- [Counter-Strike, half-life and more](https://forums.alliedmods.net/showthread.php?t=319430)
 | 
			
		||||
 | 
			
		||||
### API
 | 
			
		||||
@@ -130,18 +130,18 @@ Used by the projects below. Feel free to make a PR to add your project to this l
 | 
			
		||||
 | 
			
		||||
Questions or want to test on your favorite platform? Join below:
 | 
			
		||||
 | 
			
		||||
- [Discord][mb-discord]
 | 
			
		||||
- [Gitter][mb-gitter]
 | 
			
		||||
- [IRC][mb-irc]
 | 
			
		||||
- [Discord][mb-discord]
 | 
			
		||||
- [Keybase][mb-keybase]
 | 
			
		||||
- [Matrix][mb-matrix]
 | 
			
		||||
- [Slack][mb-slack]
 | 
			
		||||
- [Mattermost][mb-mattermost]
 | 
			
		||||
- [Rocket.Chat][mb-rocketchat]
 | 
			
		||||
- [XMPP][mb-xmpp] (matterbridge@conference.jabber.de)
 | 
			
		||||
- [Twitch][mb-twitch]
 | 
			
		||||
- [Zulip][mb-zulip]
 | 
			
		||||
- [Slack][mb-slack]
 | 
			
		||||
- [Telegram][mb-telegram]
 | 
			
		||||
- [Keybase][mb-keybase]
 | 
			
		||||
- [Twitch][mb-twitch]
 | 
			
		||||
- [XMPP][mb-xmpp] (matterbridge@conference.jabber.de)
 | 
			
		||||
- [Zulip][mb-zulip]
 | 
			
		||||
 | 
			
		||||
## Screenshots
 | 
			
		||||
 | 
			
		||||
@@ -151,7 +151,7 @@ See https://github.com/42wim/matterbridge/wiki
 | 
			
		||||
 | 
			
		||||
### Binaries
 | 
			
		||||
 | 
			
		||||
- Latest stable release [v1.17.2](https://github.com/42wim/matterbridge/releases/latest)
 | 
			
		||||
- Latest stable release [v1.17.3](https://github.com/42wim/matterbridge/releases/latest)
 | 
			
		||||
- Development releases (follows master) can be downloaded [here](https://dl.bintray.com/42wim/nightly/)
 | 
			
		||||
 | 
			
		||||
To install or upgrade just download the latest [binary](https://github.com/42wim/matterbridge/releases/latest) and follow the instructions on the [howto](https://github.com/42wim/matterbridge/wiki/How-to-create-your-config) for a step by step walkthrough for creating your configuration.
 | 
			
		||||
@@ -324,32 +324,32 @@ Matterbridge wouldn't exist without these libraries:
 | 
			
		||||
- gops - https://github.com/google/gops
 | 
			
		||||
- gozulipbot - https://github.com/ifo/gozulipbot
 | 
			
		||||
- irc - https://github.com/lrstanley/girc
 | 
			
		||||
- mattermost - https://github.com/mattermost/mattermost-server
 | 
			
		||||
- keybase - https://github.com/keybase/go-keybase-chat-bot
 | 
			
		||||
- matrix - https://github.com/matrix-org/gomatrix
 | 
			
		||||
- sshchat - https://github.com/shazow/ssh-chat
 | 
			
		||||
- mattermost - https://github.com/mattermost/mattermost-server
 | 
			
		||||
- msgraph.go - https://github.com/yaegashi/msgraph.go
 | 
			
		||||
- slack - https://github.com/nlopes/slack
 | 
			
		||||
- sshchat - https://github.com/shazow/ssh-chat
 | 
			
		||||
- 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
 | 
			
		||||
- whatsapp - https://github.com/Rhymen/go-whatsapp/
 | 
			
		||||
- zulip - https://github.com/ifo/gozulipbot
 | 
			
		||||
- tengo - https://github.com/d5/tengo
 | 
			
		||||
- keybase - https://github.com/keybase/go-keybase-chat-bot
 | 
			
		||||
- msgraph.go - https://github.com/yaegashi/msgraph.go
 | 
			
		||||
- whatsapp - https://github.com/Rhymen/go-whatsapp/
 | 
			
		||||
- xmpp - https://github.com/mattn/go-xmpp
 | 
			
		||||
- zulip - https://github.com/ifo/gozulipbot
 | 
			
		||||
 | 
			
		||||
<!-- Links -->
 | 
			
		||||
 | 
			
		||||
[mb-discord]: https://discord.gg/AkKPtrQ
 | 
			
		||||
[mb-gitter]: https://gitter.im/42wim/matterbridge
 | 
			
		||||
[mb-irc]: https://webchat.freenode.net/?channels=matterbridgechat
 | 
			
		||||
[mb-discord]: https://discord.gg/AkKPtrQ
 | 
			
		||||
[mb-keybase]: https://keybase.io/team/matterbridge
 | 
			
		||||
[mb-matrix]: https://riot.im/app/#/room/#matterbridge:matrix.org
 | 
			
		||||
[mb-slack]: https://join.slack.com/matterbridgechat/shared_invite/MjEwODMxNjU1NDMwLTE0OTk2MTU3NTMtMzZkZmRiNDZhOA
 | 
			
		||||
[mb-mattermost]: https://framateam.org/signup_user_complete/?id=tfqm33ggop8x3qgu4boeieta6e
 | 
			
		||||
[mb-msteams]: https://teams.microsoft.com/join/hj92x75gd3y7
 | 
			
		||||
[mb-rocketchat]: https://open.rocket.chat/channel/matterbridge
 | 
			
		||||
[mb-xmpp]: https://inverse.chat/
 | 
			
		||||
[mb-slack]: https://join.slack.com/matterbridgechat/shared_invite/MjEwODMxNjU1NDMwLTE0OTk2MTU3NTMtMzZkZmRiNDZhOA
 | 
			
		||||
[mb-telegram]: https://t.me/Matterbridge
 | 
			
		||||
[mb-twitch]: https://www.twitch.tv/matterbridge
 | 
			
		||||
[mb-whatsapp]: https://www.whatsapp.com/
 | 
			
		||||
[mb-keybase]: https://keybase.io/team/matterbridge
 | 
			
		||||
[mb-xmpp]: https://inverse.chat/
 | 
			
		||||
[mb-zulip]: https://matterbridge.zulipchat.com/register/
 | 
			
		||||
[mb-telegram]: https://t.me/Matterbridge
 | 
			
		||||
[mb-msteams]: https://teams.microsoft.com/join/hj92x75gd3y7
 | 
			
		||||
 
 | 
			
		||||
@@ -4,6 +4,7 @@ import (
 | 
			
		||||
	"log"
 | 
			
		||||
	"strings"
 | 
			
		||||
	"sync"
 | 
			
		||||
	"time"
 | 
			
		||||
 | 
			
		||||
	"github.com/42wim/matterbridge/bridge/config"
 | 
			
		||||
	"github.com/sirupsen/logrus"
 | 
			
		||||
@@ -74,6 +75,7 @@ func (b *Bridge) joinChannels(channels map[string]config.ChannelInfo, exists map
 | 
			
		||||
	for ID, channel := range channels {
 | 
			
		||||
		if !exists[ID] {
 | 
			
		||||
			b.Log.Infof("%s: joining %s (ID: %s)", b.Account, channel.Name, ID)
 | 
			
		||||
			time.Sleep(time.Duration(b.GetInt("JoinDelay")) * time.Millisecond)
 | 
			
		||||
			err := b.JoinChannel(channel)
 | 
			
		||||
			if err != nil {
 | 
			
		||||
				return err
 | 
			
		||||
 
 | 
			
		||||
@@ -89,6 +89,7 @@ type Protocol struct {
 | 
			
		||||
	IgnoreNicks            string // all protocols
 | 
			
		||||
	IgnoreMessages         string // all protocols
 | 
			
		||||
	Jid                    string // xmpp
 | 
			
		||||
	JoinDelay              string // all protocols
 | 
			
		||||
	Label                  string // all protocols
 | 
			
		||||
	Login                  string // mattermost, matrix
 | 
			
		||||
	MediaDownloadBlackList []string
 | 
			
		||||
 
 | 
			
		||||
@@ -54,12 +54,12 @@ func (b *Birc) handleFiles(msg *config.Message) bool {
 | 
			
		||||
	for _, f := range msg.Extra["file"] {
 | 
			
		||||
		fi := f.(config.FileInfo)
 | 
			
		||||
		if fi.Comment != "" {
 | 
			
		||||
			msg.Text += fi.Comment + ": "
 | 
			
		||||
			msg.Text += fi.Comment + " : "
 | 
			
		||||
		}
 | 
			
		||||
		if fi.URL != "" {
 | 
			
		||||
			msg.Text = fi.URL
 | 
			
		||||
			if fi.Comment != "" {
 | 
			
		||||
				msg.Text = fi.Comment + ": " + fi.URL
 | 
			
		||||
				msg.Text = fi.Comment + " : " + fi.URL
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		b.Local <- config.Message{Text: msg.Text, Username: msg.Username, Channel: msg.Channel, Event: msg.Event}
 | 
			
		||||
 
 | 
			
		||||
@@ -2,6 +2,7 @@ package brocketchat
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"github.com/42wim/matterbridge/bridge/config"
 | 
			
		||||
	"github.com/matterbridge/Rocket.Chat.Go.SDK/models"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func (b *Brocketchat) handleRocket() {
 | 
			
		||||
@@ -38,6 +39,23 @@ func (b *Brocketchat) handleRocketHook(messages chan *config.Message) {
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (b *Brocketchat) handleStatusEvent(ev models.Message, rmsg *config.Message) bool {
 | 
			
		||||
	switch ev.Type {
 | 
			
		||||
	case "":
 | 
			
		||||
		// this is a normal message, no processing needed
 | 
			
		||||
		// return true so the message is not dropped
 | 
			
		||||
		return true
 | 
			
		||||
	case sUserJoined, sUserLeft:
 | 
			
		||||
		rmsg.Event = config.EventJoinLeave
 | 
			
		||||
		return true
 | 
			
		||||
	case sRoomChangedTopic:
 | 
			
		||||
		rmsg.Event = config.EventTopicChange
 | 
			
		||||
		return true
 | 
			
		||||
	}
 | 
			
		||||
	b.Log.Debugf("Dropping message with unknown type: %s", ev.Type)
 | 
			
		||||
	return false
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (b *Brocketchat) handleRocketClient(messages chan *config.Message) {
 | 
			
		||||
	for message := range b.messageChan {
 | 
			
		||||
		// skip messages with same ID, apparently messages get duplicated for an unknown reason
 | 
			
		||||
@@ -59,7 +77,12 @@ func (b *Brocketchat) handleRocketClient(messages chan *config.Message) {
 | 
			
		||||
			UserID:   message.User.ID,
 | 
			
		||||
			ID:       message.ID,
 | 
			
		||||
		}
 | 
			
		||||
		messages <- rmsg
 | 
			
		||||
 | 
			
		||||
		// handleStatusEvent returns false if the message should be dropped
 | 
			
		||||
		// in that case it is probably some modification to the channel we do not want to relay
 | 
			
		||||
		if b.handleStatusEvent(m, rmsg) {
 | 
			
		||||
			messages <- rmsg
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -29,6 +29,12 @@ type Brocketchat struct {
 | 
			
		||||
	sync.RWMutex
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
	sUserJoined       = "uj"
 | 
			
		||||
	sUserLeft         = "ul"
 | 
			
		||||
	sRoomChangedTopic = "room_changed_topic"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func New(cfg *bridge.Config) bridge.Bridger {
 | 
			
		||||
	newCache, err := lru.New(100)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
 
 | 
			
		||||
@@ -137,12 +137,6 @@ func (b *Bslack) skipMessageEvent(ev *slack.MessageEvent) bool {
 | 
			
		||||
		hasOurCallbackID = ok && block.BlockID == "matterbridge_"+b.uuid
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Skip any messages that we made ourselves or from 'slackbot' (see #527).
 | 
			
		||||
	if ev.Username == sSlackBotUser ||
 | 
			
		||||
		(b.rtm != nil && ev.Username == b.si.User.Name) || hasOurCallbackID {
 | 
			
		||||
		return true
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if ev.SubMessage != nil {
 | 
			
		||||
		// It seems ev.SubMessage.Edited == nil when slack unfurls.
 | 
			
		||||
		// Do not forward these messages. See Github issue #266.
 | 
			
		||||
@@ -155,6 +149,16 @@ func (b *Bslack) skipMessageEvent(ev *slack.MessageEvent) bool {
 | 
			
		||||
		if ev.SubType == "message_replied" && ev.Hidden {
 | 
			
		||||
			return true
 | 
			
		||||
		}
 | 
			
		||||
		if len(ev.SubMessage.Blocks.BlockSet) == 1 {
 | 
			
		||||
			block, ok := ev.SubMessage.Blocks.BlockSet[0].(*slack.SectionBlock)
 | 
			
		||||
			hasOurCallbackID = ok && block.BlockID == "matterbridge_"+b.uuid
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Skip any messages that we made ourselves or from 'slackbot' (see #527).
 | 
			
		||||
	if ev.Username == sSlackBotUser ||
 | 
			
		||||
		(b.rtm != nil && ev.Username == b.si.User.Name) || hasOurCallbackID {
 | 
			
		||||
		return true
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if len(ev.Files) > 0 {
 | 
			
		||||
 
 | 
			
		||||
@@ -64,6 +64,7 @@ const (
 | 
			
		||||
	editSuffixConfig      = "EditSuffix"
 | 
			
		||||
	iconURLConfig         = "iconurl"
 | 
			
		||||
	noSendJoinConfig      = "nosendjoinpart"
 | 
			
		||||
	messageLength         = 3000
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func New(cfg *bridge.Config) bridge.Bridger {
 | 
			
		||||
@@ -194,6 +195,7 @@ func (b *Bslack) Send(msg config.Message) (string, error) {
 | 
			
		||||
		b.Log.Debugf("=> Receiving %#v", msg)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	msg.Text = helper.ClipMessage(msg.Text, messageLength)
 | 
			
		||||
	msg.Text = b.replaceCodeFence(msg.Text)
 | 
			
		||||
 | 
			
		||||
	// Make a action /me of the message
 | 
			
		||||
 
 | 
			
		||||
@@ -23,7 +23,8 @@ Check:
 | 
			
		||||
// HandleError received from WhatsApp
 | 
			
		||||
func (b *Bwhatsapp) HandleError(err error) {
 | 
			
		||||
	// ignore received invalid data errors. https://github.com/42wim/matterbridge/issues/843
 | 
			
		||||
	if strings.Contains(err.Error(), "error processing data: received invalid data") {
 | 
			
		||||
	// ignore tag 174 errors. https://github.com/42wim/matterbridge/issues/1094
 | 
			
		||||
	if strings.Contains(err.Error(), "error processing data: received invalid data") || strings.Contains(err.Error(), "invalid string with tag 174") {
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										34
									
								
								bridge/xmpp/handler.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								bridge/xmpp/handler.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,34 @@
 | 
			
		||||
package bxmpp
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"github.com/42wim/matterbridge/bridge/config"
 | 
			
		||||
	"github.com/42wim/matterbridge/bridge/helper"
 | 
			
		||||
	"github.com/matterbridge/go-xmpp"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// handleDownloadAvatar downloads the avatar of userid from channel
 | 
			
		||||
// sends a EVENT_AVATAR_DOWNLOAD message to the gateway if successful.
 | 
			
		||||
// logs an error message if it fails
 | 
			
		||||
func (b *Bxmpp) handleDownloadAvatar(avatar xmpp.AvatarData) {
 | 
			
		||||
	rmsg := config.Message{
 | 
			
		||||
		Username: "system",
 | 
			
		||||
		Text:     "avatar",
 | 
			
		||||
		Channel:  b.parseChannel(avatar.From),
 | 
			
		||||
		Account:  b.Account,
 | 
			
		||||
		UserID:   avatar.From,
 | 
			
		||||
		Event:    config.EventAvatarDownload,
 | 
			
		||||
		Extra:    make(map[string][]interface{}),
 | 
			
		||||
	}
 | 
			
		||||
	if _, ok := b.avatarMap[avatar.From]; !ok {
 | 
			
		||||
		b.Log.Debugf("Avatar.From: %s", avatar.From)
 | 
			
		||||
 | 
			
		||||
		err := helper.HandleDownloadSize(b.Log, &rmsg, avatar.From+".png", int64(len(avatar.Data)), b.General)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			b.Log.Error(err)
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
		helper.HandleDownloadData(b.Log, &rmsg, avatar.From+".png", rmsg.Text, "", &avatar.Data, b.General)
 | 
			
		||||
		b.Log.Debugf("Avatar download complete")
 | 
			
		||||
		b.Remote <- rmsg
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										30
									
								
								bridge/xmpp/helpers.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								bridge/xmpp/helpers.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,30 @@
 | 
			
		||||
package bxmpp
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"regexp"
 | 
			
		||||
 | 
			
		||||
	"github.com/42wim/matterbridge/bridge/config"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
var pathRegex = regexp.MustCompile("[^a-zA-Z0-9]+")
 | 
			
		||||
 | 
			
		||||
// GetAvatar constructs a URL for a given user-avatar if it is available in the cache.
 | 
			
		||||
func getAvatar(av map[string]string, userid string, general *config.Protocol) string {
 | 
			
		||||
	if hash, ok := av[userid]; ok {
 | 
			
		||||
		// NOTE: This does not happen in bridge/helper/helper.go but messes up XMPP
 | 
			
		||||
		id := pathRegex.ReplaceAllString(userid, "_")
 | 
			
		||||
		return general.MediaServerDownload + "/" + hash + "/" + id + ".png"
 | 
			
		||||
	}
 | 
			
		||||
	return ""
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (b *Bxmpp) cacheAvatar(msg *config.Message) string {
 | 
			
		||||
	fi := msg.Extra["file"][0].(config.FileInfo)
 | 
			
		||||
	/* if we have a sha we have successfully uploaded the file to the media server,
 | 
			
		||||
	so we can now cache the sha */
 | 
			
		||||
	if fi.SHA != "" {
 | 
			
		||||
		b.Log.Debugf("Added %s to %s in avatarMap", fi.SHA, msg.UserID)
 | 
			
		||||
		b.avatarMap[msg.UserID] = fi.SHA
 | 
			
		||||
	}
 | 
			
		||||
	return ""
 | 
			
		||||
}
 | 
			
		||||
@@ -23,12 +23,15 @@ type Bxmpp struct {
 | 
			
		||||
	xmppMap   map[string]string
 | 
			
		||||
	connected bool
 | 
			
		||||
	sync.RWMutex
 | 
			
		||||
 | 
			
		||||
	avatarMap map[string]string
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func New(cfg *bridge.Config) bridge.Bridger {
 | 
			
		||||
	return &Bxmpp{
 | 
			
		||||
		Config:  cfg,
 | 
			
		||||
		xmppMap: make(map[string]string),
 | 
			
		||||
		Config:    cfg,
 | 
			
		||||
		xmppMap:   make(map[string]string),
 | 
			
		||||
		avatarMap: make(map[string]string),
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -69,6 +72,10 @@ func (b *Bxmpp) Send(msg config.Message) (string, error) {
 | 
			
		||||
	}
 | 
			
		||||
	b.Log.Debugf("=> Receiving %#v", msg)
 | 
			
		||||
 | 
			
		||||
	if msg.Event == config.EventAvatarDownload {
 | 
			
		||||
		return b.cacheAvatar(&msg), nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Upload a file (in XMPP case send the upload URL because XMPP has no native upload support).
 | 
			
		||||
	if msg.Extra != nil {
 | 
			
		||||
		for _, rmsg := range helper.HandleExtra(&msg, b.General) {
 | 
			
		||||
@@ -230,6 +237,12 @@ func (b *Bxmpp) handleXMPP() error {
 | 
			
		||||
					event = config.EventTopicChange
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				avatar := getAvatar(b.avatarMap, v.Remote, b.General)
 | 
			
		||||
				if avatar == "" {
 | 
			
		||||
					b.Log.Debugf("Requesting avatar data")
 | 
			
		||||
					b.xc.AvatarRequestData(v.Remote)
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				msgID := v.ID
 | 
			
		||||
				if v.ReplaceID != "" {
 | 
			
		||||
					msgID = v.ReplaceID
 | 
			
		||||
@@ -239,6 +252,7 @@ func (b *Bxmpp) handleXMPP() error {
 | 
			
		||||
					Text:     v.Text,
 | 
			
		||||
					Channel:  b.parseChannel(v.Remote),
 | 
			
		||||
					Account:  b.Account,
 | 
			
		||||
					Avatar:   avatar,
 | 
			
		||||
					UserID:   v.Remote,
 | 
			
		||||
					ID:       msgID,
 | 
			
		||||
					Event:    event,
 | 
			
		||||
@@ -255,6 +269,8 @@ func (b *Bxmpp) handleXMPP() error {
 | 
			
		||||
				b.Log.Debugf("<= Message is %#v", rmsg)
 | 
			
		||||
				b.Remote <- rmsg
 | 
			
		||||
			}
 | 
			
		||||
		case xmpp.AvatarData:
 | 
			
		||||
			b.handleDownloadAvatar(v)
 | 
			
		||||
		case xmpp.Presence:
 | 
			
		||||
			// Do nothing.
 | 
			
		||||
		}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										19
									
								
								changelog.md
									
									
									
									
									
								
							
							
						
						
									
										19
									
								
								changelog.md
									
									
									
									
									
								
							@@ -1,3 +1,22 @@
 | 
			
		||||
# v1.17.3
 | 
			
		||||
 | 
			
		||||
## Enhancements
 | 
			
		||||
 | 
			
		||||
- xmpp: Implement User Avatar spoofing of XMPP users #1090
 | 
			
		||||
- rocketchat: Relay Joins/Topic changes in RocketChat bridge (#1085)
 | 
			
		||||
- irc: Add JoinDelay option (irc). Fixes #1084 (#1098)
 | 
			
		||||
- slack: Clip too long messages on 3000 length (slack). Fixes #1081 (#1102)
 | 
			
		||||
 | 
			
		||||
## Bugfix
 | 
			
		||||
 | 
			
		||||
- general: Fix the behavior of ShowTopicChange and SyncTopic (#1086)
 | 
			
		||||
- slack: Prevent image/message looping (slack). Fixes #1088 (#1096)
 | 
			
		||||
- whatsapp: Ignore non-critical errors (whatsapp). Fixes #1094 (#1100)
 | 
			
		||||
- irc: Add extra space before colon in attachments (irc). Fixes #1089 (#1101)
 | 
			
		||||
 | 
			
		||||
This release couldn't exist without the following contributors:
 | 
			
		||||
@42wim, @ldruschk, @qaisjp, @Polynomdivision
 | 
			
		||||
 | 
			
		||||
# v1.17.2
 | 
			
		||||
 | 
			
		||||
## Enhancements
 | 
			
		||||
 
 | 
			
		||||
@@ -169,7 +169,7 @@ func (gw *Gateway) ignoreEvent(event string, dest *bridge.Bridge) bool {
 | 
			
		||||
	switch event {
 | 
			
		||||
	case config.EventAvatarDownload:
 | 
			
		||||
		// Avatar downloads are only relevant for telegram and mattermost for now
 | 
			
		||||
		if dest.Protocol != "mattermost" && dest.Protocol != "telegram" {
 | 
			
		||||
		if dest.Protocol != "mattermost" && dest.Protocol != "telegram" && dest.Protocol != "xmpp" {
 | 
			
		||||
			return true
 | 
			
		||||
		}
 | 
			
		||||
	case config.EventJoinLeave:
 | 
			
		||||
@@ -179,7 +179,7 @@ func (gw *Gateway) ignoreEvent(event string, dest *bridge.Bridge) bool {
 | 
			
		||||
		}
 | 
			
		||||
	case config.EventTopicChange:
 | 
			
		||||
		// only relay topic change when used in some way on other side
 | 
			
		||||
		if dest.GetBool("ShowTopicChange") && dest.GetBool("SyncTopic") {
 | 
			
		||||
		if !dest.GetBool("ShowTopicChange") && !dest.GetBool("SyncTopic") {
 | 
			
		||||
			return true
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										4
									
								
								go.mod
									
									
									
									
									
								
							
							
						
						
									
										4
									
								
								go.mod
									
									
									
									
									
								
							@@ -21,10 +21,10 @@ require (
 | 
			
		||||
	github.com/keybase/go-keybase-chat-bot v0.0.0-20200226211841-4e48f3eaef3e
 | 
			
		||||
	github.com/labstack/echo/v4 v4.1.13
 | 
			
		||||
	github.com/lrstanley/girc v0.0.0-20190801035559-4fc93959e1a7
 | 
			
		||||
	github.com/matterbridge/Rocket.Chat.Go.SDK v0.0.0-20190210153444-cc9d05784d5d
 | 
			
		||||
	github.com/matterbridge/Rocket.Chat.Go.SDK v0.0.0-20200411204219-d5c18ce75048
 | 
			
		||||
	github.com/matterbridge/discordgo v0.18.1-0.20200308151012-aa40f01cbcc3
 | 
			
		||||
	github.com/matterbridge/emoji v2.1.1-0.20191117213217-af507f6b02db+incompatible
 | 
			
		||||
	github.com/matterbridge/go-xmpp v0.0.0-20200329150250-5812999b292b
 | 
			
		||||
	github.com/matterbridge/go-xmpp v0.0.0-20200418225040-c8a3a57b4050
 | 
			
		||||
	github.com/matterbridge/gomatrix v0.0.0-20200209224845-c2104d7936a6
 | 
			
		||||
	github.com/matterbridge/gozulipbot v0.0.0-20190212232658-7aa251978a18
 | 
			
		||||
	github.com/matterbridge/logrus-prefixed-formatter v0.0.0-20180806162718-01618749af61
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										8
									
								
								go.sum
									
									
									
									
									
								
							
							
						
						
									
										8
									
								
								go.sum
									
									
									
									
									
								
							@@ -124,14 +124,14 @@ github.com/lrstanley/girc v0.0.0-20190801035559-4fc93959e1a7 h1:BS9tqL0OCiOGuy/C
 | 
			
		||||
github.com/lrstanley/girc v0.0.0-20190801035559-4fc93959e1a7/go.mod h1:liX5MxHPrwgHaKowoLkYGwbXfYABh1jbZ6FpElbGF1I=
 | 
			
		||||
github.com/magiconair/properties v1.8.1 h1:ZC2Vc7/ZFkGmsVC9KvOjumD+G5lXy2RtTKyzRKO2BQ4=
 | 
			
		||||
github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
 | 
			
		||||
github.com/matterbridge/Rocket.Chat.Go.SDK v0.0.0-20190210153444-cc9d05784d5d h1:F+Sr+C0ojSlYQ37BLylQtSFmyQULe3jbAygcyXQ9mVs=
 | 
			
		||||
github.com/matterbridge/Rocket.Chat.Go.SDK v0.0.0-20190210153444-cc9d05784d5d/go.mod h1:c6MxwqHD+0HvtAJjsHMIdPCiAwGiQwPRPTp69ACMg8A=
 | 
			
		||||
github.com/matterbridge/Rocket.Chat.Go.SDK v0.0.0-20200411204219-d5c18ce75048 h1:B9HaistmV+MD8/33BXmZe1zPIn+RImAFVXNNSOrwU2E=
 | 
			
		||||
github.com/matterbridge/Rocket.Chat.Go.SDK v0.0.0-20200411204219-d5c18ce75048/go.mod h1:c6MxwqHD+0HvtAJjsHMIdPCiAwGiQwPRPTp69ACMg8A=
 | 
			
		||||
github.com/matterbridge/discordgo v0.18.1-0.20200308151012-aa40f01cbcc3 h1:VP/DNRn2HtrVRN6+X3h4FDcQI2OOKT+88WUi21ZD1Kw=
 | 
			
		||||
github.com/matterbridge/discordgo v0.18.1-0.20200308151012-aa40f01cbcc3/go.mod h1:5a1bHtG/38ofcx9cgwM5eTW/Pl4SpbQksNDnTRcGA2Y=
 | 
			
		||||
github.com/matterbridge/emoji v2.1.1-0.20191117213217-af507f6b02db+incompatible h1:oaOqwbg5HxHRxvAbd84ks0Okwoc1ISyUZ87EiVJFhGI=
 | 
			
		||||
github.com/matterbridge/emoji v2.1.1-0.20191117213217-af507f6b02db+incompatible/go.mod h1:igE6rUAn3jai2wCdsjFHfhUoekjrFthoEjFObKKwSb4=
 | 
			
		||||
github.com/matterbridge/go-xmpp v0.0.0-20200329150250-5812999b292b h1:ZYI2HCj9zPzI4Si1ouSOi/ImA2xSQLUCJPQsLWr8FE0=
 | 
			
		||||
github.com/matterbridge/go-xmpp v0.0.0-20200329150250-5812999b292b/go.mod h1:ECDRehsR9TYTKCAsRS8/wLeOk6UUqDydw47ln7wG41Q=
 | 
			
		||||
github.com/matterbridge/go-xmpp v0.0.0-20200418225040-c8a3a57b4050 h1:kWkP1lXpkvtoNL08jkP3XQH/zvDOEXJpdCJd/DlIvMw=
 | 
			
		||||
github.com/matterbridge/go-xmpp v0.0.0-20200418225040-c8a3a57b4050/go.mod h1:ECDRehsR9TYTKCAsRS8/wLeOk6UUqDydw47ln7wG41Q=
 | 
			
		||||
github.com/matterbridge/gomatrix v0.0.0-20200209224845-c2104d7936a6 h1:Kl65VJv38HjYFnnwH+MP6Z8hcJT5UHuSpHVU5vW1HH0=
 | 
			
		||||
github.com/matterbridge/gomatrix v0.0.0-20200209224845-c2104d7936a6/go.mod h1:+jWeaaUtXQbBRdKYWfjW6JDDYiI2XXE+3NnTjW5kg8g=
 | 
			
		||||
github.com/matterbridge/gozulipbot v0.0.0-20190212232658-7aa251978a18 h1:fLhwXtWGtfTgZVxHG1lcKjv+re7dRwyyuYFNu69xdho=
 | 
			
		||||
 
 | 
			
		||||
@@ -15,7 +15,7 @@ import (
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
var (
 | 
			
		||||
	version = "1.17.2"
 | 
			
		||||
	version = "1.17.3"
 | 
			
		||||
	githash string
 | 
			
		||||
 | 
			
		||||
	flagConfig  = flag.String("conf", "matterbridge.toml", "config file")
 | 
			
		||||
 
 | 
			
		||||
@@ -177,6 +177,12 @@ StripNick=false
 | 
			
		||||
#OPTIONAL (default false)
 | 
			
		||||
ShowTopicChange=false
 | 
			
		||||
 | 
			
		||||
#Delay in milliseconds between channel joins
 | 
			
		||||
#Only useful when you have a LOT of channels to join
 | 
			
		||||
#See https://github.com/42wim/matterbridge/issues/1084
 | 
			
		||||
#OPTIONAL (default 0)
 | 
			
		||||
JoinDelay=0
 | 
			
		||||
 | 
			
		||||
###################################################################
 | 
			
		||||
#XMPP section
 | 
			
		||||
###################################################################
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										4
									
								
								vendor/github.com/matterbridge/Rocket.Chat.Go.SDK/models/message.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								vendor/github.com/matterbridge/Rocket.Chat.Go.SDK/models/message.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -7,6 +7,7 @@ type Message struct {
 | 
			
		||||
	RoomID   string `json:"rid"`
 | 
			
		||||
	Msg      string `json:"msg"`
 | 
			
		||||
	EditedBy string `json:"editedBy,omitempty"`
 | 
			
		||||
	Type     string `json:"t,omitempty"`
 | 
			
		||||
 | 
			
		||||
	Groupable bool `json:"groupable,omitempty"`
 | 
			
		||||
 | 
			
		||||
@@ -16,6 +17,9 @@ type Message struct {
 | 
			
		||||
 | 
			
		||||
	Mentions []User `json:"mentions,omitempty"`
 | 
			
		||||
	User     *User  `json:"u,omitempty"`
 | 
			
		||||
 | 
			
		||||
	Attachments []Attachment `json:"attachments,omitempty"`
 | 
			
		||||
 | 
			
		||||
	PostMessage
 | 
			
		||||
 | 
			
		||||
	// Bot         interface{}  `json:"bot"`
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										22
									
								
								vendor/github.com/matterbridge/Rocket.Chat.Go.SDK/realtime/messages.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										22
									
								
								vendor/github.com/matterbridge/Rocket.Chat.Go.SDK/realtime/messages.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -191,6 +191,26 @@ func getMessageFromData(data interface{}) *models.Message {
 | 
			
		||||
 | 
			
		||||
func getMessageFromDocument(arg *gabs.Container) *models.Message {
 | 
			
		||||
	var ts *time.Time
 | 
			
		||||
	var attachments []models.Attachment
 | 
			
		||||
 | 
			
		||||
	attachmentSrc, err := arg.Path("attachments").Children()
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		attachments = make([]models.Attachment, 0)
 | 
			
		||||
	} else {
 | 
			
		||||
		attachments = make([]models.Attachment, len(attachmentSrc))
 | 
			
		||||
		for i, attachment := range attachmentSrc {
 | 
			
		||||
			attachments[i] = models.Attachment{
 | 
			
		||||
				Timestamp:         stringOrZero(attachment.Path("ts").Data()),
 | 
			
		||||
				Title:             stringOrZero(attachment.Path("title").Data()),
 | 
			
		||||
				TitleLink:         stringOrZero(attachment.Path("title_link").Data()),
 | 
			
		||||
				TitleLinkDownload: stringOrZero(attachment.Path("title_link_download").Data()),
 | 
			
		||||
				ImageURL:          stringOrZero(attachment.Path("image_url").Data()),
 | 
			
		||||
 | 
			
		||||
				AuthorName:        stringOrZero(arg.Path("u.name").Data()),
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	date := stringOrZero(arg.Path("ts.$date").Data())
 | 
			
		||||
	if len(date) > 0 {
 | 
			
		||||
		if ti, err := strconv.ParseFloat(date, 64); err == nil {
 | 
			
		||||
@@ -202,11 +222,13 @@ func getMessageFromDocument(arg *gabs.Container) *models.Message {
 | 
			
		||||
		ID:        stringOrZero(arg.Path("_id").Data()),
 | 
			
		||||
		RoomID:    stringOrZero(arg.Path("rid").Data()),
 | 
			
		||||
		Msg:       stringOrZero(arg.Path("msg").Data()),
 | 
			
		||||
		Type:      stringOrZero(arg.Path("t").Data()),
 | 
			
		||||
		Timestamp: ts,
 | 
			
		||||
		User: &models.User{
 | 
			
		||||
			ID:       stringOrZero(arg.Path("u._id").Data()),
 | 
			
		||||
			UserName: stringOrZero(arg.Path("u.username").Data()),
 | 
			
		||||
		},
 | 
			
		||||
		Attachments: attachments,
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										170
									
								
								vendor/github.com/matterbridge/go-xmpp/xmpp.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										170
									
								
								vendor/github.com/matterbridge/go-xmpp/xmpp.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -713,85 +713,119 @@ func (c *Client) Recv() (stanza interface{}, err error) {
 | 
			
		||||
						Errors: errsStr,
 | 
			
		||||
					}, nil
 | 
			
		||||
				}
 | 
			
		||||
			case v.Type == "result" && v.ID == "unsub1":
 | 
			
		||||
				// Unsubscribing MAY contain a pubsub element. But it does
 | 
			
		||||
				// not have to
 | 
			
		||||
				return PubsubUnsubscription{
 | 
			
		||||
					SubID:  "",
 | 
			
		||||
					JID:    v.From,
 | 
			
		||||
					Node:   "",
 | 
			
		||||
					Errors: nil,
 | 
			
		||||
				}, nil
 | 
			
		||||
			case v.Query.XMLName.Local == "pubsub":
 | 
			
		||||
			case v.Type == "result":
 | 
			
		||||
				switch v.ID {
 | 
			
		||||
				case "sub1":
 | 
			
		||||
					// Subscription or unsubscription was successful
 | 
			
		||||
					var sub clientPubsubSubscription
 | 
			
		||||
					err := xml.Unmarshal([]byte(v.Query.InnerXML), &sub)
 | 
			
		||||
					if err != nil {
 | 
			
		||||
						return PubsubSubscription{}, err
 | 
			
		||||
					}
 | 
			
		||||
					if v.Query.XMLName.Local == "pubsub" {
 | 
			
		||||
						// Subscription or unsubscription was successful
 | 
			
		||||
						var sub clientPubsubSubscription
 | 
			
		||||
						err := xml.Unmarshal([]byte(v.Query.InnerXML), &sub)
 | 
			
		||||
						if err != nil {
 | 
			
		||||
							return PubsubSubscription{}, err
 | 
			
		||||
						}
 | 
			
		||||
 | 
			
		||||
					return PubsubSubscription{
 | 
			
		||||
						SubID:  sub.SubID,
 | 
			
		||||
						JID:    sub.JID,
 | 
			
		||||
						Node:   sub.Node,
 | 
			
		||||
						Errors: nil,
 | 
			
		||||
					}, nil
 | 
			
		||||
				case "unsub1":
 | 
			
		||||
					var sub clientPubsubSubscription
 | 
			
		||||
					err := xml.Unmarshal([]byte(v.Query.InnerXML), &sub)
 | 
			
		||||
					if err != nil {
 | 
			
		||||
						return PubsubUnsubscription{}, err
 | 
			
		||||
					}
 | 
			
		||||
 | 
			
		||||
					return PubsubUnsubscription{
 | 
			
		||||
						SubID:  sub.SubID,
 | 
			
		||||
						JID:    v.From,
 | 
			
		||||
						Node:   sub.Node,
 | 
			
		||||
						Errors: nil,
 | 
			
		||||
					}, nil
 | 
			
		||||
				case "items1", "items3":
 | 
			
		||||
					var p clientPubsubItems
 | 
			
		||||
					err := xml.Unmarshal([]byte(v.Query.InnerXML), &p)
 | 
			
		||||
					if err != nil {
 | 
			
		||||
						return PubsubItems{}, err
 | 
			
		||||
					}
 | 
			
		||||
 | 
			
		||||
					switch p.Node {
 | 
			
		||||
					case XMPPNS_AVATAR_PEP_DATA:
 | 
			
		||||
						return handleAvatarData(p.Items[0].Body,
 | 
			
		||||
							v.From,
 | 
			
		||||
							p.Items[0].ID)
 | 
			
		||||
					case XMPPNS_AVATAR_PEP_METADATA:
 | 
			
		||||
						return handleAvatarMetadata(p.Items[0].Body,
 | 
			
		||||
							v.From)
 | 
			
		||||
					default:
 | 
			
		||||
						return PubsubItems{
 | 
			
		||||
							p.Node,
 | 
			
		||||
							pubsubItemsToReturn(p.Items),
 | 
			
		||||
						return PubsubSubscription{
 | 
			
		||||
							SubID:  sub.SubID,
 | 
			
		||||
							JID:    sub.JID,
 | 
			
		||||
							Node:   sub.Node,
 | 
			
		||||
							Errors: nil,
 | 
			
		||||
						}, nil
 | 
			
		||||
					}
 | 
			
		||||
				case "unsub1":
 | 
			
		||||
					if v.Query.XMLName.Local == "pubsub" {
 | 
			
		||||
						var sub clientPubsubSubscription
 | 
			
		||||
						err := xml.Unmarshal([]byte(v.Query.InnerXML), &sub)
 | 
			
		||||
						if err != nil {
 | 
			
		||||
							return PubsubUnsubscription{}, err
 | 
			
		||||
						}
 | 
			
		||||
 | 
			
		||||
						return PubsubUnsubscription{
 | 
			
		||||
							SubID:  sub.SubID,
 | 
			
		||||
							JID:    v.From,
 | 
			
		||||
							Node:   sub.Node,
 | 
			
		||||
							Errors: nil,
 | 
			
		||||
						}, nil
 | 
			
		||||
					} else {
 | 
			
		||||
						// Unsubscribing MAY contain a pubsub element. But it does
 | 
			
		||||
						// not have to
 | 
			
		||||
						return PubsubUnsubscription{
 | 
			
		||||
							SubID:  "",
 | 
			
		||||
							JID:    v.From,
 | 
			
		||||
							Node:   "",
 | 
			
		||||
							Errors: nil,
 | 
			
		||||
						}, nil
 | 
			
		||||
					}
 | 
			
		||||
				case "info1":
 | 
			
		||||
					if v.Query.XMLName.Space == XMPPNS_DISCO_ITEMS {
 | 
			
		||||
						var itemsQuery clientDiscoItemsQuery
 | 
			
		||||
						err := xml.Unmarshal(v.InnerXML, &itemsQuery)
 | 
			
		||||
						if err != nil {
 | 
			
		||||
							return []DiscoItem{}, err
 | 
			
		||||
						}
 | 
			
		||||
 | 
			
		||||
						return DiscoItems{
 | 
			
		||||
							Jid:   v.From,
 | 
			
		||||
							Items: clientDiscoItemsToReturn(itemsQuery.Items),
 | 
			
		||||
						}, nil
 | 
			
		||||
					}
 | 
			
		||||
				case "info3":
 | 
			
		||||
					if v.Query.XMLName.Space == XMPPNS_DISCO_INFO {
 | 
			
		||||
						var disco clientDiscoQuery
 | 
			
		||||
						err := xml.Unmarshal(v.InnerXML, &disco)
 | 
			
		||||
						if err != nil {
 | 
			
		||||
							return DiscoResult{}, err
 | 
			
		||||
						}
 | 
			
		||||
 | 
			
		||||
						return DiscoResult{
 | 
			
		||||
							Features:   clientFeaturesToReturn(disco.Features),
 | 
			
		||||
							Identities: clientIdentitiesToReturn(disco.Identities),
 | 
			
		||||
						}, nil
 | 
			
		||||
					}
 | 
			
		||||
				case "items1", "items3":
 | 
			
		||||
					if v.Query.XMLName.Local == "pubsub" {
 | 
			
		||||
						var p clientPubsubItems
 | 
			
		||||
						err := xml.Unmarshal([]byte(v.Query.InnerXML), &p)
 | 
			
		||||
						if err != nil {
 | 
			
		||||
							return PubsubItems{}, err
 | 
			
		||||
						}
 | 
			
		||||
 | 
			
		||||
						switch p.Node {
 | 
			
		||||
						case XMPPNS_AVATAR_PEP_DATA:
 | 
			
		||||
							return handleAvatarData(p.Items[0].Body,
 | 
			
		||||
								v.From,
 | 
			
		||||
								p.Items[0].ID)
 | 
			
		||||
						case XMPPNS_AVATAR_PEP_METADATA:
 | 
			
		||||
							return handleAvatarMetadata(p.Items[0].Body,
 | 
			
		||||
								v.From)
 | 
			
		||||
						default:
 | 
			
		||||
							return PubsubItems{
 | 
			
		||||
								p.Node,
 | 
			
		||||
								pubsubItemsToReturn(p.Items),
 | 
			
		||||
							}, nil
 | 
			
		||||
						}
 | 
			
		||||
					}
 | 
			
		||||
					// Note: XEP-0084 states that metadata and data
 | 
			
		||||
					// should be fetched with an id of retrieve1.
 | 
			
		||||
					// Since we already have PubSub implemented, we
 | 
			
		||||
					// can just use items1 and items3 to do the same
 | 
			
		||||
					// as an Avatar node is just a PEP (PubSub) node.
 | 
			
		||||
					/*case "retrieve1":
 | 
			
		||||
					var p clientPubsubItems
 | 
			
		||||
					err := xml.Unmarshal([]byte(v.Query.InnerXML), &p)
 | 
			
		||||
					if err != nil {
 | 
			
		||||
						return PubsubItems{}, err
 | 
			
		||||
					}
 | 
			
		||||
					if v.Query.XMLName.Local == "pubsub" {
 | 
			
		||||
						var p clientPubsubItems
 | 
			
		||||
						err := xml.Unmarshal([]byte(v.Query.InnerXML), &p)
 | 
			
		||||
						if err != nil {
 | 
			
		||||
							return PubsubItems{}, err
 | 
			
		||||
						}
 | 
			
		||||
 | 
			
		||||
					switch p.Node {
 | 
			
		||||
					case XMPPNS_AVATAR_PEP_DATA:
 | 
			
		||||
						return handleAvatarData(p.Items[0].Body,
 | 
			
		||||
							v.From,
 | 
			
		||||
							p.Items[0].ID)
 | 
			
		||||
					case XMPPNS_AVATAR_PEP_METADATA:
 | 
			
		||||
						return handleAvatarMetadata(p.Items[0].Body,
 | 
			
		||||
							v
 | 
			
		||||
						switch p.Node {
 | 
			
		||||
						case XMPPNS_AVATAR_PEP_DATA:
 | 
			
		||||
							return handleAvatarData(p.Items[0].Body,
 | 
			
		||||
								v.From,
 | 
			
		||||
								p.Items[0].ID)
 | 
			
		||||
						case XMPPNS_AVATAR_PEP_METADATA:
 | 
			
		||||
							return handleAvatarMetadata(p.Items[0].Body,
 | 
			
		||||
								v.From)
 | 
			
		||||
						}
 | 
			
		||||
					}*/
 | 
			
		||||
				}
 | 
			
		||||
			case v.Query.XMLName.Local == "":
 | 
			
		||||
@@ -1049,6 +1083,8 @@ type clientIQ struct {
 | 
			
		||||
	Query   XMLElement `xml:",any"`
 | 
			
		||||
	Error   clientError
 | 
			
		||||
	Bind    bindBind
 | 
			
		||||
 | 
			
		||||
	InnerXML []byte `xml:",innerxml"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type clientError struct {
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										99
									
								
								vendor/github.com/matterbridge/go-xmpp/xmpp_disco.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										99
									
								
								vendor/github.com/matterbridge/go-xmpp/xmpp_disco.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,99 @@
 | 
			
		||||
package xmpp
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"encoding/xml"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
	XMPPNS_DISCO_ITEMS = "http://jabber.org/protocol/disco#items"
 | 
			
		||||
	XMPPNS_DISCO_INFO  = "http://jabber.org/protocol/disco#info"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type clientDiscoFeature struct {
 | 
			
		||||
	XMLName xml.Name `xml:"feature"`
 | 
			
		||||
	Var     string   `xml:"var,attr"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type clientDiscoIdentity struct {
 | 
			
		||||
	XMLName  xml.Name `xml:"identity"`
 | 
			
		||||
	Category string   `xml:"category,attr"`
 | 
			
		||||
	Type     string   `xml:"type,attr"`
 | 
			
		||||
	Name     string   `xml:"name,attr"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type clientDiscoQuery struct {
 | 
			
		||||
	XMLName    xml.Name              `xml:"query"`
 | 
			
		||||
	Features   []clientDiscoFeature  `xml:"feature"`
 | 
			
		||||
	Identities []clientDiscoIdentity `xml:"identity"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type clientDiscoItem struct {
 | 
			
		||||
	XMLName xml.Name `xml:"item"`
 | 
			
		||||
	Jid     string   `xml:"jid,attr"`
 | 
			
		||||
	Node    string   `xml:"node,attr"`
 | 
			
		||||
	Name    string   `xml:"name,attr"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type clientDiscoItemsQuery struct {
 | 
			
		||||
	XMLName xml.Name          `xml:"query"`
 | 
			
		||||
	Items   []clientDiscoItem `xml:"item"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type DiscoIdentity struct {
 | 
			
		||||
	Category string
 | 
			
		||||
	Type     string
 | 
			
		||||
	Name     string
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type DiscoItem struct {
 | 
			
		||||
	Jid  string
 | 
			
		||||
	Name string
 | 
			
		||||
	Node string
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type DiscoResult struct {
 | 
			
		||||
	Features   []string
 | 
			
		||||
	Identities []DiscoIdentity
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type DiscoItems struct {
 | 
			
		||||
	Jid   string
 | 
			
		||||
	Items []DiscoItem
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func clientFeaturesToReturn(features []clientDiscoFeature) []string {
 | 
			
		||||
	var ret []string
 | 
			
		||||
 | 
			
		||||
	for _, feature := range features {
 | 
			
		||||
		ret = append(ret, feature.Var)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return ret
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func clientIdentitiesToReturn(identities []clientDiscoIdentity) []DiscoIdentity {
 | 
			
		||||
	var ret []DiscoIdentity
 | 
			
		||||
 | 
			
		||||
	for _, id := range identities {
 | 
			
		||||
		ret = append(ret, DiscoIdentity{
 | 
			
		||||
			Category: id.Category,
 | 
			
		||||
			Type:     id.Type,
 | 
			
		||||
			Name:     id.Name,
 | 
			
		||||
		})
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return ret
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func clientDiscoItemsToReturn(items []clientDiscoItem) []DiscoItem {
 | 
			
		||||
	var ret []DiscoItem
 | 
			
		||||
	for _, item := range items {
 | 
			
		||||
		ret = append(ret, DiscoItem{
 | 
			
		||||
			Jid:  item.Jid,
 | 
			
		||||
			Name: item.Name,
 | 
			
		||||
			Node: item.Node,
 | 
			
		||||
		})
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return ret
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										20
									
								
								vendor/github.com/matterbridge/go-xmpp/xmpp_information_query.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										20
									
								
								vendor/github.com/matterbridge/go-xmpp/xmpp_information_query.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -10,10 +10,26 @@ const IQTypeSet = "set"
 | 
			
		||||
const IQTypeResult = "result"
 | 
			
		||||
 | 
			
		||||
func (c *Client) Discovery() (string, error) {
 | 
			
		||||
	const namespace = "http://jabber.org/protocol/disco#items"
 | 
			
		||||
	// use getCookie for a pseudo random id.
 | 
			
		||||
	reqID := strconv.FormatUint(uint64(getCookie()), 10)
 | 
			
		||||
	return c.RawInformationQuery(c.jid, c.domain, reqID, IQTypeGet, namespace, "")
 | 
			
		||||
	return c.RawInformationQuery(c.jid, c.domain, reqID, IQTypeGet, XMPPNS_DISCO_ITEMS, "")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Discover information about a node
 | 
			
		||||
func (c *Client) DiscoverNodeInfo(node string) (string, error) {
 | 
			
		||||
	query := fmt.Sprintf("<query xmlns='%s' node='%s'/>", XMPPNS_DISCO_INFO, node)
 | 
			
		||||
	return c.RawInformation(c.jid, c.domain, "info3", IQTypeGet, query)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Discover items that the server exposes
 | 
			
		||||
func (c *Client) DiscoverServerItems() (string, error) {
 | 
			
		||||
	return c.DiscoverEntityItems(c.domain)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Discover items that an entity exposes
 | 
			
		||||
func (c *Client) DiscoverEntityItems(jid string) (string, error) {
 | 
			
		||||
	query := fmt.Sprintf("<query xmlns='%s'/>", XMPPNS_DISCO_ITEMS)
 | 
			
		||||
	return c.RawInformation(c.jid, jid, "info1", IQTypeGet, query)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// RawInformationQuery sends an information query request to the server.
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										4
									
								
								vendor/modules.txt
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								vendor/modules.txt
									
									
									
									
										vendored
									
									
								
							@@ -95,7 +95,7 @@ github.com/labstack/gommon/random
 | 
			
		||||
github.com/lrstanley/girc
 | 
			
		||||
# github.com/magiconair/properties v1.8.1
 | 
			
		||||
github.com/magiconair/properties
 | 
			
		||||
# github.com/matterbridge/Rocket.Chat.Go.SDK v0.0.0-20190210153444-cc9d05784d5d
 | 
			
		||||
# github.com/matterbridge/Rocket.Chat.Go.SDK v0.0.0-20200411204219-d5c18ce75048
 | 
			
		||||
github.com/matterbridge/Rocket.Chat.Go.SDK/models
 | 
			
		||||
github.com/matterbridge/Rocket.Chat.Go.SDK/realtime
 | 
			
		||||
github.com/matterbridge/Rocket.Chat.Go.SDK/rest
 | 
			
		||||
@@ -103,7 +103,7 @@ github.com/matterbridge/Rocket.Chat.Go.SDK/rest
 | 
			
		||||
github.com/matterbridge/discordgo
 | 
			
		||||
# github.com/matterbridge/emoji v2.1.1-0.20191117213217-af507f6b02db+incompatible
 | 
			
		||||
github.com/matterbridge/emoji
 | 
			
		||||
# github.com/matterbridge/go-xmpp v0.0.0-20200329150250-5812999b292b
 | 
			
		||||
# github.com/matterbridge/go-xmpp v0.0.0-20200418225040-c8a3a57b4050
 | 
			
		||||
github.com/matterbridge/go-xmpp
 | 
			
		||||
# github.com/matterbridge/gomatrix v0.0.0-20200209224845-c2104d7936a6
 | 
			
		||||
github.com/matterbridge/gomatrix
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user