Notifications
Created by Gustaf Neumann, last modified by Gustaf Neumann 17 Feb 2008, at 07:08 AM
The notifications package allows you to send notifications through any defined communications medium (e.g. email, sms) upon some event occuring within the system.
This tutorial steps through the process of integrating the notifications package with your package.
First step is to create the notification types. To do this a script similar to the one below needs to be loaded into Postgresql. I create this script in a package-name/sql/postgresql/package-name-notifications-init.sql file. I then load this file from my create sql file. The following code snippet is taken from Weblogger. It creates a lars_blogger_notif notification type (which was created above).
create function inline_0() returns integer as ' declare impl_id integer; v_foo integer; begin -- the notification type impl impl_id := acs_sc_impl__new ( ''NotificationType'', ''lars_blogger_notif_type'', ''lars-blogger'' ); v_foo := acs_sc_impl_alias__new ( ''NotificationType'', ''lars_blogger_notif_type'', ''GetURL'', ''lars_blogger::notification::get_url'', ''TCL'' ); v_foo := acs_sc_impl_alias__new ( ''NotificationType'', ''lars_blogger_notif_type'', ''ProcessReply'', ''lars_blogger::notification::process_reply'', ''TCL'' ); PERFORM acs_sc_binding__new ( ''NotificationType'', ''lars_blogger_notif_type'' ); v_foo:= notification_type__new ( NULL, impl_id, ''lars_blogger_notif'', ''Blog Notification'', ''Notifications for Blog'', now(), NULL, NULL, NULL ); -- enable the various intervals and delivery methods insert into notification_types_intervals (type_id, interval_id) select v_foo, interval_id from notification_intervals where name in (''instant'',''hourly'',''daily''); insert into notification_types_del_methods (type_id, delivery_method_id) select v_foo, delivery_method_id from notification_delivery_methods where short_name in (''email''); return (0); end; ' language 'plpgsql'; select inline_0(); drop function inline_0();
You also need a drop script. This is untested for comptability with the above script.
-- @author gwong@orchardlabs.com,ben@openforce.biz -- @creation-date 2002-05-16 -- -- This code is newly concocted by Ben, but with significant concepts and code -- lifted from Gilbert's UBB forums. Thanks Orchard Labs. -- Lars and Jade in turn lifted this from gwong and ben. create function inline_0 () returns integer as ' declare row record; begin for row in select nt.type_id from notification_types nt where nt.short_name in (''lars_blogger_notif_type'',''lars_blogger_notif'') loop perform notification_type__delete(row.type_id); end loop; return null; end;' language 'plpgsql'; select inline_0(); drop function inline_0 (); -- -- Service contract drop stuff was missing - Roberto Mello -- create function inline_0() returns integer as ' declare impl_id integer; v_foo integer; begin -- the notification type impl impl_id := acs_sc_impl__get_id ( ''NotificationType'', -- impl_contract_name ''lars_blogger_notif_type'' -- impl_name ); PERFORM acs_sc_binding__delete ( ''NotificationType'', ''lars_blogger_notif_type'' ); v_foo := acs_sc_impl_alias__delete ( ''NotificationType'', -- impl_contract_name ''lars_blogger_notif_type'', -- impl_name ''GetURL'' -- impl_operation_name ); v_foo := acs_sc_impl_alias__delete ( ''NotificationType'', -- impl_contract_name ''lars_blogger_notif_type'', -- impl_name ''ProcessReply'' -- impl_operation_name ); select into v_foo type_id from notification_types where sc_impl_id = impl_id and short_name = ''lars_blogger_notif''; perform notification_type__delete (v_foo); delete from notification_types_intervals where type_id = v_foo and interval_id in ( select interval_id from notification_intervals where name in (''instant'',''hourly'',''daily'') ); delete from notification_types_del_methods where type_id = v_foo and delivery_method_id in ( select delivery_method_id from notification_delivery_methods where short_name in (''email'') ); return (0); end; ' language 'plpgsql'; select inline_0(); drop function inline_0();
The next step is to setup our notification creation. A new notification must be added to the notification table for each blog entry added. We do this using the notification::new procedure
notification::new -type_id [notification::type::get_type_id -short_name lars_blogger_notif] -object_id $blog(package_id) -response_id $blog(entry_id) -notif_subject $blog(title) -notif_text $new_content
This code is placed in the tcl procedure that creates blog entries, right after the entry gets created in the code. The $blog(package_id)
is the OpenACS object_id of the Weblogger instance to which the entry has been posted to and the $new_content
is the content of the entry. This example uses the package_id for the object_id, which results in setting up notifications for all changes for blogger entries in this package. However, if you instead used the blog_entry_id or something like that, you could set up per-item notifications. The forums packages does this -- you can look at it for an example.
The final step is to setup the notification subscription process. In this example we want to let a user find out when a new entry has been posted to the blog. To do this we put a link on the blog that allows them to subscribe to notifications of new entries. The notifications/requests-new page is very handy in this situation.
Such a link can be created using the notification::display::request_widget
proc:
set notification_chunk [notification::display::request_widget -type lars_blogger_notif -object_id $package_id -pretty_name [lars_blog_name] -url [lars_blog_public_package_url] ]
which will return something like
You may <a href="/notifications/request-new?...">request notification</a> for Weblogger.
which can be readily put on the blog index page. The pretty_name
parameter is what appears at the end of the text returned (i.e. "... request notification</a> for pretty_name"), The url
parameter should be set to the address we want the user to be redirected to after they have finished the subscription process.
This should be all you need to implement a notification system. For more examples look at the forums package.