Allow the XMPP bridge to use slack compatible webhooks (xmpp) (#1364)

* Add mod_slack_webhook support to the XMPP bridge

* Replace b.webhookURL with b.GetString

* Do not return a message ID on webhook POST

* Add the XMPP webhook to the sample configuration
This commit is contained in:
Alexander 2021-01-21 22:50:04 +01:00 committed by GitHub
parent adc0912efa
commit 4ac6366706
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 56 additions and 6 deletions

View File

@ -1,8 +1,11 @@
package bxmpp package bxmpp
import ( import (
"bytes"
"crypto/tls" "crypto/tls"
"encoding/json"
"fmt" "fmt"
"net/http"
"strings" "strings"
"sync" "sync"
"time" "time"
@ -86,14 +89,21 @@ func (b *Bxmpp) Send(msg config.Message) (string, error) {
} }
// Upload a file (in XMPP case send the upload URL because XMPP has no native upload support). // Upload a file (in XMPP case send the upload URL because XMPP has no native upload support).
var err error
if msg.Extra != nil { if msg.Extra != nil {
for _, rmsg := range helper.HandleExtra(&msg, b.General) { for _, rmsg := range helper.HandleExtra(&msg, b.General) {
b.Log.Debugf("=> Sending attachement message %#v", rmsg) b.Log.Debugf("=> Sending attachement message %#v", rmsg)
if _, err := b.xc.Send(xmpp.Chat{ if b.GetString("WebhookURL") != "" {
Type: "groupchat", err = b.postSlackCompatibleWebhook(msg)
Remote: rmsg.Channel + "@" + b.GetString("Muc"), } else {
Text: rmsg.Username + rmsg.Text, _, err = b.xc.Send(xmpp.Chat{
}); err != nil { Type: "groupchat",
Remote: rmsg.Channel + "@" + b.GetString("Muc"),
Text: rmsg.Username + rmsg.Text,
})
}
if err != nil {
b.Log.WithError(err).Error("Unable to send message with share URL.") b.Log.WithError(err).Error("Unable to send message with share URL.")
} }
} }
@ -102,13 +112,24 @@ func (b *Bxmpp) Send(msg config.Message) (string, error) {
} }
} }
if b.GetString("WebhookURL") != "" {
b.Log.Debugf("Sending message using Webhook")
err := b.postSlackCompatibleWebhook(msg)
if err != nil {
b.Log.Errorf("Failed to send message using webhook: %s", err)
return "", err
}
return "", nil
}
// Post normal message.
var msgReplaceID string var msgReplaceID string
msgID := xid.New().String() msgID := xid.New().String()
if msg.ID != "" { if msg.ID != "" {
msgID = msg.ID msgID = msg.ID
msgReplaceID = msg.ID msgReplaceID = msg.ID
} }
// Post normal message.
b.Log.Debugf("=> Sending message %#v", msg) b.Log.Debugf("=> Sending message %#v", msg)
if _, err := b.xc.Send(xmpp.Chat{ if _, err := b.xc.Send(xmpp.Chat{
Type: "groupchat", Type: "groupchat",
@ -122,6 +143,25 @@ func (b *Bxmpp) Send(msg config.Message) (string, error) {
return msgID, nil return msgID, nil
} }
func (b *Bxmpp) postSlackCompatibleWebhook(msg config.Message) error {
type XMPPWebhook struct {
Username string `json:"username"`
Text string `json:"text"`
}
webhookBody, err := json.Marshal(XMPPWebhook{
Username: msg.Username,
Text: msg.Text,
})
if err != nil {
b.Log.Errorf("Failed to marshal webhook: %s", err)
return err
}
resp, err := http.Post(b.GetString("WebhookURL")+"/"+msg.Channel, "application/json", bytes.NewReader(webhookBody))
resp.Body.Close()
return err
}
func (b *Bxmpp) createXMPP() error { func (b *Bxmpp) createXMPP() error {
if !strings.Contains(b.GetString("Jid"), "@") { if !strings.Contains(b.GetString("Jid"), "@") {
return fmt.Errorf("the Jid %s doesn't contain an @", b.GetString("Jid")) return fmt.Errorf("the Jid %s doesn't contain an @", b.GetString("Jid"))
@ -378,6 +418,11 @@ func (b *Bxmpp) skipMessage(message xmpp.Chat) bool {
return true return true
} }
// Ignore messages posted by our webhook
if b.GetString("WebhookURL") != "" && strings.Contains(message.ID, "webhookbot") {
return true
}
// skip delayed messages // skip delayed messages
return !message.Stamp.IsZero() && time.Since(message.Stamp).Minutes() > 5 return !message.Stamp.IsZero() && time.Since(message.Stamp).Minutes() > 5
} }

View File

@ -310,6 +310,11 @@ StripNick=false
#OPTIONAL (default false) #OPTIONAL (default false)
ShowTopicChange=false ShowTopicChange=false
#Enable sending messages using a webhook instead of regular MUC messages.
#Only works with a prosody server using mod_slack_webhook. Does not support editing.
#OPTIONAL (default "")
WebhookURL="https://yourdomain/prosody/msg/someid"
################################################################### ###################################################################
#mattermost section #mattermost section
################################################################### ###################################################################