Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save tomorgan/5083819 to your computer and use it in GitHub Desktop.
Save tomorgan/5083819 to your computer and use it in GitHub Desktop.
Simplest example using UCMA UserEndpoint to send an IM. Note: no error handling, assumes IM always accepted etc. For learning only :)
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;
}
}
}
@rohitmsaxena
Copy link

On line 54 I am getting the following error:

An exception of type 'Microsoft.Rtc.Signaling.TlsFailureException' occurred in Microsoft.Rtc.Collaboration.dll but was not handled in user code

Additional information: The target principal name is incorrect

Any idea on how to resolve this problem?

@CrazyTuna
Copy link

Try changing line 47 with :
_endpoint.BeginEstablish(UserEndpointEstablishCompleted, _endpoint);

and line 54 with:
var currentEndpoint = ar.AsyncState as LocalEndpoint;
currentEndpoint.EndEstablish(ar);

@rohitmsaxena
Copy link

Turned out the problem there could be solved with setting it to use x64 rather then allowing the program to choose.

However, now I have the new problem of it saying:

An exception of type 'Microsoft.Rtc.Signaling.TlsFailureException' occurred in Microsoft.Rtc.Collaboration.dll but was not handled in user code

Additional information: The target principal name is incorrect

It says this at the line with EndEstablish(ar); (regardless of if I use the changes you suggested or not)

@MahendraRai
Copy link

At line 42, while initializing UserEndpointSettings you must specify the server FQDN along with the sipaddress.
Hope this helps. :)

@ericrrichards
Copy link

Kind of off-topic, but I was wondering if you knew anything about page-mode messaging (https://msdn.microsoft.com/EN-US/library/dn466059.aspx https://msdn.microsoft.com/en-us/library/dn466061.aspx)?

I've been working on a high-volume Lync/Skype for Business alerting system and came across this reference (https://msdn.microsoft.com/en-us/library/office/hh347364(v=office.14).aspx), which had gotten me on the track of looking into page-mode messaging. So far I haven't been able to get anything working - any attempt to try to actually send a message with the RealTimeEndpoint.SendMessage() method as shown in the examples results in:

ResponseCode=481 ResponseText=Call Leg/Transaction Does Not Exist
DiagnosticInformation=ErrorCode=52085,Source=,Reason=Dialog does not exist
Microsoft.Rtc.Signaling.DiagnosticHeader

I'm not sure what the hangup is, whether I am doing something wrong or whether this is something that the normal Lync/Skype client doesn't support - I suspect the latter, since it does work if I try to send to a recipient that is signed in using Pidgin and the SipE plugin.

Any thoughts? Any help would be very appreciated.

@dipincluster
Copy link

@tomorgan don't you need the FQDN of the Skype for business for this code sample to work??

@nithishanf
Copy link

@tomorgan I am facing an issue with the code. Can you help me with any fix.
Issue : When two people ping to the Bot, it is not able to handle that. When the second person pings, the first conversation stops abruptly. And it establishes connection with second. After that, even if the first pings , it gets the Sender details but replies to the second user's window.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment