vCard support
This commit is contained in:
parent
ae2470dcb7
commit
416c708909
|
@ -24,6 +24,85 @@ type PresenceXVCardUpdatePhoto struct {
|
||||||
Text string `xml:",chardata"`
|
Text string `xml:",chardata"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// IqVcardTemp is from XEP-0054
|
||||||
|
type IqVcardTemp struct {
|
||||||
|
XMLName xml.Name `xml:"vcard-temp vCard"`
|
||||||
|
Fn IqVcardFn
|
||||||
|
Nickname IqVcardNickname
|
||||||
|
N IqVcardN
|
||||||
|
Tel IqVcardTel
|
||||||
|
Photo IqVcardPhoto
|
||||||
|
}
|
||||||
|
|
||||||
|
// IqVcardFn is vCard/FN
|
||||||
|
type IqVcardFn struct {
|
||||||
|
XMLName xml.Name `xml:"FN"`
|
||||||
|
Text string `xml:",chardata"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// IqVcardNickname is vCard/NICKNAME
|
||||||
|
type IqVcardNickname struct {
|
||||||
|
XMLName xml.Name `xml:"NICKNAME"`
|
||||||
|
Text string `xml:",chardata"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// IqVcardN is vCard/N
|
||||||
|
type IqVcardN struct {
|
||||||
|
XMLName xml.Name `xml:"N"`
|
||||||
|
Family IqVcardNFamily
|
||||||
|
Given IqVcardNGiven
|
||||||
|
Middle IqVcardNMiddle
|
||||||
|
}
|
||||||
|
|
||||||
|
// IqVcardNFamily is vCard/N/FAMILY
|
||||||
|
type IqVcardNFamily struct {
|
||||||
|
XMLName xml.Name `xml:"FAMILY"`
|
||||||
|
Text string `xml:",chardata"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// IqVcardNGiven is vCard/N/GIVEN
|
||||||
|
type IqVcardNGiven struct {
|
||||||
|
XMLName xml.Name `xml:"GIVEN"`
|
||||||
|
Text string `xml:",chardata"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// IqVcardNMiddle is vCard/N/MIDDLE
|
||||||
|
type IqVcardNMiddle struct {
|
||||||
|
XMLName xml.Name `xml:"MIDDLE"`
|
||||||
|
Text string `xml:",chardata"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// IqVcardTel is vCard/TEL
|
||||||
|
type IqVcardTel struct {
|
||||||
|
XMLName xml.Name `xml:"TEL"`
|
||||||
|
Number IqVcardTelNumber
|
||||||
|
}
|
||||||
|
|
||||||
|
// IqVcardTelNumber is vCard/TEL/NUMBER
|
||||||
|
type IqVcardTelNumber struct {
|
||||||
|
XMLName xml.Name `xml:"NUMBER"`
|
||||||
|
Text string `xml:",chardata"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// IqVcardPhoto is vCard/PHOTO
|
||||||
|
type IqVcardPhoto struct {
|
||||||
|
XMLName xml.Name `xml:"PHOTO"`
|
||||||
|
Type IqVcardPhotoType
|
||||||
|
Binval IqVcardPhotoBinval
|
||||||
|
}
|
||||||
|
|
||||||
|
// IqVcardPhotoType is vCard/PHOTO/TYPE
|
||||||
|
type IqVcardPhotoType struct {
|
||||||
|
XMLName xml.Name `xml:"TYPE"`
|
||||||
|
Text string `xml:",chardata"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// IqVcardPhotoBinval is vCard/PHOTO/BINVAL
|
||||||
|
type IqVcardPhotoBinval struct {
|
||||||
|
XMLName xml.Name `xml:"BINVAL"`
|
||||||
|
Text string `xml:",chardata"`
|
||||||
|
}
|
||||||
|
|
||||||
// Namespace is a namespace!
|
// Namespace is a namespace!
|
||||||
func (c PresenceNickExtension) Namespace() string {
|
func (c PresenceNickExtension) Namespace() string {
|
||||||
return c.XMLName.Space
|
return c.XMLName.Space
|
||||||
|
@ -34,6 +113,11 @@ func (c PresenceXVCardUpdateExtension) Namespace() string {
|
||||||
return c.XMLName.Space
|
return c.XMLName.Space
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Namespace is a namespace!
|
||||||
|
func (c IqVcardTemp) Namespace() string {
|
||||||
|
return c.XMLName.Space
|
||||||
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
// presence nick
|
// presence nick
|
||||||
stanza.TypeRegistry.MapExtension(stanza.PKTPresence, xml.Name{
|
stanza.TypeRegistry.MapExtension(stanza.PKTPresence, xml.Name{
|
||||||
|
@ -46,4 +130,10 @@ func init() {
|
||||||
"vcard-temp:x:update",
|
"vcard-temp:x:update",
|
||||||
"x",
|
"x",
|
||||||
}, PresenceXVCardUpdateExtension{})
|
}, PresenceXVCardUpdateExtension{})
|
||||||
|
|
||||||
|
// iq vcard request
|
||||||
|
stanza.TypeRegistry.MapExtension(stanza.PKTIQ, xml.Name{
|
||||||
|
"vcard-temp",
|
||||||
|
"vCard",
|
||||||
|
}, IqVcardTemp{})
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,16 @@
|
||||||
package xmpp
|
package xmpp
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
|
"encoding/base64"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
|
"io"
|
||||||
|
"os"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"dev.narayana.im/narayana/telegabber/persistence"
|
"dev.narayana.im/narayana/telegabber/persistence"
|
||||||
|
"dev.narayana.im/narayana/telegabber/xmpp/extensions"
|
||||||
"dev.narayana.im/narayana/telegabber/xmpp/gateway"
|
"dev.narayana.im/narayana/telegabber/xmpp/gateway"
|
||||||
|
|
||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
|
@ -25,7 +30,84 @@ func HandleIq(s xmpp.Sender, p stanza.Packet) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Printf("Iq: %#v\n", iq)
|
log.Debugf("%#v", iq)
|
||||||
|
if iq.Type == "get" {
|
||||||
|
_, ok := iq.Payload.(*extensions.IqVcardTemp)
|
||||||
|
if ok {
|
||||||
|
log.WithFields(log.Fields{
|
||||||
|
"from": iq.From,
|
||||||
|
"to": iq.To,
|
||||||
|
}).Warn("VCard request")
|
||||||
|
|
||||||
|
fromJid, err := xmpp.NewJid(iq.From)
|
||||||
|
if err != nil {
|
||||||
|
log.Error("Invalid from JID!")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
session, ok := sessions[fromJid.Bare()]
|
||||||
|
if !ok {
|
||||||
|
log.Error("IQ from stranger")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
toParts := strings.Split(iq.To, "@")
|
||||||
|
toID, err := strconv.ParseInt(toParts[0], 10, 64)
|
||||||
|
if err != nil {
|
||||||
|
log.Error("Invalid IQ to")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
chat, user, err := session.GetContactByID(toID, nil)
|
||||||
|
if err != nil {
|
||||||
|
log.Error(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
vcard := extensions.IqVcardTemp{}
|
||||||
|
if chat != nil {
|
||||||
|
vcard.Fn.Text = chat.Title
|
||||||
|
|
||||||
|
if chat.Photo != nil {
|
||||||
|
path := chat.Photo.Small.Local.Path
|
||||||
|
file, err := os.Open(path)
|
||||||
|
if err == nil {
|
||||||
|
defer file.Close()
|
||||||
|
|
||||||
|
buf := new(bytes.Buffer)
|
||||||
|
binval := base64.NewEncoder(base64.StdEncoding, buf)
|
||||||
|
_, err = io.Copy(binval, file)
|
||||||
|
if err == nil {
|
||||||
|
vcard.Photo.Type.Text = "image/jpeg"
|
||||||
|
vcard.Photo.Binval.Text = buf.String()
|
||||||
|
} else {
|
||||||
|
log.Errorf("Error calculating hash: %v", path)
|
||||||
|
}
|
||||||
|
} else if path != "" {
|
||||||
|
log.Errorf("Photo does not exist: %v", path)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if user != nil {
|
||||||
|
vcard.Nickname.Text = user.Username
|
||||||
|
vcard.N.Given.Text = user.FirstName
|
||||||
|
vcard.N.Family.Text = user.LastName
|
||||||
|
vcard.Tel.Number.Text = user.PhoneNumber
|
||||||
|
}
|
||||||
|
|
||||||
|
answer := stanza.IQ{
|
||||||
|
Attrs: stanza.Attrs{
|
||||||
|
From: iq.To,
|
||||||
|
To: iq.From,
|
||||||
|
Id: iq.Id,
|
||||||
|
Type: "result",
|
||||||
|
},
|
||||||
|
Payload: vcard,
|
||||||
|
}
|
||||||
|
log.Debugf("%#v", answer)
|
||||||
|
|
||||||
|
_ = s.Send(answer)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// HandleMessage processes an incoming XMPP message
|
// HandleMessage processes an incoming XMPP message
|
||||||
|
|
Loading…
Reference in a new issue