actionhero
Version:
actionhero.js is a multi-transport API Server with integrated cluster capabilities and delayed tasks
146 lines (145 loc) • 5.88 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.ChatRoom = void 0;
const index_1 = require("../index");
/**
* Chat & Realtime Communication Methods
*/
class ChatRoom extends index_1.Initializer {
constructor() {
super();
this.name = "chatRoom";
this.loadPriority = 520;
this.startPriority = 200;
}
async initialize(config) {
if (config.redis.enabled === false) {
return;
}
index_1.api.chatRoom = {
middleware: {},
globalMiddleware: [],
messageChannel: "/actionhero/chat/chat",
keys: {
rooms: "actionhero:chatRoom:rooms",
members: "actionhero:chatRoom:members:",
},
};
/**
* Send a message to all members of a chat room. This is used by the server.
*/
index_1.api.chatRoom.broadcast = async (connection, room, message) => {
if (!room || !message) {
throw new Error(config.errors.connectionRoomAndMessage(connection));
}
else if (connection.rooms === undefined ||
connection.rooms.indexOf(room) > -1) {
const payload = {
messageType: "chat",
serverToken: config.general.serverToken,
serverId: index_1.id,
message: message,
sentAt: new Date().getTime(),
connection: {
id: connection.id || "0",
room: room,
},
};
const messagePayload = index_1.api.chatRoom.generateMessagePayload(payload);
const newPayload = await index_1.api.chatRoom.runMiddleware(connection, messagePayload.room, "onSayReceive", messagePayload);
const payloadToSend = {
messageType: "chat",
serverToken: config.general.serverToken,
serverId: index_1.id,
message: newPayload.message,
sentAt: newPayload.sentAt,
connection: {
id: newPayload.from,
room: newPayload.room,
},
};
await index_1.redis.publish(payloadToSend);
}
else {
throw new Error(config.errors.connectionNotInRoom(connection, room));
}
};
index_1.api.chatRoom.generateMessagePayload = (message) => {
return {
message: message.message,
room: message.connection.room,
from: message.connection.id,
context: "user",
sentAt: message.sentAt,
};
};
index_1.api.chatRoom.incomingMessage = (message) => {
const messagePayload = index_1.api.chatRoom.generateMessagePayload(message);
Object.keys(index_1.api.connections.connections).forEach((connectionId) => {
const connection = index_1.api.connections.connections[connectionId];
// we can parallelize this, no need to await
index_1.api.chatRoom.incomingMessagePerConnection(connection, messagePayload);
});
};
index_1.api.chatRoom.incomingMessagePerConnection = async (connection, messagePayload) => {
if (connection.canChat === true &&
connection.rooms.indexOf(messagePayload.room) > -1) {
try {
const newMessagePayload = await index_1.api.chatRoom.runMiddleware(connection, messagePayload.room, "say", messagePayload);
connection.sendMessage(newMessagePayload, "say");
}
catch (error) {
index_1.log(error, "warning", { messagePayload, connection });
}
}
};
index_1.api.chatRoom.runMiddleware = async (connection, room, direction, messagePayload) => {
let newMessagePayload;
if (messagePayload) {
newMessagePayload = Object.assign({}, messagePayload);
}
for (const name of index_1.api.chatRoom.globalMiddleware) {
const m = index_1.api.chatRoom.middleware[name];
if (typeof m[direction] === "function") {
if (messagePayload) {
const data = await m[direction](connection, room, newMessagePayload);
if (data) {
newMessagePayload = data;
}
}
else {
await m[direction](connection, room);
}
}
}
return newMessagePayload;
};
}
async start(config) {
if (config.redis.enabled === false) {
return;
}
index_1.api.redis.subscriptionHandlers.chat = (message) => {
if (index_1.api.chatRoom) {
index_1.api.chatRoom.incomingMessage(message);
}
};
if (config.general.startingChatRooms) {
const rooms = Object.keys(config.general.startingChatRooms);
for (const room of rooms) {
index_1.log(`ensuring the existence of the chatRoom: ${room}`);
try {
await index_1.chatRoom.add(room);
}
catch (error) {
if (!error
.toString()
.match(await config.errors.connectionRoomExists(room))) {
throw error;
}
}
}
}
}
}
exports.ChatRoom = ChatRoom;