Log Site Activity with Message and Rules

The Message module is a general logging utility tool that site builders can use to create user friendly logs. Let’s say for example, you want to create a log for all new “Blog” posts and then display a list of logs on a website via a block within a sidebar column. Message module makes it extremely easy to do all of this without writing a single line of code.

In this article I’ll show you how to setup a message type, create the message logs using Rules and then we’ll display a list of the logs using the Views module.

If you want to see this functionality in action, download and install the example module from GitHub.

Getting started

Before we start, we’ll have to download and enable a few modules. Go ahead and download the following modules:

If you use Drush, run the following command:

$ drush dl message views ctools entity token entityreference rules features strongarm

  • Message
  • Token
  • Entity API
  • Entity tokens
  • Entity reference
  • Chaos tools
  • Views
  • Views UI
  • Rules
  • Rules UI

This may seem like a lot of modules, however most sites that I work on these days the above modules are already installed.

Message types

The first piece of work we need to do is configure the message type and attach a field to this new message type. Message types are entities, so you can attach any type of field to an entity the same way as with content types.

Let’s go ahead and create the message type. Go to Structure -> “Message types” (admin/structure/messages).

Click on the “Add message type” link and enter in “Log new content” as the Description and enter in some placeholder text into the message text field. Scroll to the bottom and click on “Save message type”.

Now we’ll need to add an entity reference field on the message type. We’ll add an entity reference field so that we can reference the created content for later use. 

From the “Message types” page (admin/structure/messages), click on” manage fields”.

Create a new field and select “Entity reference” from the field drop-down.

Go back and edit the message type that you created earlier. Within the “Token” table, click on “Message” and you should see [message:field-message-content]. We’ll use the title of the created content within our message. 

Change the message text to the following message:

[message:field-message-content:title] has been added by [message:user:name].

When a message log is created, the Message module (thanks to Token) will convert [message:field-message-content:title] to the content title and [message:user:name] to the user who is creating the content. This will all make sense soon, I promise.

Message rule

In the section above we worked on configuring a message type, now we’ll use the Rules module to create the actual message when a new blog post is created. Rules is a module which allows site builders to define specific actions based on an event. For example, you can use Rules to send an email when a user comments on a piece of content and this can all be achieved without writing a single line of code. Rules is a powerful module and if you have never used it before, I recommend you spend a little bit of time learning how to use the module. You’ll be amazed by what you can do with Rules.

Check out the Learn the Rules framework series of screencasts on using Rules from NodeOne if you want to learn more.

To create a rule, go to Configuration -> Rules and click on the “Add new rule” link.

Enter in "Log new content into" into the Name field and select "After saving new content" from the “React on event” drop-down field.

At this point we have simply created a rule for a specific event, this rule will be executed after a new piece of content has been saved. Let's go ahead and add a condition so that the rule only runs if the saved content is a blog post.

Click on the "Add condition" link within the Conditions area.

Select "Content is of type" from the conditions drop-down, at this point the page should reload, and then select "Blog" from the Content types field set and click on “Save”.

We have the event and condition, however, now we have to tell rules what the action should be for the rule. 

Click on the "Add action" link within the Actions, then select "Create a new entity" from the action drop-down. The page should reload and display a drop-down list of entities. Select "Message" and click on “Continue”.

Select "log_new_content" from the Message type drop-down and add “node:author” as the data selector and then click on “Save”.

When we created a message type, we also attached an entity reference field on the message type. Let's go ahead and populate the entity reference field when the message is created.

Click on the “Add action” link and select “Set a data value” from the actions drop-down. On the first data selector we must select the entity reference field in the message log. At this point we are specifying which field we need to modify. Select or enter “entity-created:field-message-content” in the Data selector field and click on “Continue”.

Finally, we must specify which entity or content we want to reference. In our case it would simply be “node”. Enter in “node” in the Data selector field and click on “Save”.

Go ahead and test out the rule. You will see that when you create a blog post, a message log should be created. You can view a list of messages by going to Content -> Messages (admin/content/message).

Display message logs with Views

In the previous section we configured a rule which’ll create a message log when a Blog post is created by a user. As stated before a message log is an entity, this gives us the ability to create a view using Views to display the message logs. In this section we’ll create a simple block view that displays the top five message logs in a sidebar column.

If you have used Views in the past, than creating a block view of message logs will be fairly straight forward. However, let’s quickly go through the steps necessary in creating a block view.

Go to Structure -> Views and click on the “Add new view” (admin/structure/views/add) link.

