summaryrefslogtreecommitdiff
path: root/src/server/api/endpoints/messaging/messages
diff options
context:
space:
mode:
Diffstat (limited to 'src/server/api/endpoints/messaging/messages')
-rw-r--r--src/server/api/endpoints/messaging/messages/create.ts125
-rw-r--r--src/server/api/endpoints/messaging/messages/delete.ts12
-rw-r--r--src/server/api/endpoints/messaging/messages/read.ts17
3 files changed, 118 insertions, 36 deletions
diff --git a/src/server/api/endpoints/messaging/messages/create.ts b/src/server/api/endpoints/messaging/messages/create.ts
index 388852b9cd..f5d7cf2b38 100644
--- a/src/server/api/endpoints/messaging/messages/create.ts
+++ b/src/server/api/endpoints/messaging/messages/create.ts
@@ -1,19 +1,22 @@
import $ from 'cafy';
import { ID } from '../../../../../misc/cafy-id';
-import { publishMainStream } from '../../../../../services/stream';
+import { publishMainStream, publishGroupMessagingStream } from '../../../../../services/stream';
import { publishMessagingStream, publishMessagingIndexStream } from '../../../../../services/stream';
import pushSw from '../../../../../services/push-notification';
import define from '../../../define';
import { ApiError } from '../../../error';
import { getUser } from '../../../common/getters';
-import { MessagingMessages, DriveFiles, Mutings } from '../../../../../models';
+import { MessagingMessages, DriveFiles, Mutings, UserGroups, UserGroupJoinings } from '../../../../../models';
import { MessagingMessage } from '../../../../../models/entities/messaging-message';
import { genId } from '../../../../../misc/gen-id';
import { types, bool } from '../../../../../misc/schema';
+import { User } from '../../../../../models/entities/user';
+import { UserGroup } from '../../../../../models/entities/user-group';
+import { Not } from 'typeorm';
export const meta = {
desc: {
- 'ja-JP': '指定したユーザーへMessagingのメッセージを送信します。',
+ 'ja-JP': 'トークメッセージを送信します。',
'en-US': 'Create a message of messaging.'
},
@@ -25,13 +28,21 @@ export const meta = {
params: {
userId: {
- validator: $.type(ID),
+ validator: $.optional.type(ID),
desc: {
'ja-JP': '対象のユーザーのID',
'en-US': 'Target user ID'
}
},
+ groupId: {
+ validator: $.optional.type(ID),
+ desc: {
+ 'ja-JP': '対象のグループのID',
+ 'en-US': 'Target group ID'
+ }
+ },
+
text: {
validator: $.optional.str.pipe(MessagingMessages.isValidText)
},
@@ -60,6 +71,18 @@ export const meta = {
id: '11795c64-40ea-4198-b06e-3c873ed9039d'
},
+ noSuchGroup: {
+ message: 'No such group.',
+ code: 'NO_SUCH_GROUP',
+ id: 'c94e2a5d-06aa-4914-8fa6-6a42e73d6537'
+ },
+
+ groupAccessDenied: {
+ message: 'You can not send messages to groups that you have not joined.',
+ code: 'GROUP_ACCESS_DENIED',
+ id: 'd96b3cca-5ad1-438b-ad8b-02f931308fbd'
+ },
+
noSuchFile: {
message: 'No such file.',
code: 'NO_SUCH_FILE',
@@ -75,16 +98,38 @@ export const meta = {
};
export default define(meta, async (ps, user) => {
- // Myself
- if (ps.userId === user.id) {
- throw new ApiError(meta.errors.recipientIsYourself);
- }
+ let recipientUser: User | undefined;
+ let recipientGroup: UserGroup | undefined;
- // Fetch recipient
- const recipient = await getUser(ps.userId).catch(e => {
- if (e.id === '15348ddd-432d-49c2-8a5a-8069753becff') throw new ApiError(meta.errors.noSuchUser);
- throw e;
- });
+ if (ps.userId != null) {
+ // Myself
+ if (ps.userId === user.id) {
+ throw new ApiError(meta.errors.recipientIsYourself);
+ }
+
+ // Fetch recipient (user)
+ recipientUser = await getUser(ps.userId).catch(e => {
+ if (e.id === '15348ddd-432d-49c2-8a5a-8069753becff') throw new ApiError(meta.errors.noSuchUser);
+ throw e;
+ });
+ } else if (ps.groupId != null) {
+ // Fetch recipient (group)
+ recipientGroup = await UserGroups.findOne(ps.groupId);
+
+ if (recipientGroup == null) {
+ throw new ApiError(meta.errors.noSuchGroup);
+ }
+
+ // check joined
+ const joining = await UserGroupJoinings.findOne({
+ userId: user.id,
+ userGroupId: recipientGroup.id
+ });
+
+ if (joining == null) {
+ throw new ApiError(meta.errors.groupAccessDenied);
+ }
+ }
let file = null;
if (ps.fileId != null) {
@@ -107,32 +152,49 @@ export default define(meta, async (ps, user) => {
id: genId(),
createdAt: new Date(),
fileId: file ? file.id : null,
- recipientId: recipient.id,
+ recipientId: recipientUser ? recipientUser.id : null,
+ groupId: recipientGroup ? recipientGroup.id : null,
text: ps.text ? ps.text.trim() : null,
userId: user.id,
- isRead: false
+ isRead: false,
+ reads: [] as any[]
} as MessagingMessage);
const messageObj = await MessagingMessages.pack(message);
- // 自分のストリーム
- publishMessagingStream(message.userId, message.recipientId, 'message', messageObj);
- publishMessagingIndexStream(message.userId, 'message', messageObj);
- publishMainStream(message.userId, 'messagingMessage', messageObj);
+ if (recipientUser) {
+ // 自分のストリーム
+ publishMessagingStream(message.userId, recipientUser.id, 'message', messageObj);
+ publishMessagingIndexStream(message.userId, 'message', messageObj);
+ publishMainStream(message.userId, 'messagingMessage', messageObj);
- // 相手のストリーム
- publishMessagingStream(message.recipientId, message.userId, 'message', messageObj);
- publishMessagingIndexStream(message.recipientId, 'message', messageObj);
- publishMainStream(message.recipientId, 'messagingMessage', messageObj);
+ // 相手のストリーム
+ publishMessagingStream(recipientUser.id, message.userId, 'message', messageObj);
+ publishMessagingIndexStream(recipientUser.id, 'message', messageObj);
+ publishMainStream(recipientUser.id, 'messagingMessage', messageObj);
+ } else if (recipientGroup) {
+ // グループのストリーム
+ publishGroupMessagingStream(recipientGroup.id, 'message', messageObj);
+
+ // メンバーのストリーム
+ const joinings = await UserGroupJoinings.find({ userGroupId: recipientGroup.id });
+ for (const joining of joinings) {
+ publishMessagingIndexStream(joining.userId, 'message', messageObj);
+ publishMainStream(joining.userId, 'messagingMessage', messageObj);
+ }
+ }
// 2秒経っても(今回作成した)メッセージが既読にならなかったら「未読のメッセージがありますよ」イベントを発行する
setTimeout(async () => {
- const freshMessage = await MessagingMessages.findOne({ id: message.id });
+ const freshMessage = await MessagingMessages.findOne(message.id);
if (freshMessage == null) return; // メッセージが削除されている場合もある
- if (!freshMessage.isRead) {
+
+ if (recipientUser) {
+ if (freshMessage.isRead) return; // 既読
+
//#region ただしミュートされているなら発行しない
const mute = await Mutings.find({
- muterId: recipient.id,
+ muterId: recipientUser.id,
});
const mutedUserIds = mute.map(m => m.muteeId.toString());
if (mutedUserIds.indexOf(user.id) != -1) {
@@ -140,8 +202,15 @@ export default define(meta, async (ps, user) => {
}
//#endregion
- publishMainStream(message.recipientId, 'unreadMessagingMessage', messageObj);
- pushSw(message.recipientId, 'unreadMessagingMessage', messageObj);
+ publishMainStream(recipientUser.id, 'unreadMessagingMessage', messageObj);
+ pushSw(recipientUser.id, 'unreadMessagingMessage', messageObj);
+ } else if (recipientGroup) {
+ const joinings = await UserGroupJoinings.find({ userGroupId: recipientGroup.id, userId: Not(user.id) });
+ for (const joining of joinings) {
+ if (freshMessage.reads.includes(joining.userId)) return; // 既読
+ publishMainStream(joining.userId, 'unreadMessagingMessage', messageObj);
+ pushSw(joining.userId, 'unreadMessagingMessage', messageObj);
+ }
}
}, 2000);
diff --git a/src/server/api/endpoints/messaging/messages/delete.ts b/src/server/api/endpoints/messaging/messages/delete.ts
index 6a896cd8d1..fb1bb42a56 100644
--- a/src/server/api/endpoints/messaging/messages/delete.ts
+++ b/src/server/api/endpoints/messaging/messages/delete.ts
@@ -1,7 +1,7 @@
import $ from 'cafy';
import { ID } from '../../../../../misc/cafy-id';
import define from '../../../define';
-import { publishMessagingStream } from '../../../../../services/stream';
+import { publishMessagingStream, publishGroupMessagingStream } from '../../../../../services/stream';
import * as ms from 'ms';
import { ApiError } from '../../../error';
import { MessagingMessages } from '../../../../../models';
@@ -10,7 +10,7 @@ export const meta = {
stability: 'stable',
desc: {
- 'ja-JP': '指定したメッセージを削除します。',
+ 'ja-JP': '指定したトークメッセージを削除します。',
'en-US': 'Delete a message.'
},
@@ -57,6 +57,10 @@ export default define(meta, async (ps, user) => {
await MessagingMessages.delete(message.id);
- publishMessagingStream(message.userId, message.recipientId, 'deleted', message.id);
- publishMessagingStream(message.recipientId, message.userId, 'deleted', message.id);
+ if (message.recipientId) {
+ publishMessagingStream(message.userId, message.recipientId, 'deleted', message.id);
+ publishMessagingStream(message.recipientId, message.userId, 'deleted', message.id);
+ } else if (message.groupId) {
+ publishGroupMessagingStream(message.groupId, 'deleted', message.id);
+ }
});
diff --git a/src/server/api/endpoints/messaging/messages/read.ts b/src/server/api/endpoints/messaging/messages/read.ts
index 50b7f39870..dd3449af15 100644
--- a/src/server/api/endpoints/messaging/messages/read.ts
+++ b/src/server/api/endpoints/messaging/messages/read.ts
@@ -1,13 +1,13 @@
import $ from 'cafy';
import { ID } from '../../../../../misc/cafy-id';
-import read from '../../../common/read-messaging-message';
import define from '../../../define';
import { ApiError } from '../../../error';
import { MessagingMessages } from '../../../../../models';
+import { readUserMessagingMessage, readGroupMessagingMessage } from '../../../common/read-messaging-message';
export const meta = {
desc: {
- 'ja-JP': '指定した自分宛てのメッセージを既読にします。',
+ 'ja-JP': '指定した自分宛てのトークメッセージを既読にします。',
'en-US': 'Mark as read a message of messaging.'
},
@@ -39,12 +39,21 @@ export const meta = {
export default define(meta, async (ps, user) => {
const message = await MessagingMessages.findOne({
id: ps.messageId,
- recipientId: user.id
});
if (message == null) {
throw new ApiError(meta.errors.noSuchMessage);
}
- read(user.id, message.userId, [message.id]);
+ if (message.recipientId) {
+ await readUserMessagingMessage(user.id, message.recipientId, [message.id]).catch(e => {
+ if (e.id === 'e140a4bf-49ce-4fb6-b67c-b78dadf6b52f') throw new ApiError(meta.errors.noSuchMessage);
+ throw e;
+ });
+ } else if (message.groupId) {
+ await readGroupMessagingMessage(user.id, message.groupId, [message.id]).catch(e => {
+ if (e.id === '930a270c-714a-46b2-b776-ad27276dc569') throw new ApiError(meta.errors.noSuchMessage);
+ throw e;
+ });
+ }
});