Sending notifications

Previous: Working with the enactment history ] [ Top:  ] [ Next: Taking external action ]

I've put a lot of thought into how nofications (alerts) should work. I've finally come up with the following scheme. First, the alert itself is basically the message, with attributes for recipient, sender, subject, etc. The body of the alert is the body of the message. This is interpreted in the context of a datasheet if one is associated with the alert.

The datasheet is thus the primary context of an alert, but other objects also make sense. For instance, if I have a user profile, it makes sense to be able to send a message to that user directly. Similarly, tasks, requests, and procdefs all make sense as contexts if you simply send the message to the owner of the object.

If an object other than a user is given as the context, then it's searched for a user object in it with the same name as the recipient. Otherwise we treat the user given as the recipient. Either way, we look at the recipient for a preferred modality of notification (say, email), then check our configuration for the adaptor used to address that modality (say, smtp:www.vivtek.com). In addition, we collect an adaptorlist of notification adaptors which the system should always copy to; this will allow for logging of notifications, backup to database, and the like.

I'm sure that even this fairly complicated rigamarole will get even more complicated once it hits reality...
 
WFTK_EXPORT int wftk_notify (void * session, XML * context, XML * alert) {
   WFTK_ADAPTOR * ad;
   WFTK_ADAPTORLIST * adlist;
   XML * user = context;
   XML * from;
   const char * preferred_modality = "";
   const char * always_list;
   char *tovalue;
   XML * temp;

   if (!xml_is (context, "user")) {
      tovalue = wftk_value_interpreta (session, context, xml_attrval (alert, "to"));
      user = xml_firstelem (user);
      while (user) {
         if (xml_is (user, "user") && !strcmp (xml_attrval (user, "id"), tovalue)) break;
         user = xml_nextelem (user);
      }
      free (tovalue);
   }

   if (*xml_attrval (alert, "from")) {
      tovalue = wftk_value_interpreta (session, context, xml_attrval (alert, "from"));
      from = wftk_user_retrieve (session, context, tovalue);
      free (tovalue);
      preferred_modality = xml_attrval (from, "notifyvia");
      if (!*preferred_modality) preferred_modality = config_get_value (session, "notify.default");
      if (*preferred_modality) {
         xml_set (alert, "from_addr", xml_attrval (from, preferred_modality));
      }
      xml_set (alert, "from_name", xml_attrval (from, "name"));
   } else {
      xml_set (alert, "from_addr", config_get_value (session, "notify.system_from"));
      xml_set_nodup (alert, "from_name", wftk_value_interpreta (session, context, config_get_value (session, "notify.system_name")));
   }

   if (user) {
      wftk_user_synch (session, user);
      preferred_modality = xml_attrval (user, "notifyvia");
      if (!*preferred_modality) preferred_modality = config_get_value (session, "notify.default");
      if (*preferred_modality) {
         xml_set (alert, "to_addr", xml_attrval (user, preferred_modality));
         xml_set (alert, "to_name", xml_attrval (user, "name"));

         temp = xml_create ("value");
         xml_setf (temp, "value", "notify.%s", preferred_modality);
         ad = wftk_get_adaptor (session, NOTIFY, config_get_value (session, xml_attrval (temp, "value")));
         xml_free (temp);
         if (ad) {
            wftk_call_adaptor (ad, "send", context, alert);
            wftk_free_adaptor (session, ad);
         }
      }
   } else {
      preferred_modality = config_get_value (session, "notify.default");
      xml_set_nodup (alert, "to_addr", wftk_value_interpreta (session, context, xml_attrval (alert, "to")));

      temp = xml_create ("value");
      xml_setf (temp, "value", "notify.%s", preferred_modality);
      ad = wftk_get_adaptor (session, NOTIFY, config_get_value (session, xml_attrval (temp, "value")));
      xml_free (temp);
      if (ad) {
         wftk_call_adaptor (ad, "send", context, alert);
         wftk_free_adaptor (session, ad);
      }
   }

   adlist = wftk_get_adaptorlist (session, NOTIFY);
   if (adlist) {
      wftk_call_adaptorlist (adlist, "send", context, alert);
      wftk_free_adaptorlist (session, adlist);
   }
   return 1;
}
Previous: Working with the enactment history ] [ Top:  ] [ Next: Taking external action ]


This code and documentation are released under the terms of the GNU license. They are additionally copyright (c) 2000, Vivtek. All rights reserved except those explicitly granted under the terms of the GNU license.