BuddyPress

BuddyPress: Adding Custom Notifications

Social networks run on notifications and BuddyPress helps make that happen. BuddyPress sends out notifications for various actions on the site, like when you get a message from a friend or when someone replies to your status update. Though BuddyPress sends out quite a few notifications, you might want to add custom notifications for other actions. For example, you may want to send out a notification when a friends birthday is near.

In this tutorial, we will go over the code necessary to send a member a notification when someone comments on their blog post. You don’t need a lot of code to add notifications; they just require special formatting.

The first thing required is that notifications are attached to a BuddyPress Component. No worries though–you do not actually have to create a full component! It just needs to be registered by adding to an array. Adding a “fake” component to the registered component array is done by adding a filter to bp_notifications_get_registered_components. In the code snip below we are adding a fake component called “custom”. You can name this fake component anything. We will use this name later when adding the notification.

function custom_filter_notifications_get_registered_components( $component_names = array() ) {

    // Force $component_names to be an array
    if ( ! is_array( $component_names ) ) {
        $component_names = array();
    }

    // Add 'custom' component to registered components array
    array_push( $component_names, 'custom' );

    // Return component's with 'custom' appended
    return $component_names;
}
add_filter( 'bp_notifications_get_registered_components', 'custom_filter_notifications_get_registered_components' );

Once we have the fake component registered, we need to create a function to format what is actually displayed on the members notification table list. In the image below you can see the column “Notification”. The content of this box is what we need to format. This should be a short message to explain the notification and to link back to a piece of content. In this case, it’s the comment link:

not-table

There are a couple caveats when formatting this callback function. We need to take into account the admin bar markup. We need to pass back a string and also an array. Formatted as such:

// WordPress Toolbar
if ( 'string' === $format ) {
    $return = apply_filters( 'custom_filter', '<a href="' . esc_url( $custom_link ) . '" title="' . esc_attr( $custom_title ) . '">' . esc_html( $custom_text ) . '</a>', $custom_text, $custom_link );

// Deprecated BuddyBar
} else {
    $return = apply_filters( 'custom_filter', array(
        'text' => $custom_text,
        'link' => $custom_link
    ), $custom_link, (int) $total_items, $custom_text, $custom_title );
}

The other caveat is adding a notification doesn’t really add anything until it is displayed. The only thing that is saved is the item id (what you want to link to). In our code we are doing notifications for comments, so we save the comment id and then during the call back formatting function get the required data to display. See the code below where we get the $item_id and use it with get_comment() to compile whats shown in that Notification box in the table list. The $item_id is set during the action that adds the notification. The $custom_text can be customized to fit the content you are linking to.

The format code needs to be wrapped in an action check; if this is not done it will reformat every notification. Note: Notifications are built each time they are displayed. In the code example I have set the action to be ‘custom_action’. You can name this anything–when adding the notification later you specify this action.

function custom_format_buddypress_notifications( $action, $item_id, $secondary_item_id, $total_items, $format = 'string' ) {

    // New custom notifications
    if ( 'custom_action' === $action ) {
    
        $comment = get_comment( $item_id );
    
        $custom_title = $comment->comment_author . ' commented on the post ' . get_the_title( $comment->comment_post_ID );
        $custom_link  = get_comment_link( $comment );
        $custom_text = $comment->comment_author . ' commented on your post ' . get_the_title( $comment->comment_post_ID );

        // WordPress Toolbar
        if ( 'string' === $format ) {
            $return = apply_filters( 'custom_filter', '<a href="' . esc_url( $custom_link ) . '" title="' . esc_attr( $custom_title ) . '">' . esc_html( $custom_text ) . '</a>', $custom_text, $custom_link );

        // Deprecated BuddyBar
        } else {
            $return = apply_filters( 'custom_filter', array(
                'text' => $custom_text,
                'link' => $custom_link
            ), $custom_link, (int) $total_items, $custom_text, $custom_title );
        }
        
        return $return;
        
    }
    
}
add_filter( 'bp_notifications_get_notifications_for_user', 'custom_format_buddypress_notifications', 10, 5 );

Now we need to hook to an action to run the bp_notifications_add_notification() function and save that item id. You can hook to almost any action for the type of notification you want to send. That birthday notification example mentioned at the beginning of this tutorial could be hooked to run on login and then cycle through friend ids and then when it finds a friend with a birthday in a set time, save that user id and then the format callback function can retrieve that friends id and display an appropriate notification.

In our case we are hooking to wp_insert_comment. This hook allows us to get the comment id to save as the item id to be used in the format callback function. You also need to provide the user id of who will be receiving this notification.

In this case, we want to notify the post author. We can tap into the wp_insert_comment hook, as it has the comment object and provides the post id the comment is getting attached to. Then we can get the author id from the get_post() response. You will see an argument for ‘component_name’ and ‘component_action’. The ‘component_name’ is the fake component we registered in custom_filter_notifications_get_registered_components(). The ‘component_action’ is the action we wrapped around our formatting code earlier. This is so the format code only runs on specific notifications.

