kopia lustrzana https://github.com/tmsmr/xmpp-webhook
Merge branch 'master' into mellium-xmpp
commit
4f8859d49c
|
@ -0,0 +1,17 @@
|
|||
FROM golang:1.13-alpine3.10 as builder
|
||||
MAINTAINER Thomas Maier <contact@thomas-maier.net>
|
||||
RUN apk add --no-cache git
|
||||
COPY . /build
|
||||
WORKDIR /build
|
||||
RUN GOOS=linux GOARCH=amd64 go build
|
||||
|
||||
FROM alpine:3.10
|
||||
RUN apk add --no-cache ca-certificates
|
||||
COPY --from=builder /build/xmpp-webhook /xmpp-webhook
|
||||
RUN adduser -D -g '' xmpp-webhook
|
||||
USER xmpp-webhook
|
||||
ENV XMPP_ID="" \
|
||||
XMPP_PASS="" \
|
||||
XMPP_RECEIVERS=""
|
||||
EXPOSE 4321
|
||||
CMD ["/xmpp-webhook"]
|
|
@ -19,13 +19,20 @@ curl -X POST -d @grafana-webhook-alert-example.json localhost:4321/grafana
|
|||
```
|
||||
- After parsing the body in the appropriate `parserFunc`, the notification is then distributed to the configured receivers.
|
||||
|
||||
## Run with Docker
|
||||
### Build it
|
||||
- Build image: `docker build -t xmpp-webhook .`
|
||||
- Run: `docker run -e "XMPP_ID=alerts@example.org" -e "XMPP_PASS=xxx" -e "XMPP_RECEIVERS=receiver1@example.org,receiver2@example.org" -p 4321:4321 -d --name xmpp-webhook xmpp-webhook`
|
||||
### Use prebuilt image from Docker Hub
|
||||
- Run: `docker run -e "XMPP_ID=alerts@example.org" -e "XMPP_PASS=xxx" -e "XMPP_RECEIVERS=receiver1@example.org,receiver2@example.org" -p 4321:4321 -d --name xmpp-webhook opthomasprime/xmpp-webhook:latest`
|
||||
|
||||
## Installation
|
||||
IMPORTANT NOTE: For the sake of simplicity, `xmpp-webhook` is not reconnecting to the XMPP server after a connection-loss. If you use the provided `xmpp-webhook.service` - Systemd will manage the reconnect by restarting the service.
|
||||
|
||||
- Download and extract the latest tarball (GitHub release page)
|
||||
- Install the binary: `install -D -m 744 xmpp-webhook /usr/local/bin/xmpp-webhook`
|
||||
- Install the service: `install -D -m 644 xmpp-webhook.service /etc/systemd/system/xmpp-webhook.service`
|
||||
- Configure XMMP credentials in `/etc/xmpp-webhook.env`. e.g.:
|
||||
- Configure XMPP credentials in `/etc/xmpp-webhook.env`. e.g.:
|
||||
|
||||
```
|
||||
XMPP_ID='bot@example.com'
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
version: "3.7"
|
||||
services:
|
||||
prosody:
|
||||
build:
|
||||
context: ./prosody
|
||||
network_mode: host
|
||||
recipient-a:
|
||||
build:
|
||||
context: ./recipient
|
||||
network_mode: host
|
||||
depends_on:
|
||||
- prosody
|
||||
restart: always
|
||||
environment:
|
||||
- XMPP_ID=recipient-a@localhost
|
||||
- XMPP_PASS=insecure
|
||||
recipient-b:
|
||||
build:
|
||||
context: ./recipient
|
||||
network_mode: host
|
||||
depends_on:
|
||||
- prosody
|
||||
restart: always
|
||||
environment:
|
||||
- XMPP_ID=recipient-b@localhost
|
||||
- XMPP_PASS=insecure
|
|
@ -0,0 +1,6 @@
|
|||
FROM unclev/prosody-docker-extended:0.11
|
||||
|
||||
ADD ./dev-server.sh /dev-server.sh
|
||||
|
||||
ENTRYPOINT ["/dev-server.sh"]
|
||||
CMD ["prosody"]
|
|
@ -0,0 +1,26 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
# applies https://modules.prosody.im/mod_auth_any.html and https://modules.prosody.im/mod_roster_allinall.html for testing
|
||||
|
||||
PROSODY_CONF=/etc/prosody/prosody.cfg.lua
|
||||
AUTH_ANY='authentication = "any"'
|
||||
MODULES='modules_enabled = { "auth_any", "roster_allinall" }'
|
||||
|
||||
function changes_missing {
|
||||
if grep -q "$AUTH_ANY" $PROSODY_CONF; then
|
||||
return 1
|
||||
else
|
||||
return 0
|
||||
fi
|
||||
}
|
||||
|
||||
function apply_changes {
|
||||
echo "$AUTH_ANY" >> $PROSODY_CONF
|
||||
echo "$MODULES" >> $PROSODY_CONF
|
||||
}
|
||||
|
||||
if changes_missing; then
|
||||
apply_changes
|
||||
fi
|
||||
|
||||
/usr/bin/entrypoint.sh "$@"
|
|
@ -0,0 +1,2 @@
|
|||
go.sum
|
||||
recipient
|
|
@ -0,0 +1,9 @@
|
|||
FROM golang:1.13-alpine3.10 as builder
|
||||
RUN apk add --no-cache git
|
||||
COPY . /build
|
||||
WORKDIR /build
|
||||
RUN go build
|
||||
|
||||
FROM alpine:3.10
|
||||
COPY --from=builder /build/recipient /recipient
|
||||
CMD /recipient
|
|
@ -0,0 +1,9 @@
|
|||
module github.com/opthomas-prime/xmpp-webhook/dev/xmpp-dev-stack/recipient
|
||||
|
||||
go 1.13
|
||||
|
||||
require (
|
||||
mellium.im/sasl v0.2.1
|
||||
mellium.im/xmlstream v0.14.0
|
||||
mellium.im/xmpp v0.14.0
|
||||
)
|
|
@ -0,0 +1,87 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/tls"
|
||||
"encoding/xml"
|
||||
"fmt"
|
||||
"io"
|
||||
"log"
|
||||
"mellium.im/sasl"
|
||||
"mellium.im/xmlstream"
|
||||
"mellium.im/xmpp"
|
||||
"mellium.im/xmpp/dial"
|
||||
"mellium.im/xmpp/jid"
|
||||
"mellium.im/xmpp/stanza"
|
||||
"os"
|
||||
)
|
||||
|
||||
func panicOnErr(err error) {
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
type MessageBody struct {
|
||||
stanza.Message
|
||||
Body string `xml:"body"`
|
||||
}
|
||||
|
||||
func main() {
|
||||
xi := os.Getenv("XMPP_ID")
|
||||
xp := os.Getenv("XMPP_PASS")
|
||||
|
||||
if xi == "" || xp == "" {
|
||||
log.Fatal("XMPP_ID, XMPP_PASS not set")
|
||||
}
|
||||
|
||||
address, err := jid.Parse(xi)
|
||||
panicOnErr(err)
|
||||
|
||||
var dialer = dial.Dialer{NoTLS: true}
|
||||
conn, err := dialer.Dial(context.TODO(), "tcp", address)
|
||||
panicOnErr(err)
|
||||
|
||||
tlsConfig := tls.Config{InsecureSkipVerify: true}
|
||||
|
||||
session, err := xmpp.NegotiateSession(
|
||||
context.TODO(),
|
||||
address.Domain(),
|
||||
address,
|
||||
conn,
|
||||
false,
|
||||
xmpp.NewNegotiator(xmpp.StreamConfig{Features: []xmpp.StreamFeature{
|
||||
xmpp.BindResource(),
|
||||
xmpp.StartTLS(true, &tlsConfig),
|
||||
xmpp.SASL("", xp, sasl.ScramSha1Plus, sasl.ScramSha1, sasl.Plain),
|
||||
}}),
|
||||
)
|
||||
panicOnErr(err)
|
||||
|
||||
fmt.Println("connected")
|
||||
|
||||
err = session.Send(context.TODO(), stanza.WrapPresence(address, stanza.AvailablePresence, nil))
|
||||
panicOnErr(err)
|
||||
|
||||
err = session.Serve(xmpp.HandlerFunc(func(t xmlstream.TokenReadEncoder, start *xml.StartElement) error {
|
||||
d := xml.NewTokenDecoder(t)
|
||||
if start.Name.Local != "message" {
|
||||
return nil
|
||||
}
|
||||
|
||||
msg := MessageBody{}
|
||||
err = d.DecodeElement(&msg, start)
|
||||
if err != nil && err != io.EOF {
|
||||
return nil
|
||||
}
|
||||
|
||||
if msg.Body == "" || msg.Type != stanza.ChatMessage {
|
||||
return nil
|
||||
}
|
||||
|
||||
fmt.Printf("%s: %s\n", msg.From, msg.Body)
|
||||
|
||||
return nil
|
||||
}))
|
||||
panicOnErr(err)
|
||||
}
|
Ładowanie…
Reference in New Issue