Bell notifications via apex

You can definitely send Bell Notifications via apex. Andrew Fawcett explained this feature in detail in his article

A month ago I had a task to send a notification to my user when deletion of test data is finished. This is an example code how it was done:

public class MyBellNotification
    public static void notifyCurrentUser(String message)
        Http h = new Http();
        HttpRequest req = new HttpRequest();
            + '/services/data/v46.0/actions/standard/customNotificationAction');
        req.setHeader('Authorization', 'Bearer ' + UserInfo.getSessionId());
        req.setHeader('Content-Type', 'application/json');
        CustomNotificationActionInput input = new CustomNotificationActionInput();
        input.customNotifTypeId = '0ML0b000000KyjGGAS';
        input.recipientIds = new List<String>{UserInfo.getUserId()};
        input.title = 'Test Data Operation Completed';
        input.body = message;
        input.targetId = '0ML0b000000KyjGGAS';
        CustomNotificationAction action = new CustomNotificationAction();
        action.inputs = new List<CustomNotificationActionInput>{input};
        HttpResponse res = h.send(req);

    public class CustomNotificationAction
        public List<CustomNotificationActionInput> inputs { get; set; }

    public class CustomNotificationActionInput
        public String customNotifTypeId { get; set; }
        public List<String> recipientIds { get; set; }
        public String title { get; set; }
        public String body { get; set; }
        public String targetId { get; set; }

A few things to note:

  1. You need to define a new Notification Type under the Setup menu.
  2. Get the Id of the Notification Type you created. Just run the following query in the Developer Console's Query Editor SELECT Id, DeveloperName FROM CustomNotificationType.
  3. Use this ID in the input.customNotifTypeId = '0ML0b000000KyjGGAS'; and input.targetId = '0ML0b000000KyjGGAS'; fields. If you want you can use the id of an Attendant record in the targetId field. It will generate a link to that record in the notification text.
  4. Since this implementation requires an API callout, you cannot perform DML operations in the same transaction prior to calling this code or in triggers. A workaround to this is to define a Queueable class and call that class instead. See below:

public without sharing class Notification implements Queueable, Database.AllowsCallouts { String message;

public Notification(String message)
    this.message = message;

public void execute(QueueableContext context)


This is just a use case sample DO NOT USE this lines in your code as you will delete 10,000 accounts from your org:

Database.delete(Database.query('SELECT Id FROM Account LIMIT 10000 WHERE isTestData__c = TRUE'));
System.enqueueJob(new Notification('Records deleted'));

From Winter 2021 you will be able to send notifications directly using apex. The below code works in the winter 2021 release preview orgs.

Id typeId = [SELECT Id FROM CUstomNotificationType WHERE DeveloperName = 'notification type name'].Id;
Messaging.CustomNotification notification = new Messaging.CustomNotification();
notification.setBody('This is body of the custom notification!');
notification.setTitle('Hi this is first notification sent using apex!');
notification.setNotificationTypeId(typeId );
notification.setTargetId('006B0000005hCxzIAE'); // target object id
notification.send(new Set<String> { Userinfo.getUserId() }); // target user id.

Send Custom Notifications from Apex

I have written a detailed blog post about this code.

You can achieve the bell notification through the new Summer '19 Custom Notifications feature however, it's not triggerable via APEX just yet. I know this doesn't directly answer the question re: APEX, but it's a pretty simple process builder.

Upside of this is that you can also deliver these as push notifications to the user's mobile device/watch etc. (so long as they have the Salesforce1 app installed).