Enter in a name into the View name field and select “Message” from the Show drop-down and select “log_new_content” from the Type drop-down. Also tick the “Create a block” checkbox and then click on “Continue & edit”.

We’ll keep this view simple and just add two fields. One for the message and another for the “View more” link.

Click on the “add” button next to fields and select the “Message: Render message (Get text)”. By adding this field you should see the render message.

The last field we need to add is the “Read more” link. To add the link we need to attach the Blog entity to this view. 

Still within the views edit page, click on the “Advanced” field-set and then click on “add” next to relationships.

Select the “Entity Reference: Referenced Entity” and click on “Apply”.

On the Configure Relationship page, tick the “Require this relationship” and click on “Apply” again.

Click on “add” next to Fields and search for “link”. Select the “Node: Link” and click on “Apply”.

Deselect the “Create a label” check-box and enter “Read more” into the “Text to display” text field.

At this point the preview should look something like this.

Finally make sure you save the view by clicking “Save”.

Let’s test out the new view block that we just created. Go to Structure -> Blocks (admin/structure/block) and add the block to a specific region.

Just style it with some CSS and you are done. If you have any questions, please leave a comment.

Ivan Zugec

About Ivan Zugec

Ivan is the founder of Web Wash and spends most of his time consulting and writing about Drupal. He's been working with Drupal for 10 years and has successfully completed several large Drupal projects in Australia.

74 thoughts on “Log Site Activity with Message and Rules”

  1. Very, very nicely put together. This got me up to speed in no time. The Message module is a pleasure to work with already. Thanks!

  2. Thanks for introducing me to this. I have a need for it. Originally I was appending lines to a textarea! The next step for me was going to be to create a logging schema table with some views data magic to handle it. Looks like this module is now a contender. It certainly would be easier to set up. I don’t know though – I feel dirty using an entity for something like logging where it will be nice to see it all in one table on the backend. A schema table feels like a better fit. That’s a “save it for the pub” conversation though πŸ™‚

    1. I do agree that entities can sometimes be a bit overkill. However, with Rules integration, you don’t have to write any custom code.

  3. Thank you so much for posting this! This is exactly what I was looking for! But, I have a few questions. I downloaded all the modules, and I set up the message types, but when I try to open “manage fields”, it says “You are not authorized to access this page”. I’m not sure why I’m getting this message since I am the admin for the site. I looked at the screenshots you had more closely and also realized that the status for the ‘log new content’ shows as overridden, whereas mine shows up as custom. I am also not using drush. Am I missing some dependency or a step in the process that would allow me to manage fields in the log content

        1. I downloaded the dev version of the Message module. I am an admin with full permissions on the site. My uid is 3, not 1. When I try to open manage fields or manage display of a message type, I get access denied. I have the same issue in 2 different websites. Any suggestions as to how I could fix this issue?

  4. Hello,

    I was wondering how can I delete this messages. For example I have a feed just like Facebook and I want users to have the possibility to delete each message individually. Can this be done?

    Many thnaks

    1. Good question.

      I have not had a need to delete messages. I don’t think Message module gives you a UI to delete message out of the box. You’ll have to write some custom code.

  5. Does the message module offer similar features as heartbeat module in that users are able to like, comment on activity? Does message module integrate nicely with User Relationships module? Can the activity created with message module work like a heartbeat stream in that the stream can encompass all message types created by all users a member has a relationship with? For example, if i would like to create message types for user creates new content, updates existing comments, becomes follower of user, updates profile, updates account, comments on comment. If I create all message types, can I place them all into 1 stream or view and have that view show all message activity for all users a member has a current relationship with?

    Additionally, what other modules social networking modules work well with message module? Any integration with flags, statuses etc.

    Sorry for all the questions. Any help is greatly appreciated.

    Thanks

    1. Message is a lot more generic than Heartbeat. Heartbeat does give you more social functionality. If you want to integrate some social functionality, you’ll have to do some custom work.

      If Heartbeat does the job than use Heartbeat.

      Hope this helps.

  6. Doesn’t it hurt performance?
    i mean each activity is a new created node of type message
    if i have 10 000 users and i want to log their activity of flag_friends
    every user adds for example 10 users a month
    then i have new 100 000 nodes a months – just for logging this activity
    is it logical? i see it costful

    1. You won’t really have performance issues unless you have written some massive SQL query or you have a lot of traffic performing INSERT queries. If the site traffic is growing make sure you are upgrading the infrastructure at the same time.

      Regarding the flag_friends question. The short answer is yes; the table will grow. Just make sure you have upgraded your infrastructure to handle it.

    2. I am also evaluating Message module for logging site activity and this is an important concern. But looking into the Message implementation, I see that message is implemented as an Entity rather than node. The overhead in creating entity is not the same as nodes.

      1. Nodes in Drupal 7 are entities as well they are just an entity type. Message module simply implements its own entity type so that site administrators can attach fields to the entity. Performance really comes down to how your hosting is setup.

  7. Great tutorial, but… How in Message Example module it is made that all of the message creation is dome WITHOUT Rules module?
    I am trying to understand this for entire day without luck.

      1. thank you! I wasted all day to understand, how it is possible without Rules – didn’t knew it is hardcoded.

  8. Trying to make everything the same with comments – got it working except that in the part
    “Finally, we must specify which entity or content we want to reference. In our case it would simply be Ò€œnodeÒ€ I cannot simply select “comment”. I think because of this when I delete a comment the message is not deleted, right?

    1. First, if you create a rule on the “After saving new content” event, you won’t get direct access to the comment entity. The “After saving new content” action is fired when a node is created. Look at using other actions.

      If you want messages to be deleted when a comment is deleted, then you’ll have to create a rule that’ll delete the messages.

      1. Hi, I am with the same task again – what you mentioned is understandable, using action “After saving new comment” but then little luck in creation the same (similar) message on comment creation. Could you please recreate this tutorial with the rule of new comment? I am trying for a few days but cannot pass values of comment into, what I do:

        Event: After new comment creation
        Conditions: none
        Action: Create new message entity “After new comment”
        Value: comment

        Now my message has Entity reference field “field_myfieldname” with Target type – comments, everything basically the same

        When looking at the messages list I see only “[message:field-myfieldname:title]” the tokens are empty.

        1. If you only get “[message:field-myfieldname:title]” in the message, then that means the referenced comment is not getting attached during the rule execution.

          Check and see if the comment is actually attached to the message entity. Also, use the debug action and see if anything is returned if you debug the “message:field-myfieldname:title” data selector.

          Go to the link below for a video on how to debug rules:

          http://nodeone.se/en/debugging-rules-configuration

          1. Thank you, will look at thaht, but I am 90% sure there is some kind of a problem. Have you done the same as in this tutorial with comments? I have a tiny bit of feeling – that there may be some sort of strange limitation as even Commons installation is not offering this.

          2. Ivan, I have 10x-double-tripple checked everything, and yes, looked at Rules debugging screencast – it is great, never used this feature before!
            Now, debugging info shows that entity is created, action is evaluated, event is fired – no errors or warnings. But the problem is absolutely the same – comment is not passed to message πŸ™ I compared to the event when node is created – it looks identical! User created/logged-in/out etc – everything works, everything is just cool, but I cannot do anything with the comment.

            It seems you are the only one capable or willing to share your Message knowledge. Can you somehow… save me from my misery and update your article with event on comment creation (and passing its values to message)? Please.

            Right now I will try to repeat the same on the clean site – it may be some module causing this

          3. I’ll look at writing a tutorial about using Message and comments together.

            Test what you’re trying to do on a fresh Drupal 7 site, very good idea.

          4. Man, I’ve spent 20+ hours just to find, that problem is my messed up comment… fields. Everything works IF I try to pass values like comment date etc – not any of the fields.
            Everything just started to work if I repeated everything on fresh clean minimal D7 install. Your tutorial is amazing and your help is invaluable!

            Thank you very much. Caseis

          5. And… everything just does NOT work again on dev site. It just works on clean install but not on fully stacked site. There seems some weird bug.

  9. Hi – thanks for the excellent tutorial, i am hoping to use this approach for a site i am currently building. However, i’m finding integration with OG tricky, ie logging messages about content that belongs to a group (and making this group information available from within the message).

    Is it possible with Rules, or does it need to be handled in code? I’ve looked at the message_og_example message which seems to vaguely make sense, however it throws errors when saving a piece of group content…

    Cheers

    1. Sorry, I don’t have any experience with using Message and OG together.

      The way I will tackle this problem is with Rules first, if I can’t get it working with Rules, then I’ll look into a custom code solution.

  10. FYI i’ve now managed to implement this – manually in code, loosely based on the message_og_example module.

    I initially tried with Rules, but it seems its not able to handle the complex data types (og_membership, og_audience etc)

    If you’re interested i can come back with more details.
    Cheers

  11. Seems you are very good in explaining stuff πŸ˜‰ — Would be cool if you could have a post about Message-Subscribe. I have a feeling the Drupal community still doesn’t see how this module along with Message-notify can be a powerful and flexible subscriptions and notifications system

    — Amitai(bu)

  12. FYI, since Entityreference prepopulate does not work with OG 7.x-1.x, I just tried Node Reference URL Widget and it worked like a charm. Thanks for the tutorial .. πŸ™‚

    1. Hi! I have the same problem but don’t know what URL parameters I must use to fill the field. Can You give me an example please. Thx πŸ™‚

  13. Thanks for the tutorial. Followed it and still don’t see the “Messages” tab under “Content”. How come?

    The log tells me this:
    Rules debug information:
    ” Reacting on event After saving new content.
    0 ms Reacting on event After saving new content.
    10.144 ms Evaluating conditions of rule Log new content. [edit]
    10.869 ms The condition node_is_of_type evaluated to TRUE [edit]
    10.898 ms AND evaluated to TRUE.
    ” Rule Log new content fires. [edit]
    0 ms Rule Log new content fires.
    5.95 ms Evaluating the action entity_create. [edit]
    7.484 ms Added the provided variable entity_created of type message [edit]
    9.01 ms Evaluating the action data_set. [edit]
    9.358 ms Rule Log new content has fired.
    20.37 ms Saved entity_created of type message.
    24.786 ms Finished reacting on event After saving new content.

    Which means it should be fine? I can even see the messages have been created in the MySQL. Did i miss something?

    1. The log “looks” fine but if you’re not seeing any messages then something is not working.

      First, make sure the rule is firing off. Add an action called “Show a message on the site”. Use this action to see if the rule is working.

      Once you know the rule is working, then setup the action to create a message entity.

  14. Thanks for the tutorial. Any idea how I owuld exand on this and also display which group the node was posted in?

    1. What do you mean by group? Content type?

      If so, then just display the content type in the view.

  15. Yes. Essentially I want to extend your example to say

    [user:name] added [node:title in [group:name]

    I just don’t know how to get the group name based on your example.

    Any help would greatly be appreciated.

    1. You should be able to access the group node by selecting it from the data selector within Rules. But, make sure you have the “og_group_ref” field on the node that you’re using to create the messages.

  16. The message is not logging the second time the rule fires.
    For example I have a content type “Sample”.
    The goal here is to log a message every time a new content of Sample content type is created.
    I have have create a message type for the Log message and created a field entity reference of node type “Sample”
    Then created a rule to trigger entity creation of and setting the data of the created entity.

    When I created a content of node type Sample for the first time. The message logs and displayed on view.
    But when I create a content of node type Sample again. The message wont log anymore.
    Please help me with my problem. Thank you.

  17. I see how this works now and it’s very good for its purpose. But how do I incorporate it dynamically into a view, I need to ‘attach’ the log time to the node it is associated with; in my case an updated field. I want to have a table with ‘name of publisher’, ‘publisher url’ and then ‘time and date publisher was paid’. Would I need to add an entity reference field to the actual message type then try to access it through views? Thanks for the info so far, I am getting there!

    1. Yes, add an entity reference, publisher and publisher URL to a message type. The same as you would on a content type. Then use Views to create a basic table.

  18. I created a message, exactly as you have here and it works fine. I have now tweaked the rule so it fires when (1) the content type updated is ‘campaign’ [as the publishers are referenced by this when they work on a campaign] and (2) the field of a reference publisher is changed to ‘PAID’ status. The rule fires perfectly but the message displayed it ignores the tokens I used and just prints the placeholders! Am I supposed to attach more than one field to the message type? At the moment I just have 1 entity reference field which I assumed would reference any other content type.

    1. I don’t know why it’s not working. If you’re trying to process a token value from a content type that is reference via an entity reference field, then you may have to add an “Entity exists by property or Entity has field” condition to your rule.

  19. A better question might have been ‘ how do I add a ‘publisher URL’ to a message type,when I add an entity reference field it just asks me which bundle I want. Not which specific field. Sorry for all the questions, I am stuck on this one!

    1. If you need to populate a field on the message type, then use the “Set a data value” action.

  20. Hi Ivan. Thank you for sharing this tutorial. I have implemented it successfully for a range of events which I have incorporated into a message stream shown by a view.
    I have a question. Do you know if it is possible for new messages to appear in the view when generated without a page post back? The way facebook activity loads.
    Best wishes
    Craig

    1. The module does not support this type of functionality out of the box, you’ll have to build it yourself.

      You could do it with jQuery or Node.js.

  21. H Ivan!
    Creat tutorial indeend.
    First I was trying to user Heartbeat-module, but could not figure out how I can bring custom fields to activity message. Such as field from node user posted (image-field etc.) and profile2 fields.

    So my question is how to bring fields from node to message? I followed your tutorial and I have now working message page which says: Node has been added by User

    How to show image field from that node and also profile2 user profile picture? Any help appreciated, thanks!

    1. You’ll have to create a field on the message type to store the referenced user.

      Then, use Rules and the “Set a data value” action to populate the user reference field on the message.

  22. Hi,
    I have a question:When adding a new message type,there is no Message text area so as to write the message.Even example message types do not have such an area.Is this a bug or am I missing something?I am using Message 7.x-1.4 version.Any suggestions would be welcome!

    1. The field should be there, I don’t know why it’s not appearing. Try reinstalling the module and also update it. 7.x-1.4 is pretty old.

  23. Hi!

    It is possible to define a view that only messages belongs to users that are members of the same groups as I?

    thx in advance
    Gerald

    1. What do you mean by “groups”, is it a role or organic groups?

      One matter what a group is, you should be able to do it with Views.

  24. Hello
    Your tutorial is very good and helpful. But i am trying the same with statuses module. i want to post status in a certain msg type via rules module.
    the problem is, when i posts something i just got “this is a politics msg default [message:field-content] by parveen” in msg type.
    i need full text/value in the place of ” [message:field-content] “…
    can you please help me…..

    1. I’ve never used Message and Statuses together so I can’t help you. I would ask in the issue queue.

  25. I just wanted to thank you for sharing; great tutorial and very helpful on a few levels for me. I also want to thank you. I am impressed with your sharing in your comments as well. Sometimes I learn more from the dialogue in the comments to your posts.

  26. I am using Rules, Message, Message Notify and Flag modules. I have followed the steps of your tutorial.
    I added a message to the activity stream when user flags a node as “Favorite”.
    My problem is I am getting notification, but the node that was flagged seems to be missing from the message entity. Please guide for the steps, or where I may be wrong

    1. Because you’re using the Flag module, you’ll need to adjust the condition of the rule to only fire off if the node has been flagged. I’ve never used Flag and Rules together so I’m sure there’s more to it.

      I would look at this page, https://www.drupal.org/node/407070

      1. Thanks for your quick response. Your tutorials are really helpful, have studied many topics. Yes, I configured the rule properly to be fired when a node is flagged, with the help of event provided by flag and rule module integration, it provided the related event. The event is firing properly and saving creating the message entity and showing message on activity stream ‘[username] liked the’. I am getting only this message.. the node name is not being printed,although I have added keyword for that too and message should be ‘[username] liked the [node-title]’

        1. It looks like the flagged node object isn’t being loaded in the rule. I’ve had this issue in the past and I had to use a condition called “Fetch entity by property” or something. In my case, the tokens weren’t being rendered because no node object was available.

          Search the Message module issue queue for similar problems.

  27. Erika Mustermann

    Thank you very much for the tutorial. I followed all the steps and it is working fine. However, I also created a rule that triggers “After deleting content”. Unfortunately, the message is not able to display title and nid anymore but I get something like ”
    [message:field-message-content:title] ([message:field-message-content:nid]) has been deleted by admin”. Also all previous entries related to that node are gone.

    Is there a way to change that?

    1. This method won’t work for deleted nodes. The `field-message-content` field is an entity reference field so the token won’t render if the node is deleted.

      You’ll need to save the message using placements and arguments. Sorry, I’ve never done this with Rules.

  28. Thank you for the post. I would like to ask you that do you suggest heartbeat or message? Some people say message. What I want to do?

    My view will be a page where all activity is shown as notifications and using the menu badges, I will have a notifications page link in the main menu with count of unread items. I do not understand the code language, I just read and implement. Is it possible to use heartbeat for logging activity and then generating notifications via message module/message notify?

    The thing attracts me is message JS module, but your comment earlier tells me that I should go with heartbeat for a social networking website.

    1. Hi Umair,

      A lot has changed since I’ve written this tutorial.

      The Message module takes more time to setup because you can use it to log all sorts of things, not just user activity.

      Heartbeat is focused only around user activities. Another thing to think about is that Message module is actively maintained. The last release of Heartbeat was in September 2012.

      Hope this helps.

      Cheers,
      Ivan

  29. This works great for content types like basic pages, articles and such like. I am using Drupal 7 and have a lot of content split into blocks across the site, is there anyway to get the content in the blocks to show when it is updated? Blocks isn’t a selectable ‘content type’ in rules and I can’t see where I can add this content in ‘views’.

Comments are closed.