A robot in your Drupal social intranet / extranet | why and how?
If you work with a team on projects, then there are (obviously) tasks to share. Including tasks to be followed up by your clients.
For example: the delivery of a design in Photoshop/fireworks for their new social intranet.
Now it can happen that somebody does not follow-up on his/her task in time resulting in problems for your planning. Usually this is not on purpose, often they simply ‘forgot’.
Waste of your time
In order to stick to the agreed planning you should check daily if there are tasks of the client that have passed their deadline.
Without teamwork tool / social intranet this is impossible. And even with the use of an online collaboration environment it is still a lot of work to check all the projects, tasks and calendars, and to manually type the emails asking for the status.
A waste of your valuable time.
So delegate this to a robot!
Better project management through a robot
Managing your projects will be much more pleasant and consistent if you put a robot to work. We did this as well in our drupal social intranet OpenLucius.
This robot is an automated script that runs every night. It checks whether the deadline of tasks has passed. If so, then the person in question will receive a notification mail in which a response is requested. This is also registered by the robot in a comment under the concerning to do (task).
This not only applies to clients, but also to deadlines for suppliers or for examples freelancers you are working with.
Automatically inform
By using this robot you avoid having to go through all the projects and tasks yourself. The robot is working and automatically informs the right people for you.
Technical implementation in Drupal
The technical implementation is roughly twofold:
- Configuration page
- A drupal script that runs periodically (cronjob)
1. Configuration page robot
We have first created a configuration page where we can set up the following:
- Is the robot activated or not.
- Which Drupal user do you want to use as the robot.
- With which status of the to do the robot needs to intervene.
- In case the robot intervenes, what is the text it needs to put in a comment.
- Prior to intervening, what is the maximum time a to do can stay open before the robot intervenes.
- In case the robot intervenes, what is the status that the to do needs to get.
A screenshot of this configuration page:
2. Script for the robot
/** * Implements hook_cron(). */ function openlucius_workflow_cron() { // Only trigger if the robot is enabled, for safety default to FALSE. if (variable_get('openlucius_workflow_robot_enabled', FALSE)) { // Get all the terms that are selected. $selected = variable_get('openlucius_workflow_robot_from_status'); // Only add them if they are checked. foreach ($selected as $key => $value) { if ($key == $value) { $in[] = $value; } } // Get all the nodes that have the from status. $query = db_select('node', 'n'); $query->join('comment', 'c', 'n.nid = c.nid'); $query->join('field_data_field_todo_label', 'term', 'n.nid = term.entity_id'); $query->fields('n', array('nid')); $query->fields('c', array('cid', 'created')); $query->fields('term', array('field_todo_label_tid')); $query->condition('field_todo_label_tid', $in, 'IN'); $query->condition('type', 'ol_todo', '='); $result = $query->execute(); $list = array(); // The results have each comment for the node, filter for the last one. foreach ($result as $item) { if (!$list[$item->nid]) { $list[$item->nid] = $item; } else { // Check if this comment is newer. if ($item->cid > $list[$item->nid]->cid) { $list[$item->nid] = $item; } } } // Defaults. $expire = strtotime('-' . variable_get('openlucius_workflow_robot_expire', '1 week')); $new_status = variable_get('openlucius_workflow_robot_to_status'); $uid = variable_get('openlucius_workflow_robot_user'); $subject = variable_get('openlucius_workflow_robot_subject'); $body = variable_get('openlucius_workflow_robot_body'); // Ok, we now have the list of all the latest comments. foreach ($list as $item) { // Check if its older then the configured time. if ($item->created < $expire) { $node = node_load($item->nid); // Change the status to the new one. $node->field_todo_label[LANGUAGE_NONE][0]['tid'] = $new_status; $node->revision = TRUE; $old_vid = $node->vid; node_save($node); // Create a new comment. $comment = (object) array( 'nid' => $node->nid, 'cid' => 0, 'pid' => 0, // Use the configured user. 'uid' => $uid, 'mail' => '', 'is_anonymous' => 0, 'homepage' => '', 'status' => COMMENT_PUBLISHED, // Use the configured subject. 'subject' => $subject, 'language' => LANGUAGE_NONE, 'comment_body' => array( LANGUAGE_NONE => array( 0 => array ( // Use the configured body. 'value' => $body, ) ) ), ); // Save the comment. comment_submit($comment); comment_save($comment); // Create a new comment alter entry, used for displaying the differences // when a comment is viewed. _openlucius_workflow_comment_alter_insert($old_vid, $node->vid, $comment->cid); } } } }
Explanation technical Drupal implementation
A rough list of what the script does:
- Check if the robot is activated
- Collect all the to do’s with a certain status (in our case: pending input, intern test ready, extern test ready & live ready)
- Check the date of the latest comments on the concerning to do’s
- ==> Now a list of to do’s is created that are inactive for too long
- Place a comment on behalf of the robot
- Set the to do in the desired status, in this case ‘open’
==> When you are now creating a Drupal View which displays a list of ‘open’ to do’s, you will see the to do’s that are inactive for too long.
Module release
We are working on creating a generic module hereof to publish on http://drupal.org.
Let me know if you are interested and contact me in case of questions.
Wrap up
So: delegate the work to a robot, save time and profit from better projects. And don’t forget to have fun working together! ;-)