go-xmpp/stanza
remicorniere 947fcf0432 PubSub protocol support (#142)
* PubSub protocol support
Added support for :
- XEP-0050   (Command))
- XEP-0060   (PubSub)
- XEP-0004   (Forms)

Fixed the NewClient function by adding parsing of the domain from the JID if no domain is provided in transport config.
Updated xmpp_jukebox example

* Delete useless pubsub errors

* README.md update
Fixed import in echo example

* Typo

* Fixed raw send on client example

* Fixed jukebox example and added a README.md
2020-01-09 15:33:11 +01:00
..
commands.go PubSub protocol support (#142) 2020-01-09 15:33:11 +01:00
commands_test.go PubSub protocol support (#142) 2020-01-09 15:33:11 +01:00
component.go Tests for Component and code style fixes (#129) 2019-11-28 17:15:15 +01:00
component_test.go PubSub protocol support (#142) 2020-01-09 15:33:11 +01:00
doc.go Spelling consistency 2019-06-29 14:57:24 +02:00
error.go PubSub protocol support (#142) 2020-01-09 15:33:11 +01:00
error_enum.go Refactor and move parsing and stanza to a separate package 2019-06-26 17:14:52 +02:00
error_test.go We do not need the Content to be innerxml. cdata is enough. 2019-09-27 18:25:27 +02:00
form.go PubSub protocol support (#142) 2020-01-09 15:33:11 +01:00
form_test.go PubSub protocol support (#142) 2020-01-09 15:33:11 +01:00
iot.go Move some IQ declaration in their own files 2019-06-27 10:22:36 +02:00
iot_test.go We do not need the Content to be innerxml. cdata is enough. 2019-09-27 18:25:27 +02:00
iq.go Tests for Component and code style fixes (#129) 2019-11-28 17:15:15 +01:00
iq_disco.go Added Roster IQs 2019-12-23 09:04:18 +01:00
iq_disco_test.go PubSub protocol support (#142) 2020-01-09 15:33:11 +01:00
iq_roster.go Added Roster IQs 2019-12-23 09:04:18 +01:00
iq_roster_test.go PubSub protocol support (#142) 2020-01-09 15:33:11 +01:00
iq_test.go Tests for Component and code style fixes (#129) 2019-11-28 17:15:15 +01:00
iq_version.go Add builder & test on software version helpers 2019-07-30 10:45:20 +02:00
iq_version_test.go Add builder & test on software version helpers 2019-07-30 10:45:20 +02:00
jid.go PubSub protocol support (#142) 2020-01-09 15:33:11 +01:00
jid_test.go PubSub protocol support (#142) 2020-01-09 15:33:11 +01:00
message.go Refactor and move parsing and stanza to a separate package 2019-06-26 17:14:52 +02:00
message_test.go Fix tests after refactor 2019-06-26 17:28:54 +02:00
msg_chat_markers.go Refactor and move parsing and stanza to a separate package 2019-06-26 17:14:52 +02:00
msg_chat_state.go Refactor and move parsing and stanza to a separate package 2019-06-26 17:14:52 +02:00
msg_html.go Refactor and move parsing and stanza to a separate package 2019-06-26 17:14:52 +02:00
msg_html_test.go Fix tests after refactor 2019-06-26 17:28:54 +02:00
msg_oob.go Refactor and move parsing and stanza to a separate package 2019-06-26 17:14:52 +02:00
msg_pubsub_event.go PubSub protocol support (#142) 2020-01-09 15:33:11 +01:00
msg_pubsub_event_test.go PubSub protocol support (#142) 2020-01-09 15:33:11 +01:00
msg_receipts.go Refactor and move parsing and stanza to a separate package 2019-06-26 17:14:52 +02:00
msg_receipts_test.go Fix tests after refactor 2019-06-26 17:28:54 +02:00
node.go Tests for Component and code style fixes (#129) 2019-11-28 17:15:15 +01:00
node_test.go We do not need the Content to be innerxml. cdata is enough. 2019-09-27 18:25:27 +02:00
ns.go Correctly open new streams after StartTLS and auth 2019-10-28 16:38:10 +01:00
open.go Transports need to handle open/close stanzas 2019-10-28 16:38:10 +01:00
packet.go Refactor and move parsing and stanza to a separate package 2019-06-26 17:14:52 +02:00
packet_enum.go Tests for Component and code style fixes (#129) 2019-11-28 17:15:15 +01:00
parser.go Changed "Disconnect" to wait for the closing stream tag. (#141) 2019-12-26 14:47:02 +01:00
pep.go PubSub protocol support (#142) 2020-01-09 15:33:11 +01:00
pres_muc.go Resync with Master 2019-06-26 18:42:40 +02:00
pres_muc_test.go Resync with Master 2019-06-26 18:42:40 +02:00
presence.go Refactor and move parsing and stanza to a separate package 2019-06-26 17:14:52 +02:00
presence_enum.go Refactor and move parsing and stanza to a separate package 2019-06-26 17:14:52 +02:00
presence_test.go Fix tests after refactor 2019-06-26 17:28:54 +02:00
pubsub.go PubSub protocol support (#142) 2020-01-09 15:33:11 +01:00
pubsub_owner.go PubSub protocol support (#142) 2020-01-09 15:33:11 +01:00
pubsub_owner_test.go PubSub protocol support (#142) 2020-01-09 15:33:11 +01:00
pubsub_test.go PubSub protocol support (#142) 2020-01-09 15:33:11 +01:00
README.md Remove Bind in the payload list, as it is intended to be used by XMPP client and not by users of the library. 2019-06-29 16:10:53 +02:00
registry.go Refactor and move parsing and stanza to a separate package 2019-06-26 17:14:52 +02:00
registry_test.go Refactor and move parsing and stanza to a separate package 2019-06-26 17:14:52 +02:00
sasl_auth.go Tests for Component and code style fixes (#129) 2019-11-28 17:15:15 +01:00
sasl_auth_test.go Fix session element parsing on IQ 2019-06-29 17:39:19 +02:00
starttls.go Add support for self-signed certificates 2019-07-15 12:22:21 +02:00
stream.go Added Roster IQs 2019-12-23 09:04:18 +01:00
stream_features.go Changed "Disconnect" to wait for the closing stream tag. (#141) 2019-12-26 14:47:02 +01:00
stream_features_test.go Transports need to handle open/close stanzas 2019-10-28 16:38:10 +01:00
stream_management.go Add initial support for stream management 2019-08-06 16:02:33 +02:00
xmpp_test.go PubSub protocol support (#142) 2020-01-09 15:33:11 +01:00

XMPP Stanza

XMPP stanza package is used to parse, marshal and unmarshal XMPP stanzas and nonzas.

Stanza creation

When creating stanzas, you can use two approaches:

  1. You can create IQ, Presence or Message structs, set the fields and manually prepare extensions struct to add to the stanza.
  2. You can use stanza build helper to be guided when creating the stanza, and have more controls performed on the final stanza.

The methods are equivalent and you can use whatever suits you best. The helpers will finally generate the same type of struct that you can build by hand.

Composing stanzas manually with structs

Here is for example how you would generate an IQ discovery result:

iqResp := stanza.NewIQ(stanza.Attrs{Type: "result", From: iq.To, To: iq.From, Id: iq.Id})
identity := stanza.Identity{
	Name:     opts.Name,
	Category: opts.Category,
	Type:     opts.Type,
}
payload := stanza.DiscoInfo{
	XMLName: xml.Name{
		Space: stanza.NSDiscoInfo,
		Local: "query",
	},
	Identity: []stanza.Identity{identity},
	Features: []stanza.Feature{
		{Var: stanza.NSDiscoInfo},
		{Var: stanza.NSDiscoItems},
		{Var: "jabber:iq:version"},
		{Var: "urn:xmpp:delegation:1"},
	},
}
iqResp.Payload = &payload

Using helpers

Here is for example how you would generate an IQ discovery result using Builder:

iq := stanza.NewIQ(stanza.Attrs{Type: "get", To: "service.localhost", Id: "disco-get-1"})
disco := iq.DiscoInfo()
disco.AddIdentity("Test Component", "gateway", "service")
disco.AddFeatures(stanza.NSDiscoInfo, stanza.NSDiscoItems, "jabber:iq:version", "urn:xmpp:delegation:1")

Payload and extensions

Message

Here is the list of implemented message extensions:

  • Delegation

  • Markable

  • MarkAcknowledged

  • MarkDisplayed

  • MarkReceived

  • StateActive

  • StateComposing

  • StateGone

  • StateInactive

  • StatePaused

  • HTML

  • OOB

  • ReceiptReceived

  • ReceiptRequest

  • Mood

Presence

Here is the list of implemented presence extensions:

  • MucPresence

IQ

IQ (Information Queries) contain a payload associated with the request and possibly an error. The main difference with Message and Presence extension is that you can only have one payload per IQ. The XMPP specification does not support having multiple payloads.

Here is the list of structs implementing IQPayloads:

  • ControlSet
  • ControlSetResponse
  • Delegation
  • DiscoInfo
  • DiscoItems
  • Pubsub
  • Version
  • Node

Finally, when the payload of the parsed stanza is unknown, the parser will provide the unknown payload as a generic Node element. You can also use the Node struct to add custom information on stanza generation. However, in both cases, you may also consider adding your own custom extensions on stanzas.

Adding your own custom extensions on stanzas

Extensions are registered on launch using the Registry. It can be used to register you own custom payload. You may want to do so to support extensions we did not yet implement, or to add your own custom extensions to your XMPP stanzas.

To create an extension you need:

  1. to create a struct for that extension. It need to have XMLName for consistency and to tagged at the struct level with xml info.
  2. It need to implement one or several extensions interface: stanza.IQPayload, stanza.MsgExtension and / or stanza.PresExtension
  3. Add that custom extension to the stanza.TypeRegistry during the file init.

Here an example code showing how to create a custom IQPayload.

package myclient

import (
	"encoding/xml"

	"gosrc.io/xmpp/stanza"
)

type CustomPayload struct {
	XMLName xml.Name `xml:"my:custom:payload query"`
	Node    string   `xml:"node,attr,omitempty"`
}

func (c CustomPayload) Namespace() string {
	return c.XMLName.Space
}

func init() {
	stanza.TypeRegistry.MapExtension(stanza.PKTIQ, xml.Name{"my:custom:payload", "query"}, CustomPayload{})
}