Creating UCMA Applications with a UserApplication instance. Example: sending IMs.
The UCMA platform is very powerful, but sometimes you just want to send a message. Of course, you can do this using the Lync Client SDK, but you might not want the obvious interaction with the Lync client and visibility that provides. If you’re writing a Windows .NET application, you might just want to perform a Lync activity within the code, silently and secretly 🙂
When you write UCMA code you choose whether to do so with UserEndpoints or with ApplicationEndpoints. UserEndpoints are tied to a specific user, a Lync account and must have a username and password. ApplicationEndpoints have to be pre-registered with the Lync Server like this and are generally more powerful than UserEndpoints.
However, if all you want to do is send a quick IM and you’re in an application that already has the user’s credentials (or you can re-prompt for them), then a UserEndpoint is fine.
Here’s a quick example showing how to do this. This code will create and establish a UserEndpoint, send an IM and then Terminate:
using Microsoft.Rtc.Collaboration; | |
using System; | |
namespace SimpleUserUCMA | |
{ | |
class Program | |
{ | |
private const string sipaddress = "sip:from@domain.com"; | |
private const string username = "USERNAME"; | |
private const string password = "PASSWORD"; | |
private const string domain = "DOMAIN"; | |
private const string destinationSip = "sip:tom@domain.com"; | |
private const string IMMessage = "Hello!"; | |
static CollaborationPlatform _collabPlatform { get; set; } | |
static UserEndpoint _endpoint { get; set; } | |
static bool _OKToQuit = false; | |
static void Main(string[] args) | |
{ | |
string userAgent = "ClientPlatformExample"; | |
var platformSettings = new ClientPlatformSettings(userAgent, Microsoft.Rtc.Signaling.SipTransportType.Tls); | |
_collabPlatform = new CollaborationPlatform(platformSettings); | |
//Start up the platform, calling back asynchronously once it's done. | |
_collabPlatform.BeginStartup(EndCollabPlatformStartup, null); | |
//In this example, wait for everything to finish before exiting | |
while (!_OKToQuit) | |
{ | |
System.Threading.Thread.Sleep(2000); | |
} | |
} | |
private static void EndCollabPlatformStartup(IAsyncResult ar) | |
{ | |
_collabPlatform.EndStartup(ar); | |
//A collaboration plaform can have one or more Endpoints. An Endpoint is tied to a SIP Address. | |
UserEndpointSettings settings = new UserEndpointSettings(sipaddress); | |
settings.Credential = new System.Net.NetworkCredential(username, password, domain); | |
settings.AutomaticPresencePublicationEnabled = true; | |
_endpoint = new UserEndpoint(_collabPlatform, settings); | |
_endpoint.BeginEstablish(UserEndpointEstablishCompleted, null); | |
} | |
private static void UserEndpointEstablishCompleted(IAsyncResult ar) | |
{ | |
_endpoint.EndEstablish(ar); | |
//Once the endpoint is in place, create a Conversation and an IM Call. | |
var Conversation = new Conversation(_endpoint); | |
var Call = new InstantMessagingCall(Conversation); | |
//When the call is established, Flow will be created. Flow is how you sent IMs around. Therefore, just before | |
//establishing, we attach an event handler to catch the flow being setup (it's state will change to Active) | |
Call.InstantMessagingFlowConfigurationRequested += Call_InstantMessagingFlowConfigurationRequested; | |
Call.BeginEstablish(destinationSip, new CallEstablishOptions(), EndBeginEstablish, Call); | |
} | |
private static void EndBeginEstablish(IAsyncResult ar) | |
{ | |
Call call = (Call)ar.AsyncState; | |
call.EndEstablish(ar); | |
} | |
static void Call_InstantMessagingFlowConfigurationRequested(object sender, InstantMessagingFlowConfigurationRequestedEventArgs e) | |
{ | |
//Once we're notified about this, we get a handle to the newly created Flow. Let's use this to register for state changes. | |
e.Flow.StateChanged += Flow_StateChanged; | |
} | |
static void Flow_StateChanged(object sender, MediaFlowStateChangedEventArgs e) | |
{ | |
if (e.State == MediaFlowState.Active) | |
{ | |
//The flow is now active! We can use it to send messages. | |
InstantMessagingFlow flow = (InstantMessagingFlow)sender; | |
flow.BeginSendInstantMessage(IMMessage, EndBeginSendInstanceMessage, flow); | |
} | |
} | |
private static void EndBeginSendInstanceMessage(IAsyncResult ar) | |
{ | |
InstantMessagingFlow flow = (InstantMessagingFlow)ar.AsyncState; | |
flow.EndSendInstantMessage(ar); | |
//Having sent the message, terminate the conversation | |
flow.Call.Conversation.BeginTerminate(EndBeginTerminate, flow.Call.Conversation); | |
} | |
private static void EndBeginTerminate(IAsyncResult ar) | |
{ | |
Conversation conversation = (Conversation)ar.AsyncState; | |
conversation.EndTerminate(ar); | |
_OKToQuit = true; | |
} | |
} | |
} |
Thank you for posting this code. I needed an alternative to using the Lync SDK to send an instant message. This code put me on the track to use SIP instea.
Hello. I’ve repeated as you posts now, but I met the error {ErrorCode=4005,Source=MyServer.COM,Reason=Destination URI either not enabled for SIP or does not exist Microsoft.Rtc.Signaling.DiagnosticHeader}. Maybe user account problem? With Lync 2010 client, it has no error. Would you please tell me that there is any setting with user?
Hi,
great job, i’m new with Lync Developing but your blog got me far ahead in the learning process.
is it possible to use UCMA SDK to create user or application endpoint that listen to incoming IM calls? without having to initiate the IM call from the UCMA application first?
appreciate your help 🙂
Hi
Thank you for posting this code.
Iâve done your code, but I met the error:
error message : Unable to establish a connection.
InnerException error message : No connection could be made because the target machine actively refused it 89.165.11.17:5061
Hi,
Thanks for great information.!! I need code sample of IM for Application Endpoints.
Please provide what changes i have do in above sample.
Thanks
Paresh