How to Send Messages to an x-bees Channel using the x-bees Conversations SDK and Node.js
This tutorial will help you send messages to an x-bees channel using the x-bees Conversations SDK and Node.js.
Introduction
Wildix offers a unified communications solution with various tools, including x-bees, for efficient team collaboration. By integrating the x-bees Conversations SDK, you can automate notifications from your services to x-bees channels, enhancing the overall user experience. This guide will help you create a basic example of sending a message with an attachment to an x-bees conversation channel.
Prerequisites
Before you begin, ensure you have the following:
- Basic knowledge of programming and system settings.
- PBX with
x-bees
orx-hoppers
licenses - Admin Access to the Wildix Management System (WMS) To retrieve your
pbxSerial
andpbxKey
. - Node.js and npm: Ensure you have Node.js (version 18.x or higher) and npm installed.
- Git: For cloning the repository.
Step 1: Clone the Examples Repository
Open your terminal and run the following commands:
git clone https://github.com/Wildix/sdk-examples.git
cd sdk-examples
Step 2: Install the Required Packages
Navigate to the conversation-api-send-message
example directory and install the necessary packages:
cd examples/conversation-api-send-message
npm install
Step 3: Configure the Demo Script
- Login to the WMS terminal:
- Login to your WMS.
- Open the Terminal (found in the header menu).
- Press
Enter
key.
- Receive pbxSerial and pbxKey:
- Paste command
cat /rw2/etc/sf2 | head -18 | tail -2 | xargs printf "pbxSerial: %s\npbxKey: %s\n"
to the terminal and pressEnter
button. - Copy the
pbxSerial
value and paste it toPBX_SERIAL
variable in./src/index.ts
file. - Copy the
pbxKey
value and paste it toPBX_KEY
variable in./src/index.ts
file.
- Get the Channel ID:
- Open x-bees in your browser.
- Select your conversation.
- Copy the
channelId
from the browser’s URL:https://app.x-bees.com/inbox/<channelId>
- Paste
channelId
to variableXBS_CHANNEL_ID
in./src/index.ts
file.
- Retrieve the User ID:
- Open x-bees in your browser.
- Open the DevTools console in your browser.
- Paste and run the following command
wx.stream._user.id
- Copy the returned
userId
- Paste the
userId
to variableXBS_USER_FROM_ID
in./src/index.ts
file.
Step 4: Run the Script
Run Script using the following command:
npm run start
A message with the attachment will be sent to your x-bees channel.
Warning
The user on whose behalf you will send a message to the channel must be present in this channel, otherwise you will get an error.
Code
Here’s a detailed explanation of the code for sending message with attachments to the x-bees channel:
import fs from 'fs';
import {PbxTokenProvider} from '@wildix/auth-utils';
import {
ConversationsClient,
GetUploadedFileInfoCommand,
SendMessageCommand,
UploadFileCommand,
} from '@wildix/xbees-conversations-client';
/*
* PBX serial & key
*
* You can receive this values after login to your PBX by ssh
* and run command `cat /rw2/etc/sf2 | head -18 | tail -2 | xargs printf "pbxSerial: %s\npbxKey: %s\n"`
* */
const PBX_SERIAL = '<pbxSerial>';
const PBX_KEY = '<pbxKey>';
/*
* x-bees channel ID
*
* You can copy the channel ID into the URL input field of your browser
* https://app.x-bees.com/inbox/<channelId>
*/
const XBS_CHANNEL_ID = '<channelId>';
/*
* x-bees userId
*
* You can get the x-bees user ID by running the following command in your browser
* from the x-bees page in the devtools console: wx.stream._user.id
*/
const XBS_USER_FROM_ID = '<userId>';
(async () => {
try {
const sendMessageResponse = await sendMessageWithAttachments(XBS_CHANNEL_ID, XBS_USER_FROM_ID, `Test message from x-bees Conversation API v2 ${new Date().toISOString()}`, [
{path: 'xbs_logo.png', contentType: 'image/png'},
{path: 'wildix_logo.png', contentType: 'image/png'},
]);
console.log('sendMessageResponse:', sendMessageResponse);
} catch (error) {
console.error('Send message error:', error);
}
})();
/**
* Sends a message to a specified channel with optional file attachments.
*
* This function first uploads any provided files to a storage service and then sends a message
* containing the text and metadata of the uploaded files to the specified channel.
*
* @async
* @param {string} channelId - The ID of the channel where the message will be sent.
* @param {string} userId - The ID of the x-bees user.
* @param {string} text - The text content of the message to be sent.
* @param {Attachment[]} [files] - An optional array of files to be attached to the message.
* Each file should contain properties like `path` and `contentType`.
*
* @returns {Promise<SendMessageOutput>} - A promise that resolves with the output of the send message operation.
* The output typically contains details about the sent message.
*
* @throws {Error} - Throws an error if the message sending or file upload fails.
* Possible reasons include invalid channel ID, file upload errors, or network issues.
*/
async function sendMessageWithAttachments(channelId, userId, text, files) {
const pbxTokenProvider = new PbxTokenProvider(PBX_SERIAL, PBX_KEY);
const client = new ConversationsClient({token: pbxTokenProvider, env: 'prod'});
let attachments = [];
if (files) {
attachments = await Promise.all(files.map((attachment) => uploadAttachment(client, channelId, userId, attachment)));
}
return client.send(new SendMessageCommand({
channelId,
text,
userId,
attachments,
}));
}
async function uploadFileToS3(presignedUploadUrl, filePath, contentType = '') {
const fileContent = fs.readFileSync(filePath);
const response = await fetch(presignedUploadUrl, {
method: 'PUT',
headers: {'Content-Type': contentType},
body: fileContent,
});
if (!response.ok) {
throw new Error(`Failed to upload file: ${response.statusText}`);
}
return response;
}
async function uploadAttachment(client, channelId, userId, attachment) {
const {fileId, presignedUploadUrl} = await client.send(new UploadFileCommand({
channelId,
name: attachment.path,
userId,
}));
const {statusText} = await uploadFileToS3(presignedUploadUrl, attachment.path, attachment.contentType);
console.log(`Upload attachment ${attachment.path} result: ${statusText}`);
const getFileInfoResponse = await client.send(new GetUploadedFileInfoCommand({
channelId,
fileId,
}));
return getFileInfoResponse.file;
}