Prev | Chapter 10. Advanced Topics | Next

## Notifications

by David Bell and Simon Carstensen

OpenACS docs are written by the named authors, and may be edited by OpenACS documentation staff.

The notifications package allows you to send notifications through any defined communications medium (e.g. email, sms) upon some event occurring 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.

Prev | Home | Next
Distributing upgrades of your package | Up | Hierarchical data