UCMA 3.0 How to build a list of recipients and then broadcast an IM call to those recipients

StackOverflow https://stackoverflow.com/questions/13074399

  •  14-07-2021
  •  | 
  •  

I am developing an application using UCMA 3.0 that will run as a service and send out periodic 'broadcasts' in the form of Instant Message calls. I have been using the book "Professional Unified Communications Development with Microsoft Lync Server 2010" and have everything provisioned fine and am able to establish an application endpoint.

I am stuck on two aspects though.

1) How to get a list of all users of Lync? Everything the UCMA can do is centered on a single user. For example it allows me to retrieve all contacts/groups present on a given users 'contact list' but does not provide any means to query for a list of available contacts that could be added to one of those contact lists. On the MSDN forum I found this post which leads me to think my best bet is simply to query AD directly.

2) What is the best way to actually send a broadcast style IM? My working premise is to attempt something like what I've found in this code example (specifically the public void SendIM() method).

So, get a list of recipients from AD, (looping on each on to check current presence?), and then use Automation to make the IM call for each recipient in the collection.

Does that make sense? Do I need to check presence of the recipient or do I just optimistically make the IM calls irregardless of their current presence status? Can anyone point me to some working code demonstrating sending an IM broadcast? You would think this is probably one of the most common use cases however the SDK samples do not cover it. Thanks in advance.



UPDATE: As Lister says, there is no 'broadcast' method. I had to loop on the recipients and make a call to send an IM for each recipient. I found I also needed to check the recipients presence status as it would attempt to send messages to offline, busy, etc, users as well, resulting in exceptions. Figured best to only send to certain presence states. Since Application Endpoints do not have user/group lists you either need to determine recipients using AD and Directory Services or simply maintain your own list of recipients. I ended up writing a workflow where users can send an IM to the automaton application endpoint to opt-in or opt-out of alert broadcasts. The workflow maintains a simple subscriber database table.

/// <summary>
/// Sending of the actual IM to broadcast subscribers.  Here we check that the presence of the target recipient
/// is in fact suitable for us to barge in with an alert.
/// </summary>
private void sendIMBroadcast(string sipTarget, byte[] htmlBytes)
{

    try {
        _appEndpoint.PresenceServices.BeginPresenceQuery(
            new List<string>() {sipTarget},
            new string[] {"state"},
            null,
            result =>
            {
                try 
                {
                    // Retrieve the results of the query.
                    IEnumerable<RemotePresentityNotification> notifications = _appEndpoint.PresenceServices.EndPresenceQuery(result);

                    // Grab the first notification in the results.
                    RemotePresentityNotification notification = notifications.FirstOrDefault();

                    if (notification == null)
                    {
                        logger.Warn("Invalid recipient for P1 broadcast: {0}", sipTarget);
                        return;
                    }

                    //ensure presense is one we want to send alert to
                    //if (notification.AggregatedPresenceState.AvailabilityValue )

                    long v = notification.AggregatedPresenceState.AvailabilityValue;
                    bool skip = false;
                    if (v >= 3000 && v <= 4499)
                    {
                        //online
                    }
                    else if (v >= 4500 && v <= 5999)
                    {
                        //idle online
                    }
                    else if (v >= 6000 && v <= 7499)
                    {
                        //busy
                        skip = true;
                    }
                    else if (v >= 7500 && v <= 8999)
                    {
                        //idle busy
                        skip = true;
                    }
                    else if (v >= 9000 && v <= 11999)
                    {
                        //dnd
                        skip = true;
                    }
                    else if (v >= 12000 && v <= 14999)
                    {
                        //brb
                        skip = true;
                    }
                    else if (v >= 15000 && v <= 17999)
                    {
                        //away
                        skip = true;
                    }
                    else if (v >= 18000)
                    {
                        //offline
                        skip = true;
                    }

                    if (skip == true)
                    {
                        logger.Debug("Skipping broadcast for user '{0}' due to presense status {1}.", sipTarget, v.ToString());
                        return;
                    }

                    logger.Debug("Sending broadcast for user '{0}' with presense status {1}.", sipTarget, v.ToString());

                    // Send an IM, create a new Conversation and make call
                    Conversation conversation = new Conversation(_appEndpoint);                     
                    InstantMessagingCall _imCall = new InstantMessagingCall(conversation);

                    try
                    {
                        ToastMessage toast = new ToastMessage("Unassigned P1 Tickets!");

                        // Establish the IM call.                 
                        _imCall.BeginEstablish(sipTarget,
                            toast,
                            new CallEstablishOptions(),
                            result2 =>
                            {
                                try
                                {
                                    // Finish the asynchronous operation.
                                    _imCall.EndEstablish(result2);

                                    _imCall.Flow.BeginSendInstantMessage(
                                        new System.Net.Mime.ContentType("text/html"),
                                        htmlBytes,
                                        ar =>
                                        {
                                            try
                                            {
                                                _imCall.Flow.EndSendInstantMessage(ar);
                                            }
                                            catch (RealTimeException rtex)
                                            {
                                                logger.Error("Failed sending P1 Broadcast Instant Message call.", rtex);
                                            }
                                        },
                                        null
                                    );
                                }
                                catch (RealTimeException rtex)
                                {
                                    // Catch and log exceptions.
                                    logger.Error("Failed establishing IM call", rtex);
                                }
                            },
                            null
                        );
                    }
                    catch (InvalidOperationException ioex)
                    {
                        logger.Error("Failed establishing IM call", ioex);
                    }

                }
                catch (RealTimeException ex)
                {
                    logger.Error("Presence query failed.", ex);
                }
            },
        null);
    }
    catch (InvalidOperationException ex) 
    {
        logger.Error("Failed accepting call and querying presence.", ex);
    }                 
}
有帮助吗?

解决方案

There really isn't a "broadcast IM" you pretty much get to iterate over your list of sip addresses you get from AD and do a BeginStartConversation on each Sip Address

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top