mirror of
https://github.com/NodeBB/NodeBB.git
synced 2025-10-26 08:36:12 +01:00
feat: integrate notifications for remote likes, follows, and announces.
Rescind notification as necessary.
This commit is contained in:
@@ -106,5 +106,10 @@
|
||||
"notificationType-post-queue": "When a new post is queued",
|
||||
"notificationType-new-post-flag": "When a post is flagged",
|
||||
"notificationType-new-user-flag": "When a user is flagged",
|
||||
"notificationType-new-reward": "When you earn a new reward"
|
||||
"notificationType-new-reward": "When you earn a new reward",
|
||||
|
||||
"activitypub.announce": "<strong>%1</strong> shared your post in <strong>%2</strong> to their followers.",
|
||||
"activitypub.announce-dual": "<strong>%1</strong> and <strong>%2</strong> shared your post in <strong>%3</strong> to their followers.",
|
||||
"activitypub.announce-triple": "<strong>%1</strong>, <strong>%2</strong> and <strong>%3</strong> shared your post in <strong>%4</strong> to their followers.",
|
||||
"activitypub.announce-multiple": "<strong>%1</strong>, <strong>%2</strong> and %3 others shared your post in <strong>%4</strong> to their followers."
|
||||
}
|
||||
|
||||
@@ -9,9 +9,11 @@ const user = require('../user');
|
||||
const posts = require('../posts');
|
||||
const topics = require('../topics');
|
||||
const categories = require('../categories');
|
||||
const notifications = require('../notifications');
|
||||
const utils = require('../utils');
|
||||
const activitypub = require('.');
|
||||
|
||||
const socketHelpers = require('../socket.io/helpers');
|
||||
const helpers = require('./helpers');
|
||||
|
||||
const inbox = module.exports;
|
||||
@@ -88,7 +90,8 @@ inbox.like = async (req) => {
|
||||
|
||||
winston.info(`[activitypub/inbox/like] id ${id} via ${actor}`);
|
||||
|
||||
await posts.upvote(id, actor);
|
||||
const result = await posts.upvote(id, actor);
|
||||
socketHelpers.upvote(result, 'notifications:upvoted-your-post-in');
|
||||
};
|
||||
|
||||
inbox.announce = async (req) => {
|
||||
@@ -112,6 +115,8 @@ inbox.announce = async (req) => {
|
||||
|
||||
pid = id;
|
||||
tid = await posts.getPostField(id, 'tid');
|
||||
|
||||
socketHelpers.sendNotificationToPostOwner(pid, actor, 'announce', 'notifications:activitypub.announce');
|
||||
} else {
|
||||
pid = object;
|
||||
pid = await activitypub.resolveId(0, pid); // in case wrong id is passed-in; unlikely, but still.
|
||||
@@ -180,7 +185,8 @@ inbox.follow = async (req) => {
|
||||
const followerRemoteCount = await db.sortedSetCard(`followersRemote:${id}`);
|
||||
await user.setUserField(id, 'followerRemoteCount', followerRemoteCount);
|
||||
|
||||
await activitypub.send('uid', id, req.body.actor, {
|
||||
user.onFollow(req.body.actor, id);
|
||||
activitypub.send('uid', id, req.body.actor, {
|
||||
type: 'Accept',
|
||||
object: {
|
||||
type: 'Follow',
|
||||
@@ -280,6 +286,7 @@ inbox.undo = async (req) => {
|
||||
await db.sortedSetRemove(`followersRemote:${id}`, actor);
|
||||
const followerRemoteCount = await db.sortedSetCard(`followerRemote:${id}`);
|
||||
await user.setUserField(id, 'followerRemoteCount', followerRemoteCount);
|
||||
notifications.rescind(`follow:${id}:uid:${actor}`);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -314,6 +321,7 @@ inbox.undo = async (req) => {
|
||||
}
|
||||
|
||||
await posts.unvote(id, actor);
|
||||
notifications.rescind(`upvote:post:${id}:uid:${actor}`);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -334,6 +342,8 @@ inbox.undo = async (req) => {
|
||||
if (existing.length) {
|
||||
await topics.events.purge(tid, existing);
|
||||
}
|
||||
|
||||
notifications.rescind(`announce:post:${id}:uid:${actor}`);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -172,27 +172,11 @@ usersAPI.changePassword = async function (caller, data) {
|
||||
|
||||
usersAPI.follow = async function (caller, data) {
|
||||
await user.follow(caller.uid, data.uid);
|
||||
await user.onFollow(caller.uid, data.uid);
|
||||
plugins.hooks.fire('action:user.follow', {
|
||||
fromUid: caller.uid,
|
||||
toUid: data.uid,
|
||||
});
|
||||
|
||||
const userData = await user.getUserFields(caller.uid, ['username', 'userslug']);
|
||||
const { displayname } = userData;
|
||||
|
||||
const notifObj = await notifications.create({
|
||||
type: 'follow',
|
||||
bodyShort: `[[notifications:user-started-following-you, ${displayname}]]`,
|
||||
nid: `follow:${data.uid}:uid:${caller.uid}`,
|
||||
from: caller.uid,
|
||||
path: `/uid/${data.uid}/followers`,
|
||||
mergeId: 'notifications:user-started-following-you',
|
||||
});
|
||||
if (!notifObj) {
|
||||
return;
|
||||
}
|
||||
notifObj.user = userData;
|
||||
await notifications.push(notifObj, [data.uid]);
|
||||
};
|
||||
|
||||
usersAPI.unfollow = async function (caller, data) {
|
||||
|
||||
@@ -403,6 +403,7 @@ Notifications.merge = async function (notifications) {
|
||||
'notifications:user-posted-in-public-room',
|
||||
'new-register',
|
||||
'post-queue',
|
||||
'notifications:activitypub.announce',
|
||||
];
|
||||
|
||||
notifications = mergeIds.reduce((notifications, mergeId) => {
|
||||
@@ -467,7 +468,8 @@ Notifications.merge = async function (notifications) {
|
||||
case 'notifications:user-started-following-you':
|
||||
case 'notifications:user-posted-to':
|
||||
case 'notifications:user-flagged-post-in':
|
||||
case 'notifications:user-flagged-user': {
|
||||
case 'notifications:user-flagged-user':
|
||||
case 'notifications:activitypub.announce': {
|
||||
const usernames = _.uniq(set.map(notifObj => notifObj && notifObj.user && notifObj.user.username));
|
||||
const numUsers = usernames.length;
|
||||
|
||||
|
||||
@@ -76,7 +76,7 @@ SocketHelpers.sendNotificationToPostOwner = async function (pid, fromuid, comman
|
||||
if (!pid || !fromuid || !notification) {
|
||||
return;
|
||||
}
|
||||
fromuid = parseInt(fromuid, 10);
|
||||
fromuid = utils.isNumber(fromuid) ? parseInt(fromuid, 10) : fromuid;
|
||||
const postData = await posts.getPostFields(pid, ['tid', 'uid', 'content']);
|
||||
const [canRead, isIgnoring] = await Promise.all([
|
||||
privileges.posts.can('topics:read', pid, postData.uid),
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
|
||||
'use strict';
|
||||
|
||||
const notifications = require('../notifications');
|
||||
const plugins = require('../plugins');
|
||||
const activitypub = require('../activitypub');
|
||||
const db = require('../database');
|
||||
@@ -96,4 +97,23 @@ module.exports = function (User) {
|
||||
const setPrefix = isRemote ? 'followingRemote' : 'following';
|
||||
return await db.isSortedSetMember(`${setPrefix}:${uid}`, theirid);
|
||||
};
|
||||
|
||||
User.onFollow = async function (uid, targetUid) {
|
||||
const userData = await User.getUserFields(uid, ['username', 'userslug']);
|
||||
const { displayname } = userData;
|
||||
|
||||
const notifObj = await notifications.create({
|
||||
type: 'follow',
|
||||
bodyShort: `[[notifications:user-started-following-you, ${displayname}]]`,
|
||||
nid: `follow:${targetUid}:uid:${uid}`,
|
||||
from: uid,
|
||||
path: `/uid/${targetUid}/followers`,
|
||||
mergeId: 'notifications:user-started-following-you',
|
||||
});
|
||||
if (!notifObj) {
|
||||
return;
|
||||
}
|
||||
notifObj.user = userData;
|
||||
await notifications.push(notifObj, [targetUid]);
|
||||
};
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user