This is part 2 of a 5 part series.
The first step in sending an IM is to create the "Application". The Application is a collection of events and resources that provides 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.
Process Flow
Initial Steps
The process to create an Application follows a linear progression through three steps:
- Connecting to Lync 2013 server
- Authenticating the User
- Creating the Application
Connecting to Lync 2013 Server
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
Information: All communication with UCWA, and your Lync servers, is performed via HTTPS. It is important to ensure your Edge Server certificates are valid to avoid errors.
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.
Authenticating the User
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 let's 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 and is just an 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.
Information: You will notice that the POST
data below isn't in JSON format, unlike most other commands.
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:
emailaddress
= your Lync Server user's SIP address password
= your Lync Server user's password in plain-text
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"
}
Information: HTTP status codes (ie 200 OK) are used throughout the UCWA framework to provide command statuses.
We're nearly there!
Important Step - Including the Access Token
From this point on, all subsequent GET
or POST
s 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 string
s, 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.
Creating the Application
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:
UserAgent
= The application user agent. Officially, this property specifies the identity of the application and can specify information about the operating system, but can also just be an arbitrary descriptor. EndpointId
= A GUID you can specify. Each application must have a unique EndpointId
Culture
= The culture and locale information. This property is used to control various language-specific items, such as the language of the online meeting announcement service.
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:snadella@contoso.com",
"_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/snadella@contoso.com"}
},
"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.
Important Application Resources
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. |