init
This commit is contained in:
commit
40ef257672
16 changed files with 552 additions and 0 deletions
8
.ci/check-gofmt
Executable file
8
.ci/check-gofmt
Executable file
|
@ -0,0 +1,8 @@
|
|||
#!/bin/bash
|
||||
|
||||
result="$(gofmt -s -l . | grep -v '^vendor/' )"
|
||||
if [ -n "$result" ]; then
|
||||
echo "Go code is not formatted, run 'gofmt -s -w .'" >&2
|
||||
echo "$result"
|
||||
exit 1
|
||||
fi
|
25
.ci/check-testfiles
Executable file
25
.ci/check-testfiles
Executable file
|
@ -0,0 +1,25 @@
|
|||
#!/usr/bin/env python
|
||||
# checks if every desired package has test files
|
||||
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
|
||||
source_re = re.compile(".*\.go")
|
||||
test_re = re.compile(".*_test\.go")
|
||||
missing = False
|
||||
|
||||
for root, dirs, files in os.walk("."):
|
||||
# ignore some paths
|
||||
if root == "." or root.startswith("./vendor") or root.startswith("./."):
|
||||
continue
|
||||
|
||||
# source files but not test files?
|
||||
if len(filter(source_re.match, files)) > 0 and len(filter(test_re.match, files)) == 0:
|
||||
print("no test files for {}".format(root))
|
||||
missing = True
|
||||
|
||||
if missing:
|
||||
sys.exit(1)
|
||||
else:
|
||||
print("every package has test files")
|
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
config.conf
|
53
.gitlab-ci.yml
Normal file
53
.gitlab-ci.yml
Normal file
|
@ -0,0 +1,53 @@
|
|||
image: golang:latest
|
||||
stages:
|
||||
- build
|
||||
- test
|
||||
- deploy
|
||||
|
||||
before_script:
|
||||
- mkdir -p "/go/src/dev.sum7.eu/$CI_PROJECT_NAMESPACE/"
|
||||
- cp -R "$CI_PROJECT_DIR" "/go/src/dev.sum7.eu/$CI_PROJECT_NAMESPACE/"
|
||||
- cd "/go/src/dev.sum7.eu/$CI_PROJECT_PATH"
|
||||
- go get -d -t ./...
|
||||
|
||||
build-my-project:
|
||||
stage: build
|
||||
script:
|
||||
- mkdir "$CI_PROJECT_DIR/bin/"
|
||||
- go install "dev.sum7.eu/$CI_PROJECT_PATH"
|
||||
- mv "/go/bin/$CI_PROJECT_NAME" "$CI_PROJECT_DIR/bin/$CI_PROJECT_NAME"
|
||||
artifacts:
|
||||
paths:
|
||||
- "bin/$CI_PROJECT_NAME"
|
||||
- config_example.toml
|
||||
|
||||
test-my-project:
|
||||
stage: test
|
||||
script:
|
||||
- go get github.com/client9/misspell/cmd/misspell
|
||||
- misspell -error .
|
||||
- ./.ci/check-gofmt
|
||||
- ./.ci/check-testfiles
|
||||
- go test $(go list ./... | grep -v /vendor/) -v -coverprofile .testCoverage.txt
|
||||
- go tool cover -func=.testCoverage.txt
|
||||
artifacts:
|
||||
paths:
|
||||
- .testCoverage.txt
|
||||
|
||||
test-race-my-project:
|
||||
stage: test
|
||||
script:
|
||||
- go test -race ./...
|
||||
|
||||
deploy:
|
||||
stage: deploy
|
||||
only:
|
||||
- master
|
||||
script:
|
||||
- go install "dev.sum7.eu/$CI_PROJECT_PATH"
|
||||
- 'which ssh-agent || ( apt-get update -y && apt-get install openssh-client -y )'
|
||||
- eval $(ssh-agent -s)
|
||||
- echo "$SSH_PRIVATE_KEY" | tr -d '\r' | ssh-add - > /dev/null
|
||||
- ssh -o StrictHostKeyChecking=no -p $SSH_PORT "$CI_PROJECT_NAME@$SSH_HOST" sudo /usr/bin/systemctl stop $CI_PROJECT_NAME
|
||||
- scp -o StrictHostKeyChecking=no -P $SSH_PORT "/go/bin/$CI_PROJECT_NAME" "$CI_PROJECT_NAME@$SSH_HOST":/opt/$CI_PROJECT_NAME/bin
|
||||
- ssh -o StrictHostKeyChecking=no -p $SSH_PORT "$CI_PROJECT_NAME@$SSH_HOST" sudo /usr/bin/systemctl start $CI_PROJECT_NAME
|
32
.test-coverage
Executable file
32
.test-coverage
Executable file
|
@ -0,0 +1,32 @@
|
|||
#!/bin/bash
|
||||
# Issue: https://github.com/mattn/goveralls/issues/20
|
||||
# Source: https://github.com/uber/go-torch/blob/63da5d33a225c195fea84610e2456d5f722f3963/.test-cover.sh
|
||||
CI=$1
|
||||
echo "run for $CI"
|
||||
|
||||
if [ "$CI" == "circle-ci" ]; then
|
||||
cd ${GOPATH}/src/github.com/${CIRCLE_PROJECT_USERNAME}/${CIRCLE_PROJECT_REPONAME}
|
||||
fi
|
||||
|
||||
echo "mode: count" > profile.cov
|
||||
FAIL=0
|
||||
|
||||
# Standard go tooling behavior is to ignore dirs with leading underscors
|
||||
for dir in $(find . -maxdepth 10 -not -path './vendor/*' -not -path './.git*' -not -path '*/_*' -type d);
|
||||
do
|
||||
if ls $dir/*.go &> /dev/null; then
|
||||
go test -v -covermode=count -coverprofile=profile.tmp $dir || FAIL=$?
|
||||
if [ -f profile.tmp ]
|
||||
then
|
||||
tail -n +2 < profile.tmp >> profile.cov
|
||||
rm profile.tmp
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
# Failures have incomplete results, so don't send
|
||||
if [ "$FAIL" -eq 0 ]; then
|
||||
goveralls -v -coverprofile=profile.cov -service=$CI -repotoken=$COVERALLS_REPO_TOKEN
|
||||
fi
|
||||
|
||||
exit $FAIL
|
21
LICENSE.md
Normal file
21
LICENSE.md
Normal file
|
@ -0,0 +1,21 @@
|
|||
MIT License
|
||||
|
||||
Copyright (c) 2017 genofire
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
52
README.md
Normal file
52
README.md
Normal file
|
@ -0,0 +1,52 @@
|
|||
# hook2xmpp
|
||||
|
||||
|
||||
[![pipeline status](https://dev.sum7.eu/genofire/hook2xmpp/badges/master/pipeline.svg)](https://dev.sum7.eu/genofire/hook2xmpp/pipelines)
|
||||
[![coverage report](https://dev.sum7.eu/genofire/hook2xmpp/badges/master/coverage.svg)](https://dev.sum7.eu/genofire/hook2xmpp/pipelines)
|
||||
[![Go Report Card](https://goreportcard.com/badge/dev.sum7.eu/genofire/hook2xmpp)](https://goreportcard.com/report/dev.sum7.eu/genofire/hook2xmpp)
|
||||
[![GoDoc](https://godoc.org/dev.sum7.eu/genofire/hook2xmpp?status.svg)](https://godoc.org/dev.sum7.eu/genofire/hook2xmpp)
|
||||
|
||||
|
||||
## Get hook2xmpp
|
||||
|
||||
#### Download
|
||||
|
||||
Latest Build binary from ci here:
|
||||
|
||||
[Download All](https://dev.sum7.eu/genofire/hook2xmpp/-/jobs/artifacts/master/download/?job=build-my-project) (with config example)
|
||||
|
||||
[Download Binary](https://dev.sum7.eu/genofire/hook2xmpp/-/jobs/artifacts/master/raw/bin/hook2xmpp?inline=false&job=build-my-project)
|
||||
|
||||
#### Build
|
||||
|
||||
```bash
|
||||
go get -u dev.sum7.eu/genofire/hook2xmpp
|
||||
```
|
||||
|
||||
## Configure
|
||||
|
||||
see `config_example.toml`
|
||||
|
||||
## Start / Boot
|
||||
|
||||
_/lib/systemd/system/hook2xmpp.service_ :
|
||||
```
|
||||
[Unit]
|
||||
Description=hook2xmpp
|
||||
After=network.target
|
||||
# After=ejabberd.service
|
||||
# After=prosody.service
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
# User=notRoot
|
||||
ExecStart=/opt/go/bin/hook2xmpp --config /etc/hook2xmpp.conf
|
||||
Restart=always
|
||||
RestartSec=5sec
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
```
|
||||
|
||||
Start: `systemctl start hook2xmpp`
|
||||
Autostart: `systemctl enable hook2xmpp`
|
19
config.go
Normal file
19
config.go
Normal file
|
@ -0,0 +1,19 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"github.com/bdlm/std/logger"
|
||||
|
||||
"dev.sum7.eu/ccchb/ccchatbot/schalter"
|
||||
)
|
||||
|
||||
type Config struct {
|
||||
LogLevel logger.Level `toml:"log_level"`
|
||||
|
||||
XMPP struct {
|
||||
Host string `toml:"host"`
|
||||
JID string `toml:"jid"`
|
||||
Password string `toml:"password"`
|
||||
} `toml:"xmpp"`
|
||||
|
||||
Schalter schalter.Schalter `toml:"schalter"`
|
||||
}
|
11
config.toml
Normal file
11
config.toml
Normal file
|
@ -0,0 +1,11 @@
|
|||
log_level = 50
|
||||
|
||||
|
||||
[xmpp]
|
||||
jid = "fluxxmpp@chat.sum7.eu"
|
||||
password = "test"
|
||||
|
||||
[schalter]
|
||||
url = "https://schalter.ccchb.de/spaceapi.json"
|
||||
|
||||
muc = ["ffhb_events@conference.chat.sum7.eu","#ccchb@irc.hackint.org"]
|
64
config_example.toml
Normal file
64
config_example.toml
Normal file
|
@ -0,0 +1,64 @@
|
|||
log_level = 50
|
||||
webserver_bind = ":8080"
|
||||
|
||||
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]]
|
||||
[[hooks.git]]
|
||||
[[hooks.gitlab]]
|
||||
[[hooks.circleci]]
|
||||
|
||||
# every hook could have following attributes:
|
||||
secret = ""
|
||||
notify_muc = []
|
||||
notify_user = []
|
||||
|
||||
# for handling webhooks from prometheus alertmanager
|
||||
|
||||
[[hooks.prometheus]]
|
||||
|
||||
# for handling webhooks from grafana
|
||||
# at http://localhost:8080/grafana
|
||||
# for image support you have to enable `external_image_storage` (e.g. `provider = local`)
|
||||
# see more at http://docs.grafana.org/installation/configuration/#external-image-storage
|
||||
[[hooks.grafana]]
|
||||
secret = "dev.sum7.eu-aShared-Secret"
|
||||
notify_muc = ["monitoring@conference.chat.sum7.eu"]
|
||||
|
||||
[[hooks.grafana]]
|
||||
secret = "dev.sum7.eu-aShared-Secret-for important messages"
|
||||
notify_user = ["user@fireorbit.de"]
|
||||
|
||||
|
||||
# for handling webhooks from git software (e.g. gitea, gogs, github)
|
||||
# at http://localhost:8080/git
|
||||
[[hooks.git]]
|
||||
secret = "github-FreifunkBremen-yanic-aShared-Secret"
|
||||
notify_muc = []
|
||||
notify_user = ["user@fireorbit.de"]
|
||||
|
||||
# for handling webhooks from gitlab
|
||||
# at http://localhost:8080/gitlab
|
||||
[[hooks.gitlab]]
|
||||
secret = "dev.sum7.eu-aShared-Secret"
|
||||
notify_muc = []
|
||||
notify_user = ["user@fireorbit.de"]
|
||||
|
||||
# for handling webhooks from circleci
|
||||
# at http://localhost:8080/circleci
|
||||
[[hooks.circleci]]
|
||||
secret = "dev.sum7.eu-aShared-Secret"
|
||||
notify_muc = []
|
||||
notify_user = ["user@fireorbit.de"]
|
||||
|
||||
|
70
main.go
Normal file
70
main.go
Normal file
|
@ -0,0 +1,70 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"os"
|
||||
"os/signal"
|
||||
"syscall"
|
||||
|
||||
"dev.sum7.eu/genofire/golang-lib/file"
|
||||
"github.com/bdlm/log"
|
||||
"gosrc.io/xmpp"
|
||||
"gosrc.io/xmpp/stanza"
|
||||
|
||||
"dev.sum7.eu/ccchb/ccchatbot/runtime"
|
||||
)
|
||||
|
||||
var config = Config{}
|
||||
|
||||
func main() {
|
||||
configFile := "config.toml"
|
||||
flag.StringVar(&configFile, "config", configFile, "path of configuration file")
|
||||
flag.Parse()
|
||||
|
||||
if err := file.ReadTOML(configFile, &config); err != nil {
|
||||
log.WithField("tip", "maybe call me with: ccchatbot --config /etc/ccchatbot.conf").Panicf("error on read config: %s", err)
|
||||
}
|
||||
|
||||
log.SetLevel(config.LogLevel)
|
||||
|
||||
router := xmpp.NewRouter()
|
||||
router.HandleFunc("presence", handlePresence)
|
||||
router.HandleFunc("message", func(s xmpp.Sender, p stanza.Packet) {
|
||||
msg, ok := p.(stanza.Message)
|
||||
if !ok {
|
||||
log.Errorf("ignoring wrong routed packet: %T", p)
|
||||
return
|
||||
}
|
||||
if err := config.Schalter.HandleBotMessage(s, msg); err != nil {
|
||||
log.Debugf("bot could not handle message: %s", err)
|
||||
}
|
||||
})
|
||||
|
||||
var err error
|
||||
client, err := xmpp.NewClient(xmpp.Config{
|
||||
Address: config.XMPP.Host,
|
||||
Jid: config.XMPP.JID,
|
||||
Password: config.XMPP.Password,
|
||||
}, router)
|
||||
|
||||
if err != nil {
|
||||
log.Panicf("error on startup xmpp client: %s", err)
|
||||
}
|
||||
|
||||
cm := xmpp.NewStreamManager(client, func(s xmpp.Sender) {
|
||||
config.Schalter.Run(s)
|
||||
})
|
||||
go func() {
|
||||
err := cm.Run()
|
||||
log.Panic("closed connection:", err)
|
||||
}()
|
||||
|
||||
// Wait for system signal
|
||||
sigs := make(chan os.Signal, 1)
|
||||
signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM)
|
||||
sig := <-sigs
|
||||
|
||||
runtime.LeaveAllMUCs(client)
|
||||
|
||||
log.Infof("closed by receiving: %s", sig)
|
||||
}
|
41
runtime/muc.go
Normal file
41
runtime/muc.go
Normal file
|
@ -0,0 +1,41 @@
|
|||
package runtime
|
||||
|
||||
import (
|
||||
"github.com/bdlm/log"
|
||||
"gosrc.io/xmpp"
|
||||
"gosrc.io/xmpp/stanza"
|
||||
)
|
||||
|
||||
var mucs []string
|
||||
|
||||
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 LeaveAllMUCs(c xmpp.Sender) {
|
||||
|
||||
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)
|
||||
}
|
||||
}
|
||||
}
|
70
runtime/send.go
Normal file
70
runtime/send.go
Normal file
|
@ -0,0 +1,70 @@
|
|||
package runtime
|
||||
|
||||
import (
|
||||
"github.com/bdlm/log"
|
||||
|
||||
"gosrc.io/xmpp"
|
||||
"gosrc.io/xmpp/stanza"
|
||||
)
|
||||
|
||||
func SendImage(client xmpp.Sender, users, mucs []string, url, desc string) {
|
||||
msg := stanza.Message{
|
||||
Attrs: stanza.Attrs{Type: stanza.MessageTypeGroupchat},
|
||||
Body: url,
|
||||
Extensions: []stanza.MsgExtension{
|
||||
stanza.OOB{URL: url, Desc: desc},
|
||||
},
|
||||
}
|
||||
|
||||
for _, muc := range mucs {
|
||||
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 users {
|
||||
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 SendText(client xmpp.Sender, users, mucs []string, 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 mucs {
|
||||
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 users {
|
||||
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)
|
||||
}
|
||||
}
|
||||
}
|
1
runtime/xmpp_test.go
Normal file
1
runtime/xmpp_test.go
Normal file
|
@ -0,0 +1 @@
|
|||
package runtime
|
26
schalter/bot.go
Normal file
26
schalter/bot.go
Normal file
|
@ -0,0 +1,26 @@
|
|||
package schalter
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"gosrc.io/xmpp"
|
||||
"gosrc.io/xmpp/stanza"
|
||||
)
|
||||
|
||||
func (s *Schalter) HandleBotMessage(c xmpp.Sender, msg stanza.Message) error {
|
||||
if msg.Body == ".status" {
|
||||
jid, _ := xmpp.NewJid(msg.From)
|
||||
reply := stanza.Message{
|
||||
Attrs: stanza.Attrs{Type: msg.Type,
|
||||
To: msg.From,
|
||||
},
|
||||
Body: s.StateString(),
|
||||
}
|
||||
if msg.Type == stanza.MessageTypeGroupchat {
|
||||
reply.To = jid.Bare()
|
||||
reply.Body = fmt.Sprintf("%s: %s", jid.Resource, reply.Body)
|
||||
}
|
||||
return c.Send(reply)
|
||||
}
|
||||
return fmt.Errorf("not handled by this bot: %v", msg)
|
||||
}
|
58
xmpp.go
Normal file
58
xmpp.go
Normal file
|
@ -0,0 +1,58 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"github.com/bdlm/log"
|
||||
"gosrc.io/xmpp"
|
||||
"gosrc.io/xmpp/stanza"
|
||||
)
|
||||
|
||||
func handlePresence(s xmpp.Sender, p stanza.Packet) {
|
||||
pres, ok := p.(stanza.Presence)
|
||||
if !ok {
|
||||
log.Errorf("blame gosrc.io/xmpp for routing: %s", p)
|
||||
return
|
||||
}
|
||||
from, err := xmpp.NewJid(pres.From)
|
||||
if err != nil {
|
||||
log.Errorf("blame gosrc.io/xmpp for jid encoding: %s", pres.From)
|
||||
return
|
||||
}
|
||||
fromBare := from.Bare()
|
||||
logPres := log.WithField("from", from)
|
||||
|
||||
switch pres.Type {
|
||||
case stanza.PresenceTypeSubscribe:
|
||||
logPres.Debugf("recv presence subscribe")
|
||||
if err := s.Send(stanza.Presence{Attrs: stanza.Attrs{
|
||||
Type: stanza.PresenceTypeSubscribed,
|
||||
To: fromBare,
|
||||
Id: pres.Id,
|
||||
}}); err != nil {
|
||||
logPres.WithField("user", pres.From).Errorf("answer of subscribe not send: %s", err)
|
||||
return
|
||||
}
|
||||
logPres.Debugf("accept new subscribe")
|
||||
|
||||
if err := s.Send(stanza.Presence{Attrs: stanza.Attrs{
|
||||
Type: stanza.PresenceTypeSubscribe,
|
||||
To: fromBare,
|
||||
}}); err != nil {
|
||||
logPres.WithField("user", pres.From).Errorf("request of subscribe not send: %s", err)
|
||||
return
|
||||
}
|
||||
logPres.Info("request also subscribe")
|
||||
case stanza.PresenceTypeSubscribed:
|
||||
logPres.Info("recv presence accepted subscribe")
|
||||
case stanza.PresenceTypeUnsubscribe:
|
||||
logPres.Info("recv presence remove subscribe")
|
||||
case stanza.PresenceTypeUnsubscribed:
|
||||
logPres.Info("recv presence removed subscribe")
|
||||
case stanza.PresenceTypeUnavailable:
|
||||
logPres.Debug("recv presence unavailable")
|
||||
case "":
|
||||
logPres.Debug("recv empty presence, maybe from joining muc")
|
||||
return
|
||||
default:
|
||||
logPres.Warnf("recv presence unsupported: %s -> %v", pres.Type, pres)
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue