Skip to:
Codex HomeBuddyPress Plugin Development → Posting Activity from Plugins

Posting Activity from Plugins


This function was introduced in BuddyPress 1.1, it’s located in /bp-activity/bp-activity-functions.php at line 997 (version 1.7-beta1). It needs an array of arguments and returns the activity id once created by the method BP_Activity_Activity::save()

BuddyPress uses some aliases to call this function from its different components as detailed in this chart :

Functions Components Types @uses
bp_activity_post_update() activity activity_update bp_activity_add()
bp_activity_new_comment() activity activity_comment
bp_xprofile_new_avatar_activity() xprofile new_avatar
bp_core_new_user_activity xprofile new_member
friends_record_activity() friends friendship_accepted
groups_record_activity() groups created_group
bp_blogs_record_activity() blogs new_blog

In the following chart, the array of arguments the function bp_activity_add() needs is detailled :

Arguments Default value Explanation
id false If an id is passed, then the activity will be updated with the value of other arguments
action The activity action – e.g. “Jon Doe posted an update”
content The content of the activity item e.g. “BuddyPress is awesome guys!”
component false The identifier of the component (groups, activity, blogs, xprofile)
type false The activity type e.g. activity_update, joined_group, new_member…
primary_link The primary URL for this item
user_id bp_loggedin_user_id() The user to record the activity for.
item_id false The id of the specific item being recorded, e.g. a group_id
secondary_item_id false A second id used to further filter e.g. a topic_id
recorded_time bp_core_current_time() The GMT time that this activity was recorded
hide_sitewide false If true, the activity will be hidden from the sitewide activity
is_spam false Is this activity item to be marked as spam?

