How to notify friends about new content?

1
0
-1

When a user publishes some new content, every user marked as a 'friend' should receive some kind of notification about it.

How can this be implemented in Drupal 7?

Topics: 

1 answer

1
+1
-1

Assuming you think of creating a view of all users marked as a friend of the current user, there is a solution to do what you're asking about. This solution uses the Rules, Views and Views Rules module, as further detailed below.

Part 1 - Required modules

1. About the Views Rules module

The Views Rules module makes Views data available in Rules, enabling intuitive rule configuration for dynamic data. Some details from its project page:

... provides two types of elements in Rules, configured with a "Rules" view display:

  • Views loop: A views loop is similar to a regular Rules loop, but allows looping over rows of view results.

    enter image description here

  • Collect view result rows (action): This action collects each variable in all view result rows into list variables for use in Rules.

Tip: When selecting the data type for variables in the view, if the field is an entity identifier (e.g. Node ID), you can set the data type to the entity type (i.e. Node) to directly use the variable in Rules as an entity!

2. Create a view of display type 'Rules'

After you enable the Views Rules module, use Views to create a view of "all users flagged as a friend of the current user". Add of view of display type Rules (important, that's the key to make it work!). Here is how you can add such display:

enter image description here

Next configure the row variables, by using the link that says "edit field info", as shown here:

enter image description here

3. Create a rule using the view of display type 'Rules'

Create a Rule like so:

  • Rules Event: After saving new content
  • Rules Conditions: No need for Rules Conditions, except in case you want to limit these notifications to (e.g.) selected content types.
  • Rules Actions:
    • Use the link that says Add view loop to add a Views loop, and select the "Rules" display created in the previous step.
    • Configure the parameters and variable names.
    • For each user contained in your Views loop, perform a Rules Action "Send an eMail", using the variables you configured at the end of the previous step (you may have to revisit the previous step to add more similar variables there if needed).

Part 2 - Example

1. Create a flag (using Flag)

Use the Flag module to create a flag labeled "Friend" (or something like that). Here is such Flag definition (in export format) you could use for it (just import it in your own site):

    $flags = array();
    // Exported flag: "Friend".
    $flags['friend'] = array (
      'entity_type' => 'user',
      'title' => 'Friend',
      'global' => '0',
      'types' => 
      array (
      ),
      'flag_short' => 'Friend',
      'flag_long' => 'Mark as friend',
      'flag_message' => 'User marked as friend',
      'unflag_short' => 'Unfriend',
      'unflag_long' => 'Remove as friend',
      'unflag_message' => 'User removed as friend',
      'unflag_denied_text' => '',
      'link_type' => 'toggle',
      'weight' => 0,
      'show_in_links' => 
      array (
        'full' => 'full',
      ),
      'show_as_field' => 0,
      'show_on_form' => 0,
      'access_author' => '',
      'show_contextual_link' => 0,
      'show_on_profile' => 1,
      'access_uid' => 'others',
      'api_version' => 3,
    );
    return $flags;

2. Create a view (using Views)

Use the Views module to create a view of users that flagged other users with that "Friend" flag. And add an extra Views display related to the "Views Rules" module (in this case the display is named ListToCreateRulesLoop ).

Here is such view (in export format) you could use for it (just import it in your own site):

    $view = new view();
    $view->name = 'my_friends';
    $view->description = '';
    $view->tag = 'default';
    $view->base_table = 'users';
    $view->human_name = 'My friends';
    $view->core = 7;
    $view->api_version = '3.0';
    $view->disabled = FALSE; /* Edit this to true to make a default view disabled initially */
 
    /* Display: Master */
    $handler = $view->new_display('default', 'Master', 'default');
    $handler->display->display_options['title'] = 'Friends';
    $handler->display->display_options['use_more_always'] = FALSE;
    $handler->display->display_options['access']['type'] = 'perm';
    $handler->display->display_options['access']['perm'] = 'access user profiles';
    $handler->display->display_options['cache']['type'] = 'none';
    $handler->display->display_options['query']['type'] = 'views_query';
    $handler->display->display_options['exposed_form']['type'] = 'basic';
    $handler->display->display_options['pager']['type'] = 'full';
    $handler->display->display_options['pager']['options']['items_per_page'] = '10';
    $handler->display->display_options['style_plugin'] = 'table';
    /* Relationship: Flags: friend */
    $handler->display->display_options['relationships']['flag_content_rel']['id'] = 'flag_content_rel';
    $handler->display->display_options['relationships']['flag_content_rel']['table'] = 'users';
    $handler->display->display_options['relationships']['flag_content_rel']['field'] = 'flag_content_rel';
    $handler->display->display_options['relationships']['flag_content_rel']['flag'] = 'friend';
    /* Field: User: Name */
    $handler->display->display_options['fields']['name']['id'] = 'name';
    $handler->display->display_options['fields']['name']['table'] = 'users';
    $handler->display->display_options['fields']['name']['field'] = 'name';
    $handler->display->display_options['fields']['name']['alter']['word_boundary'] = FALSE;
    $handler->display->display_options['fields']['name']['alter']['ellipsis'] = FALSE;
    /* Field: User: Uid */
    $handler->display->display_options['fields']['uid']['id'] = 'uid';
    $handler->display->display_options['fields']['uid']['table'] = 'users';
    $handler->display->display_options['fields']['uid']['field'] = 'uid';
    /* Field: Flags: Flagged time */
    $handler->display->display_options['fields']['timestamp']['id'] = 'timestamp';
    $handler->display->display_options['fields']['timestamp']['table'] = 'flagging';
    $handler->display->display_options['fields']['timestamp']['field'] = 'timestamp';
    $handler->display->display_options['fields']['timestamp']['relationship'] = 'flag_content_rel';
    $handler->display->display_options['fields']['timestamp']['date_format'] = 'short';
    $handler->display->display_options['fields']['timestamp']['second_date_format'] = 'long';
    /* Field: User: E-mail */
    $handler->display->display_options['fields']['mail']['id'] = 'mail';
    $handler->display->display_options['fields']['mail']['table'] = 'users';
    $handler->display->display_options['fields']['mail']['field'] = 'mail';
    /* Sort criterion: User: Created date */
    $handler->display->display_options['sorts']['created']['id'] = 'created';
    $handler->display->display_options['sorts']['created']['table'] = 'users';
    $handler->display->display_options['sorts']['created']['field'] = 'created';
    $handler->display->display_options['sorts']['created']['order'] = 'DESC';
    /* Filter criterion: User: Active */
    $handler->display->display_options['filters']['status']['id'] = 'status';
    $handler->display->display_options['filters']['status']['table'] = 'users';
    $handler->display->display_options['filters']['status']['field'] = 'status';
    $handler->display->display_options['filters']['status']['value'] = '1';
    $handler->display->display_options['filters']['status']['group'] = 1;
    $handler->display->display_options['filters']['status']['expose']['operator'] = FALSE;
 
    /* Display: Page */
    $handler = $view->new_display('page', 'Page', 'page');
    $handler->display->display_options['path'] = 'user/%/friends';
    $handler->display->display_options['menu']['type'] = 'tab';
    $handler->display->display_options['menu']['title'] = 'Friends';
    $handler->display->display_options['menu']['description'] = 'Users marked as friends';
    $handler->display->display_options['menu']['weight'] = '9';
    $handler->display->display_options['menu']['name'] = 'user-menu';
    $handler->display->display_options['menu']['context'] = 0;
    $handler->display->display_options['menu']['context_only_inline'] = 0;
 
    /* Display: ListToCreateRulesLoop */
    $handler = $view->new_display('views_rules', 'ListToCreateRulesLoop', 'views_rules_1');
    $handler->display->display_options['pager']['type'] = 'some';
    $handler->display->display_options['defaults']['fields'] = FALSE;
    /* Field: User: Name */
    $handler->display->display_options['fields']['name']['id'] = 'name';
    $handler->display->display_options['fields']['name']['table'] = 'users';
    $handler->display->display_options['fields']['name']['field'] = 'name';
    $handler->display->display_options['fields']['name']['alter']['word_boundary'] = FALSE;
    $handler->display->display_options['fields']['name']['alter']['ellipsis'] = FALSE;
    /* Field: User: Uid */
    $handler->display->display_options['fields']['uid']['id'] = 'uid';
    $handler->display->display_options['fields']['uid']['table'] = 'users';
    $handler->display->display_options['fields']['uid']['field'] = 'uid';
    /* Field: User: E-mail */
    $handler->display->display_options['fields']['mail']['id'] = 'mail';
    $handler->display->display_options['fields']['mail']['table'] = 'users';
    $handler->display->display_options['fields']['mail']['field'] = 'mail';
    $handler->display->display_options['rules_variables'] = array(
      'name' => array(
        'enabled' => 1,
        'rendered' => 0,
        'type' => 'text',
        'label' => 'User Name',
        'name' => 'user_name',
      ),
      'uid' => array(
        'enabled' => 1,
        'rendered' => 0,
        'type' => 'integer',
        'label' => 'User Id',
        'name' => 'user_id',
      ),
      'mail' => array(
        'enabled' => 1,
        'rendered' => 0,
        'type' => 'text',
        'label' => 'User eMail Id',
        'name' => 'user_email_id',
      ),
    );

After you enable the view, the result of it is that it'll show a tabular list of users, via path user/%/friends, and it will add a "Friends" tab on the user profile page (also).

Here is a sample of such table:

Name           ! Uid ! Flagged Time       ! E-mail
---------------+-----+--------------------+--------------------------
Dries.Buytaert ! 19  ! 05/09/2017 - 19:49 ! Dries@placeto.be
Some.User      ! 8   ! 05/11/2016 - 17:42 ! Some.User@placeto.be

3. Create a rule (using Rules)

Use the Rules module to create a rule as detailed in "3." of "Part 1".

Here is such rule (in export format) you could use for it (just import it in your own site, if you have the Rules UI enabled):

    { "rules_notify_friends_about_new_content" : {
        "LABEL" : "Notify friends about new content",
        "PLUGIN" : "reaction rule",
        "OWNER" : "rules",
        "REQUIRES" : [ "rules" ],
        "ON" : { "node_insert" : [] },
        "DO" : [
          { "VIEW LOOP" : {
              "VIEW" : "my_friends",
              "DISPLAY" : "views_rules_1",
              "ROW VARIABLES" : {
                "user_name" : { "user_name" : "User Name" },
                "user_id" : { "user_id" : "User Id" },
                "user_email_id" : { "user_email_id" : "User eMail Id" }
              },
              "DO" : [
                { "drupal_message" : { "message" : "Your friend with user name [user-name:value] (and id = [user-id:value]) will receive an eMail notification about your new node with title \u0022[node:title]\u0022 and node id [node:nid] (delivered to eMail Id  [user-email-id:value])." } },
                { "mail" : {
                    "to" : [ "user-email-id" ],
                    "subject" : "Your friend [node:author] created a new post ...",
                    "message" : "Go checkout the new post from [node:author] titled \u0022[node:title]\u0022, located at [node:url] ",
                    "language" : [ "" ]
                  }
                }
              ]
            }
          }
        ]
      }
    }

Note that this rule creates an appropriate eMail for each friend, but is also shows an informational message to the user creating the new post. Remove that informational message if you don't need it (anymore).

4. Demo

Here are the messages produced after saving a new node:

Your friend with user name Dries.Buytaert (and id = 19) will receive an eMail notification about your new node with title "Article about some special topic" and node id 72 (delivered to eMail Id Dries@placeto.be).

Your friend with user name Some.User (and id = 8) will receive an eMail notification about your new node with title "Article about some special topic" and node id 72 (delivered to eMail Id Some.User@placeto.be).

And this is what the eMail content looks like (eMailed to both "friends"):

Go checkout the new post from Pierre.Vriens titled "Article about some special topic", located at http://drupal.placeto.be/node/72

Voilà ...

This is how you can implement a basic solution to answer your question, i.e. "without using the message module".

But, if you're willing to go the extra mile, and also get the Message module involved, you can replace those eMails delivered to the user's friends by a solution that is fully integrated within your site. Refer to How to use Rules to replace eMails by iOS-like notifications? for an explanation about what's needed to implement this possible translation / summary of the question here:

When a user publishes some new content, I want that for every user shown as a 'friend' (in the View 'All friends'), a Facebook style notification is shown. And this in such a way that (a) the notifications are based on the Message module and (b) for each of those friends such notification can be marked as read by each friend individually.