Source: wtapi.chat.js

/**
 * A plugin that provides Chat functionality
 *
 * @version 1.0.0
 */
(function(WTAPI) {
    /**
     * Constructor for Chat plugin.
     * Instance will be created each time when new WTAPI instance is created. <br />
     * Plugin could be accessible thought WTAPI with <b>chat</b> property.
     *
     * @tutorial chat-plugin
     * @memberof WTAPI
     * @alias WTAPI.ChatPlugin
     * @augments Observer
     * @public
     * @constructor
     */
    function ChatPlugin(wtapi) {
        this._wtapi = wtapi;
        this._wtapi.registerHandler("message", this._handleMessage, this, 100);
        this._roster = this._wtapi.roster;

        // Initialize supper
        WTAPI.Observable.call(this);
    }

    ChatPlugin.prototype = Object.create(WTAPI.Observable.prototype);

    // ============================================================
    // Public events
    // ============================================================

    /**
     * Indicates that new message is received from remote user.
     *
     * @event WTAPI.ChatPlugin#message_received
     * @property {WTAPI.User} user
     * @property {WTAPI.Message} message
     */

    /**
     * Indicates that message is read by destination.
     *
     * @event WTAPI.ChatPlugin#message_delivered
     * @property {WTAPI.User} user
     * @property {string} id Id message delivered
     */

    // ============================================================
    // Public functions
    // ============================================================

    /**
     * Sends a message to user.
     *
     * @param {WTAPI.User} user
     * @param {WTAPI.Message} message
     */
    ChatPlugin.prototype.send = function(user, message) {
        var packet = new JSJaCMessage();
        packet.setID(message.getId());
        packet.setTo(user.getJid());
        packet.setType('chat');
        packet.setBody(message.getBody());

        packet.appendNode('request', {'xmlns': 'urn:xmpp:receipts'});
        packet.appendNode('markable', {'xmlns': 'urn:xmpp:chat-markers:0'});

        this._wtapi.getConnection().send(packet);
    }

    /**
     * Sends a notification that message are read by user.
     *
     * @param {WTAPI.User} user A user that send message
     * @param {WTAPI.Message} message
     */
    ChatPlugin.prototype.sendDeliveryConfirmation = function(user, message) {
        var packet = new JSJaCMessage();
        packet.setTo(user.getJid());
        packet.setType('chat');
        packet.appendNode('received', {'xmlns': 'urn:xmpp:receipts', 'id': message.getId()});
        packet.appendNode('displayed', {'xmlns': 'urn:xmpp:chat-markers:0', 'id': message.getId()});
        packet.appendNode('store', {'xmlns': 'urn:xmpp:hints'});

        this._wtapi.getConnection().send(packet);
    }

    // ============================================================
    // ChatPlugin callbacks
    // ============================================================

    /**
     * @private
     */
    ChatPlugin.prototype._handleMessage = function(packet) {
        if (this._handleMessageDelivery(packet)) {
            return true;
        }

        // Default chat message handling
        var type = packet.getType();
        var body = packet.getBody();

        if (!(type == "" || type == "chat" || type == "normal") || body.length == 0) {
            return false;
        }

        var id = packet.getID();
        var builder = new WTAPI.Message.Builder();
        builder.withId(id);
        builder.withBody(body);
        var message = builder.build();

        var nick = packet.getChildVal('nick', 'http://jabber.org/protocol/nick')
        var from = packet.getFromJID();
        var jid = from.removeResource().toString();
        var user = this._roster.getUser(jid);

        if (user === null) {
            if(nick == ''){
                nick = null;
            }
            user = this._roster.createUser(jid, nick);
        }
        this._fire("message_received", user, message);
    }

    /**
     * @private
     */
    ChatPlugin.prototype._handleMessageDelivery = function(packet) {
        var els = packet.getNode().getElementsByTagName('received');
        if (els.length == 1) {
            if(els.item(0).namespaceURI != 'urn:xmpp:receipts'){
                return false;
            }
        }else{
            els = packet.getNode().getElementsByTagName('displayed');
        }
        if (els.length == 1) {
            var received = els.item(0);
            var id = received.getAttribute('id');
            var from = packet.getFromJID();
            var jid = from.removeResource().toString();
            var user = this._roster.getUser(jid);

            if (user !== null && id !== null) {
                this._fire("message_delivered", user, id);
            }
        }
    }

    WTAPI.addPlugin("chat", ChatPlugin);
}(WTAPI));