Learn Skype Web SDK Day 15 : Receiving Instant Messages
[contemplate-1]
View Demo
Once you’ve created and started a conversation using Skype for Web API, you actually don’t need to worry about how you’re going to receive IM messages. Skype for Web will make sure that you receive messages sent to the conversation. The issue instead becomes one of “how do I found out when that’s happened”.
Each conversation has a historyService
object. This provides a collection of all messages in the conversation: incoming, outgoing, joining, leaving. IM messages have a specific type of message called a TextMessage
. By listening for messages of type TextMessage we can pull out instant messages being sent in both directions.
Of course, you probably already know when you’re sending messages to the conversation, but having them in the historyService
object means that you have one centralised place to watch to track the conversation. If you’re writing a user interface for an IM conversation, it’s much easier to use the historyService
object, where messages are ordered in the order in which they happen, than it is to fake the history when sending, which risks getting the timing wrong.
The historyService
contains some useful members to make retrieiving and staying up to date with the conversation easier. The activityItems
collection is the actual list of conversation history items. To react everytime something is added to this collection, register a listener on activityItems.added:
conversation.historyService.activityItems.added(function (newMsg) { //do something with newMsg });
Items in the activityItems
collection have the following members and methods describing the conversation item. (there are others, but I’ve pulled out the interesting ones):
- newMsg.key – a unique GUID which you can use to identify the message
- newMsg.isRead – a boolean value. Set to false initially, but you can mark messages as read to make parsing for new messages easier if needed.
- newMsg.direction() – either ‘Incoming’ or ‘Outgoing’ depending on the direction the message is travelling in
- newMsg.text() – the plaintext version of the message
- newMsg.html() – an HTML formatted version of the message, in a span tag
- newMsg.timestamp() – timestamp of the message
- newMsg.sender.uri – the sip address of the sender
- newMsg.sender.person.displayName() – the display name of the sender, if it’s known. If not, the URI is shown instead.
You also have access to the entire person object (newMsg.sender.person
) which you can use to subscribe to presence, get more information etc.
In the code sample below, the signed in user can send and receive instant messages with another user:
<div class="form-horizontal"> <div class="form-group"> <label for="username" class="col-sm-2 control-label">Username</label> <div class="col-sm-10"> <input type="email" class="form-control" id="username" placeholder="Email"> </div> </div> <div class="form-group"> <label for="password" class="col-sm-2 control-label">Password</label> <div class="col-sm-10"> <input type="password" class="form-control" id="password" placeholder="Password"> </div> </div> <div class="form-group"> <div class="col-sm-offset-2 col-sm-10"> <button class="btn btn-default" id="btnLogIn">Log in</button> </div> </div> <div class="form-group"> <div class="col-sm-offset-2 col-sm-10"> <button class="btn btn-default" id="btnLogOut">Log out</button> </div> </div> </div> <div> <span id="loginStatus"></span> </div> <hr/> <div class="form-horizontal"> <div class="form-group"> <label for="contact" class="col-sm-2 control-label">Start Conversation with:</label> <div class="col-sm-10"> <input type="email" class="form-control" id="contact" placeholder="Contact SIP Address"> </div> </div> <div class="form-group"> <div class="col-sm-offset-2 col-sm-10"> <button class="btn btn-default" id="btnStartConversation" disabled="disabled">Start</button> </div> </div> </div> <div> Conversation State: <span id="lblConversationState"></span> <ul id='conversationText'></ul> <hr/> <div class="form-horizontal"> <div class="form-group"> <label for="message" class="col-sm-2 control-label">Send Message:</label> <div class="col-sm-10"> <input type="email" class="form-control" id="message" placeholder="Message to send"> </div> </div> <div class="form-group"> <div class="col-sm-offset-2 col-sm-10"> <button class="btn btn-default" id="btnSendIM" disabled="disabled">Send IM</button> </div> </div> </div> <div id="footer"></div> <!-- This is not needed for the samples to run, but adds standard headers and footers to the samples, to display title, instructions, about etc. If you're taking this code and using it yourself, you can remove this.--> <script type="text/javascript" src="../../assets/layoutcodesample-min.js"></script> <script type="text/javascript"> <!-- These variables are only needed for laying out the code sample, they are not part of the sample code. --> var pageTitle = 'Receiving Instant Messages'; var blogPostLocation = "http://thoughtstuff.co.uk"; var githubLocation = "http://github.com"; var client; $(function () { 'use strict'; Skype.initialize({ apiKey: 'SWX-BUILD-SDK', }, function (api) { client = new api.application(); // whenever client.state changes, display its value client.signInManager.state.changed(function (state) { $('#loginStatus').text("Login State: " + state); }); }, function (err) { alert('Error loading Skype Web SDK: ' + err); }); $('#btnLogIn').click(function () { // start signing in client.signInManager.signIn({ username: $('#username').val(), password: $('#password').val() }).then(function () { //log in worked! alert('Logged in!'); $('#btnStartConversation').prop('disabled', false); }, function (error) { //Something went wrong. alert(error); }); }); $('#btnLogOut').click(function () { // start signing out client.signInManager.signOut() .then(function () { //log out worked! alert('Logged out!'); $('#btnStartConversation').prop('disabled', true); $('#btnSendIM').prop('disabled', true); }, function (error) { //Something went wrong. alert(error); }); }); $('#btnStartConversation').click(function () { StartConversation($('#contact').val()); }); $('#btnSendIM').click(function () { conversation.chatService.sendMessage($('#message').val()); }); function StartConversation (contactSIP) { //first, get the person to start a conversation with. Assume one person. var person; GetContactFromName(contactSIP).then(function (results) { results.forEach(function (result) { person = result.result; }); //create the conversation object conversation = client.conversationsManager.createConversation(); //add the person to the conversation by creating a conversation participant object var convParticipant = conversation.createParticipant(person); conversation.participants.add(convParticipant); //add the newly created conversation to the ConversationManager list client.conversationsManager.conversations.add(conversation); //register for the conversation state changing to connected. conversation.chatService.state.changed(function(newState){ $('#lblConversationState').text(newState); if (newState == 'Connected') { $('#btnSendIM').prop('disabled', false); //safe to send IMs now } }); //register for new messages added to the historyService object conversation.historyService.activityItems.added(function (newMsg){ if (newMsg.type() == 'TextMessage') { var direction; if (newMsg.direction() == 'Incoming') direction = "<--"; else { direction = "-->"; } $("#conversationText").append('<li><b>' + direction + '</b>&nbsp; ' + newMsg.sender.displayName() + ' : ' + newMsg.text() + '</li>'); } }); conversation.chatService.start(); }); } function GetContactFromName(contactSIP) { var query = client.personsAndGroupsManager.createPersonSearchQuery(); query.text(contactSIP); query.limit(1); return query.getMore(); } }); </script>
Demo Online
You can try this code out against your own Skype for Business environment by going to the demo page. From here you can also download the code from GitHub if you want to host it locally, or take it and use it in your next project.
[contemplate-2]