'use strict'; /** * Module dependencies */ import it from '../../../it'; import Message from '../../../models/messaging-message'; import { isValidText } from '../../../models/messaging-message'; import History from '../../../models/messaging-history'; import User from '../../../models/user'; import DriveFile from '../../../models/drive-file'; import serialize from '../../../serializers/messaging-message'; import publishUserStream from '../../../event'; import { publishMessagingStream } from '../../../event'; import config from '../../../../conf'; /** * Create a message * * @param {any} params * @param {any} user * @return {Promise} */ module.exports = (params, user) => new Promise(async (res, rej) => { // Get 'user_id' parameter const [recipientId, recipientIdErr] = it(params.user_id).expect.id().required().qed(); if (recipientIdErr) return rej('invalid user_id param'); // Myself if (recipientId.equals(user._id)) { return rej('cannot send message to myself'); } // Fetch recipient const recipient = await User.findOne({ _id: recipientId }, { fields: { _id: true } }); if (recipient === null) { return rej('user not found'); } // Get 'text' parameter const [text, textErr] = it(params.text).expect.string().validate(isValidText).qed(); if (textErr) return rej('invalid text'); // Get 'file_id' parameter const [fileId, fileIdErr] = it(params.file_id).expect.id().qed(); if (fileIdErr) return rej('invalid file_id param'); let file = null; if (fileId !== null) { file = await DriveFile.findOne({ _id: fileId, user_id: user._id }, { data: false }); if (file === null) { return rej('file not found'); } } // テキストが無いかつ添付ファイルも無かったらエラー if (text === null && file === null) { return rej('text or file is required'); } // メッセージを作成 const message = await Message.insert({ created_at: new Date(), file_id: file ? file._id : undefined, recipient_id: recipient._id, text: text ? text : undefined, user_id: user._id, is_read: false }); // Serialize const messageObj = await serialize(message); // Reponse res(messageObj); // 自分のストリーム publishMessagingStream(message.user_id, message.recipient_id, 'message', messageObj); publishUserStream(message.user_id, 'messaging_message', messageObj); // 相手のストリーム publishMessagingStream(message.recipient_id, message.user_id, 'message', messageObj); publishUserStream(message.recipient_id, 'messaging_message', messageObj); // 5秒経っても(今回作成した)メッセージが既読にならなかったら「未読のメッセージがありますよ」イベントを発行する setTimeout(async () => { const freshMessage = await Message.findOne({ _id: message._id }, { is_read: true }); if (!freshMessage.is_read) { publishUserStream(message.recipient_id, 'unread_messaging_message', messageObj); } }, 5000); // Register to search database if (message.text && config.elasticsearch.enable) { const es = require('../../../db/elasticsearch'); es.index({ index: 'misskey', type: 'messaging_message', id: message._id.toString(), body: { text: message.text } }); } // 履歴作成(自分) History.update({ user_id: user._id, partner: recipient._id }, { updated_at: new Date(), user_id: user._id, partner: recipient._id, message: message._id }, { upsert: true }); // 履歴作成(相手) History.update({ user_id: recipient._id, partner: user._id }, { updated_at: new Date(), user_id: recipient._id, partner: user._id, message: message._id }, { upsert: true }); });