package xmpp
import (
"fmt"
"strconv"
"time"
)
const IQTypeGet = "get"
const IQTypeSet = "set"
const IQTypeResult = "result"
const IQTypeError = "error"
func (c *Client) Discovery() (string, error) {
// use getCookie for a pseudo random id.
reqID := strconv.FormatUint(uint64(getCookie()), 10)
return c.RawInformationQuery(c.jid, c.domain, reqID, IQTypeGet, XMPPNS_DISCO_ITEMS, "")
}
// DiscoverNodeInfo discovers information about a node. Empty node queries info about server itself.
func (c *Client) DiscoverNodeInfo(node string) (string, error) {
query := fmt.Sprintf("", XMPPNS_DISCO_INFO, node)
return c.RawInformation(c.jid, c.domain, "info3", IQTypeGet, query)
}
// DiscoverInfo discovers information about given item from given jid.
func (c *Client) DiscoverInfo(from string, to string) (string, error) {
query := fmt.Sprintf("", XMPPNS_DISCO_INFO)
return c.RawInformation(from, to, "info3", IQTypeGet, query)
}
// DiscoverServerItems discover items that the server exposes.
func (c *Client) DiscoverServerItems() (string, error) {
return c.DiscoverEntityItems(c.domain)
}
// DiscoverEntityItems discovers items that an entity exposes.
func (c *Client) DiscoverEntityItems(jid string) (string, error) {
query := fmt.Sprintf("", XMPPNS_DISCO_ITEMS)
return c.RawInformation(c.jid, jid, "info1", IQTypeGet, query)
}
// RawInformationQuery sends an information query request to the server.
func (c *Client) RawInformationQuery(from, to, id, iqType, requestNamespace, body string) (string, error) {
const xmlIQ = "%s"
_, err := fmt.Fprintf(StanzaWriter, xmlIQ, xmlEscape(from), xmlEscape(to), id, iqType, requestNamespace, body)
return id, err
}
// RawInformation sends a IQ request with the payload body to the server.
func (c *Client) RawInformation(from, to, id, iqType, body string) (string, error) {
const xmlIQ = "%s"
_, err := fmt.Fprintf(StanzaWriter, xmlIQ, xmlEscape(from), xmlEscape(to), id, iqType, body)
return id, err
}
// IqVersionResponse responding with software version, according to xep-0092.
func (c *Client) IqVersionResponse(v IQ, name, version, os string) (string, error) {
if name == "" {
name = "go-xmpp"
}
if version == "" {
version = "undefined"
}
query := ""
query += fmt.Sprintf("%s", name)
query += fmt.Sprintf("%s", version)
if os != "" {
query += fmt.Sprintf("%s", os)
}
query += ""
return c.RawInformation(
v.To,
v.From,
v.ID,
IQTypeResult,
query,
)
}
// JabberIqLastResponse responding with relative time since last activity.
// Here lastActivity is unix time stamp when last activity took place since.
func (c *Client) JabberIqLastResponse(v IQ, lastActivity int64) (string, error) {
query := fmt.Sprintf(
"",
time.Now().Unix()-lastActivity,
)
return c.RawInformation(
v.To,
v.From,
v.ID,
IQTypeResult,
query,
)
}
// UrnXMPPTimeResponse implements response to query entity's current time (xep-0202).
// TimezoneOffset have format +HH:MM or -HH:MM.
func (c *Client) UrnXMPPTimeResponse(v IQ, timezoneOffset string) (string, error) {
query := fmt.Sprintf(
"",
timezoneOffset,
time.Now().UTC().Format(time.RFC3339),
)
return c.RawInformation(
v.To,
v.From,
v.ID,
IQTypeResult,
query,
)
}