function bp_custom_add_notification( $comment_id, $comment_object ) {

    $post = get_post( $comment_object->comment_post_ID );
    $author_id = $post->post_author;

    bp_notifications_add_notification( array(
        'user_id'           => $author_id,
        'item_id'           => $comment_id,
        'component_name'    => 'custom',
        'component_action'  => 'custom_action',
        'date_notified'     => bp_core_current_time(),
        'is_new'            => 1,
    ) );
    
}
add_action( 'wp_insert_comment', 'bp_custom_add_notification', 99, 2 );

Thats about it–only three functions to get custom notifications in BuddyPress. Click here for the full code in this tutorial. If you got any questions, post in the comments and I’ll get notified…see what I did there?

25 thoughts on “BuddyPress: Adding Custom Notifications

  1. Thank you for the post. It really helped getting my head around this.

    I copied your full sample code into bp-custom.php. I didnt change a single line. The notification is added to the db, no problem. But the notification is blank. I went through the normal debugging routine and it turns out that there is a conflict with bbPress 2.5.8

    Here’s my setup
    WP 2015 Theme
    WP 4.3.1
    All plugins deactivated except BP 2.3.4 (works. notification isn’t blank)
    All plugins deactivated except BP 2.3.4 & bbPress 2.5.8 (doesnt work. notifications are blank)

    If I try to echo $action in custom_format_buddypress_notifications its blank so it never steps through the custom_filter filtering.

    1. Hello Shawn,

      I assume you fixed this issue ?
      Can you provide the full code ?

      I am terrible at .php and my notifications are showing blank.

  2. Hello. First of all thank you for your contribution. By testing your code I see that in reviewing the message remains as unread.

    I am very interested in this question because I want to use my blog as a forum without installing wordpress bbPress and notify the users that are friends, which has created a new blog post.

    My knowledge of php are basic. For now understand that would have to double if (‘custom_action’ === $ action) {} and modify it to reach my goal. Am I on track?

    Again thank you very much time

    1. You would put a parameter on the end of the $custom_link to your post in the notification then when clicked it would move that notification as read.

      You would create a function that was hooked to run when yo view a blog post. Look here for example of bbPress marking notifications based on url parameter.

      https://bbpress.trac.wordpress.org/browser/trunk/src/includes/extend/buddypress/notifications.php#L146

      The function to mark items is bp_notifications_mark_notifications_by_item_id()

  3. Hi Ryan,
    i’m not a developer, but i’d like to add to notification the new activity on group.
    When there is a new activity in one of groups of a member, i’d like to see a notification.
    Can help me to do it?

    1. I can’t write the code for you but its same as above but youd need to hook into the correct filter instead of wp_insert_comment and get the correct info to pass back to notification

  4. Hi, I really appreciate Your work +1.
    But… I’m facing one problem, how to mark notification as read after user click in that notification (title)?

    Cheers

  5. Now if only we will get a tutorial that will notify of new posts from friends. Otherwise thank you for the tutorial. musch appreciated

  6. Hi Ryan, how would this work if I were to create a notification that lets the admin know when someone has left a private group – is that possible with your code?

  7. Hello Ryan,

    FIrst of all thank you very much for the tutorial! Its by far the best resource I’ve found on custom notifications.

    I’m pretty new to buddypress and been trying to “hack” my way to an app.

    I’m currently using the buddypress live notifications which works like a charm but I also need notifications for post/activity likes.

    I’ve tried both Buddypress Like and WPUlike withouth any success.

    Is this something you have attempted? I’m a bit surprised how hard it has been to achieve such functionality.

    I tried incorporating your tutorial but I’m not sure which hooks to use to save the notifications.

    Any light you can shed would be much appreciated!!

    Thank you very much for your time.

    Kind regards,
    Gab

    1. You can add a notification for anything you can hook an action to. You basically need a trigger to send off the notification. BuddyPress Like doesn’t have any hooks but you could tap into the ajax or $_POST.

  8. Hi, i need your help. I receive all the buddypress notification but never the activity post member notification. I really do not understand. Somebody can help me?
    Thanks a lot

    1. Hi Alex,

      BuddyPress only sends a notification when posting activity if the poster @ mentions.

      If you are having issues with your install I suggest you post in the buddy press.org forums

      1. Hi, i really do not found a solution. It is possible for you change the code of your notify email activity comments with activity stream feed?
        Thanks a lot

  9. Can you do another tut showing how to send a email notification when a Buddypress “friend” submit a “post” to a WordPress Site.

    This was already requested:

    pempho says:
    March 8, 2016 at 9:53 am

    Now if only we will get a tutorial that will notify of new posts from friends. Otherwise thank you for the tutorial. musch appreciated

    Exceptional work by the way.

  10. Hi, I modified your example, I wanted to add posts notifications and it worked fine, except when I tried to filter them. First you need to know how I want to filter them. – I’ve a profile field named ‘Field’ which is a dropdown list with 5 options. – I have also 5 post categories with the exact names of the ‘Field’ values. – When a post is added, If it has (e.g. A,B,C) categories I want a notification for every user who has his ‘Field’ value is equal to A,B or C.
    Here is the full code:
    `
    function custom_filter_notifications_get_registered_components( $component_names = array() ) {
    if ( ! is_array( $component_names ) ) {
    $component_names = array();
    }
    array_push( $component_names, ‘custom’ );
    return $component_names;
    }
    add_filter( ‘bp_notifications_get_registered_components’, ‘custom_filter_notifications_get_registered_components’ );
    function custom_format_buddypress_notifications( $action, $item_id, $secondary_item_id, $total_items, $format = ‘string’ ) {
    if ( ‘custom_action’ === $action ) {
    $post = get_post( $item_id );
    $recent_author = get_user_by( ‘ID’, $post->post_author );
    $author_display_name = $recent_author->display_name;
    $custom_title = $author_display_name . ‘ has posted a new post: ‘ . get_the_title($post);
    $custom_text = $author_display_name. ‘ has posted a new post: ‘ . get_the_title($post);
    // WordPress Toolbar
    if ( ‘string’ === $format ) {
    $return = apply_filters( ‘custom_filter’, ‘‘ . esc_html( $custom_text ) . ‘‘, $custom_text, $custom_link );
    // Deprecated BuddyBar
    } else {
    $return = apply_filters( ‘custom_filter’, array(
    ‘text’ => $custom_text,
    ‘link’ => $custom_link
    ), $custom_link, (int) $total_items, $custom_text, $custom_title );
    }

    return $return;

    }

    }

    add_filter( ‘bp_notifications_get_notifications_for_user’, ‘custom_format_buddypress_notifications’, 10, 5 );
    function bp_custom_add_notification( $post_id, $post_object ) {

    $args = array(
    ‘blog_id’ => $GLOBALS[‘blog_id’],
    ‘role’ => ’employer’,
    ‘role__in’ => array(),
    ‘role__not_in’ => array(),
    ‘meta_key’ => ”,
    ‘meta_value’ => ”,
    ‘meta_compare’ => ”,
    ‘meta_query’ => array(),
    ‘date_query’ => array(),
    ‘include’ => array(),
    ‘exclude’ => array(),
    ‘orderby’ => ‘login’,
    ‘order’ => ‘ASC’,
    ‘offset’ => ”,
    ‘search’ => ”,
    ‘number’ => ”,
    ‘count_total’ => false,
    ‘fields’ => ‘all’,
    ‘who’ => ”
    );
    $all_users = get_users($args);

    foreach ($all_users as $user) {
    $acc_type = xprofile_get_field_data(‘Field’, $user->ID);
    if (in_category($acc_type, $post_object->ID)) {
    bp_notifications_add_notification( array(
    ‘user_id’ => $user->ID,
    ‘item_id’ => $post_id,
    ‘component_name’ => ‘custom’,
    ‘component_action’ => ‘custom_action’,
    ‘date_notified’ => bp_core_current_time(),
    ‘is_new’ => 1,
    ) );
    }

    }

    }
    add_action( ‘wp_insert_post’, ‘bp_custom_add_notification’, 99, 2 );
    `
    PS: It works without the IF STATEMENT.

  11. Hi Ryan,

    Thanks a lot for your awesome tutorials. They have been incredibly helpful. I’ve managed to create multiple notifications. When I click on the notification from the dropdown, i’d like to have it marked as read.

    I have added the following parameter action=read in the url. I cannot however manage to get the notification id to be sent as a parameter in the link. Any guidance will be super helpful as I feel very lost with this.

    Thanks

    1. Hi Claudio,

      This is sounding like custom functionality with regards to how Notifications work in BuddyPress. That said, I have looked over how the “read” link from http://DOMAIN.com/members/USERNAME/notifications/ work, and they also include a nonce value and the notification ID to be marked as read, on top of the action you’re already providing. I’d recommend looking over the bp-notifications/bp-notifications-template.php file as well as the top of bp-notifications/bp-notifications.actions.php file to see what all is available. Hopefully that gives a better idea of what all is involved to potentially make the dropdown in the admin bar work that way.

    2. Hi Claudio,

      You can retrieve the notification ID and wpnonce using bp_get_the_notification_mark_read_url(). These can then be added to the custom link to the comment using add_query_arg. The problem is that when action=read, the function bp_notifications_action_mark_read calls the function bp_notifications_mark_notification, which calls bp_displayed_user_id(), but the latter doesn’t return anything when used in the dropdown. Creating a replacement bp_notifications_mark_notification function that uses bp_loggedin_user_id() instead seems to do the job!

      Ed

Have a comment?

Your email address will not be published. Required fields are marked *