Lessons Learned: Simple Urls

This is another installment in my Lessons Learned series but unlike the previous lessons this one is from a PowerShell scripting project. The goal of the project was to create a web service interface for provisioning Lync and have it front-end the necessary PowerShell scripts.

My goal was to create Simple Meet URLs but I ran into some problems as I created all my SipDomains first then tried to set up the SimpleUrls. At that point I started getting errors and my investigation of the relationship between the Sip domains and the meet URLs began. I found that there has to be a one-to-one relationship between the two…<read more>

Professional Unified Communications Development with Lync Server 2010

I just got my advance copy a few minutes ago via UPS. I already have the Kindle version for a few days and I have been reading that. I’ve seen parts of the book as the authors were writing it but now I can read it as a whole. I’ll be doing a book review soon – probably next week sometime.

You can purchase the book here – http://www.amazon.com/Professional-Unified-Communications-Development-Microsoft/dp/0470939036/ref=sr_1_2?ie=UTF8&qid=1305817868&sr=8-2#_

Lessons Learned: impersonating a user

As I mentioned in Lessons Learned: passing parameters to your workflow I’m doing a series of blog posts on things that I learned while working on my latest UCMA IVR project. The app recorded the caller’s messsage and also allowed the voice mailbox owner to record a custom greeting.

One of the problems I originally encountered occurred when the remote caller was a Lync user and was placing a  Lync audio call to another Lync user. When that happened the caller would see something like this –


At this point in the call it is just a call between two Lync users and everything looks and works as you would expect.  The problem occurs when the called party doesn’t answer or manually redirects the call to voice mail. When my application took over the call the caller’s Lync window would show the name of my app and  look like this –



Not exactly what I wanted the caller to see. The caller should see the name of the person they are calling throughout the life of the call. Fortunately UCMA has a facility that makes that simple. All I needed to do was have my application impersonate the called party and that can be dome with a s single line of code. I added this to myAudioVideoCallReceived event handler

e.Call.Conversation.Impersonate(e.TransferredBy, e.Call.Conversation.LocalParticipant.PhoneUri, e.Call.Conversation.LocalParticipant.DisplayName);

That code told my application to impersonate the called party. I only wish that this method was a little better documented. All references  that I found were in the scope of a B2B call where the UCMA application sits in the middle between the calling party and the called party. That wasn’t the case with my app as it is an endpoint. I wasn’t sure if it would work in my case but it did.Note that for the third parameter I used the caled party’s display name but that parameter is just a simple string and you could use it to cause any text to appear.

Simple and easy.


New Unified Communications Blog to Watch

Chris Schindler has started a new blog called unifyingcommunications that is looking very interesting. In the early days of GotSpeech.net Chris was instrumental in getting the word out about this site. Now I am returning the favor and also adding him to my required reading list.

Chris is a Senior Program Manager in the in Unified Communications and has some great insight. I hope yo enjoy reading what he has to say as much as I do.


Lessons Learned: passing parameters to your workflow

I just came off of a large UCMA 3.0 project writing an IVR app that records a voice mail and also allows you to customize your mailbox greeting. I spent lots of time on the project and learned quite a bit about how UCMA differs from the Speech Server apps that we are all used to building. I discovered some bugs (or undocumented features) and worked my way through some stuff that wasn’t well documented. It was tough at times but I learned a lot and now I am going to pass that on to you. I’ve decided to do a series of “Lessons Learned”. I’ll cover things that aren’t obvious, aren’t part of the default features and in one case a bug (or at least I think it is a bug). Unfortunately I can’t just post the complete code but I will post snippets where appropriate and you can fill in the connecting parts.

One of the things my app does is make a branching decision at the top. The same app handles both the voice mail recording function as well as the custom greeting recording. the app doesn’t prompt the caller for which action to take – it just “knows” and the caller has no idea that it is the same application doing both. It does this by looking at the SIP header as the custom greeting calls have a custom parameter in the SIP header. I’ll cover how to access the parameter value in another post. Today I’m going to assume you have it and now need to pass it into your work flow.

Every UCMA application should have an event handler to handle receiving calls. This event fires once the call comes in and is essentially where your code really starts running. The event should look like this:

       private static void AudioVideoCallReceived(object sender, CallReceivedEventArgs<AudioVideoCall> e)

Somewhere in the method (usually at the bottom) you call the method to create your workflow passing in any parameters that you need. In the code below I am passing in a string called resource that tells the workflow the type of call is coming in – voice mail or custom greeting:

            StartWorkflow(e.Call, e.RequestData, e.TransferredBy.ToString(), e.RemoteParticipant.ToString(), resource);

