dmoler

Acknowledging a notification programmatically

Blog Post created by dmoler on Apr 9, 2010

There have been questions recently regarding how to acknowledge a notification programmatically.  There seem to be two common sources of confusion: which methods to use and what subscriber Guid to pass.  Acknowledgment should be done using the ANNotification object but there are several acknowledgment-related methods.  The instance methods are used on the server-side and they won't produce any effect when run from a client.  Instead the static ANNotification.AcknowledgeInstance / AcknowledgeSubscription / AddComment methods should be used.  When calling these methods a Guid identifying a subscriber must be specified to associate the comment/acknowledgment with.  This Guid should be the ID of an AFNotificationContactTemplate (delivery endpoint in the UI) that has an AFNotificationContact instance subscribed to the notification.  Note that every AFNotificationContact instance will have a corresponding Template but may or may not have an AFContact associated.

 

In the example below, I show a method that takes an AFContact and looks up the corresponding AFNotificationContact on a notification.  From the AFNotificationContact I pass in the Template.ID to the acknowledgment methods.  (UPDATE: I have modified the code slightly to get the last instance from a static ANNotification call - this is preferred to using an instance of ANNotification)

 

static void AcknowledgeActiveNotification(AFNotification notification, AFContact contact,
    ANAcknowledgmentType acknowledgmentType, string comment)
{
    // Note that to acknowledge or comment, we need to pass a AFNotificationContactTemplate (delivery endpoint in the UI)
    //   that is subscribed to the notification so that the comment/acknowledgment can be associated with that contact.
    //   This method will search a AFNotificationContacts collection to find a subscription whose AFContact matches the one we specifed.
    //   We will associate the comment/acknowledgement with this AFNotificationContact's Template.
    AFNotificationContact notificationContact = FindContactSubscription(notification.NotificationContacts, contact);

 

    // query for the last instance of the notifiation
    ANInstance lastInstance = ANNotification.GetLastInstance(notification);

 

    if (!lastInstance.IsActive)
    {
        Console.WriteLine("Last instance is inactive");
        return;
    }

 

    try
    {
        if (acknowledgmentType == ANAcknowledgmentType.Instance)
        {
            // this acknowledges the notification, even if the required acknowledgments are not met
            ANAcknowledgmentReturnStatus ackResult = ANNotification.AcknowledgeInstance(
                notification,                       // the AF notification
                lastInstance.InstanceID,            // the instance ID
                notificationContact.Template.ID,    // the ID of the AFNotificationContactTemplate
                comment);         
            Console.WriteLine("Instance acknowledgment: " + ackResult);
        }
        else if (acknowledgmentType == ANAcknowledgmentType.Subscription)
        {
            // this acknowledges a single subscription, but may not cause the notification to be acknowledged
            //   if there are > 1 required acknowledgments
            ANAcknowledgmentReturnStatus ackResult = ANNotification.AcknowledgeSubscription(
                notification,
                lastInstance.InstanceID,
                notificationContact.Template.ID,
                comment);
            Console.WriteLine("Subscription acknowledgment: " + ackResult);
        }
        else if (acknowledgmentType == ANAcknowledgmentType.Comment)
        {
            // This adds a comment, but does not perform any acknowledgment
            string errorMessage;
            bool result = ANNotification.AddComment(
                notification,
                lastInstance.InstanceID,
                notificationContact.Template.ID,
                comment,
                out errorMessage);
            Console.WriteLine("Comment added: " + result);
            if (!String.IsNullOrEmpty(errorMessage))
            {
                Console.WriteLine("Comment error: " + errorMessage);
            }
        }
    }
    catch (Exception excp)
    {
        Console.WriteLine(excp.Message);
    }
}

 

// recursively check the subscriber hierarchy looking for a AFNotificationContact associated with the specified AFContact
static AFNotificationContact FindContactSubscription(AFNotificationContacts subscribers, AFContact contact)
{
    if (contact == null || subscribers == null)
    {
        return null;
    }

 

    AFNotificationContact associatedSubscriber = null;
    foreach (AFNotificationContact subscriber in subscribers)
    {
        if (subscriber.Contact == contact)
        {
            associatedSubscriber = subscriber;
        }
        else if (subscriber.NotificationContacts != null)
        {
            // if we didn't find the contact, but this has subitems (a group or escal) we need to search them
            associatedSubscriber = FindContactSubscription(subscriber.NotificationContacts, contact);
        }

 

        if (associatedSubscriber != null)
        {
            break;
        }
    }

 

    return associatedSubscriber;
}

Outcomes