actionhero
Version:
The reusable, scalable, and quick node.js API server for stateless and stateful applications
145 lines (144 loc) • 6.31 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.ChatRoomInitializer = void 0;
const index_1 = require("../index");
/**
* Chat & Realtime Communication Methods
*/
class ChatRoomInitializer extends index_1.Initializer {
constructor() {
super();
this.broadcast = async (connection, room, message) => {
if (!connection)
connection = {};
if (!room || !message) {
throw new Error(index_1.config.errors.connectionRoomAndMessage(connection));
}
else if (connection.rooms === undefined ||
connection.rooms.indexOf(room) > -1) {
const payload = {
messageType: "chat",
serverToken: index_1.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);
if (newPayload !== null && newPayload !== undefined) {
const payloadToSend = {
messageType: "chat",
serverToken: index_1.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(index_1.config.errors.connectionNotInRoom(connection, room));
}
};
this.generateMessagePayload = (message) => {
return {
message: message.message,
room: message.connection.room,
from: message.connection.id,
context: "user",
sentAt: message.sentAt,
}; // we want to relax the return type to a Record so that this method can be modified by users
};
this.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);
});
};
this.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);
if (newMessagePayload !== null) {
connection.sendMessage(newMessagePayload, "say");
}
}
catch (error) {
(0, index_1.log)(error, "warning", { messagePayload, connection });
}
}
};
this.runMiddleware = async (connection, room, direction, messagePayload) => {
var _a;
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) {
newMessagePayload =
(_a = (await m[direction](connection, room, newMessagePayload))) !== null && _a !== void 0 ? _a : null;
}
else {
await m[direction](connection, room);
}
}
}
return newMessagePayload;
};
this.removeMember = (connectionId, room, toWaitRemote = true) => index_1.chatRoom.removeMember(connectionId, room, toWaitRemote);
this.name = "chatRoom";
this.loadPriority = 520;
this.startPriority = 200;
}
async initialize() {
index_1.api.chatRoom = {
middleware: {},
globalMiddleware: [],
messageChannel: "/actionhero/chat/chat",
keys: {
rooms: "actionhero:chatRoom:rooms",
members: "actionhero:chatRoom:members:",
},
broadcast: this.broadcast,
generateMessagePayload: this.generateMessagePayload,
incomingMessage: this.incomingMessage,
incomingMessagePerConnection: this.incomingMessagePerConnection,
runMiddleware: this.runMiddleware,
removeMember: this.removeMember,
};
}
async start() {
index_1.api.redis.subscriptionHandlers.chat = (message) => {
if (index_1.api.chatRoom) {
index_1.api.chatRoom.incomingMessage(message);
}
};
for (const [room, options] of Object.entries(index_1.config.general.startingChatRooms)) {
(0, index_1.log)(`ensuring the existence of the chatRoom: ${room}`, "debug");
try {
await index_1.chatRoom.add(room);
}
catch (error) {
if (!error
.toString()
.match(await index_1.config.errors.connectionRoomExists(room))) {
throw error;
}
}
}
}
}
exports.ChatRoomInitializer = ChatRoomInitializer;