Back stepping slightly here but in order to pass something into your workflow you have to declare a variable in your workflow to receive it and setup a get/set for it. Once your workflow starts you can then access it like any other variable in your code:

        private string resource;

        public string Resource
            get { return resource; }
            set { resource = value; }

Now lets go back to the  StartWorkflow method as it is there that all of the magic occurs. First you need to create a Dictionary object then you need to add your variable to the Dictionary:

             // Create the parameters for the workflow
            Dictionary<string, object> parameters = new Dictionary<string, object>();

            parameters.Add(“Resource”, resource);

This is where it gets a little tricky. If you misspell  the parameter your workflow does not work and any error messages you may get don’t make any sense. Just make sure you spell the parameter names the same as the public parameter you created in your workflow code.

Now all that is left is to create the workflow passing in the  Dictionary object like this:

             WorkflowInstance workflowInstance = _workflowRuntime.CreateWorkflow(typeof(Workflow1), parameters);

The rest of the code for starting your can figure out from the code samples that Microsoft supplies when you install UCMA 3.0.

I’m going to try and post a new “Lessons Learned” post each week as my time permits.

I hope this helps. As always I would love to hear your feedback and questions on this post.


New Lync Server 2010 Books

Microsoft Lync Server 2010 Unleashed by Alex Lewis , Andrew Abbate and Tom Pacyk will be in stock at Amazon on April 6th. I’ve been conversing with Alex while the book was being written and I can’t wait to get my hands on a copy. I’m a big fan of Sams’ Unleased series of books and since this one is on Lync Server I’m definitely going to add it to my library.

I was a contributing writer on this book having written the development chapter and I can’t wait to get my hands on it.



As  developer I am looking forward to the release of Professional Unified Communications Development with Microsoft Lync Server 2010 by Geroge Durzi and Michael Greenlee which is due out on May 23rd.

I’ve been in touch with Michael off and on throughout the writing of this book and have reviewed several of the chapters. The book is going to really fill a void that we UCMA developers have been facing and is another book that I’ll be adding to my library. I asked Michael to make the sample code relevant and complete and from what I have seen they have done that. I learned a few things from just reading the early versions of the chapters. I’ll blog more on this book once I get my hands on it. I’m also trying to come up with a contest or something with the book as a prize. It’s been a long time since I did something like that so I think it is time for another giveaway.


Enjoy and I would like to hear your feedback on these books.

I’m in Redmond next week for the MVP Summit

I’ll be in Bellevue and Redomd next week for the Microsoft 20111 MVP Summit along with my fellow MVPs.

This will be the 5th Summit and I’m looking forward to a great time visiting with my fellow MVPs and the Lync Product Group. My past Summits have always been both informative and fun and I expect this one to be no different. The only bad thing is things run all day and into the night and I’ll be in a timezone I’m not adjusted too. But I guess I’ll have it easier than the guys and gals coming form Europe,and the Orient.

I’ll be Tweeting my experiences but don’t expect any juicy tidbits as most things and all the content will be under NDA.

I am also speaking in late March at the Orlando .NET User Group Code Camp and I’ll blog about that soon.

Impesonating a user in a UCMA call

Recently I was working on an application endpoint that records a Lync audio call. I got that working fine but when a Lync user called another user and the call then got redirected to my application the name in the Communicator window would change to the name that my app was registered as. Not a good thing as I wanted my callers to think they were leaving a voice mail for the user.

This is a common thing to do in a Back to Back call scenario where you impersonate a different user for the second leg (which you originate in your app). But my call was actually terminating with my app so there was no second leg that I was connecting to. I wasn’t sure if this was possible so I went digging around in the debugger and IntelliSense (both are my best friends). This is what I came up with and it works great..


        private static void AudioVideoCallReceived(object sender, CallReceivedEventArgs<AudioVideoCall> e)


            Trace.WriteLineIf(tracer.TraceVerbose, “AudioVideoCallReceived”);

            Debug.Assert(e != null, “e != null”);

            Debug.Assert(e.RequestData != null, “e.RequestData != null”);


            if (e.RequestData != null)


                e.Call.Conversation.Impersonate(e.TransferredBy, e.Call.Conversation.LocalParticipant.PhoneUri, e.Call.Conversation.LocalParticipant.DisplayName);




            StartWorkflow(e.Call, e.RequestData, e.TransferredBy.ToString(), e.RemoteParticipant.ToString());



Now the caller only sees the original caller’s name and status when talking to my application. Note that the values don’t have to resolve to real addresses but they do need to be properly formatted.