UNPKG

4.67 kBJavaScriptView Raw
1'use strict';
2
3const async = require('async');
4
5const nconf = require.main.require('nconf');
6const db = require.main.require('./src/database');
7const meta = require.main.require('./src/meta');
8const emailer = require.main.require('./src/emailer');
9const notifications = require.main.require('./src/notifications');
10const user = require.main.require('./src/user');
11
12const categoryNotifications = module.exports;
13
14categoryNotifications.isSubscribed = async function (uid, cid) {
15 return await db.isSortedSetMember(`cid:${cid}:subscribed:uids`, uid);
16};
17
18categoryNotifications.subscribe = async function (uid, cid) {
19 await db.sortedSetAdd(`cid:${cid}:subscribed:uids`, Date.now(), uid);
20};
21
22categoryNotifications.unsubscribe = async function (uid, cid) {
23 await db.sortedSetRemove(`cid:${cid}:subscribed:uids`, uid);
24};
25
26categoryNotifications.onUserDelete = async function (data) {
27 const cids = await db.getSortedSetRange('categories:cid', 0, -1);
28 await db.sortedSetsRemove(
29 cids.map(cid => `cid:${cid}:subscribed:uids`),
30 data.uid
31 );
32};
33
34async function getSubscribers(cid, exceptUid) {
35 const uids = await db.getSortedSetRange(`cid:${cid}:subscribed:uids`, 0, -1);
36 return uids.filter(uid => parseInt(uid, 10) !== parseInt(exceptUid, 10));
37}
38
39categoryNotifications.onTopicPost = async function (topic) {
40 const settings = await meta.settings.get('category-notifications');
41 settings.type = settings.type || 'email';
42
43 if (settings.type === 'notification') {
44 await sendTopicNotification(topic);
45 } else if (settings.type === 'email') {
46 await sendTopicEmail(topic);
47 } else if (settings.type === 'both') {
48 await Promise.all([
49 sendTopicEmail(topic),
50 sendTopicNotification(topic),
51 ]);
52 }
53};
54
55categoryNotifications.onTopicReply = async function (post) {
56 const settings = await meta.settings.get('category-notifications');
57 settings.type = settings.type || 'email';
58
59 if (settings.type === 'notification') {
60 await sendPostNotification(post);
61 } else if (settings.type === 'email') {
62 await sendPostEmail(post);
63 } else if (settings.type === 'both') {
64 await Promise.all([
65 sendPostEmail(post),
66 sendPostNotification(post),
67 ]);
68 }
69};
70
71async function sendTopicNotification(topic) {
72 const uids = await getSubscribers(topic.cid, topic.user.uid);
73 if (!uids.length) {
74 return;
75 }
76
77 const notification = await notifications.create({
78 bodyShort: `[[notifications:user_posted_topic, ${topic.user.username}, ${topic.title}]]`,
79 bodyLong: topic.mainPost.content,
80 pid: topic.mainPost.pid,
81 path: `/post/${topic.mainPost.pid}`,
82 nid: `tid:${topic.tid}:uid:${topic.uid}`,
83 tid: topic.tid,
84 from: topic.uid,
85 });
86 notifications.push(notification, uids);
87}
88
89async function sendTopicEmail(topic) {
90 let uids = await getSubscribers(topic.cid, topic.user.uid);
91 uids = await user.blocks.filterUids(topic.user.uid, uids);
92 if (!uids.length) {
93 return;
94 }
95
96 const tpl = 'categoryNotifications_topic';
97 const params = {
98 subject: `[[categorynotifications:new-topic-in, ${topic.category.name}]]`,
99 site_title: meta.config.title || 'NodeBB',
100 url: nconf.get('url'),
101 title: topic.title,
102 topicSlug: topic.slug,
103 category: {
104 name: topic.category.name,
105 slug: topic.category.slug,
106 },
107 content: topic.mainPost.content,
108 user: {
109 slug: topic.user.userslug,
110 name: topic.user.username,
111 picture: topic.user.picture,
112 },
113 };
114
115 await async.eachLimit(uids, 50, async (uid) => {
116 await emailer.send(tpl, uid, params);
117 });
118}
119
120async function sendPostNotification(post) {
121 const uids = await getSubscribers(post.topic.cid, post.user.uid);
122 if (!uids.length) {
123 return;
124 }
125
126 const notification = await notifications.create({
127 bodyShort: `[[notifications:user_posted_to, ${post.user.username}, ${post.topic.title}]]`,
128 bodyLong: post.content,
129 pid: post.pid,
130 path: `/post/${post.pid}`,
131 nid: `tid:${post.topic.tid}:pid:${post.pid}:uid:${post.uid}`,
132 tid: post.topic.tid,
133 from: post.uid,
134 });
135 notifications.push(notification, uids);
136}
137
138async function sendPostEmail(post) {
139 let uids = await getSubscribers(post.topic.cid, post.user.uid);
140 uids = await user.blocks.filterUids(post.user.uid, uids);
141 if (!uids.length) {
142 return;
143 }
144
145 const tpl = 'categoryNotifications_post';
146 const params = {
147 subject: `[[categorynotifications:new-reply-in, ${post.topic.title}]]`,
148 site_title: meta.config.title || 'NodeBB',
149 url: nconf.get('url'),
150 title: post.topic.title,
151 topicSlug: post.topic.slug,
152 content: post.content,
153 user: {
154 slug: post.user.userslug,
155 name: post.user.username,
156 picture: post.user.picture,
157 },
158 pid: post.pid,
159 };
160
161 await async.eachLimit(uids, 50, async (uid) => {
162 await emailer.send(tpl, uid, params);
163 });
164}