Using Enhanced Messaging
While Enhanced Messaging is interesting for Asterisk 13, it is very interesting for Asterisk 15 and later. Imagine a video conference using Asterisk 15's Selective Forwarding Unit (SFU) capability in ConfBridge. Enhanced Messaging allows the conference participants to chat while participating in the conference. CyberMegaPhone is an example for such a video conference application.
Configuring Asterisk
There is no additional configuration needed. Enhanced Messaging is built-in and always available.
In the browser...
How you design the user interface portion is totally up to you but here is a sample of how CyberMegaPhone could be extended to send a message using JsSIP. In this example, this._ua is a JsSIP.UA instance and this.rtc is a JsSIP.RTCSession instance. Refer to the CyberMegaPhone code to see where this might fit.
CyberMegaPhone.prototype.sendMessage = function (string_msg, options = {} ) { /* * You could allow the user to set a nickname * for themselves which JsSIP can send as the * display name in the SIP From header. In the code * that receives the message, you can then grab the * display name from the packet. */ if (options.from) { from = options.from; this._ua.set("display_name", from); } /* * The message payload can be any UTF-8 string but you are not * limited to plain text. The Content-Type must be set to one * of the text/ or application/ types but as long as the sender * and receiver agree on the payload format, it can contain * whatever you want. In this example, we are going to send * a JSON blob. * * If you do not want to alter the display name on the actual * SIP MESSAGE From header, you could include the user's * nickname in the payload. */ let msg = { 'From': from, 'Body': string_msg }; let body = JSON.stringify(msg); let extraHeaders = [ 'Content-Type: application/x-myphone-confbridge-chat+json' ]; this.rtc.sendRequest(JsSIP.C.MESSAGE, { extraHeaders, body: body, eventHandlers: options.handlers }); }; /* * Now here is how you would call sendMessage */ phone.sendMessage("Hello!", {from: "My Name", handlers: { onSuccessResponse(response) { // You may want to show an indicator that the message was sent successfully. console.log("Message Sent: " + response); }, onErrorResponse(response) { console.log("Message ERROR: " + response); }, onTransportError() { console.log("Could not send message"); }, onRequestTimeout() { console.log("Timeout sending message"); }, onDialogError() { console.log("Dialog Error sending message"); }, }});
Congratulations, you have just sent a text message! Assuming the user called a conference bridge in the first place, all the other participants should receive it. The code to retrieve the message is even simpler than the code to send it. Once again, in this CyberMegaPhone example, this._ua is the JsSIP.UA instance.
this._ua.on('newMessage', function (data) { /* We do not care about messages we send. */ if (data.originator === 'local') { return; } /* Grab the Content-Type header from the packet */ let ct = data.request.headers['Content-Type'][0].raw; /* Make sure the message is one we care about */ if (ct === 'application/x-myphone-confbridge-chat+json') { /* Parse the body back into an object */ let msg = JSON.parse(data.request.body); /* Tell the UI that we got a chat message */ that.raise('messageReceived', msg); } });