Forum OpenACS Development: To design a reminders package or enhance acs_events package to do it

I want to write a reminders package.  Unlike notifications, a reminders package would support other packages (most notably the calendar) by providing a way to register requests for reminders to be displayed or emailed at some time before an event occurs.

I've done small amonts of OpenACS dev work before, but this would be my most ambitious undertaking so far.

My major goal is to allow the calendar package to be easily enhanced to request reminders.

From what I can tell, such a reminders system would be closely linked to acs_events.  In fact, my first question is, should this be implemented by adding it the acs_events package?

I picture having a reminders table with the following columns:
event_id: the event to be reminded of
party_id: the party to be reminded
recurrance_id: if not null, this reminder applies to all occurances
reminder information (i.e. how long before the event to remind, how many reminders to give, in what form (e.g. email), etc.)

Doing reminders on recurring events and tracking changes in event times seem to be the most complicated parts.  The rest seems fairly straight forward.

Comments?

Hey, this will be really useful, actually I had a suggestion to add reminders to the project-manager pkg.
I think this do not needs to be tied to acs-events, so instead of event_id you might use object_id.

Then you have a sweeper that scans your remiders, as notifications has, and send them. You probably will need to know when the actual object will take place, and from there, when you do you want to have the reminder (one week before, each day for a week before it happens, etc), and then schedule your reminders, and relate them to the original reminder request.
This perhaps can be tied to notifications, but seems that we might create another monster ... :O

Everything depends on how flexible / sophisticated you want your system, I suggest as simple as possible.

<blockquote>Doing reminders on recurring events and tracking changes in event times seem to be the most complicated parts.
</blockquote>

I dont think this part will be hard at all ..., since seems just calling the same proc several times with different params, and of course, whenever happens a change in the object that has a reminder associated, must be able to change or keep the previous reminder request.

Roc, project-manager actually does have reminders. If you look in the parameters for project-manager, you can set them to run once a day.
I also suggest to not tie this to acs_events. Firstly it is only calendar that uses acs_events and if I had the time and data I would probably just update the calendar data model by removing acs_events: this package has been there for more than two years to provide an abstraction to hook other packages' data into calendar and nobody has used it. Conceptually views would fit in here much better.

By using the object_id you can set reminders on arbitrary objects. What about just allowing the user to set an arbitrary reminder time? And put some intelligence only into the proposal, *not* into the database. Like this - meta-tcl code on the set-reminder page:

if object_type equals calendar
  find_out event time
  substract 1 day if > 1 week away
  substract 8 hours < 1 week away
  substract 1 hour if < 2 days away
  propose this setting as event time

elseif object_type equals project_task
  always substract 1 day
  propose this setting as event time

I'd just go ahead and have object_id, reminder_time, reminder_user_id or reminder_party_id in this table.

Subsequent versions of course need to be i18nized, reminder text need to be editable etc. But for starters a very light-weight package should do it.

Should the reminders table be created as an ACS object type, i.e. set up with acs_object_type__create_type()?

Secondly, should entries in the reminders table be their own objects (which would make the first answer a definite 'yes')?

For the moment, this table doesn't seem to require any of that stuff, since it simply ties together already existing objects with a party and a message.  It will be a service, and entries will be created or modified by other packages that want to set up reminders.  Therefore, having its own permissions model seems unnecessary.

I'm in the process of writing the SQL creation code.

All these replies are very encouraging.

I see from Rocael that I could let the caller give the reminder service multiple calls for recurring events so that becomes a non-issue.

I see that the minmal reminder package would simply be a place to register a date and time for a message to go out, and it would be the responsibility of the caller (from another package) to maintain and update it if the time changes (cascade deletes would take care of objects that are deleted -- or should the caller be required to explicitly delete reminders?).

It seems to me that the reminder package should know the actual time of the event and the relative time(s) for the reminder(s), or provide functions interfaces to calculate this sort of thing.  Otherwise, I can imagine other packages having to implement the same code over and over again (e.g. Days, Weeks, or Hours in advance).

