Quick start: Open channel
This tutorial walks you through building a basic open channel integration with the Nexconn Chat SDK for Web.
Prerequisites
Create a developer account and obtain your App Key.
Step 1: Import the SDK
Install the latest version via NPM:
npm install @nexconn/engine@latest @nexconn/chat@latest -S
Step 2: Initialize the SDK
Import the required modules and initialize with your App Key. Call initialization only once during the app lifecycle. Use areaCode to select your data center region (defaults to Singapore).
import {
NCEngine,
AreaCode,
OpenChannel,
MessageType,
TextMessageContent,
ImageMessageContent,
Message,
MessageHandler,
} from '@nexconn/chat';
NCEngine.initialize({ appKey: '<Your-AppKey>', areaCode: AreaCode.SG });
Use areaCode to specify your data center region (e.g., AreaCode.SG, AreaCode.NA). See Initialize for all available regions.
Step 3: Add a message listener
Register a message listener to receive incoming messages. Call addMessageHandler before connecting. You can register multiple listeners with different uniqueId values.
NCEngine.addMessageHandler('open-channel-handler', new MessageHandler({
onMessageReceived({ messages }) {
console.log('Messages received:', messages);
},
}));
Step 4: Connect to the chat server
Step 4.1: Get an access token
The client SDK does not provide a token API. Your app server must call the Server API to register a user and obtain an access token.
Include the following HTTP headers in all Server API requests:
App-Key: Your App KeyNonce: A random numberTimestamp: Unix timestampSignature: SHA1 hash ofApp Secret + Nonce + Timestamp
Request body requires userId, name, and avatarUrl:
POST /v4/auth/access-token/issue HTTP/1.1
Host: api.sg-light-api.com
App-Key: Your_AppKey
Nonce: 14314
Timestamp: 1408710653491
Signature: 45beb7cc7307889a8e711219a47b7cf6a5b000e8
Content-Type: application/json
{
"userId": "jlk456j5",
"name": "Ironman",
"avatarUrl": "http://abc.com/myportrait.jpg"
}
The response contains the user ID and access token:
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
{"code":0, "result":{"userId":"jlk456j5", "accessToken":"sfd9823ihufi"}}
Step 4.2: Connect
NCEngine.connect({ token: '<Your-Token>' }).then((res) => {
if (res.code === 0) {
console.log('Connected. User ID:', res.data?.userId);
} else {
console.warn('Connection failed. Code:', res.code);
}
});
Step 5: Join an open channel
Users must join an open channel before sending or receiving messages.
const channelId = 'my-open-channel';
const channel = new OpenChannel(channelId);
const { code, data } = await channel.enterChannel({
messageCount: 0, // Number of historical messages to fetch on join (0 = none)
});
if (code === 0) {
console.log('Joined open channel:', data);
} else {
console.log('Join failed. Code:', code);
}
Step 6: Send messages
Send a text message:
import { OpenChannel, SendTextMessageParams } from '@nexconn/chat';
const channel = new OpenChannel('my-open-channel');
const params = new SendTextMessageParams({ text: 'Hello, open channel!' });
const { code, data } = await channel.sendMessage(params);
if (code === 0) {
console.log('Message sent:', data);
} else {
console.log('Send failed. Code:', code);
}
Send an image message:
import { OpenChannel, Helper } from '@nexconn/chat';
const channel = new OpenChannel('my-open-channel');
const result = await Helper.createSendImageMessageParams(file); // file: File object
if (result.isOk) {
const params = result.data;
params.onUploadProgress = (progress) => {
console.log('Upload progress:', progress); // 0–100
};
params.onUploadComplete = (remoteUrl) => {
console.log('Upload complete:', remoteUrl);
};
const { code, data } = await channel.sendMediaMessage(params);
if (code === 0) {
console.log('Image message sent:', data);
}
}
Step 7: Get remote messages
Enable Open Channel Cloud Storage to store open channel messages on the server.
const query = OpenChannel.createOpenChannelMessagesQuery({
channelId: 'my-open-channel',
pageSize: 10,
isAscending: false, // false: newest first, true: oldest first
startTime: 0, // Unix timestamp; 0 = start from the latest
});
const { code, data: page } = await query.loadNextPage();
if (code === 0) {
console.log('Messages:', page.data);
} else {
console.log('Failed to get messages. Code:', code);
}
Step 8: Recall a message
To remove a message for all participants, use deleteMessageForAll with the Message object:
const channel = new OpenChannel('my-open-channel');
// First retrieve the message object from history
const query = OpenChannel.createOpenChannelMessagesQuery({
channelId: 'my-open-channel',
pageSize: 10,
isAscending: false,
startTime: 0,
});
const { code, data: page } = await query.loadNextPage();
if (code === 0 && page.data.length > 0) {
const { code: recallCode } = await channel.deleteMessageForAll(page.data[0]);
if (recallCode === 0) {
console.log('Message recalled');
}
}
Step 9: Moderation
The messaging service supports various moderation capabilities managed through the Server API.
Block a user
POST /v4/user/ban HTTP/1.1
Host: api.sg-light-api.com
App-Key: uwd1c0sxdlx2
Nonce: 14314
Timestamp: 1408710653491
Signature: 45beb7cc7307889a8e711219a47b7cf6a5b000e8
Content-Type: application/json
{
"userIds": ["UserA"],
"durationMinutes": 10
}
Appendix: Implement likes in an open channel
Use a custom message type to implement a like feature.
-
Register a custom message type before calling
connect:TypeScriptimport { NCEngine } from '@nexconn/chat';
NCEngine.registerCustomMessages([{
messageType: 'Xapp:Chatroom:Like',
isPersited: true,
isCounted: true,
}]); -
Send a like message:
TypeScriptimport { OpenChannel, SendMessageParams } from '@nexconn/chat';
const channel = new OpenChannel('my-open-channel');
const params = new SendMessageParams<Record<string, never>>({}, 'Xapp:Chatroom:Like');
const { code } = await channel.sendMessage(params); -
Handle incoming like messages:
TypeScriptNCEngine.addMessageHandler('like-handler', new MessageHandler({
onMessageReceived({ messages }) {
messages.forEach((msg) => {
if (msg.messageType === 'Xapp:Chatroom:Like') {
console.log('Like received');
}
});
},
}));