The hide_sitewide argument is responsible for the visibility of the activity. If set to true, the activity won’t show in the sitewide activities (Activity Directory).
It means the activity will be “private” and only visible for the logged in user when viewing his profile activities (if the argument user_id is the logged in user id) and for the displayed hidden or private group when viewing its activity page (if the component argument is ‘groups’ and the argument ‘item_id’ is the one of the group displayed.

Hooking Activities in plugins.

If the Activity component is active ( bp_is_active( ‘activity’ ) ), it can be interesting to hook the bp_activity_add function to fire some actions just after the activity has been recorded. It informs us about what just happened. For instance, we could automate a mail to inform the community admin of the creation of new groups :

function bp_plugin_hook_activity_add( $args ) {

	// sends an email to admin to inform him of a group creation
	if( $args['type'] == 'created_group' )
		wp_mail( get_option( 'admin_email' ), 'New group!', $args['action'], 'Content-Type: text/html' );


add_action( 'bp_activity_add', 'bp_plugin_hook_activity_add', 10, 1 );

The advantage in this case is that we take benefit of the action argument to get some useful information such as the group creator and the permalink to the group. Of course, if the Activity component is not active, then we need to hook ‘groups_group_create_complete’ and build a mail thanks to the group_id that this hook comes with.

In the Activity component, the 2 aliases ( bp_activity_post_update & bp_activity_new_comment ) have their own hooks, so we can rely on them to be sure, for instance in the first case, an activity update has just been recorded.

function bp_plugin_hook_activity_posted_update( $content, $user_id, $activity_id ) {
	// this is a silly example : just to illustrate !!
	$activity_count = get_user_meta( $user_id, 'silly_activity_counter' );

	$activity_count = empty( $activity_count ) ? 1 : intval( $activity_count ) + 1 ;

	update_user_meta( $user_id, 'silly_activity_counter', $activity_count );


add_action( 'bp_activity_posted_update', 'bp_plugin_hook_activity_posted_update', 10, 3 );

Of course we could use an equivalent function to count the activity comments of a user by relying on the ‘bp_activity_comment_posted’ hook.

Concerning, the other aliases, we need to hook bp_activity_add(). So we’ll have to check for the component argument or the type argument in order to, for instance, add some actions in case of a new topic update or more globally of a group update.

function bp_plugin_hook_group_activity( $args ) {

	if( $args['type'] == 'new_forum_topic' )
		// a new topic has been posted !!

	if( $args['component'] == 'groups' )
		// a new group update has been posted !!


add_action( 'bp_activity_add', 'bp_plugin_hook_group_activity', 11, 1 );

Once again, as explained earlier, if the activity component is not active, and if you need to fire some actions, for the different types (in other words events) listed in the first chart, you’ll need to rely on other hooks (e.g. : ‘groups_group_create_complete’, ‘bp_core_activated_user’…). But It’s an article about playing with activities, so i’ll focus on it 😉

Finally we can hook an activity before it has been saved. Although i discourage its use to modify the value of the activity arguments, community admins can use a particular hook to neutralize some mini activities if they wish to. Mini activities don’t have content and are used to log simple events such as the creation of a group, the fact that a member became a member of a group, etc. Lately, i was asked how to avoid recording activities when members are becoming friends or when a member joins a group. This can be achieve by hooking ‘bp_activity_before_save’.

function bp_plugin_dont_save_minis( $activity_object ) {
	// friendship_created is fired when a member accepts a friend request
	// joined_group is fired when a member joins a group.
	$exclude = array( 'friendship_created', 'joined_group');

	// if the activity type is empty, it stops BuddyPress BP_Activity_Activity::save() function
	if( in_array( $activity_object->type, $exclude ) )
		$activity_object->type = false;


add_action('bp_activity_before_save', 'bp_plugin_dont_save_minis', 10, 1 );

Recording activities for a custom component.

Well it’s quite easy, we just need to use the function bp_activity_add() and to customize its arguments regarding our component need.

function bp_plugin_record_activity() {

	$activity_id = bp_activity_add( array(
		'action'            => 'bp plugin action',
		'content'           => 'bp plugin content',
		/* the component argument will be set to our component's identifier */
		'component'         => 'bp_plugin',
		/* the type argument will be set to our component's type */
		'type'              => 'bp_plugin_update',
	) );

	return $activity_id;

Now to take a full benefit of our custom activities, we also need to customize the available options of the activity filters that are located in the sitewide Activity directory, in the user’s profile activity page and in the group’s activity page :

function bp_plugin_activity_filter() {
	<option value="bp_plugin_update"><?php _e( 'BP plugin update' ); ?></option>

// Activity Directory
add_action( 'bp_activity_filter_options', 'bp_plugin_activity_filter' );

// member's profile activity
add_action( 'bp_member_activity_filter_options', 'bp_plugin_activity_filter' );

// Group's activity
add_action( 'bp_group_activity_filter_options', 'bp_plugin_activity_filter' );

We should also think about the very nice admin interface introduced in BuddyPress 1.6. To customize its activity types filter, we just need to register our plugin type by hooking ‘bp_register_activity_actions’ :

function bp_plugin_activity_actions() {
	$bp = buddypress();

	   for the purpose of this tutorial we arbitrary set the $bp->component->id
	   !important you have to use the BP_Component class to do so
	   See :
	$bp->bp_plugin = new stdClass();
	$bp->bp_plugin->id = 'bp_plugin';

	// Bail if activity is not active
	if ( ! bp_is_active( 'activity' ) )
		return false;

	bp_activity_set_action( $bp->bp_plugin->id, 'bp_plugin_update', __( 'BP plugin update' ) );


add_action( 'bp_register_activity_actions', 'bp_plugin_activity_actions' );

Finally if your component’s plugin deals with a custom post type, you can also take benefit of the Site Tracking component to automatically record an activity. Personaly, in this case, i prefer to build my own function to control the activity arguments. But you could filter the hooks ‘bp_blogs_record_post_post_types’ and ‘bp_blogs_record_comment_post_types’ in order to generate an activity with a type argument of “new_blog_post” when a custom post type is published and of “new_blog_comment” when a comment is posted on your custom post type.

function bp_plugin_custom_post_type( $post_type ) {
	$post_type[] = 'bp_plugin_post_type';

	return $post_type;

add_filter( 'bp_blogs_record_post_post_types', 'bp_plugin_custom_post_type', 10, 1);
add_filter( 'bp_blogs_record_comment_post_types', 'bp_plugin_custom_post_type', 10, 1);

Fully enjoy bp_activity_set_action()

In the previous section, you’ve seen how to use this function to add the custom plugin activity action to the dropdown filters of the Activity Administration screens.
Since BuddyPress 2.0 and 2.1, this function has evolved and has now 3 more parameters to help plugin developers to have more control on :

function bp_plugin_activity_actions() {
    $bp = buddypress();

       for the purpose of this tutorial we arbitrary set the $bp->component->id
       !important you have to use the BP_Component class to do so
       See :
    $bp->bp_plugin = new stdClass();
    $bp->bp_plugin->id = 'bp_plugin';

    	$bp->bp_plugin->id,                        // The unique string ID of the component the activity action is attached to
    	'bp_plugin_update',                        // the action type
    	__( 'BP plugin update', 'plugin-domain' ), // the action description used in Activity Administration screens dropdown filters
    	'bp_plugin_format_bp_plugin_update',       // A callable function for formatting the action string
    	__( 'BP plugin update', 'plugin-domain' ), // the action label of the activity front-end dropdown filters
    	array( 'activity', 'member' )              // Activity stream contexts where the filter should appear
add_action( 'bp_register_activity_actions', 'bp_plugin_activity_actions' );

 * Callable function for formatting the action string
 * Since 2.0 activity action strings are generated dynamically, for a better compatibility with multilingual sites
function bp_plugin_format_bp_plugin_update( $action = '', $activity = null ) {
	$action = sprintf( __( '%s shared a new BP plugin update', 'plugin-domain' ), bp_core_get_userlink( $activity->user_id ) );

	return $action;

As you can see in the above code, you can set the callable function for formatting the action string using the 4th argument of bp_activity_set_action()

You can also set the 5th and 6th argument instead of using the 'bp_activity_filter_options' hook to set the label and the contexts where your option will appear in the available dropdowns :

Please note that this possibility was introduced in BuddyPress 2.1. It will work for the configs using the templates included in BuddyPress (BP Theme Compat). Some BuddyPress Themes might not have updated their activity templates (activity/index.php, groups\single\activity.php, members\single\activity.php).

Skip to toolbar