diff --git a/public/language/en-GB/admin/settings/activitypub.json b/public/language/en-GB/admin/settings/activitypub.json
index 1b00672e0f..5ab4fa43e8 100644
--- a/public/language/en-GB/admin/settings/activitypub.json
+++ b/public/language/en-GB/admin/settings/activitypub.json
@@ -22,8 +22,9 @@
"rules-intro": "Content discovered via ActivityPub can be automatically categorized based on certain rules (e.g. hashtag)",
"rules.modal.title": "How it works",
"rules.modal.instructions": "Any incoming content is checked against these categorization rules, and matching content is automatically moved into the category of choice.
N.B. Content that is already categorized (i.e. in a remote category) will not pass through these rules.",
- "rules.modal.values-multiple": "To match multiple values, separate entries with a comma (e.g. one,two,three)",
"rules.add": "Add New Rule",
+ "rules.help-hashtag": "Topics containing this case-insensitive hashtag will match. Do not enter the # symbol",
+ "rules.help-user": "Topics created by the entered user will match. Enter a handle or full ID (e.g. bob@example.org or https://example.org/users/bob.",
"rules.type": "Type",
"rules.value": "Value",
"rules.cid": "Category",
diff --git a/public/src/admin/settings/activitypub.js b/public/src/admin/settings/activitypub.js
index 8c79d95b4b..0da00293de 100644
--- a/public/src/admin/settings/activitypub.js
+++ b/public/src/admin/settings/activitypub.js
@@ -6,7 +6,8 @@ define('admin/settings/activitypub', [
'categorySelector',
'api',
'alerts',
-], function (Benchpress, bootbox, categorySelector, api, alerts) {
+ 'translator',
+], function (Benchpress, bootbox, categorySelector, api, alerts, translator) {
const Module = {};
Module.init = function () {
@@ -95,6 +96,21 @@ define('admin/settings/activitypub', [
modal.find('input').focus();
});
+
+ // help text
+ const updateHelp = async (key, el) => {
+ const text = await translator.translate(`[[admin/settings/activitypub:rules.help-${key}]]`);
+ el.innerHTML = text;
+ };
+ const helpTextEl = modal.get(0).querySelector('#help-text');
+ const typeEl = modal.get(0).querySelector('#type');
+ updateHelp(modal.get(0).querySelector('#type option').value, helpTextEl);
+ if (typeEl && helpTextEl) {
+ typeEl.addEventListener('change', function () {
+ updateHelp(this.value, helpTextEl);
+ });
+ }
+
// category switcher
categorySelector.init(modal.find('[component="category-selector"]'), {
onSelect: function (selectedCategory) {
diff --git a/src/activitypub/notes.js b/src/activitypub/notes.js
index 3a00323859..cc5e7fe393 100644
--- a/src/activitypub/notes.js
+++ b/src/activitypub/notes.js
@@ -417,6 +417,13 @@ async function assignCategory(post) {
}
break;
}
+
+ case 'user': {
+ if (post.uid === value) {
+ activitypub.helpers.log(`[activitypub] - Rule match: user ${value}; cid: ${target}`);
+ return target;
+ }
+ }
}
}
diff --git a/src/activitypub/rules.js b/src/activitypub/rules.js
index 3a9a560552..9b3a002aab 100644
--- a/src/activitypub/rules.js
+++ b/src/activitypub/rules.js
@@ -3,6 +3,8 @@
const db = require('../database');
const utils = require('../utils');
+const activitypub = require('.');
+
const Rules = module.exports;
Rules.list = async () => {
@@ -19,6 +21,15 @@ Rules.list = async () => {
Rules.add = async (type, value, cid) => {
const uuid = utils.generateUUID();
+ // normalize user rule values into a uid
+ if (type === 'user' && value.indexOf('@') !== -1) {
+ const response = await activitypub.actors.assert(value);
+ if (!response) {
+ throw new Error('[[error:no-user]]');
+ }
+ value = await db.getObjectField('handle:uid', String(value).toLowerCase());
+ }
+
await Promise.all([
db.setObject(`rid:${uuid}`, { type, value, cid }),
db.sortedSetAdd('categorization:rid', Date.now(), uuid),
diff --git a/src/views/admin/partials/activitypub/rules.tpl b/src/views/admin/partials/activitypub/rules.tpl
index e321a86744..33273942b5 100644
--- a/src/views/admin/partials/activitypub/rules.tpl
+++ b/src/views/admin/partials/activitypub/rules.tpl
@@ -8,13 +8,14 @@
[[admin/settings/activitypub:rules.modal.values-multiple]]
+