mirror of
https://github.com/NodeBB/NodeBB.git
synced 2025-10-26 16:46: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-post-queue": "When a new post is queued",
|
||||||
"notificationType-new-post-flag": "When a post is flagged",
|
"notificationType-new-post-flag": "When a post is flagged",
|
||||||
"notificationType-new-user-flag": "When a user 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 posts = require('../posts');
|
||||||
const topics = require('../topics');
|
const topics = require('../topics');
|
||||||
const categories = require('../categories');
|
const categories = require('../categories');
|
||||||
|
const notifications = require('../notifications');
|
||||||
const utils = require('../utils');
|
const utils = require('../utils');
|
||||||
const activitypub = require('.');
|
const activitypub = require('.');
|
||||||
|
|
||||||
|
const socketHelpers = require('../socket.io/helpers');
|
||||||
const helpers = require('./helpers');
|
const helpers = require('./helpers');
|
||||||
|
|
||||||
const inbox = module.exports;
|
const inbox = module.exports;
|
||||||
@@ -88,7 +90,8 @@ inbox.like = async (req) => {
|
|||||||
|
|
||||||
winston.info(`[activitypub/inbox/like] id ${id} via ${actor}`);
|
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) => {
|
inbox.announce = async (req) => {
|
||||||
@@ -112,6 +115,8 @@ inbox.announce = async (req) => {
|
|||||||
|
|
||||||
pid = id;
|
pid = id;
|
||||||
tid = await posts.getPostField(id, 'tid');
|
tid = await posts.getPostField(id, 'tid');
|
||||||
|
|
||||||
|
socketHelpers.sendNotificationToPostOwner(pid, actor, 'announce', 'notifications:activitypub.announce');
|
||||||
} else {
|
} else {
|
||||||
pid = object;
|
pid = object;
|
||||||
pid = await activitypub.resolveId(0, pid); // in case wrong id is passed-in; unlikely, but still.
|
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}`);
|
const followerRemoteCount = await db.sortedSetCard(`followersRemote:${id}`);
|
||||||
await user.setUserField(id, 'followerRemoteCount', followerRemoteCount);
|
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',
|
type: 'Accept',
|
||||||
object: {
|
object: {
|
||||||
type: 'Follow',
|
type: 'Follow',
|
||||||
@@ -280,6 +286,7 @@ inbox.undo = async (req) => {
|
|||||||
await db.sortedSetRemove(`followersRemote:${id}`, actor);
|
await db.sortedSetRemove(`followersRemote:${id}`, actor);
|
||||||
const followerRemoteCount = await db.sortedSetCard(`followerRemote:${id}`);
|
const followerRemoteCount = await db.sortedSetCard(`followerRemote:${id}`);
|
||||||
await user.setUserField(id, 'followerRemoteCount', followerRemoteCount);
|
await user.setUserField(id, 'followerRemoteCount', followerRemoteCount);
|
||||||
|
notifications.rescind(`follow:${id}:uid:${actor}`);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -314,6 +321,7 @@ inbox.undo = async (req) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
await posts.unvote(id, actor);
|
await posts.unvote(id, actor);
|
||||||
|
notifications.rescind(`upvote:post:${id}:uid:${actor}`);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -334,6 +342,8 @@ inbox.undo = async (req) => {
|
|||||||
if (existing.length) {
|
if (existing.length) {
|
||||||
await topics.events.purge(tid, existing);
|
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) {
|
usersAPI.follow = async function (caller, data) {
|
||||||
await user.follow(caller.uid, data.uid);
|
await user.follow(caller.uid, data.uid);
|
||||||
|
await user.onFollow(caller.uid, data.uid);
|
||||||
plugins.hooks.fire('action:user.follow', {
|
plugins.hooks.fire('action:user.follow', {
|
||||||
fromUid: caller.uid,
|
fromUid: caller.uid,
|
||||||
toUid: data.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) {
|
usersAPI.unfollow = async function (caller, data) {
|
||||||
|
|||||||
@@ -403,6 +403,7 @@ Notifications.merge = async function (notifications) {
|
|||||||
'notifications:user-posted-in-public-room',
|
'notifications:user-posted-in-public-room',
|
||||||
'new-register',
|
'new-register',
|
||||||
'post-queue',
|
'post-queue',
|
||||||
|
'notifications:activitypub.announce',
|
||||||
];
|
];
|
||||||
|
|
||||||
notifications = mergeIds.reduce((notifications, mergeId) => {
|
notifications = mergeIds.reduce((notifications, mergeId) => {
|
||||||
@@ -467,7 +468,8 @@ Notifications.merge = async function (notifications) {
|
|||||||
case 'notifications:user-started-following-you':
|
case 'notifications:user-started-following-you':
|
||||||
case 'notifications:user-posted-to':
|
case 'notifications:user-posted-to':
|
||||||
case 'notifications:user-flagged-post-in':
|
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 usernames = _.uniq(set.map(notifObj => notifObj && notifObj.user && notifObj.user.username));
|
||||||
const numUsers = usernames.length;
|
const numUsers = usernames.length;
|
||||||
|
|
||||||
|
|||||||
@@ -76,7 +76,7 @@ SocketHelpers.sendNotificationToPostOwner = async function (pid, fromuid, comman
|
|||||||
if (!pid || !fromuid || !notification) {
|
if (!pid || !fromuid || !notification) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
fromuid = parseInt(fromuid, 10);
|
fromuid = utils.isNumber(fromuid) ? parseInt(fromuid, 10) : fromuid;
|
||||||
const postData = await posts.getPostFields(pid, ['tid', 'uid', 'content']);
|
const postData = await posts.getPostFields(pid, ['tid', 'uid', 'content']);
|
||||||
const [canRead, isIgnoring] = await Promise.all([
|
const [canRead, isIgnoring] = await Promise.all([
|
||||||
privileges.posts.can('topics:read', pid, postData.uid),
|
privileges.posts.can('topics:read', pid, postData.uid),
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
|
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
|
const notifications = require('../notifications');
|
||||||
const plugins = require('../plugins');
|
const plugins = require('../plugins');
|
||||||
const activitypub = require('../activitypub');
|
const activitypub = require('../activitypub');
|
||||||
const db = require('../database');
|
const db = require('../database');
|
||||||
@@ -96,4 +97,23 @@ module.exports = function (User) {
|
|||||||
const setPrefix = isRemote ? 'followingRemote' : 'following';
|
const setPrefix = isRemote ? 'followingRemote' : 'following';
|
||||||
return await db.isSortedSetMember(`${setPrefix}:${uid}`, theirid);
|
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