Notifications
This section explains how to send and receive various types of notifications and manage event subscriptions within Blocklet applications. Notifications are crucial for user engagement and inter-component communication within the Blocklet Server ecosystem. You can send direct messages to users, broadcast information to public channels, or publish events to the global event bus.
For details on user authentication, refer to the Auth Service documentation. To understand how Blocklets interact with each other, see Component Interaction.
Notification and Event Flow#
The Blocklet SDK facilitates various communication patterns. The following diagram illustrates the primary channels for sending and receiving notifications and events:
Sending Notifications#
The Blocklet SDK provides several methods to send notifications to users, channels, or external relays.
sendToUser
#
Sends a notification directly to one or more user DID Wallets. This is suitable for personalized messages.
Parameters
Name | Type | Description |
---|---|---|
|
| The DID of the target user(s) or a wildcard |
|
| The notification payload. This can be a single |
|
| Optional. An object with additional sending options. |
TNotificationInput
Structure
TNotificationInput
is an array of TNotification
objects, or a single TNotification
object. A TNotification
object can represent various types of notifications:
Field | Type | Description | Values (for |
---|---|---|---|
|
| The type of notification. |
|
|
| (Optional) The title of the notification. | |
|
| (Optional) The main content of the notification. | |
|
| (Optional) The severity level. |
|
|
| (Optional) An array of attachments to display as blocks. | |
|
| (Optional) An array of attachments to display. | |
|
| (Optional) An array of actions/buttons for the user. | |
|
| (Required for | |
|
| (Optional for | |
|
| (Required for | |
|
| (Required for | |
|
| (Optional) Activity details for activity-type notifications. |
TNotificationAttachment
Structure
Field | Type | Description | Values (for |
---|---|---|---|
|
| The type of attachment. |
|
|
| The data specific to the attachment type. | (Structure varies by |
|
| (Required for |
TNotificationAction
Structure
Field | Type | Description |
---|---|---|
|
| The internal name of the action. |
|
| (Optional) The display title of the action button. |
|
| (Optional) Text color for the button. |
|
| (Optional) Background color for the button. |
|
| (Optional) A URI to navigate to when the action is triggered. |
TNotificationActivity
Structure
Field | Type | Description | Values (for |
---|---|---|---|
|
| The type of activity. |
|
|
| The DID of the actor performing the activity. | |
|
| The target of the activity. (Structure varies by | |
|
| (Optional) Additional metadata for the activity. (Structure varies by |
TSendOptions
Structure
Field | Type | Description |
---|---|---|
|
| If |
|
| The locale for the notification content. |
|
| An array of channels to send the notification through (e.g., |
|
| Time-to-live for the message in minutes (0-7200). |
|
| If |
Returns
Name | Type | Description |
---|---|---|
|
| The response from the Blocklet Server, typically including |
Example: Sending a simple notification
import { sendToUser, NOTIFICATION_TYPES } from '@blocklet/sdk/service/notification';
async function sendSimpleNotification(recipientDid) {
try {
const notification = {
type: NOTIFICATION_TYPES.NOTIFICATION,
title: 'Welcome to Our Blocklet!',
body: 'Thank you for joining. Explore our features now.',
severity: 'success',
actions: [{
name: 'view_dashboard',
title: 'Go to Dashboard',
link: '/dashboard'
}]
};
const result = await sendToUser(recipientDid, notification);
console.log('Notification sent successfully:', result);
} catch (error) {
console.error('Failed to send notification:', error.message);
}
}
sendSimpleNotification('did:abt:zNKJjJ9WfM2yQdYfF5xT4s3pC1vU0h7g6e'); // Replace with actual user DID
Example Response
{
"status": "ok",
"hash": "b9f7a7c8d9e0f1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d3e4f5a6",
"message": "Notification sent successfully"
}
broadcast
#
Broadcasts a notification to a specific application channel. By default, it sends to the Blocklet's public channel, making it suitable for announcements or general updates to all connected instances and users of the Blocklet.
Parameters
Name | Type | Description |
---|---|---|
|
| The notification payload. This can be a single |
|
| Optional. An object with additional sending options. Can specify |
Returns
Name | Type | Description |
---|---|---|
|
| The response from the Blocklet Server, typically including |
Example: Broadcasting an app update
import { broadcast, NOTIFICATION_TYPES } from '@blocklet/sdk/service/notification';
import { getAppPublicChannel } from '@blocklet/meta/lib/channel'; // Helper to get default public channel
import { getSender } from '@blocklet/sdk/service/notification'; // Helper to get sender DID
async function broadcastAppUpdate() {
try {
const sender = getSender();
const channel = getAppPublicChannel(sender.appDid);
const notification = {
type: NOTIFICATION_TYPES.NOTIFICATION,
title: 'App Update Available!',
body: 'Version 2.0 brings new features and improvements.',
severity: 'info',
actions: [{
name: 'view_changelog',
title: 'View Changelog',
link: '/changelog'
}]
};
const result = await broadcast(notification, { channel, event: 'app_update' });
console.log('Broadcast sent successfully:', result);
} catch (error) {
console.error('Failed to send broadcast:', error.message);
}
}
broadcastAppUpdate();
Example Response
{
"status": "ok",
"hash": "c0d1e2f3a4b5c6d7e8f9a0b1c2d3e4f5a6b7c8d9e0f1a2b3c4d5e6f7a8b9c0d1",
"message": "Broadcast sent successfully"
}
sendToRelay
#
Sends arbitrary data to a specified relay topic and event. This is useful for communicating with external systems or services that are connected to the Blocklet Server via a relay channel.
Parameters
Name | Type | Description |
---|---|---|
|
| The topic of the relay channel. |
|
| The specific event name for the relay message. |
|
| The data payload to send to the relay. |
Returns
Name | Type | Description |
---|---|---|
|
| The response from the Blocklet Server, typically including |
Example: Sending data to an external webhook relay
import { sendToRelay } from '@blocklet/sdk/service/notification';
async function sendWebhookData(orderId, orderDetails) {
try {
const result = await sendToRelay(
'payment_updates', // topic
'order_completed', // event
{ orderId, status: 'completed', details: orderDetails } // data
);
console.log('Data sent to relay successfully:', result);
} catch (error) {
console.error('Failed to send data to relay:', error.message);
}
}
sendWebhookData('order_123', { amount: 100, currency: 'USD' });
Example Response
{
"status": "ok",
"hash": "d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2c3d4e5",
"message": "Data sent to relay successfully"
}
sendToMail
#
Sends a notification as an email to one or more email addresses. This method leverages the Blocklet Server's underlying email service.
Parameters
Name | Type | Description |
---|---|---|
|
| The email address(es) of the recipient(s). |
|
| The notification payload to be sent as an email. |
|
| Optional. An object with additional sending options, similar to |
Returns
Name | Type | Description |
---|---|---|
|
| The response from the Blocklet Server, typically including |
Example: Sending a password reset email
import { sendToMail, NOTIFICATION_TYPES } from '@blocklet/sdk/service/notification';
async function sendPasswordResetEmail(userEmail, resetLink) {
try {
const notification = {
type: NOTIFICATION_TYPES.NOTIFICATION,
title: 'Password Reset Request',
body: `Click the link to reset your password: ${resetLink}`,
severity: 'normal',
actions: [{
name: 'reset_password',
title: 'Reset Password',
link: resetLink
}]
};
const result = await sendToMail(userEmail, notification);
console.log('Password reset email sent successfully:', result);
} catch (error) {
console.error('Failed to send password reset email:', error.message);
}
}
sendPasswordResetEmail('user@example.com', 'https://yourblocklet.com/reset?token=xyz');
Example Response
{
"status": "ok",
"hash": "e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d3e4f5a6b7c8d9e0f1a2b3c4d5e6f7",
"message": "Email sent successfully"
}
publish
(Event Bus)#
Publishes a custom event to the global Blocklet Server Event Bus. This allows different Blocklets and components to communicate and react to specific occurrences within the ecosystem without direct knowledge of each other. All subscribed Blocklets will receive the event.
Parameters
Name | Type | Description |
---|---|---|
|
| The name of the event (e.g., |
|
| The event payload. |
|
| Optional. A unique ID for the event. If not provided, |
|
| Optional. The ISO timestamp of the event. If not provided, |
|
| The main data associated with the event. Can include |
Returns
Name | Type | Description |
---|---|---|
|
| The response from the Blocklet Server, typically including |
Example: Publishing a user creation event
import { publish } from '@blocklet/sdk/service/eventbus';
async function publishUserCreatedEvent(userId, username) {
try {
const result = await publish('user.created', {
data: {
object_type: 'User',
object_id: userId,
user: { id: userId, name: username, status: 'active' }
}
});
console.log('Event published successfully:', result);
} catch (error) {
console.error('Failed to publish event:', error.message);
}
}
publishUserCreatedEvent('user_abc', 'Alice');
Example Response
{
"status": "ok",
"hash": "f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9",
"message": "Event published successfully"
}
Receiving Notifications and Events#
The Blocklet SDK provides event listeners to handle incoming notifications and events from various channels.
on
#
Registers a listener for general Blocklet events, including HI
notifications (from the app's public channel) and internal Blocklet Server events (such as BlockletInternalEvents
and TeamEvents
). This method automatically ensures the WebSocket client is initialized.
Parameters
Name | Type | Description |
---|---|---|
|
| The name of the event to listen for (e.g., |
|
| The callback function to execute when the event is received. The arguments passed to the callback depend on the specific event type. |
Returns
Name | Type | Description |
---|---|---|
|
| The EventEmitter instance, allowing for method chaining (e.g., |
Example: Listening for HI
notifications
import { on, NOTIFICATION_TYPES } from '@blocklet/sdk/service/notification';
function handleHiNotification(response) {
console.log('Received HI notification:', response);
// response typically includes: { type: 'hi', sender: { appDid: '...', name: '...' } }
}
on(NOTIFICATION_TYPES.HI, handleHiNotification);
console.log('Listening for HI notifications...');
Example Callback Payload for HI
event
{
"type": "hi",
"sender": {
"appDid": "did:abt:zNKu7qY1vX6z...",
"name": "Another Blocklet",
"description": "A friendly Blocklet saying hello"
}
}
Example: Listening for a team event (e.g., TeamEvents.USER_JOINED
)
import { on } from '@blocklet/sdk/service/notification';
import { TeamEvents } from '@blocklet/constant';
function handleUserJoined(data) {
console.log('User joined team:', data);
// data typically includes: { user: { did: '...', fullName: '...', ... } }
}
on(TeamEvents.USER_JOINED, handleUserJoined);
console.log('Listening for USER_JOINED events...');
Example Callback Payload for TeamEvents.USER_JOINED
{
"user": {
"did": "did:abt:zNKiD2R...",
"pk": "0x...",
"role": "member",
"avatar": "https://.../avatar.png",
"fullName": "John Doe",
"email": "john.doe@example.com",
"approved": true,
"createdAt": 1678886400000,
"updatedAt": 1678886400000,
"locale": "en-US",
"firstLoginAt": 1678886400000,
"lastLoginAt": 1678886400000
}
}
_message.on
#
Registers a listener for messages specifically received from user DID Wallets via direct channels. This is where your Blocklet would receive responses to connect
requests or custom messages sent from a user's wallet. This method also ensures the WebSocket client is initialized.
Parameters
Name | Type | Description |
---|---|---|
|
| The type of message event to listen for (e.g., |
|
| The callback function to execute when a message is received. It receives the |
Returns
Name | Type | Description |
---|---|---|
|
| The EventEmitter instance. |
Example: Listening for connect
responses
import { _message, NOTIFICATION_TYPES } from '@blocklet/sdk/service/notification';
function handleConnectResponse(response) {
console.log('Received connect response:', response);
// response typically includes: { type: 'connect', status: 'ok', response: { userDid: '...', ... } }
}
_message.on(NOTIFICATION_TYPES.CONNECT, handleConnectResponse);
console.log('Listening for connect responses...');
Example Callback Payload for connect
event
{
"id": "msg_abcdef123456",
"createdAt": "2024-03-15T10:00:00.000Z",
"type": "connect",
"receiver": {
"did": "did:abt:zNKu7qY1vX6z..."
},
"response": {
"status": "ok",
"userDid": "did:abt:zNKiD2R...",
"wallet": {
"name": "My DID Wallet",
"appDid": "did:abt:zNKJjJ9WfM2yQdYfF5xT4s3pC1vU0h7g6e"
}
}
}
subscribe
(Event Bus)#
Subscribes to all events published on the global Blocklet Server Event Bus. The callback receives a TEvent
object, allowing your Blocklet to react to various system-wide or cross-Blocklet events. This method ensures the WebSocket client is initialized.
Parameters
Name | Type | Description |
---|---|---|
|
| The callback function to execute when an event bus event is received. It receives the |
Returns
Name | Type | Description |
---|---|---|
| This method does not return a value. |
Example: Subscribing to all event bus events
import { subscribe } from '@blocklet/sdk/service/eventbus';
function handleEventBusEvent(event) {
console.log('Received Event Bus event:', event);
// event is a TEvent object
}
subscribe(handleEventBusEvent);
console.log('Subscribed to Event Bus...');
Example Callback Payload for Event Bus event (TEvent
)
{
"id": "evt_T2UiJ2VHUxVo3J6BuULkrp15",
"source": "did:abt:zNKJjJ9WfM2yQdYfF5xT4s3pC1vU0h7g6e",
"type": "customer.subscription.renewed",
"time": "2025-02-19T03:46:42.662Z",
"spec_version": "1.0.0",
"object_type": "Subscription",
"object_id": "sub_hmL7FQTmMbYVELkH6uVo6m9P",
"data": {
"type": "application/json",
"object": {
"id": "sub_hmL7FQTmMbYVELkH6uVo6m9P"
},
"previous_attributes": {}
}
}
off
, _message.off
, unsubscribe
#
These methods are used to remove previously registered event listeners.
off
: Removes listeners registered withon
._message.off
: Removes listeners registered with_message.on
.unsubscribe
: Removes listeners registered withsubscribe
.
Each method takes the event name and the original callback function as arguments to specify which listener to remove.
Example: Removing a listener
import { on, off, NOTIFICATION_TYPES } from '@blocklet/sdk/service/notification';
function temporaryHandler(response) {
console.log('Temporary HI notification:', response);
// After receiving it once, remove the listener
off(NOTIFICATION_TYPES.HI, temporaryHandler);
console.log('Temporary HI listener removed.');
}
on(NOTIFICATION_TYPES.HI, temporaryHandler);
console.log('Temporary HI listener added.');
This section provided a comprehensive overview of sending and receiving notifications and events within your Blocklet applications using the Blocklet SDK. You can now implement robust communication flows for user interaction and inter-component messaging. Next, explore how Blocklets interact directly with each other in the Component Interaction section.