### Client Setup and Example Usage Source: https://github.com/xmppjs/xmpp.js/blob/main/packages/client/README.md Demonstrates how to import the client, set up connection options, handle events like 'error', 'offline', and 'online', and send stanzas. This example shows a basic echo bot functionality. ```APIDOC ## Setup ```js import { client, xml, jid } from "@xmpp/client"; ``` or ```html ``` Replace `VERSION` with the desired version number. ```js const { client, xml, jid } = window.XMPP; ``` ## Example ```js import { client, xml } from "@xmpp/client"; import debug from "@xmpp/debug"; const xmpp = client({ service: "ws://localhost:5280/xmpp-websocket", domain: "localhost", lang: "en", resource: "example", username: "username", password: "password", }); debug(xmpp, true); xmpp.on("error", (err) => { console.error(err); }); xmpp.on("offline", () => { console.log("offline"); }); xmpp.on("stanza", onStanza); async function onStanza(stanza) { if (stanza.is("message")) { xmpp.removeListener("stanza", onStanza); await xmpp.send(xml("presence", { type: "unavailable" })); await xmpp.stop(); } } xmpp.on("online", async (address) => { console.log("online as", address.toString()); // Makes itself available await xmpp.send(xml("presence")); // Sends a chat message to itself const message = xml( "message", { type: "chat", to: address }, xml("body", {}, "hello world"), ); await xmpp.send(message); }); await xmpp.start(); ``` ``` -------------------------------- ### Install @xmpp/uri Package Source: https://github.com/xmppjs/xmpp.js/blob/main/packages/uri/README.md Install the package using npm. ```sh npm install @xmpp/uri ``` -------------------------------- ### Install @xmpp/resolve Source: https://github.com/xmppjs/xmpp.js/blob/main/packages/resolve/README.md Install the package using npm. ```bash npm install @xmpp/resolve ``` -------------------------------- ### Install @xmpp/xml Source: https://github.com/xmppjs/xmpp.js/blob/main/packages/xml/README.md Install the @xmpp/xml package. Note that it's a dependency of @xmpp/client and @xmpp/component, so manual installation might not be needed. ```bash npm install @xmpp/xml ``` -------------------------------- ### Install @xmpp/middleware Source: https://github.com/xmppjs/xmpp.js/blob/main/packages/middleware/README.md Install the middleware package using npm. ```sh npm install @xmpp/middleware ``` -------------------------------- ### Full XMPP Client Example Source: https://github.com/xmppjs/xmpp.js/blob/main/packages/client/README.md A comprehensive example demonstrating how to set up, connect, send messages, and handle events with the XMPP client. It includes connection, debugging, error handling, and message sending logic. ```javascript import { client, xml } from "@xmpp/client"; import debug from "@xmpp/debug"; const xmpp = client({ service: "ws://localhost:5280/xmpp-websocket", domain: "localhost", lang: "en", resource: "example", username: "username", password: "password", }); debug(xmpp, true); xmpp.on("error", (err) => { console.error(err); }); xmpp.on("offline", () => { console.log("offline"); }); xmpp.on("stanza", onStanza); async function onStanza(stanza) { if (stanza.is("message")) { xmpp.removeListener("stanza", onStanza); await xmpp.send(xml("presence", { type: "unavailable" })); await xmpp.stop(); } } xmpp.on("online", async (address) => { console.log("online as", address.toString()); // Makes itself available await xmpp.send(xml("presence")); // Sends a chat message to itself const message = xml( "message", { type: "chat", to: address }, xml("body", {}, "hello world"), ); await xmpp.send(message); }); await xmpp.start(); ``` -------------------------------- ### start Source: https://github.com/xmppjs/xmpp.js/blob/main/packages/client/README.md Starts the XMPP connection. The client will automatically attempt to reconnect if disconnected. ```APIDOC ## start Starts the connection. Attempts to reconnect will automatically happen if it cannot connect or gets disconnected. ```js xmpp.on("online", (address) => { console.log("online", address.toString()); }); await xmpp.start(); ``` Returns a promise that resolves if the first attempt succeed or rejects if the first attempt fails. ``` -------------------------------- ### Clone and Build xmpp.js Source: https://github.com/xmppjs/xmpp.js/blob/main/CONTRIBUTING.md Clone the repository and run the initial build process. Ensure you have npm version 7 or higher installed. ```sh git clone git@github.com:xmppjs/xmpp.js.git # Replace with your fork cd xmpp.js make ``` -------------------------------- ### Example Debug Output Source: https://github.com/xmppjs/xmpp.js/blob/main/packages/debug/README.md This is an example of the log output generated by the debug module, showing the flow of XMPP stanzas and status updates. ```xml status connecting status connect status opening IN SCRAM-SHA-1 PLAIN status open OUT IN OUT IN status opening IN status open OUT example IN username@localhost/example status online username@localhost/example online as username@localhost/example OUT OUT IN IN OUT status closing IN status close status disconnecting status disconnect [object Object] status offline offline ``` -------------------------------- ### Example Resolved Endpoints Source: https://github.com/xmppjs/xmpp.js/blob/main/packages/resolve/README.md This is an example of the data structure returned by the resolve function, detailing various connection endpoints. ```json [ { "address": "93.113.206.189", "family": 4, "name": "xmppjs.org", "port": 5222, "priority": 5, "weight": 0, }, { "address": "2a03:75c0:39:3458::1", "family": 6, "name": "xmppjs.org", "port": 5222, "priority": 5, "weight": 0, }, {"address": "93.113.206.189", "family": 4}, {"address": "2a03:75c0:39:3458::1", "family": 6}, { "attribute": "_xmpp-client-websocket", "uri": "wss://xmppjs.org:443/websocket", }, { "attribute": "_xmpp-client-xbosh", "uri": "https://xmppjs.org:443/bosh", }, ] ``` -------------------------------- ### Add IQ Get Handler Source: https://github.com/xmppjs/xmpp.js/blob/main/packages/iq/README.md Register a handler for incoming `get` IQ requests. The handler receives a context and should return the child element for the response. ```javascript iqCallee.get("foo:bar", "foo", (ctx) => { return xml("foo", { xmlns: "foo:bar" }); }); ``` -------------------------------- ### Start XMPP Component Connection Source: https://github.com/xmppjs/xmpp.js/blob/main/packages/component/README.md Initiate the connection process for the XMPP component. This method attempts to connect and authenticate, with automatic reconnection if the initial attempt fails or the connection is lost. ```javascript xmpp.on("online", (address) => { console.log("online", address.toString()); }); await xmpp.start(); ``` -------------------------------- ### Run CI Tests Locally Source: https://github.com/xmppjs/xmpp.js/blob/main/CONTRIBUTING.md If GitHub Actions tests fail, you can run them locally after installing prosody version 0.13 or higher. ```sh make ci ``` -------------------------------- ### Stream Management Delay Element Example Source: https://github.com/xmppjs/xmpp.js/blob/main/packages/stream-management/README.md An example of the XML structure for a delay element, indicating a stanza was meant to be sent at a specific time. ```xml ``` -------------------------------- ### Send IQ Get Request Source: https://github.com/xmppjs/xmpp.js/blob/main/packages/iq/README.md A convenient method to send a `get` IQ request. It accepts and returns a child element instead of a full IQ stanza. ```javascript const foo = await iqCaller.get( xml("foo", "foo:bar"), to, // "to" attribute, optional timeout, // 30 seconds timeout - default ); console.log(foo); ``` -------------------------------- ### Convert JID to String and Get Bare JID Source: https://github.com/xmppjs/xmpp.js/blob/main/packages/jid/README.md Convert a JID instance to its string representation. Retrieve the bare JID (without the resource part) using the bare() method. ```javascript addr.toString(); // alice@wonderland.net/rabbithole addr.bare(); // returns a JID without resource ``` -------------------------------- ### IQ Callee - Get Handler Source: https://github.com/xmppjs/xmpp.js/blob/main/packages/iq/README.md Adds a handler for incoming 'get' IQ requests. The handler is invoked with a context object and should return an XML element that will be used as the child element of the response stanza. ```APIDOC ## Callee - get ### Description Add a `get` handler. ### Method Signature ```javascript get(namespace, tagName, handler) ``` ### Parameters #### `namespace` (string) - Required - The namespace of the child element to match. #### `tagName` (string) - Required - The tag name of the child element to match. #### `handler` (function) - Required - A function that takes a context object and returns an XML element for the response. - `ctx`: Context object provided to the handler. ### Handler Return Value - The XML element returned by the handler will be the child element of the response sent to the caller. ### Example ```javascript iqCallee.get("foo:bar", "foo", (ctx) => { return xml("foo", { xmlns: "foo:bar" }); }); ``` ``` -------------------------------- ### IQ Caller - Get Source: https://github.com/xmppjs/xmpp.js/blob/main/packages/iq/README.md A convenient method to send a 'get' IQ request. It simplifies the process by accepting and returning a child element instead of a full IQ stanza, behaving similarly to the general request method. ```APIDOC ## Caller - get ### Description A convenient method to send a `get` request. Behaves like [request](#request) but accepts/returns a child element instead of an `iq`. ### Method Signature ```javascript async get(childElement, to, timeout) ``` ### Parameters #### `childElement` (xml node) - Required - The child element to be wrapped in a 'get' IQ stanza. #### `to` (string) - Optional - The 'to' attribute for the IQ stanza. #### `timeout` (number) - Optional - The timeout in milliseconds for receiving a response. ### Request Example ```javascript const foo = await iqCaller.get( xml("foo", "foo:bar"), to, // "to" attribute, optional timeout, // 30 seconds timeout - default ); console.log(foo); ``` ``` -------------------------------- ### Get and Set Reconnect Delay Source: https://github.com/xmppjs/xmpp.js/blob/main/packages/reconnect/README.md Configure the delay in milliseconds between connection loss and the next reconnection attempt. The default delay is 1000ms. ```javascript reconnect.delay; // 1000 reconnect.delay = 2000; ``` -------------------------------- ### Access and Modify JID Components Source: https://github.com/xmppjs/xmpp.js/blob/main/packages/jid/README.md Get and set the local, domain, and resource parts of a JID instance using direct property access or dedicated setter/getter methods. ```javascript /* * local */ addr.local = "alice"; addr.local; // alice // same as addr.setLocal("alice"); addr.getLocal(); // alice /* * domain */ addr.domain = "wonderland.net"; addr.domain; // wonderland.net // same as addr.setDomain("wonderland.net"); addr.getDomain(); // wonderland.net /* * resource */ addr.resource = "rabbithole"; addr.resource; // rabbithole // same as addr.setResource("rabbithole"); addr.getResource(); // rabbithole ``` -------------------------------- ### Get child element by name Source: https://github.com/xmppjs/xmpp.js/blob/main/packages/xml/README.md Retrieve a direct child element by its tag name using the 'getChild()' method. ```javascript message.getChild("body").toString(); // '3' ``` -------------------------------- ### Send IQ Request Source: https://github.com/xmppjs/xmpp.js/blob/main/packages/iq/README.md Send an IQ request and get a promise that resolves with the response, rejects with `StanzaError` on error, `TimeoutError` on timeout, or `Error` otherwise. The `id` and `to` attributes are optional. ```javascript const response = await iqCaller.request( xml("iq", { type: "get" }, xml("foo", "foo:bar")), 30 * 1000, // 30 seconds timeout - default ); const foo = response.getChild("foo", "foo:bar"); console.log(foo); ``` -------------------------------- ### Embed and read JSON within XML Source: https://github.com/xmppjs/xmpp.js/blob/main/packages/xml/README.md Embed JSON data within XML elements, recommended to use appropriate semantics. The example shows writing JSON using JSX and reading it using getChildText and JSON.parse. ```javascript /** @jsx xml */ // write message.append( {JSON.stringify(days)} , ); // read JSON.parse( message .getChild("myevent", "xmpp:example.org") .getChildText("json", "urn:xmpp:json:0"), ); ``` -------------------------------- ### Get children elements by name Source: https://github.com/xmppjs/xmpp.js/blob/main/packages/xml/README.md Retrieve all direct child elements with a specific tag name using the 'getChildren()' method. This returns an array, allowing for further array method manipulation. ```javascript message.getChild("days").getChildren("day"); // [...] ``` -------------------------------- ### Component Initialization and Usage Source: https://github.com/xmppjs/xmpp.js/blob/main/packages/component/README.md Demonstrates how to initialize a component, handle events like errors and online status, and send messages. ```APIDOC ## Initialize Component ```javascript import { component, xml, jid } from "@xmpp/component"; import debug from "@xmpp/debug"; const xmpp = component({ service: "xmpp://localhost:5347", domain: "component.localhost", password: "mysecretcomponentpassword", }); debug(xmpp, true); ``` ## Event Handling ### Error Event ```javascript xmpp.on("error", (err) => { console.error(err); }); ``` ### Offline Event ```javascript xmpp.on("offline", () => { console.log("offline"); }); ``` ### Stanza Event (Example: Echo Bot) ```javascript xmpp.on("stanza", async (stanza) => { if (stanza.is("message")) { const { to, from } = stanza.attrs; stanza.attrs.from = to; stanza.attrs.to = from; await xmpp.send(stanza); } }); ``` ### Online Event ```javascript xmpp.on("online", async (address) => { console.log("online as", address.toString()); // Sends a chat message to itself const message = xml( "message", { type: "chat", to: address }, xml("body", {}, "hello world") ); await xmpp.send(message); }); ``` ## Start Connection ```javascript await xmpp.start(); ``` ``` -------------------------------- ### JID Creation and Usage Source: https://github.com/xmppjs/xmpp.js/blob/main/packages/jid/README.md Demonstrates how to create JID instances using different formats and how to access and modify their components (local, domain, resource). ```APIDOC ## JID Creation and Manipulation ### Description This section covers the creation of JID objects and the methods available for accessing and modifying their components. ### Usage Import the jid function from the library: ```javascript import jid from "@xmpp/jid"; ``` **Creating JIDs:** Create a full JID from a string: ```javascript const addr = jid("alice@wonderland.net/rabbithole"); ``` Create a JID from its components: ```javascript const addr = jid("alice", "wonderland.net", "rabbithole"); ``` Create a domain JID: ```javascript const addr = jid("wonderland.net"); ``` Check if an object is a JID instance: ```javascript addr instanceof jid.JID; // true ``` **Accessing and Modifying Components:** **Local Part:** ```javascript addr.local = "alice"; addr.local; // "alice" // or using a method addr.setLocal("alice"); addr.getLocal(); // "alice" ``` **Domain Part:** ```javascript addr.domain = "wonderland.net"; addr.domain; // "wonderland.net" // or using a method addr.setDomain("wonderland.net"); addr.getDomain(); // "wonderland.net" ``` **Resource Part:** ```javascript addr.resource = "rabbithole"; addr.resource; // "rabbithole" // or using a method addr.setResource("rabbithole"); addr.getResource(); // "rabbithole" ``` **String Representation:** Get the full JID string: ```javascript addr.toString(); // "alice@wonderland.net/rabbithole" ``` Get the bare JID (without resource): ```javascript addr.bare(); // returns a JID without resource ``` **Comparison:** Check if two JIDs are equal: ```javascript addr.equals(some_jid); // returns true if the two JIDs are equal, false otherwise // or using a static method jid.equal(addr, some_jid); ``` ``` -------------------------------- ### Initialize Middleware with Client Source: https://github.com/xmppjs/xmpp.js/blob/main/packages/middleware/README.md Initialize the middleware with an XMPP client entity. ```javascript import { Client } from "@xmpp/client"; import middleware from "@xmpp/middleware"; const client = new Client(); const app = middleware({ entity: client }); ``` -------------------------------- ### Configure Client with Static Resource String Source: https://github.com/xmppjs/xmpp.js/blob/main/packages/client-core/src/bind2/README.md Use this when you want to set a static resource for your client. The server will choose the resource if omitted. ```javascript import { xmpp } from "@xmpp/client"; const client = xmpp({ resource: "laptop" }); ``` -------------------------------- ### Configure Client with Resource Function Source: https://github.com/xmppjs/xmpp.js/blob/main/packages/client-core/src/bind2/README.md Provide a function to dynamically determine the resource each time binding occurs. This function will be called on every (re)connect. ```javascript import { xmpp } from "@xmpp/client"; const client = xmpp({ resource: onBind }); async function onBind(bind) { const resource = await fetchResource(); return resource; } ``` -------------------------------- ### app.use Source: https://github.com/xmppjs/xmpp.js/blob/main/packages/middleware/README.md Registers a middleware function to handle incoming stanzas. The middleware receives a context object and a next function. ```APIDOC ## app.use ### Description Registers a middleware function for incoming stanzas. ### Parameters #### Context (`ctx`) - `ctx` (object) - The context object for the middleware. - `next` (function) - A function to call the next middleware in the stack. ### Example ```javascript app.use((ctx, next) => { // Middleware logic here }); ``` ``` -------------------------------- ### Import IQ Callee Source: https://github.com/xmppjs/xmpp.js/blob/main/packages/iq/README.md Import the `client` or `component` and access the `iqCallee` from the XMPP instance. ```javascript import { client } from "@xmpp/client"; // or component const xmpp = client(...); const {iqCallee} = xmpp; ``` -------------------------------- ### Publish a New Version Source: https://github.com/xmppjs/xmpp.js/blob/main/CONTRIBUTING.md Navigate to the xmpp.js directory and use Lerna to publish a new version of the package. ```sh cd xmpp.js npx lerna publish ``` -------------------------------- ### Get child element text value Source: https://github.com/xmppjs/xmpp.js/blob/main/packages/xml/README.md Conveniently retrieve the text content of a direct child element using the 'getChildText()' method. ```javascript message.getChildText("body"); // '3' ``` -------------------------------- ### Create and Validate JID Instances Source: https://github.com/xmppjs/xmpp.js/blob/main/packages/jid/README.md Import the jid function and use it to create JID instances from string representations or by providing local, domain, and resource parts. Verify instance type. ```javascript import jid from "@xmpp/jid"; /* * All return an instance of jid.JID */ const addr = jid("alice@wonderland.net/rabbithole"); const addr = jid("alice", "wonderland.net", "rabbithole"); addr instanceof jid.JID; // true // domain JIDs are created passing the domain as the first argument const addr = jid("wonderland.net"); ``` -------------------------------- ### Configure SASL2 with Object Credentials Source: https://github.com/xmppjs/xmpp.js/blob/main/packages/sasl2/README.md Provide credentials directly as an object when initializing the XMPP client. This is suitable for static credentials. ```javascript import { xmpp } from "@xmpp/client"; const client = xmpp({ credentials: { username: "foo", password: "bar", }, }); ``` -------------------------------- ### Import IQ Caller Source: https://github.com/xmppjs/xmpp.js/blob/main/packages/iq/README.md Import the `client` or `component` and access the `iqCaller` from the XMPP instance. ```javascript import { client } from "@xmpp/client"; // or component const xmpp = client(...); const {iqCaller} = xmpp; ``` -------------------------------- ### Client Options Source: https://github.com/xmppjs/xmpp.js/blob/main/packages/client/README.md Configuration options available when initializing the XMPP client. These options control connection details, authentication, and stream attributes. ```APIDOC ## client - `options` <`Object`> - `service` `` The service to connect to, accepts an URI or a domain. - `domain` lookup and connect to the most secure endpoint using [@xmpp/resolve](/packages/resolve) - `xmpp://hostname:port` plain TCP, may be upgraded to TLS by [@xmpp/starttls](/packages/starttls) - `xmpps://hostname:port` direct TLS - `ws://hostname:port/path` plain WebSocket - `wss://hostname:port/path` secure WebSocket - `domain` `` Optional domain of the service, if omitted will use the hostname from `service`. Useful when the service domain is different than the service hostname. - `lang` `` Optional language tag for the stream, sets the `xml:lang` attribute on the stream per [RFC 6120 Section 4.7.4](https://xmpp.org/rfcs/rfc6120.html#streams-attr-xmllang). Useful for servers that use this attribute to determine the language for error messages. - `resource` ` Optional resource for [resource binding](/packages/resource-binding) - `username` `` Optional username for [sasl](/packages/sasl) - `password` `` Optional password for [sasl](/packages/sasl) - `timeout` ` { console.error(err); }); xmpp.on("offline", () => { console.log("offline"); }); xmpp.once("stanza", async (stanza) => { if (stanza.is("message")) { await xmpp.stop(); } }); xmpp.on("online", async (address) => { console.log("online as", address.toString()); // Sends a chat message to itself const message = xml( "message", { type: "chat", to: address }, xml("body", {}, "hello world"), ); await xmpp.send(message); }); await xmpp.start(); ``` -------------------------------- ### Component API Reference Source: https://github.com/xmppjs/xmpp.js/blob/main/packages/component/README.md Details the available methods and events on the xmpp component instance. ```APIDOC ## `component(options)` Initializes a new component instance. ### Options - `service` (string): The service URI to connect to (e.g., `xmpp://localhost:5347`). - `domain` (string): The domain of the component. - `password` (string): The password for authentication. - `timeout` (number, optional): Timeout in milliseconds (defaults to 2000). Returns an `xmpp` object. ## `xmpp` Object An instance of `EventEmitter` with the following properties and methods: ### Status - `status` (string): Current connection status (e.g., `online`, `offline`, `connecting`). ### Events - `status` (string): Emitted when the connection status changes. - `error` (Error): Emitted when an error occurs. - `stanza` (Element): Emitted when a stanza is received and parsed. - `online` (Jid): Emitted when the component is connected, authenticated, and ready. - `offline`: Emitted when the connection is closed and no further reconnect attempts will be made. ### Methods - `start()`: Starts the connection. Returns a promise that resolves on success or rejects on failure. - `stop()`: Stops the connection and prevents auto-reconnect. Returns a promise. - `disconnect()`: Disconnects without preventing auto-reconnect. Returns a promise. - `send(stanza)`: Sends a stanza. Returns a promise that resolves when the stanza is sent. ``` -------------------------------- ### Include Client Script (Browser) Source: https://github.com/xmppjs/xmpp.js/blob/main/packages/client/README.md Include the XMPP client script in an HTML file for browser usage. Replace VERSION with the desired version number. ```html ``` -------------------------------- ### Implement an XMPP Component Echo Bot Source: https://github.com/xmppjs/xmpp.js/blob/main/packages/component/README.md This snippet demonstrates how to create a simple echo bot by listening for 'stanza' events. When a message stanza is received, it's sent back to the original sender. ```javascript // Simple echo bot example xmpp.on("stanza", (stanza) => { console.log(stanza.toString()); if (!stanza.is("message")) return; const { to, from } = stanza.attrs; stanza.attrs.from = to; stanza.attrs.to = from; xmpp.send(stanza); }); ``` -------------------------------- ### Enable Debugging for XMPP Client Source: https://github.com/xmppjs/xmpp.js/blob/main/packages/debug/README.md Import and initialize the debug module with your XMPP client. Debugging is enabled if `process.env.XMPP_DEBUG` is set, or it can be forced on by passing `true` as the second argument. ```javascript import { client } from "@xmpp/client"; // or component, ... import debug from "@xmpp/debug"; const xmpp = client(...); debug(xmpp); // requires process.env.XMPP_DEBUG // or debug(xmpp, true); // always enabled ``` -------------------------------- ### Register Incoming Stanza Middleware Source: https://github.com/xmppjs/xmpp.js/blob/main/packages/middleware/README.md Register a middleware function to handle incoming stanzas using the `use` method. ```javascript app.use((ctx, next) => {}); ``` -------------------------------- ### Run Tests in xmpp.js Source: https://github.com/xmppjs/xmpp.js/blob/main/CONTRIBUTING.md Execute the test suite after making code changes. For faster iteration, consider using Jest's watch mode for specific test files. ```sh make test ``` -------------------------------- ### Configure SASL with Authentication Function Source: https://github.com/xmppjs/xmpp.js/blob/main/packages/sasl/README.md Provide a function to dynamically fetch credentials or handle authentication logic on each connection. Useful for interactive prompts or fetching from secure sources. ```javascript import { xmpp } from "@xmpp/client"; const client = xmpp({ credentials: onAuthenticate }); async function onAuthenticate(authenticate, mechanisms) { console.debug("authenticate", mechanisms); const credentials = { username: await prompt("enter username"), password: await prompt("enter password"), }; console.debug("authenticating"); await authenticate(credentials, mechanisms[0]); console.debug("authenticated"); } ``` -------------------------------- ### Access Client in Browser Source: https://github.com/xmppjs/xmpp.js/blob/main/packages/client/README.md Access the XMPP client and related utilities from the window object after including the script in an HTML file. ```javascript const { client, xml, jid } = window.XMPP; ``` -------------------------------- ### Import xml function Source: https://github.com/xmppjs/xmpp.js/blob/main/packages/xml/README.md Import the xml function for use in your project. This is typically done when using @xmpp/client or @xmpp/component. ```javascript import xml from "@xmpp/xml"; import { xml } from "@xmpp/client"; import { xml } from "@xmpp/component"; ``` -------------------------------- ### Add IQ Set Handler Source: https://github.com/xmppjs/xmpp.js/blob/main/packages/iq/README.md Register a handler for incoming `set` IQ requests. The handler receives a context and should return the child element for the response. ```javascript iqCallee.set("foo:bar", "foo", (ctx) => { return xml("foo", { xmlns: "foo:bar" }); }); ``` -------------------------------- ### Configure SASL2 with Authentication Function Source: https://github.com/xmppjs/xmpp.js/blob/main/packages/sasl2/README.md Provide a function to handle authentication dynamically on each connection or reconnection. This allows for interactive credential entry or fetching from secure sources. ```javascript import { xmpp, xml } from "@xmpp/client"; const client = xmpp({ credentials: authenticate, }); async function onAuthenticate(authenticate, mechanisms) { console.debug("authenticate", mechanisms); const credentials = { username: await prompt("enter username"), password: await prompt("enter password"), }; console.debug("authenticating"); // userAgent is optional const userAgent = await getUserAgent(); await authenticate(credentials, mechanisms[0], userAgent); console.debug("authenticated"); } async function getUserAgent() { let id = localStorage.get("user-agent-id"); if (!id) { id = await crypto.randomUUID(); localStorage.set("user-agent-id", id); } // https://xmpp.org/extensions/xep-0388.html#initiation return xml("user-agent", { id }, [ xml("software", {}, "xmpp.js"), xml("device", {}, "Sonny's laptop"), ]); } ``` -------------------------------- ### XMPP Client Instance Events Source: https://github.com/xmppjs/xmpp.js/blob/main/packages/client/README.md Details the events emitted by the XMPP client instance, including status changes, errors, received stanzas, and successful connection. ```APIDOC ## xmpp `xmpp` is an instance of [EventEmitter](https://nodejs.org/api/events.html). ### status `online` indicates that `xmpp` is authenticated and addressable. It is emitted every time there is a successfull (re)connection. `offline` indicates that `xmpp` disconnected and no automatic attempt to reconnect will happen (after calling `xmpp.stop()`). Additional status: - `connecting`: Socket is connecting - `connect`: Socket is connected - `opening`: Stream is opening - `open`: Stream is open - `closing`: Stream is closing - `close`: Stream is closed - `disconnecting`: Socket is disconnecting - `disconnect`: Socket is disconnected You can read the current status using the `status` property. ```js const isOnline = xmpp.status === "online"; ``` You can listen for status change using the `status` event. ### Event `status` Emitted when the status changes. ```js xmpp.on("status", (status) => { console.debug(status); }); ``` ### Event `error` Emitted when an error occurs. For connection errors, `xmpp` will reconnect on its own using [@xmpp/reconnect](/packages/reconnect) however a listener MUST be attached to avoid uncaught exceptions. - `` ```js xmpp.on("error", (error) => { console.error(error); }); ``` ### Event `stanza` Emitted when a stanza is received and parsed. - [``](/packages/xml) ```js // Simple echo bot example xmpp.on("stanza", (stanza) => { console.log(stanza.toString()); if (!stanza.is("message")) return; const { to, from } = stanza.attrs; stanza.attrs.from = to; stanza.attrs.to = from; xmpp.send(stanza); }); ``` ### Event `online` Emitted when connected, authenticated and ready to receive/send stanzas. - [``](/packages/jid) ```js xmpp.on("online", (address) => { console.log("online as", address.toString()); }); ``` ``` -------------------------------- ### JID Escaping Source: https://github.com/xmppjs/xmpp.js/blob/main/packages/jid/README.md Explains how the library handles JID escaping according to XEP-0106, which is necessary for characters not allowed in the local part of a JID. ```APIDOC ## JID Escaping (XEP-0106) ### Description This section details the implementation of JID escaping as defined in XEP-0106, which allows for the representation of characters that are not permitted in the local part of a JID. ### Usage When creating a JID with characters that need escaping, the library handles it automatically: ```javascript const addr = jid("contact@example.net", "xmpp.net"); addr.toString(); // "contact\40example.net@xmpp.net" // For display purposes, you can get an unescaped version: addr.toString(true); // "contact@example.net@xmpp.net" ``` For user input, it is recommended to use the `jid()` constructor directly, which will handle escaping if necessary: ```javascript // Recommended for user input jid("contact@example.net", "xmpp.net"); // Avoid this if the input might contain special characters that need escaping // jid("contact@example.net@xmpp.net"); ``` ``` -------------------------------- ### Generate and Parse XMPP Date/Time Source: https://github.com/xmppjs/xmpp.js/blob/main/packages/time/README.md Import the time module to generate current date/time strings or parse custom date inputs. Accepts Date objects or strings for parsing. ```javascript import * as time from "@xmpp/time"; time.date(); // '2016-11-18' time.time(); // '20:45:30.221Z' time.datetime(); // '2016-11-18T20:45:53.513Z' time.offset(); // '-1:00' // each method accepts an optional date or string argument time.datetime("05 October 2011 14:48 UTC"); // '2011-10-05T14:48:00.000Z' time.datetime(new Date("05 October 2011 14:48 UTC")); // '2011-10-05T14:48:00.000Z' ``` -------------------------------- ### Implement Custom Token Storage for Fast Authentication Source: https://github.com/xmppjs/xmpp.js/blob/main/packages/client-core/src/fast/README.md Supply custom functions to store and retrieve authentication tokens for fast authentication. This enables persistent token storage across sessions. If fast authentication fails, regular authentication will be used. ```javascript import { xmpp } from "@xmpp/client"; const client = xmpp({ ... }); client.fast.fetchToken = async () => { const value = await secureStorage.get("token") return JSON.parse(value); } client.fast.saveToken = async (token) => { await secureStorage.set("token", JSON.stringify(token)); } client.fast.removeToken = async () => { await secureStorage.del("token"); } ``` -------------------------------- ### Escape and Unescape JID Local Parts Source: https://github.com/xmppjs/xmpp.js/blob/main/packages/jid/README.md Demonstrates JID escaping and unescaping according to XEP-0106. Use the toString(true) option for display purposes only. ```javascript const addr = jid("contact@example.net", "xmpp.net"); addr.toString(); // contact\40example.net@xmpp.net // for display purpose only addr.toString(true); // contact@example.net@xmpp.net ``` ```javascript jid("contact@example.net", "xmpp.net"); // over jid("contact@example.net@xmpp.net"); ``` -------------------------------- ### Prepend content to XML element Source: https://github.com/xmppjs/xmpp.js/blob/main/packages/xml/README.md Add new text or element nodes to the beginning of an existing XML element using the 'prepend()' method. It returns the parent element. ```javascript message.prepend(xml("foo")); message.prepend("bar"); message.prepend(days.map((day) => xml("day", {}, day))); // // Tuesday // Monday // bar // // ... // ``` -------------------------------- ### Check if Connection is Secure Source: https://github.com/xmppjs/xmpp.js/blob/main/packages/client/README.md Use isSecure() to determine if the current connection is considered secure. This includes localhost, encrypted channels (wss, xmpps, starttls), and returns false if there is no connection. ```javascript console.log(xmpp.isSecure()); ``` -------------------------------- ### Listen for Reconnecting Event Source: https://github.com/xmppjs/xmpp.js/blob/main/packages/reconnect/README.md Subscribe to the 'reconnecting' event to be notified every time the module attempts to re-establish a connection. ```javascript reconnect.on("reconnecting", () => { console.log("reconnecting"); }); ``` -------------------------------- ### Send Stanza with XMPP Component Source: https://github.com/xmppjs/xmpp.js/blob/main/packages/component/README.md Send an XMPP stanza using the component. This method serializes the stanza and writes it to the socket. It returns a promise that resolves on success or rejects on failure. ```javascript await xmpp.send(xml("presence")); ``` -------------------------------- ### Access root node Source: https://github.com/xmppjs/xmpp.js/blob/main/packages/xml/README.md Navigate to the root XML element using the 'root()' method. ```javascript console.log(message.getChild("days").root() === message); ``` -------------------------------- ### xmpp.reconnect Source: https://github.com/xmppjs/xmpp.js/blob/main/packages/component/README.md Handles the reconnection logic for the XMPP client. Refer to the @xmpp/reconnect package for detailed documentation. ```APIDOC ## xmpp.reconnect ### Description See [@xmpp/reconnect](/packages/reconnect). ### Details This method is an alias or integration point for the reconnection functionality provided by the `@xmpp/reconnect` package. For detailed usage, parameters, and behavior, please consult the documentation for that specific package. ``` -------------------------------- ### Write XML using factory function Source: https://github.com/xmppjs/xmpp.js/blob/main/packages/xml/README.md Generate XML elements using the xml factory function. It supports nested elements and dynamic content generation using array mapping. ```javascript import xml from "@xmpp/xml"; const recipient = "user@example.com"; const days = ["Monday", "Tuesday", "Wednesday"]; const message = xml( "message", { to: recipient }, xml("body", {}, 1 + 2), xml( "days", {}, days.map((day, idx) => xml("day", { idx }, day)), ), ); ``` -------------------------------- ### sendMany Source: https://github.com/xmppjs/xmpp.js/blob/main/packages/client/README.md Sends multiple XMPP stanzas efficiently. ```APIDOC ## sendMany Sends multiple stanzas. Here is an example sending the same text message to multiple recipients. ```js const message = "Hello"; const recipients = ["romeo@example.com", "juliet@example.com"]; const stanzas = recipients.map((address) => xml("message", { to: address, type: "chat" }, xml("body", null, message)), ); await xmpp.sendMany(stanzas); ``` Returns a promise that resolves once all the stanzas have been sent. If you need to send a stanza to multiple recipients we recommend using [Extended Stanza Addressing](https://xmpp.org/extensions/xep-0033.html) instead. ``` -------------------------------- ### Listen for XMPP Component Online Event Source: https://github.com/xmppjs/xmpp.js/blob/main/packages/component/README.md Attach a listener to the 'online' event to execute code once the component has successfully connected and authenticated with the XMPP server. The event provides the component's JID. ```javascript xmpp.on("online", (address) => { console.log("online as", address.toString()); }); ``` -------------------------------- ### Instantiate XMPPError Source: https://github.com/xmppjs/xmpp.js/blob/main/packages/error/README.md Import and instantiate the XMPPError class with a condition, optional text, and an associated XML element. The created error object inherits from the native JavaScript Error class. ```javascript import XMPPError from "@xmpp/error"; const error = new XMPPError("service-unavailable", "optional text", element); error instanceof Error; // true error.condition === "service-unavailable"; // true error.text === "service-unavailabe - optional text"; // true error.element === element; // true ``` -------------------------------- ### Write XML using JSX Source: https://github.com/xmppjs/xmpp.js/blob/main/packages/xml/README.md Generate XML elements using JSX syntax, which requires a preprocessor like TypeScript or Babel with the appropriate plugin. Ensure the xml function is imported and aliased as 'xml' for JSX. ```javascript /** @jsx xml */ import xml from "@xmpp/xml"; const recipient = "user@example.com"; const days = ["Monday", "Tuesday"]; const message = ( {1 + 2} {days.map((day, idx) => ( ${day} ))} ); ``` -------------------------------- ### send Source: https://github.com/xmppjs/xmpp.js/blob/main/packages/client/README.md Sends a single XMPP stanza over the connection. ```APIDOC ## send Sends a stanza. ```js await xmpp.send(xml("presence")); ``` Returns a promise that resolves once the stanza is serialized and written to the socket or rejects if any of those fails. ``` -------------------------------- ### Listen for XMPP Component Status Changes Source: https://github.com/xmppjs/xmpp.js/blob/main/packages/component/README.md Attach a listener to the 'status' event to be notified whenever the connection status of the XMPP component changes. This is useful for reacting to connection state transitions. ```javascript xmpp.on("status", (status) => { console.debug(status); }); ``` -------------------------------- ### Compare JIDs for Equality Source: https://github.com/xmppjs/xmpp.js/blob/main/packages/jid/README.md Check if two JID instances are equal using the equals() method on a JID instance or the static equal() method. ```javascript addr.equals(some_jid); // returns true if the two JIDs are equal, false otherwise // same as jid.equal(addr, some_jid); ``` -------------------------------- ### Generate XMPP ID Source: https://github.com/xmppjs/xmpp.js/blob/main/packages/id/README.md Import and use the id function to generate a unique ID. No arguments are required. ```javascript import id from "@xmpp/id"; console.log(id()); // ymg806tinn ``` -------------------------------- ### Resolve XMPP Endpoints with Options Source: https://github.com/xmppjs/xmpp.js/blob/main/packages/resolve/README.md Use the resolve function to find XMPP endpoints for a given domain. Optional parameters can specify SRV record details and IP address family. ```javascript import resolve from "@xmpp/resolve"; // optional const options = { srv: [{ service: "xmpp-client", protocol: "tcp" }], // SRV records family: undefined, // IP version; 4, 6 or undefined for both }; resolve("jabberfr.org", options).then(console.log).catch(console.error); ``` -------------------------------- ### Handle Connection Errors Source: https://github.com/xmppjs/xmpp.js/blob/main/packages/reconnect/README.md Listen for the 'error' event on the entity to catch any errors that occur during the reconnection process. ```javascript entity.on("error", (err) => { console.error(err); }); ``` -------------------------------- ### Send IQ Set Request Source: https://github.com/xmppjs/xmpp.js/blob/main/packages/iq/README.md A convenient method to send a `set` IQ request. It accepts and returns a child element instead of a full IQ stanza. ```javascript const foo = await iqCaller.set( xml("foo", "foo:bar"), to, // "to" attribute, optional timeout, // 30 seconds timeout - default ); console.log(foo); ``` -------------------------------- ### Handle XMPP Component Errors Source: https://github.com/xmppjs/xmpp.js/blob/main/packages/component/README.md Implement an error handler for the 'error' event. This is crucial for managing connection errors, as the component may attempt to reconnect automatically. ```javascript xmpp.on("error", (error) => { console.error(error); }); ``` -------------------------------- ### Parse XML string Source: https://github.com/xmppjs/xmpp.js/blob/main/packages/xml/README.md Use the 'parse' function from '@xmpp/xml/lib/parse.js' to parse XML strings into XML structures. Use with caution on untrusted input. ```javascript import { escapeXML, escapeXMLText } from "@xmpp/xml"; import parse from "@xmpp/xml/lib/parse.js"; const ctx = parse("hello world"); ctx.getChildText("body"); // hello world ```