Давайте изучим возможности чата Twilio с помощью JavaScript SDK для создания масштабируемого и надежного приложения для чата.
Эта статья поможет вам интегрировать приложение чата с API-интерфейсом Twilio для общения в angular, но это еще не все; вы можете найти больше вариантов использования или примеров, упомянутых здесь.
Теперь давайте начнем и создадим пример приложения чата, чтобы продемонстрировать то же самое.

Предпосылки
- узел Js
- Менеджер пакетов: npm
- Создайте одну Бесплатную учетную запись Twilio, чтобы начать использовать ту же
- Угловой интерфейс командной строки
Шаги:
Сначала настроим Backend-код.
Запустите указанные ниже команды, чтобы создать новый проект NodeJS, chat-backend.
mkdir chat-backend cd chat-backend npm init
Теперь установим необходимые пакеты express, dotenv и Twilio.
npm i express npm i dotenv npm i twilio
Создайте файл .env и добавьте все необходимые переменные конфигурации из консоли Twilio.
TWILIO_ACCOUNT_SID= TWILIO_AUTH_TOKEN= TWILIO_SERVICE_SID= TWILIO_API_KEY= TWILIO_API_SECRET=
Теперь давайте настроим файлы index.js и chat.js, как указано ниже.
index.js
require('dotenv').config();
const express = require("express");
var app = express();
const chat = require('./chat');
app.use(function(req, res, next) {
res.setHeader('Access-Control-Allow-Origin', '*');
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE');
res.setHeader('Access-Control-Allow-Headers', 'Content-Type');
res.setHeader('Access-Control-Allow-Credentials', true);
next();
});
app.get("/", function (request, response) {
response.send("Hello World!");
})
app.get("/getToken", function (request, response) {
let token = chat.getToken(request.query.userName);
response.send(JSON.stringify(token));
})
app.listen(3000, function () {
console.log("Started application on port %d", 3000);
});
чат.js
const accountSid = process.env.TWILIO_ACCOUNT_SID;
const authToken = process.env.TWILIO_AUTH_TOKEN;
const serviceSid = process.env.TWILIO_SERVICE_SID;
const apiKey = process.env.TWILIO_API_KEY;
const apiSecret = process.env.TWILIO_API_SECRET;
const client = require('twilio')(accountSid, authToken);
// Create a twilio access token
function getToken(identity) {
const AccessToken = require('twilio').jwt.AccessToken;
const ChatGrant = AccessToken.ChatGrant;
const chatGrant = new ChatGrant({
serviceSid: serviceSid,
});
const token = new AccessToken(
accountSid,
apiKey,
apiSecret,
{
identity: identity,
ttl: 3600
}
);
token.addGrant(chatGrant);
return token.toJwt();
}
module.exports = {getToken};
Здесь мы закончили с внутренним кодом, необходимым для работы с приложением чата; давайте запустим сервер и проверим то же самое
npm start
Поскольку мы закончили с настройкой бэкенда, теперь давайте перейдем к созданию проекта Angular.
Запустите указанные ниже команды, чтобы создать новый угловой проект с помощью angular-cli.
ng new twilio-chat-example cd twilio-chat-example ng serve
давайте установим пакет диалога Twilio и начнем работать над JS SDK
npm install --save @twilio/conversations
Создайте новый компонент для работы с twilio JS SDK.
ng g c chats
Во-первых, вам понадобится токен доступа для настройки клиента и прослушивания клиентских событий. Вызовите созданный API /getToken с уникальным именем пользователя ИЛИ идентификатором пользователя, который вернет токен доступа для использования и прослушивания клиентских событий.
connectTwilio() {
this.isLoading = true;
this.getToken().subscribe(token => {
this.client = new Client(token);
this.isLoading = false;
this.listenToEvents();
}, error => console.log(error));
}
После инициализации клиента вы можете получить каналы, на которые подписан пользователь, обновить количество непрочитанных сообщений, сообщения и список вновь созданных чатов с заданной обработкой событий.
Прослушайте события tokenAboutToExpire и tokenExpired, чтобы обновить созданный токен и продолжить работу со службами Twilio.
listenToEvents() {
this.client.on('initialized', () => {
console.log('Client initialized');
this.fetchUserChats();
});
this.client.on('initFailed', (error: any) => {
console.log('Client initialization failed: ', error);
});
this.client.on('connectionStateChanged', (state: ConnectionState) => {
console.log('Connection state change: ', state);
});
this.client.on('connectionError', (error: any) => {
console.log('Connection error: ', error);
});
this.client.on('tokenAboutToExpire', () => {
console.log('About to expire');
this.getToken().subscribe(async (token) => {
this.client = await this.client.updateToken(token);
})
});
this.client.on('tokenExpired', () => {
console.log('Token expired');
this.client.removeAllListeners();
this.connectTwilio();
});
this.client.on('conversationAdded', (conv: Conversation) => {
setTimeout(async () => {
if (conv.dateCreated && conv.dateCreated > this.currentTime) {
console.log('Conversation added', conv);
await conv.setAllMessagesUnread();
let newChat = {
chat: conv,
unreadCount: 0,
lastMessage: ''
}
this.chatList = [newChat,...this.chatList];
}
}, 500);
});
this.client.on('messageAdded', async (msg: Message) => {
console.log('Message added', msg);
if (this.currentConversation && this.currentConversation.sid === msg.conversation.sid) {
this.messages.push(msg);
await this.currentConversation.updateLastReadMessageIndex(msg.index);
this.chatList = this.chatList.map(el => {
if(el.chat.sid === this.currentConversation.sid){
el.lastMessage = msg.body;
}
return el;
});
} else {
this.chatList = this.chatList.map(el => {
if(el.chat.sid === msg.conversation.sid){
el.lastMessage = msg.body;
el.unreadCount++;
}
return el;
});
}
});
this.client.on('typingStarted', (user: Participant) => {
console.log('typing..', user);
if (user.conversation.sid === this.currentConversation.sid) this.isTyping = true;
});
this.client.on('typingEnded', (user: Participant) => {
console.log('typing end..', user);
if (user.conversation.sid === this.currentConversation.sid) this.isTyping = false;
});
}
Получить подписанные разговоры пользователей для страницы со списком
fetchUserChats() {
this.isLoading = true;
this.client.getSubscribedConversations().then(convs => {
let chats:any = [...convs.items];
chats.forEach( async (chat:Conversation) => {
let obj = {
chat: chat,
unreadCount: await chat.getUnreadMessagesCount(),
lastMessage: (await chat.getMessages()).items[chat.lastReadMessageIndex || 0].body
}
this.chatList.push(obj);
})
this.isLoading = false;
}).catch(error => console.log(error));
}
Как указано ниже, создайте новый чат с помощью клиентской функции createConversation. Создайте новый разговор — присоединитесь к нему — добавьте других пользователей по их личности.
newChat() {
this.isLoading = true;
this.client.getUser(this.newUser).then(res => {
this.client.createConversation({
friendlyName: `${this.newUser}-${this.userName}`,
}).then(async (channel: Conversation) => {
channel.join().then(async () => {
await channel.setAllMessagesUnread();
channel.add(this.newUser).then(() => {
this.currentConversation = channel;
this.openChat(channel);
this.scrollToBottom();
this.isLoading = false;
})
});
}).catch(error => console.log(error));
}).catch(err => {
this.isLoading = false;
this.error = 'User not found in Twilio';
setTimeout(() => {
this.error = null;
}, 2000);
this.newUser = null;
});
}
Отправьте сообщение другим участникам беседы.
sendMessage() {
this.currentConversation.sendMessage(this.message).then(result => {
this.message = '';
}).catch(err => console.log(err));
}
Получение сообщений: когда вы нажимаете на чат из списка, вам нужно получать сообщения, как показано ниже, и сбрасывать счетчик непрочитанных сообщений до индекса последнего сообщения.
Примечание. реализуйте загрузку сообщений в прокрутке, так как getMessages будет возвращать 30 элементов за раз, а также реализуйте аналогичный процесс для получения разговоров пользователей.
fetchMessages(skip?: number) {
this.isLoading = true;
this.currentConversation.getMessages(30, skip).then(async (result) => {
this.messages = [...result.items, ...this.messages];
if (!skip) {
let resetTo = this.messages.length >= 1 ? this.messages[this.messages.length - 1].index : 0;
await this.currentConversation.updateLastReadMessageIndex(resetTo);
this.chatList = this.chatList.map( el => {
if(el.chat.sid == this.currentConversation.sid){
el.unreadCount = 0;
}
return el;
})
}
this.isLoading = false;
}).catch(error => {
this.isLoading = false;
console.log(error)
});
}
Вы в основном закончили базовую настройку SDK. Clone/ обратитесь к этот пример для получения дополнительной информации.
Это базовый пример создания приложения чата с беседами Twilio. Вы можете проверить другие вещи в его официальном документе для прикрепления мультимедиа, закрытия чатов (управление состоянием разговора), индикаторов доступности, работы с внешними каналами и т. д.
То, что нужно запомнить
- Не добавляйте несколько слушателей для одного и того же события, чтобы избежать неправильного поведения.
- Проверьте лимиты разговора Twilio один раз, прежде чем создавать логический поток в соответствии с вашим вариантом использования.
- Взгляните на тарифный план Twilio, так как это платная услуга.
Оставайтесь с нами на Simform Engineering, чтобы быть в курсе последних тенденций в экосистеме разработки программного обеспечения.
Рекомендации
Документация:https://www.twilio.com/docs/conversations
Пример: Посмотрите пример видео по данной ссылке GitHub для примера
(Внешний интерфейс) https://github.com/Khushbu-2112/Twilio-chat-frontend-Example
(Бэкенд) https://github.com/Khushbu-2112/Twilio-chat- бэкенд-пример