first version with gosrc.io/xmpp
This commit is contained in:
parent
f35f1eac42
commit
18676475d3
|
@ -7,7 +7,7 @@ import (
|
|||
|
||||
libHTTP "dev.sum7.eu/genofire/golang-lib/http"
|
||||
"github.com/bdlm/log"
|
||||
xmpp "github.com/mattn/go-xmpp"
|
||||
"gosrc.io/xmpp"
|
||||
|
||||
"dev.sum7.eu/genofire/hook2xmpp/runtime"
|
||||
)
|
||||
|
@ -30,7 +30,7 @@ func (r requestBody) String() string {
|
|||
}
|
||||
|
||||
func init() {
|
||||
runtime.HookRegister[hookType] = func(client *xmpp.Client, hooks []runtime.Hook) func(w http.ResponseWriter, r *http.Request) {
|
||||
runtime.HookRegister[hookType] = func(client xmpp.Sender, hooks []runtime.Hook) func(w http.ResponseWriter, r *http.Request) {
|
||||
log.WithField("type", hookType).Info("loaded")
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
logger := log.WithField("type", hookType)
|
||||
|
@ -47,12 +47,14 @@ func init() {
|
|||
})
|
||||
|
||||
ok := false
|
||||
msg := request.String()
|
||||
|
||||
for _, hook := range hooks {
|
||||
if request.Payload.VCSURL != hook.Secret {
|
||||
continue
|
||||
}
|
||||
logger.Infof("run hook")
|
||||
runtime.Notify(client, hook, request.String())
|
||||
runtime.Notify(client, hook, msg, msg)
|
||||
ok = true
|
||||
}
|
||||
if !ok {
|
||||
|
|
|
@ -1,13 +1,16 @@
|
|||
log_level = 50
|
||||
webserver_bind = ":8080"
|
||||
|
||||
[xmpp]
|
||||
host = "fireorbit.de"
|
||||
username = "bot@fireorbit.de"
|
||||
password = "example"
|
||||
startup_notify_user = ["user@fireorbit.de"]
|
||||
startup_notify_muc = []
|
||||
|
||||
nickname = "logbot"
|
||||
|
||||
[xmpp]
|
||||
address = "fireorbit.de"
|
||||
jid = "bot@fireorbit.de"
|
||||
password = "example"
|
||||
|
||||
# suported hooks are, which could be declared multiple times with different `secrets` (see [[hooks.grafana]]):
|
||||
[[hooks.grafana]]
|
||||
[[hooks.prometheus]]
|
||||
|
|
|
@ -7,8 +7,8 @@ import (
|
|||
|
||||
libHTTP "dev.sum7.eu/genofire/golang-lib/http"
|
||||
"github.com/bdlm/log"
|
||||
xmpp "github.com/mattn/go-xmpp"
|
||||
"github.com/mitchellh/mapstructure"
|
||||
"gosrc.io/xmpp"
|
||||
|
||||
"dev.sum7.eu/genofire/hook2xmpp/runtime"
|
||||
)
|
||||
|
@ -21,7 +21,7 @@ var eventHeader = map[string]string{
|
|||
const hookType = "git"
|
||||
|
||||
func init() {
|
||||
runtime.HookRegister[hookType] = func(client *xmpp.Client, hooks []runtime.Hook) func(w http.ResponseWriter, r *http.Request) {
|
||||
runtime.HookRegister[hookType] = func(client xmpp.Sender, hooks []runtime.Hook) func(w http.ResponseWriter, r *http.Request) {
|
||||
log.WithField("type", hookType).Info("loaded")
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
logger := log.WithField("type", hookType)
|
||||
|
@ -62,12 +62,14 @@ func init() {
|
|||
})
|
||||
|
||||
ok := false
|
||||
msg := request.String(event)
|
||||
|
||||
for _, hook := range hooks {
|
||||
if secret != hook.Secret {
|
||||
continue
|
||||
}
|
||||
logger.Infof("run hook")
|
||||
runtime.Notify(client, hook, request.String(event))
|
||||
runtime.Notify(client, hook, msg, msg)
|
||||
ok = true
|
||||
}
|
||||
if !ok {
|
||||
|
|
|
@ -10,7 +10,7 @@ import (
|
|||
|
||||
libHTTP "dev.sum7.eu/genofire/golang-lib/http"
|
||||
"github.com/bdlm/log"
|
||||
xmpp "github.com/mattn/go-xmpp"
|
||||
"gosrc.io/xmpp"
|
||||
|
||||
"dev.sum7.eu/genofire/hook2xmpp/runtime"
|
||||
)
|
||||
|
@ -24,7 +24,7 @@ var eventHeader = map[string]string{
|
|||
const hookType = "gitlab"
|
||||
|
||||
func init() {
|
||||
runtime.HookRegister[hookType] = func(client *xmpp.Client, hooks []runtime.Hook) func(w http.ResponseWriter, r *http.Request) {
|
||||
runtime.HookRegister[hookType] = func(client xmpp.Sender, hooks []runtime.Hook) func(w http.ResponseWriter, r *http.Request) {
|
||||
log.WithField("type", hookType).Info("loaded")
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
event := r.Header.Get("X-Gitlab-Event")
|
||||
|
@ -131,7 +131,7 @@ func init() {
|
|||
continue
|
||||
}
|
||||
logger.Infof("run hook")
|
||||
runtime.Notify(client, hook, msg)
|
||||
runtime.Notify(client, hook, msg, msg)
|
||||
ok = true
|
||||
}
|
||||
if !ok {
|
||||
|
|
|
@ -6,7 +6,7 @@ import (
|
|||
|
||||
libHTTP "dev.sum7.eu/genofire/golang-lib/http"
|
||||
"github.com/bdlm/log"
|
||||
xmpp "github.com/mattn/go-xmpp"
|
||||
"gosrc.io/xmpp"
|
||||
|
||||
"dev.sum7.eu/genofire/hook2xmpp/runtime"
|
||||
)
|
||||
|
@ -39,7 +39,7 @@ func (r requestBody) String() string {
|
|||
}
|
||||
|
||||
func init() {
|
||||
runtime.HookRegister[hookType] = func(client *xmpp.Client, hooks []runtime.Hook) func(w http.ResponseWriter, r *http.Request) {
|
||||
runtime.HookRegister[hookType] = func(client xmpp.Sender, hooks []runtime.Hook) func(w http.ResponseWriter, r *http.Request) {
|
||||
log.WithField("type", hookType).Info("loaded")
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
logger := log.WithField("type", hookType)
|
||||
|
@ -65,12 +65,14 @@ func init() {
|
|||
})
|
||||
|
||||
ok = false
|
||||
msg := request.String()
|
||||
|
||||
for _, hook := range hooks {
|
||||
if secret != hook.Secret {
|
||||
continue
|
||||
}
|
||||
|
||||
runtime.Notify(client, hook, request.String())
|
||||
runtime.Notify(client, hook, msg, msg)
|
||||
if request.ImageURL != "" {
|
||||
runtime.NotifyImage(client, hook, request.ImageURL, request.String())
|
||||
} else {
|
||||
|
|
70
main.go
70
main.go
|
@ -9,7 +9,7 @@ import (
|
|||
|
||||
"dev.sum7.eu/genofire/golang-lib/file"
|
||||
"github.com/bdlm/log"
|
||||
"github.com/mattn/go-xmpp"
|
||||
"gosrc.io/xmpp"
|
||||
|
||||
_ "dev.sum7.eu/genofire/hook2xmpp/circleci"
|
||||
_ "dev.sum7.eu/genofire/hook2xmpp/git"
|
||||
|
@ -19,39 +19,36 @@ import (
|
|||
"dev.sum7.eu/genofire/hook2xmpp/runtime"
|
||||
)
|
||||
|
||||
var config = runtime.Config{}
|
||||
|
||||
func main() {
|
||||
configFile := "config.conf"
|
||||
flag.StringVar(&configFile, "config", configFile, "path of configuration file")
|
||||
flag.Parse()
|
||||
|
||||
config := &runtime.Config{}
|
||||
|
||||
if err := file.ReadTOML(configFile, config); err != nil {
|
||||
if err := file.ReadTOML(configFile, &config); err != nil {
|
||||
log.WithField("tip", "maybe call me with: hook2xmpp--config /etc/hook2xmpp.conf").Panicf("error on read config: %s", err)
|
||||
}
|
||||
|
||||
log.SetLevel(config.LogLevel)
|
||||
|
||||
// load config
|
||||
options := xmpp.Options{
|
||||
Host: config.XMPP.Host,
|
||||
User: config.XMPP.Username,
|
||||
Resource: config.XMPP.Resource,
|
||||
Password: config.XMPP.Password,
|
||||
StartTLS: config.XMPP.StartTLS,
|
||||
NoTLS: config.XMPP.NoTLS,
|
||||
Debug: config.XMPP.Debug,
|
||||
Session: config.XMPP.Session,
|
||||
Status: config.XMPP.Status,
|
||||
StatusMessage: config.XMPP.StatusMessage,
|
||||
}
|
||||
client, err := options.NewClient()
|
||||
router := xmpp.NewRouter()
|
||||
var err error
|
||||
client, err := xmpp.NewClient(xmpp.Config{
|
||||
Address: config.XMPP.Address,
|
||||
Jid: config.XMPP.JID,
|
||||
Password: config.XMPP.Password,
|
||||
}, router)
|
||||
|
||||
if err != nil {
|
||||
log.Panicf("error on startup xmpp client: %s", err)
|
||||
}
|
||||
|
||||
go runtime.Start(client)
|
||||
|
||||
cm := xmpp.NewStreamManager(client, postStartup)
|
||||
go func() {
|
||||
err := cm.Run()
|
||||
log.Panic("closed connection:", err)
|
||||
}()
|
||||
for hookType, getHandler := range runtime.HookRegister {
|
||||
hooks, ok := config.Hooks[hookType]
|
||||
if ok {
|
||||
|
@ -68,45 +65,14 @@ func main() {
|
|||
}
|
||||
}()
|
||||
|
||||
var mucs []string
|
||||
for _, muc := range config.StartupNotifyMuc {
|
||||
mucs = append(mucs, muc)
|
||||
client.JoinMUCNoHistory(muc, config.Nickname)
|
||||
}
|
||||
for _, hooks := range config.Hooks {
|
||||
for _, hook := range hooks {
|
||||
for _, muc := range hook.NotifyMuc {
|
||||
mucs = append(mucs, muc)
|
||||
client.JoinMUCNoHistory(muc, config.Nickname)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
notify := func(msg string) {
|
||||
for _, muc := range config.StartupNotifyMuc {
|
||||
client.SendHtml(xmpp.Chat{Remote: muc, Type: "groupchat", Text: msg})
|
||||
}
|
||||
for _, user := range config.StartupNotifyUser {
|
||||
client.SendHtml(xmpp.Chat{Remote: user, Type: "chat", Text: msg})
|
||||
}
|
||||
}
|
||||
|
||||
log.Infof("started hock2xmpp with %s", client.JID())
|
||||
notify("startup of hock2xmpp")
|
||||
|
||||
// Wait for system signal
|
||||
sigs := make(chan os.Signal, 1)
|
||||
signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM)
|
||||
sig := <-sigs
|
||||
|
||||
notify("stopped of hock2xmpp")
|
||||
|
||||
for _, muc := range mucs {
|
||||
client.LeaveMUC(muc)
|
||||
}
|
||||
closeXMPP(client)
|
||||
|
||||
srv.Close()
|
||||
client.Close()
|
||||
|
||||
log.Infof("closed by receiving: %s", sig)
|
||||
}
|
||||
|
|
|
@ -8,8 +8,8 @@ import (
|
|||
|
||||
libHTTP "dev.sum7.eu/genofire/golang-lib/http"
|
||||
"github.com/bdlm/log"
|
||||
xmpp "github.com/mattn/go-xmpp"
|
||||
"github.com/prometheus/alertmanager/notify/webhook"
|
||||
"gosrc.io/xmpp"
|
||||
|
||||
"dev.sum7.eu/genofire/hook2xmpp/runtime"
|
||||
)
|
||||
|
@ -17,7 +17,7 @@ import (
|
|||
const hookType = "prometheus"
|
||||
|
||||
func init() {
|
||||
runtime.HookRegister[hookType] = func(client *xmpp.Client, hooks []runtime.Hook) func(w http.ResponseWriter, r *http.Request) {
|
||||
runtime.HookRegister[hookType] = func(client xmpp.Sender, hooks []runtime.Hook) func(w http.ResponseWriter, r *http.Request) {
|
||||
log.WithField("type", hookType).Info("loaded")
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
logger := log.WithField("type", hookType)
|
||||
|
@ -51,7 +51,7 @@ func init() {
|
|||
continue
|
||||
}
|
||||
logger.Infof("run hook")
|
||||
runtime.Notify(client, hook, content)
|
||||
runtime.Notify(client, hook, content, content)
|
||||
ok = true
|
||||
}
|
||||
if !ok {
|
||||
|
|
|
@ -7,16 +7,9 @@ type Config struct {
|
|||
WebserverBind string `toml:"webserver_bind"`
|
||||
|
||||
XMPP struct {
|
||||
Host string `toml:"host"`
|
||||
Username string `toml:"username"`
|
||||
Resource string `toml:"resource"`
|
||||
Password string `toml:"password"`
|
||||
Debug bool `toml:"debug"`
|
||||
NoTLS bool `toml:"no_tls"`
|
||||
StartTLS bool `toml:"start_tls"`
|
||||
Session bool `toml:"session"`
|
||||
Status string `toml:"status"`
|
||||
StatusMessage string `toml:"status_message"`
|
||||
Address string `toml:"address"`
|
||||
JID string `toml:"jid"`
|
||||
Password string `toml:"password"`
|
||||
} `toml:"xmpp"`
|
||||
|
||||
Nickname string `toml:"nickname"`
|
||||
|
|
|
@ -3,10 +3,10 @@ package runtime
|
|||
import (
|
||||
"net/http"
|
||||
|
||||
xmpp "github.com/mattn/go-xmpp"
|
||||
"gosrc.io/xmpp"
|
||||
)
|
||||
|
||||
type HookHandler func(*xmpp.Client, []Hook) func(http.ResponseWriter, *http.Request)
|
||||
type HookHandler func(xmpp.Sender, []Hook) func(http.ResponseWriter, *http.Request)
|
||||
|
||||
var HookRegister map[string]HookHandler
|
||||
|
||||
|
|
|
@ -1,51 +1,70 @@
|
|||
package runtime
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/bdlm/log"
|
||||
xmpp "github.com/mattn/go-xmpp"
|
||||
|
||||
"gosrc.io/xmpp"
|
||||
"gosrc.io/xmpp/stanza"
|
||||
)
|
||||
|
||||
func Start(client *xmpp.Client) {
|
||||
for {
|
||||
m, err := client.Recv()
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
switch v := m.(type) {
|
||||
case xmpp.Chat:
|
||||
if v.Type == "chat" {
|
||||
log.Debugf("from %s: %s", v.Remote, v.Text)
|
||||
}
|
||||
if v.Type == "groupchat" {
|
||||
}
|
||||
case xmpp.Presence:
|
||||
// do nothing
|
||||
}
|
||||
func NotifyImage(client xmpp.Sender, hook Hook, url string, desc string) {
|
||||
msg := stanza.Message{
|
||||
Attrs: stanza.Attrs{Type: stanza.MessageTypeGroupchat},
|
||||
Body: url,
|
||||
Extensions: []stanza.MsgExtension{
|
||||
stanza.OOB{URL: url, Desc: desc},
|
||||
},
|
||||
}
|
||||
}
|
||||
func NotifyImage(client *xmpp.Client, hook Hook, url string, desc string) {
|
||||
msg := fmt.Sprintf(`<message to='%%s' type='%%s'>
|
||||
<body>%s</body>
|
||||
<x xmlns='jabber:x:oob'>
|
||||
<url>%s</url>
|
||||
<desc>%s</desc>
|
||||
</x>
|
||||
</message>`, url, url, desc)
|
||||
|
||||
for _, muc := range hook.NotifyMuc {
|
||||
client.SendOrg(fmt.Sprintf(msg, muc, "groupchat"))
|
||||
msg.To = muc
|
||||
if err := client.Send(msg); err != nil {
|
||||
log.WithFields(map[string]interface{}{
|
||||
"muc": muc,
|
||||
"url": url,
|
||||
}).Errorf("error on image notify: %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
msg.Type = stanza.MessageTypeChat
|
||||
for _, user := range hook.NotifyUser {
|
||||
client.SendOrg(fmt.Sprintf(msg, user, "chat"))
|
||||
msg.To = user
|
||||
if err := client.Send(msg); err != nil {
|
||||
log.WithFields(map[string]interface{}{
|
||||
"user": user,
|
||||
"url": url,
|
||||
}).Errorf("error on image notify: %s", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
func Notify(client *xmpp.Client, hook Hook, msg string) {
|
||||
|
||||
func Notify(client xmpp.Sender, hook Hook, text, html string) {
|
||||
msg := stanza.Message{
|
||||
Attrs: stanza.Attrs{Type: stanza.MessageTypeGroupchat},
|
||||
Body: text,
|
||||
Extensions: []stanza.MsgExtension{
|
||||
stanza.HTML{Body: stanza.HTMLBody{InnerXML: html}},
|
||||
},
|
||||
}
|
||||
|
||||
for _, muc := range hook.NotifyMuc {
|
||||
client.SendHtml(xmpp.Chat{Remote: muc, Type: "groupchat", Text: msg})
|
||||
msg.To = muc
|
||||
if err := client.Send(msg); err != nil {
|
||||
log.WithFields(map[string]interface{}{
|
||||
"muc": muc,
|
||||
"text": text,
|
||||
}).Errorf("error on notify: %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
msg.Type = stanza.MessageTypeChat
|
||||
for _, user := range hook.NotifyUser {
|
||||
client.SendHtml(xmpp.Chat{Remote: user, Type: "chat", Text: msg})
|
||||
msg.To = user
|
||||
if err := client.Send(msg); err != nil {
|
||||
log.WithFields(map[string]interface{}{
|
||||
"user": user,
|
||||
"text": text,
|
||||
}).Errorf("error on notify: %s", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,89 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"github.com/bdlm/log"
|
||||
"gosrc.io/xmpp"
|
||||
"gosrc.io/xmpp/stanza"
|
||||
)
|
||||
|
||||
var mucs []string
|
||||
|
||||
func notify(c xmpp.Sender, text string) {
|
||||
msg := stanza.Message{
|
||||
Attrs: stanza.Attrs{Type: stanza.MessageTypeGroupchat},
|
||||
Body: text,
|
||||
}
|
||||
|
||||
for _, muc := range config.StartupNotifyMuc {
|
||||
msg.To = muc
|
||||
if err := c.Send(msg); err != nil {
|
||||
log.WithFields(map[string]interface{}{
|
||||
"muc": muc,
|
||||
"msg": text,
|
||||
}).Errorf("error on startup notify: %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
msg.Type = stanza.MessageTypeChat
|
||||
for _, user := range config.StartupNotifyUser {
|
||||
msg.To = user
|
||||
if err := c.Send(msg); err != nil {
|
||||
log.WithFields(map[string]interface{}{
|
||||
"user": user,
|
||||
"msg": text,
|
||||
}).Errorf("error on startup notify: %s", err)
|
||||
}
|
||||
}
|
||||
log.Infof("notify: %s", text)
|
||||
}
|
||||
|
||||
func joinMUC(c xmpp.Sender, to, nick string) error {
|
||||
|
||||
toJID, err := xmpp.NewJid(to)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
toJID.Resource = nick
|
||||
jid := toJID.Full()
|
||||
|
||||
mucs = append(mucs, jid)
|
||||
|
||||
return c.Send(stanza.Presence{Attrs: stanza.Attrs{To: jid},
|
||||
Extensions: []stanza.PresExtension{
|
||||
stanza.MucPresence{
|
||||
History: stanza.History{MaxStanzas: stanza.NewNullableInt(0)},
|
||||
}},
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
func postStartup(c xmpp.Sender) {
|
||||
for _, muc := range config.StartupNotifyMuc {
|
||||
if err := joinMUC(c, muc, config.Nickname); err != nil {
|
||||
log.WithField("muc", muc).Errorf("error on joining muc: %s", err)
|
||||
}
|
||||
}
|
||||
for _, hooks := range config.Hooks {
|
||||
for _, hook := range hooks {
|
||||
for _, muc := range hook.NotifyMuc {
|
||||
if err := joinMUC(c, muc, config.Nickname); err != nil {
|
||||
log.WithField("muc", muc).Errorf("error on joining muc: %s", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
notify(c, "started hock2xmpp")
|
||||
}
|
||||
|
||||
func closeXMPP(c xmpp.Sender) {
|
||||
notify(c, "stopped of hock2xmpp")
|
||||
|
||||
for _, muc := range mucs {
|
||||
if err := c.Send(stanza.Presence{Attrs: stanza.Attrs{
|
||||
To: muc,
|
||||
Type: stanza.PresenceTypeUnavailable,
|
||||
}}); err != nil {
|
||||
log.WithField("muc", muc).Errorf("error on leaving muc: %s", err)
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue