summaryrefslogtreecommitdiff
path: root/src/models/notification.ts
blob: 097e3e691f18136917967582d592605e6f010b31 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
import * as mongo from 'mongodb';
const deepcopy = require('deepcopy');
import db from '../db/mongodb';
import { IUser, pack as packUser } from './user';
import { pack as packNote } from './note';

const Notification = db.get<INotification>('notifications');
export default Notification;

export interface INotification {
	_id: mongo.ObjectID;
	createdAt: Date;

	/**
	 * 通知の受信者
	 */
	notifiee?: IUser;

	/**
	 * 通知の受信者
	 */
	notifieeId: mongo.ObjectID;

	/**
	 * イニシエータ(initiator)、Origin。通知を行う原因となったユーザー
	 */
	notifier?: IUser;

	/**
	 * イニシエータ(initiator)、Origin。通知を行う原因となったユーザー
	 */
	notifierId: mongo.ObjectID;

	/**
	 * 通知の種類。
	 * follow - フォローされた
	 * mention - 投稿で自分が言及された
	 * reply - (自分または自分がWatchしている)投稿が返信された
	 * renote - (自分または自分がWatchしている)投稿がRenoteされた
	 * quote - (自分または自分がWatchしている)投稿が引用Renoteされた
	 * reaction - (自分または自分がWatchしている)投稿にリアクションされた
	 * poll_vote - (自分または自分がWatchしている)投稿の投票に投票された
	 */
	type: 'follow' | 'mention' | 'reply' | 'renote' | 'quote' | 'reaction' | 'poll_vote';

	/**
	 * 通知が読まれたかどうか
	 */
	isRead: Boolean;
}

/**
 * Notificationを物理削除します
 */
export async function deleteNotification(notification: string | mongo.ObjectID | INotification) {
	let n: INotification;

	// Populate
	if (mongo.ObjectID.prototype.isPrototypeOf(notification)) {
		n = await Notification.findOne({
			_id: notification
		});
	} else if (typeof notification === 'string') {
		n = await Notification.findOne({
			_id: new mongo.ObjectID(notification)
		});
	} else {
		n = notification as INotification;
	}

	if (n == null) return;

	// このNotificationを削除
	await Notification.remove({
		_id: n._id
	});
}

/**
 * Pack a notification for API response
 */
export const pack = (notification: any) => new Promise<any>(async (resolve, reject) => {
	let _notification: any;

	// Populate the notification if 'notification' is ID
	if (mongo.ObjectID.prototype.isPrototypeOf(notification)) {
		_notification = await Notification.findOne({
			_id: notification
		});
	} else if (typeof notification === 'string') {
		_notification = await Notification.findOne({
			_id: new mongo.ObjectID(notification)
		});
	} else {
		_notification = deepcopy(notification);
	}

	// Rename _id to id
	_notification.id = _notification._id;
	delete _notification._id;

	// Rename notifierId to userId
	_notification.userId = _notification.notifierId;
	delete _notification.notifierId;

	const me = _notification.notifieeId;
	delete _notification.notifieeId;

	// Populate notifier
	_notification.user = await packUser(_notification.userId, me);

	switch (_notification.type) {
		case 'follow':
		case 'receiveFollowRequest':
			// nope
			break;
		case 'mention':
		case 'reply':
		case 'renote':
		case 'quote':
		case 'reaction':
		case 'poll_vote':
			// Populate note
			_notification.note = await packNote(_notification.noteId, me);
			break;
		default:
			console.error(`Unknown type: ${_notification.type}`);
			break;
	}

	resolve(_notification);
});