UNPKG

actionhero

Version:

The reusable, scalable, and quick node.js API server for stateless and stateful applications

145 lines (144 loc) 6.31 kB
"use strict"; 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;