Features I eventually would like to add are:
- be able to easily set up multiple reminders for a single event.
- confirm acknowledgement of reminders and repeat if not acknowledged within some period of time (I know some organizations where feedback if a reminder wasn't acknowledged/confirmed would be appreciated).

Finally, it sounds like much of the code to do this might be found in the project manager package.  If done correctly, that code could just be moved into the reminder service and used by project manager also.

It doesn't sound like this should be an extension of acs_events at all but it might be worthwhile investigating the use of the abstractions acs-events provides. I used acs-events when I ported over the old Events Management package and found it straightforward and easy to use (of course, it appears as if it was essentially abstraction of the old events package so it fit with the updated events package very well). We were going to work on calendar integration but haven't gotten that far (yet). Anyhow, I just wanted to point out that acs-events *has* been used.
Michael, is that code you are referring to in the OpenACS CVS repository?

What is the old Event Management package?

Dirk, The ported Events Management package is in contrib/packages/events/. The old version I'm referring to was just called Events (I believe) and it was part of ACS 3.x.
Collapse
Posted by Randy Kunkee on
I have implemented a 0.1d version of a reminder package.  This is a request for comments.

Package name: reminder
Table: reminders

To set a reminder, the user calls reminder__new (a Tcl entry point should probably be provided).

Here is the sql for creating reminder__new:

CREATE OR REPLACE FUNCTION reminder__new(
        integer,                -- reminder.object_id%TYPE
        integer,                -- reminder.reminder_from_id%TYPE
        integer,                -- reminder.reminder_to_id%TYPE
        timestamptz,            -- reminder.reminder_time%TYPE
        varchar                -- reminder.reminder_msg%TYPE
)
RETURNS integer
AS 'declare
        new__object_id          alias for $1;
        new__from_id            alias for $2;
        new__to_id              alias for $3;
        new__when              alias for $4;
        new__msg                alias for $5;
    begin
        insert into reminders
                (object_id, reminder_from_id, reminder_to_id, reminder_time, reminder_msg)
        values
                (new__object_id, new__from_id, new__to_id, new__when, new__msg);
            return 0;
    end;'
LANGUAGE 'plpgsql';

This works with the table defined below.  A reminder-init.tcl schedules reminder::task::email_reminder, which sends an email out at the specified time (using code shameless ripped from the Project Manager package -- thank you).  Currently it sweeps for reminders every 60 seconds, but this will become a package parameter.  As I've written this, I've thought of several other things that could be done better, but for now I'm resisting temptation and wanting to make sure I'm on the right track of providing what people want, and especially something that can be used by the Calendar package (Dirk?).

create table reminders (
        object_id              integer
                                constraint reminders_object_id_fk
                                references acs_objects(object_id)
                                on delete cascade,
        reminder_from_id        integer
                                constraint reminders_to_id_fk
                                references parties(party_id)
                                on delete cascade,
        reminder_to_id          integer
                                constraint reminders_from_id_fk
                                references parties(party_id)
                                on delete cascade,
        reminder_time          timestamptz, -- constraint > now
        reminder_msg            varchar(1000),
        constraint reminders_unique
        unique (object_id, reminder_to_id,reminder_time)
);

comment on table reminders is '
        Table reminders maps the many to many relationship between
        a reminder and a party and the owner of the reminder.
';

comment on column reminders.object_id is '
        The object that owns this reminder.
';

comment on column reminders.reminder_from_id is '
        The party_id from whom the message will appear to be sent.
        Defaults to the owner_id of the object if null.
';

comment on column reminders.reminder_to_id is '
        The party_id to whom to send the reminder.
';

comment on column reminders.reminder_time is '
        The time to send out the reminder.
';

comment on column reminders.reminder_msg is '
        Message to send/display.
';

Collapse
Posted by Jade Rubick on
Will the reminders be recurring? Now it looks like they'll just get one email in the future?
Collapse
Posted by Randy Kunkee on
The initial idea was that if somebody wanted multiple reminders, the requesting package would perform multiple reminder__new calls.  However, I think it would be nice to have that feature.  (This could get complicated - there are multiple reminders about a single event and reminders associated with a recurring event.)  Other ideas I have are:

- handle destination party ids that are groups of people and email everyone in the group.
- handle bounces and notify somebody if the email didn't make it.
- require positive feedback from the receiver and notify the caller if a confirmation isn't received within a certain period of time (perhaps leave it to the caller to handle the second part).
- add a sequence (perhaps reminder_id) that can be stored by the caller and used to update or delete the reminder (probably should do this one soon).
- maybe allow arbitrary actions other than email.  Perhaps this is going too far, i.e. at that point its like creating an 'at' command.
- provide some sort of message template to free packages of having to construct a message (not sure if this would really be useful).

Collapse
Posted by Malte Sussdorff on
I'd add a "method", which defines what delivery procedure to use (this way enabling IM, SMS or RSS in addition to e-mail).

I'd handle reccuring reminders as well internally with the option to nag the reciever til he confirms (so the system automatically sends out the reminder but only informs the caller once the confirmation is recieved).

Don't bother yourself with the message template as all the packages that are going to use the reminder system, will have to decide how to create the reminder internally anyway.

You are missing the differentiation between HTML and plain/text. Maybe there are even more types of content when sending a reminder, but at least these two have to be present so you can send out alternative e-mails. If a package only provides your e.g. with html content, start a converter to store the text content as well.

While we are at it, create a user preference that will allow the user to decide if he wants to recieve reminders in e-mail or text format. Once this works, it should be extended to let users decide, which reminder(types) he wants to recieve via which method in what format.

Last but not least, a small description on how to move from notifications to reminders would be nice as well (unless you see these two as totally seperate pieces of software).

Collapse
Posted by Randy O'Meara on
Malte,

Is there a facility in place (in general) to set user preferences as you describe? Or, could the new ams service possibly be used to extend an object type for this?

Collapse
Posted by Malte Sussdorff on
It would be great if there was one single place to setup user preferences, but to my knowledge there does not exist one. Therefore you have two options.

a) Expand the APM with a user_preferences table: "package_id,parameter_id,party_id,value" and store the values there

b) Do it on your own in the reminder package.

I do not thing that the new ams service could be used for this, but maybe the ASM people have more of an insight there.