feat: integrate notifications for remote likes, follows, and announces.

Rescind notification as necessary.
This commit is contained in:
Julian Lam
2024-02-29 16:09:57 -05:00
parent 0f99ae1f45
commit c707a32aa9
6 changed files with 43 additions and 22 deletions

View File

@@ -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."
}

View File

@@ -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}`);
}
}
};

View File

@@ -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) {

View File

@@ -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;

View File

@@ -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),

View File

@@ -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]);
};
};