This repository has been archived on 2020-09-27. You can view files and clone it, but cannot push or open issues or pull requests.
thrempp/component/xmpp.go

144 lines
3.1 KiB
Go

package component
import (
"github.com/bdlm/log"
"gosrc.io/xmpp"
)
type Config struct {
Type string
Host string
Connection string
Secret string
Special map[string]interface{}
xmpp *xmpp.Component
comp Component
}
func (c *Config) Start() error {
c.xmpp = &xmpp.Component{Host: c.Host, Secret: c.Secret}
err := c.xmpp.Connect(c.Connection)
if err != nil {
return err
}
out, err := c.comp.Connect()
if err != nil {
return err
}
go c.recieve(out)
go c.sender()
return nil
}
func (c *Config) recieve(packets chan xmpp.Packet) {
logger := log.WithField("type", c.Type)
for packet := range packets {
switch p := packet.(type) {
case xmpp.Message:
if p.PacketAttrs.From == "" {
p.PacketAttrs.From = c.Host
} else {
p.PacketAttrs.From += "@" + c.Host
}
logger.WithFields(map[string]interface{}{
"from": p.PacketAttrs.From,
"to": p.PacketAttrs.To,
"id": p.PacketAttrs.Id,
}).Debug(p.XMPPFormat())
c.xmpp.Send(p)
default:
log.Warn("ignoring packet:", packet)
}
}
}
func (c *Config) sender() {
logger := log.WithField("type", c.Type)
for {
packet, err := c.xmpp.ReadPacket()
if err != nil {
logger.Panicf("connection closed%s", err)
return
}
switch p := packet.(type) {
case xmpp.IQ:
attrs := p.PacketAttrs
loggerIQ := logger.WithFields(map[string]interface{}{
"from": attrs.From,
"to": attrs.To,
})
switch inner := p.Payload[0].(type) {
case *xmpp.DiscoInfo:
loggerIQ.Debug("Disco Info")
if p.Type == "get" {
iq := xmpp.NewIQ("result", attrs.To, attrs.From, attrs.Id, "en")
var identity xmpp.Identity
if inner.Node == "" {
identity = xmpp.Identity{
Name: c.Type,
Category: "gateway",
Type: "service",
}
}
payload := xmpp.DiscoInfo{
Identity: identity,
Features: []xmpp.Feature{
{Var: "http://jabber.org/protocol/disco#info"},
{Var: "http://jabber.org/protocol/disco#item"},
{Var: xmpp.NSSpaceXEP0184Receipt},
{Var: xmpp.NSSpaceXEP0333ChatMarkers},
},
}
iq.AddPayload(&payload)
_ = c.xmpp.Send(iq)
}
case *xmpp.DiscoItems:
loggerIQ.Debug("DiscoItems")
if p.Type == "get" {
iq := xmpp.NewIQ("result", attrs.To, attrs.From, attrs.Id, "en")
var payload xmpp.DiscoItems
if inner.Node == "" {
payload = xmpp.DiscoItems{
Items: []xmpp.DiscoItem{
{Name: c.Type, JID: c.Host, Node: "node1"},
},
}
}
iq.AddPayload(&payload)
_ = c.xmpp.Send(iq)
}
default:
logger.Debug("ignoring iq packet", inner)
xError := xmpp.Err{
Code: 501,
Reason: "feature-not-implemented",
Type: "cancel",
}
reply := p.MakeError(xError)
_ = c.xmpp.Send(&reply)
}
case xmpp.Message:
logger.WithFields(map[string]interface{}{
"from": p.PacketAttrs.From,
"to": p.PacketAttrs.To,
"id": p.PacketAttrs.Id,
}).Debug(p.XMPPFormat())
c.comp.Send(packet)
case xmpp.Presence:
logger.Debug("Received presence:", p.Type)
default:
logger.Debug("ignoring packet:", packet)
}
}
}