educt-server/build/app/Store/MessageStore.js
2022-06-12 22:05:55 +03:00

85 lines
3.5 KiB
JavaScript

"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const Logger_1 = __importDefault(global[Symbol.for('ioc.use')]("Adonis/Core/Logger"));
const User_1 = __importDefault(global[Symbol.for('ioc.use')]("App/Models/User"));
const luxon_1 = require("luxon");
const nanoid_1 = require("nanoid");
const MESSAGE_TTL = 185 * 24 * 60 * 60;
const MAX_MESSAGES_HISTORY = 100;
class RedisMessageStore {
constructor(redisClient) {
Object.defineProperty(this, "redisClient", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
this.redisClient = redisClient;
}
async add(firstUserId, secondUserId, data) {
try {
const msgId = (0, nanoid_1.nanoid)();
const msgKey = `${firstUserId}:${msgId}`;
const key = `message:${msgKey}`;
await this.redisClient
.multi()
.hmset(key, {
from: data.from,
to: data.to,
content: data.content,
time: luxon_1.DateTime.now().toISO(),
})
.expire(key, MESSAGE_TTL)
.exec();
const convKey = this.createConversationKey(firstUserId, secondUserId);
const msgKeys = await this.redisClient.lrange(convKey, 0, -1);
await this.redisClient.lpush(convKey, msgKey);
if (msgKeys.length >= MAX_MESSAGES_HISTORY) {
const deletedMsgKey = await this.redisClient.rpop(convKey);
await this.redisClient.del(`message:${deletedMsgKey}`);
}
return 'OK';
}
catch (error) {
Logger_1.default.error(error);
return 'ERROR';
}
}
async getHistory(firstUserId, secondUserId) {
const convKey = this.createConversationKey(firstUserId, secondUserId);
const msgKeys = await this.redisClient.lrange(convKey, 0, -1);
const messages = await Promise.all(msgKeys.map(key => `message:${key}`).map(key => this.getMessage(key)));
return messages.sort((m1, m2) => new Date(m1.time).valueOf() - new Date(m2.time).valueOf());
}
async getConversations(userId) {
const conversations = await this.redisClient.keys(`conversation:*${userId}*`);
const userIds = conversations
.map(id => id.split(':')[1])
.map(id => (userId !== id.split('&')[0] ? id.split('&')[0] : id.split('&')[1]));
const users = await User_1.default.query().select('id', 'first_name', 'last_name').where('id', 'in', userIds);
const result = await Promise.all(users.map(async (u) => {
const convKey = this.createConversationKey(userId, u.id);
const msgKey = await this.redisClient.lindex(convKey, 0);
const lastMessage = await this.getMessage(`message:${msgKey}`);
return {
userId: u.id,
fullname: `${u.first_name} ${u.last_name}`,
lastMessage,
};
}));
return result;
}
async getMessage(key) {
const message = (await this.redisClient.hgetall(key));
return message;
}
createConversationKey(userId1, userId2) {
const [id1, id2] = [userId1, userId2].sort();
return `conversation:${id1}&${id2}`;
}
}
exports.default = RedisMessageStore;
//# sourceMappingURL=MessageStore.js.map