Note: This article is for Microsoft Lync 2013, which is no longer supported by Microsoft.
This is part 2 of a 4 part series.
Further reading:
The first step in sending an IM is to create the "Application". The Application is a collection of events and resources that provide the ability to control most aspects of the Lync experience, including sending Instant Messages.
In this tutorial we'll only focus on sending an IM, however the Application can provide access to contacts, meetings, schedules, presence subscriptions and much more. Head over to http://ucwa.lync.com/ for the full API reference.
The process to create an Application follows a linear progression through three steps.
The first step is to send a GET request to your server's autodiscovery URL. The URL is configured when you deploy your Lync environment, and is typically in the format below:
https://lyncdiscover.contoso.com
https://lyncdiscover.yourdomain.com
Once you have sent this post, UCWA will then return a set of values in JSON format, containing the user (Authentication) and xframe URL, which is used for authentication throughout the process.
{
"_links":{
"self":{"href":"https://lync.contoso.com/Autodiscover/AutodiscoverService.svc/root?originalDomain=contoso.com"},
"user":{"href":"https://lync.contoso.com/Autodiscover/AutodiscoverService.svc/root/oauth/user?originalDomain=contoso.com"},
"xframe":{"href":"https://lync.contoso.com/Autodiscover/XFrame/XFrame.html"}
}
}
Keep a record of these URLs (and all others returned by UCWA in later steps), as they are used regularly.
To authenticate a Lync user account to use UCWA, the user URL is passed your authentication details.
The next step is to send an invalid GET to this URL, in order to generate an OAuth token, that is used in all future requests. This is a rather counter-intuitive step, but it works and is documented by Microsoft, so lets go with it.
Send a GET on the user URL
https://lync.contoso.com/Autodiscover/AutodiscoverService.svc/root/oauth/user?originalDomain=contoso.com
UCWA will then return an OAuth token in the body of the response.
{
"access_token":"cwt=AAEBHAEFAAAAAAAFFQAAAJdB...............zc1QkIJYbhraQgI",
"expires_in":27113,
"ms_rtc_identityscope":"local",
"token_type":"Bearer"
}
The token shown above is concatenated an just and example, so please don't use it!
UCWA supports multiple authentication methods, but the easiest to use is basic username/password authentication. To Authenticate, simply pass these details as a webticket to UCWA via the base URL returned earlier.
Send a GET on UCWA
GET https://lync.contoso.com/WebTicket/oauthtoken
With the POST data being:
grant_type=password&username=[emailaddress]&password=[password]
Definitions:
UCWA will then return the following with a HTTP Status Code of 200
{
"access_token":"cwt=AAEBHAEFAAAAAAAFFQAAAJdB...............zc1QkIJYbhraQgI",
"expires_in":27113,
"ms_rtc_identityscope":"local",
"token_type":"Bearer"
}
We're nearly there!
From this point on, all subsequent GET or POSTs must contain the Access Token retrieved above, in the HTTP header.
Depending on your language or framework of choice, the format of the HTTP header string included in future must be in the following format:
Authorization: Bearer cwt=AAEB...buHc
If you are using Microsoft's .NET framework, the webRequest class (from System.Net) has the ability to add custom HTTP Header strings, which will meet this requirement.
C# Example
WebRequest request = WebRequest.Create("https://...");
request.Headers.Add("Authorization", "Bearer cwt=AAEB...buHc");
VB.NET Example
Dim request As WebRequest = WebRequest.Create("https://...")
request.Headers.Add("Authorization", "Bearer cwt=AAEB...buHc")
The URL and token above have been abbreviated for simplicity. This addition is mandatory, so don't forget.
Assuming you've provided appropriate credentials and have received a 200 OK response code (Authenticated!), the next step is to start the Application and retrieve the event URLs that will be used throughout your adventure with UCWA.
Send a GET on the user URL again.
GET https://lync.contoso.com/Autodiscover/AutodiscoverService.svc/root/oauth/user?originalDomain=contoso.com
UCWA will then return the Application URL, that is used to retrieve the full Application event resource group.
{
"_links":{
"self":{"href":"https://lync.contoso.com/Autodiscover/AutodiscoverService.svc/root/user"},
"applications":{"href":"https://lync.contoso.com/ucwa/oauth/v1/applications"},
"xframe":{"href":"https://lync.contoso.com/Autodiscover/XFrame/XFrame.html"}
}
}
The final step is to send a POST to the applications URL, and store the resources that are returned. You also need to pass JSON data that registers your application.
Send a POST on the xxx URL
POST https://lync.contoso.com/ucwa/oauth/v1/applications
With the POST data being:
{
"UserAgent":"My UCWA Application",
"EndpointId":"ab14caff-9361-8cc3-124f-cad1ffa8c999",
"Culture":"en-US",
}
Definitions:
If successful, UCWA will respond with 201 Created, and JSON data representing the entire collection Application event URLs.
{
"culture":"en-US",
"userAgent":"UCWA Samples",
"_links":{
"self":{"href":"/ucwa/oauth/v1/applications/105"},
"batch":{"href":"/ucwa/oauth/v1/applications/105/batch"},
"events":{"href":"/ucwa/oauth/v1/applications/105/events?ack=1"}
},
"_embedded":{
"me":{
"name":"Satya Nadella",
"uri":"sip:[email protected]",
"_links":{
"self":{"href":"/ucwa/oauth/v1/applications/105/me"},
"makeMeAvailable":{"href":"/ucwa/oauth/v1/applications/105/me/makeMeAvailable"},
"callForwardingSettings":{"href":"/ucwa/oauth/v1/applications/105/me/callForwardingSettings"},
"phones":{"href":"/ucwa/oauth/v1/applications/105/me/phones"},
"photo":{"href":"/ucwa/oauth/v1/applications/105/photos/[email protected]"}
},
"rel":"me"
},
"people":{
"_links":{
"self":{"href":"/ucwa/oauth/v1/applications/105/people"},
"presenceSubscriptions":{"href":"/ucwa/oauth/v1/applications/105/people/presenceSubscriptions"},
"subscribedContacts":{"href":"/ucwa/oauth/v1/applications/105/people/subscribedContacts"},
"presenceSubscriptionMemberships":{"href":"/ucwa/oauth/v1/applications/105/people/presenceSubscriptionMemberships"},
"myGroups":{"href":"/ucwa/oauth/v1/applications/105/people/groups"},
"myGroupMemberships":{"href":"/ucwa/oauth/v1/applications/105/people/groupMemberships"},
"myContacts":{"href":"/ucwa/oauth/v1/applications/105/people/contacts"},
"myPrivacyRelationships":{"href":"/ucwa/oauth/v1/applications/105/people/privacyRelationships"},
"myContactsAndGroupsSubscription":{"href":"/ucwa/oauth/v1/applications/105/people/contactsAndGroupsSubscription"},
"search":{"href":"/ucwa/oauth/v1/applications/105/people/search"}
},
"rel":"people"
},
"onlineMeetings":{
"_links":{
"self":{"href":"/ucwa/oauth/v1/applications/105/onlineMeetings"},
"myOnlineMeetings":{"href":"/ucwa/oauth/v1/applications/105/onlineMeetings/myOnlineMeetings"},
"onlineMeetingDefaultValues":{"href":"/ucwa/oauth/v1/applications/105/onlineMeetings/defaultValues"},
"onlineMeetingEligibleValues":{"href":"/ucwa/oauth/v1/applications/105/onlineMeetings/eligibleValues"},
"onlineMeetingInvitationCustomization":{"href":"/ucwa/oauth/v1/applications/105/onlineMeetings/customInvitation"},
"onlineMeetingPolicies":{"href":"/ucwa/oauth/v1/applications/105/onlineMeetings/policies"},
"phoneDialInInformation":{"href":"/ucwa/oauth/v1/applications/105/onlineMeetings/phoneDialInInformation"},
"myAssignedOnlineMeeting":{"href":"/ucwa/oauth/v1/applications/105/onlineMeetings/myOnlineMeetings/1XAW22CG"}
},
"rel":"onlineMeetings"
},
"communication":{
"4d221db7-4af0-476b-9443-8bc874283085":"please pass this in a PUT request",
"supportedModalities":[],
"supportedMessageFormats":["Plain"],
"_links":{
"self":{"href":"/ucwa/oauth/v1/applications/105/communication"},
"conversations":{"href":"/ucwa/oauth/v1/applications/105/communication/conversations?filter=active"},
"startMessaging":{"href":"/ucwa/oauth/v1/applications/105/communication/messagingInvitations"},
"startOnlineMeeting":{"href":"/ucwa/oauth/v1/applications/105/communication/onlineMeetingInvitations?onlineMeetingUri=adhoc"},
"joinOnlineMeeting":{"href":"/ucwa/oauth/v1/applications/105/communication/onlineMeetingInvitations"}
},
"rel":"communication",
"etag":"3140562359"
}
},
"rel":"application"
}
The reference to 105 above is the ApplicationID, and will change for each application you create.
Whilst all the resources shown above have their place, these are the most commonly used.
| Resource | Description |
| _links.self | Base resource for the current Application |
| _links.event | The Events URL increments for each change in modality or activity, and represents the next URL to query in order to get the current Application or Conversation state. |
| _embedded.me.makeMeAvailable | Demonstrated in part 5 of this tutorial, used to change the availability and messaging modality. |
| _embedded.communication.supportedMessageFormats | Demonstrated in part 5 of this tutorial, used to change the type of Instant Message permitted, such as Plain Text or HTML. |
| _embedded.communication.conversations | A collection of resources representing status and settings of an IM conversation. |
| _embedded.communication.startMessaging | The event used to begin an IM conversation. |
| Skype Web SDK: Getting Started |
| Skype Web SDK: Audio & Video |
| What is Kutamo? |
| Kilimanjaro Climb |
| Kilimanjaro 2015 |
| Kilimanjaro 2013 |
| Australian Postcodes |
| New Zealand Postcodes |
| Worldwide City Database |
| Kilimanjaro Climbs |
| Kutamo Studios |
| Kutamo Meetings |
| Litzi |
| ErrLog.IO |
| Kutamo |