nodebb-plugin-discord-onekite 1.1.10 → 1.1.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -4
- package/library.js +45 -16
- package/package.json +1 -1
- package/static/lib/admin.js +0 -1
- package/templates/admin/plugins/discord-onekite.tpl +6 -9
package/README.md
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
# nodebb-plugin-discord-onekite v1.1.
|
|
1
|
+
# nodebb-plugin-discord-onekite v1.1.4.3
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
Everything else unchanged from v1.1.6.
|
|
3
|
+
Fix: syntax error in library.js (newline in join string).
|
|
4
|
+
Keeps v1.1.4-based changes: single clickable link line + excerpt below.
|
package/library.js
CHANGED
|
@@ -8,6 +8,7 @@ const middleware = require.main.require('./src/middleware');
|
|
|
8
8
|
|
|
9
9
|
const topics = require.main.require('./src/topics');
|
|
10
10
|
const posts = require.main.require('./src/posts');
|
|
11
|
+
const user = require.main.require('./src/user');
|
|
11
12
|
|
|
12
13
|
const controllers = require('./lib/controllers');
|
|
13
14
|
|
|
@@ -37,6 +38,15 @@ function ensureAbsoluteUrl(baseUrl, maybeUrl) {
|
|
|
37
38
|
return s;
|
|
38
39
|
}
|
|
39
40
|
|
|
41
|
+
function isValidHttpUrl(s) {
|
|
42
|
+
try {
|
|
43
|
+
const u = new URL(s);
|
|
44
|
+
return u.protocol === 'http:' || u.protocol === 'https:';
|
|
45
|
+
} catch {
|
|
46
|
+
return false;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
40
50
|
function stripHtml(html) {
|
|
41
51
|
if (!html) return '';
|
|
42
52
|
return String(html)
|
|
@@ -89,15 +99,15 @@ async function postToDiscord(webhookUrl, payload) {
|
|
|
89
99
|
}
|
|
90
100
|
}
|
|
91
101
|
|
|
92
|
-
async function sendDiscord(webhookUrl, payload) {
|
|
102
|
+
async function sendDiscord(webhookUrl, payload, fallbackContent) {
|
|
93
103
|
if (!webhookUrl) return;
|
|
104
|
+
|
|
94
105
|
try {
|
|
95
106
|
await postToDiscord(webhookUrl, payload);
|
|
96
107
|
} catch (e) {
|
|
97
|
-
|
|
98
|
-
if (e && e.statusCode === 400 && payload && payload.content) {
|
|
108
|
+
if (e && e.statusCode === 400 && fallbackContent) {
|
|
99
109
|
try {
|
|
100
|
-
await postToDiscord(webhookUrl, { content:
|
|
110
|
+
await postToDiscord(webhookUrl, { content: fallbackContent });
|
|
101
111
|
return;
|
|
102
112
|
} catch (e2) {
|
|
103
113
|
console.error(e2);
|
|
@@ -121,25 +131,39 @@ async function getPostExcerpt(pid) {
|
|
|
121
131
|
async function buildPayload({ tid, pid, isReply }) {
|
|
122
132
|
const baseUrl = normalizeBaseUrl(meta.config.url);
|
|
123
133
|
|
|
124
|
-
const topicData = await topics.getTopicFields(tid, ['tid', 'cid', 'title', 'slug', 'mainPid']);
|
|
134
|
+
const topicData = await topics.getTopicFields(tid, ['tid', 'uid', 'cid', 'title', 'slug', 'mainPid']);
|
|
125
135
|
if (!topicData) return null;
|
|
126
136
|
|
|
137
|
+
// Always build the forum link like the example: https://www.onekite.com/topic/<tid or slug>
|
|
127
138
|
const topicUrl = ensureAbsoluteUrl(baseUrl, `/topic/${topicData.slug || topicData.tid}`);
|
|
128
|
-
const targetUrl = (isReply && pid) ? `${topicUrl}/${pid}` : topicUrl;
|
|
129
139
|
|
|
140
|
+
// For replies, link directly to the post if possible
|
|
141
|
+
const postUrl = (isReply && pid) ? `${topicUrl}/${pid}` : topicUrl;
|
|
142
|
+
|
|
143
|
+
const u = await user.getUserFields(topicData.uid, ['username']);
|
|
130
144
|
const title = (topicData.title || (isReply ? 'Nouvelle réponse' : 'Nouveau sujet')).toString().slice(0, 256);
|
|
145
|
+
const authorName = (u && u.username ? String(u.username) : 'Utilisateur').slice(0, 256);
|
|
146
|
+
|
|
131
147
|
const excerpt = await getPostExcerpt(isReply ? pid : topicData.mainPid);
|
|
148
|
+
const description = truncate(excerpt || (isReply ? `Réponse de ${authorName}` : `Sujet créé par ${authorName}`), 500);
|
|
149
|
+
|
|
150
|
+
// Minimal embed but with URL so the title is clickable
|
|
151
|
+
const embed = {
|
|
152
|
+
title,
|
|
153
|
+
description,
|
|
154
|
+
};
|
|
155
|
+
if (isValidHttpUrl(postUrl)) embed.url = postUrl;
|
|
132
156
|
|
|
133
|
-
//
|
|
157
|
+
// Message format:
|
|
158
|
+
// 1) A single clickable link line: "🆕 Nouveau sujet : [Titre](URL)" (or reply variant)
|
|
159
|
+
// 2) Excerpt below
|
|
134
160
|
const linkLine = isReply
|
|
135
|
-
? `🗨️ Nouvelle réponse : [${title}](${
|
|
161
|
+
? `🗨️ Nouvelle réponse : [${title}](${postUrl})`
|
|
136
162
|
: `🆕 Nouveau sujet : [${title}](${topicUrl})`;
|
|
137
163
|
|
|
138
|
-
const content = [linkLine,
|
|
139
|
-
|
|
140
|
-
const embed = { title, description: excerpt || '' , url: targetUrl };
|
|
164
|
+
const content = [linkLine, description].filter(Boolean).join('\n');
|
|
141
165
|
|
|
142
|
-
return { topicData,
|
|
166
|
+
return { topicData, embed, content };
|
|
143
167
|
}
|
|
144
168
|
|
|
145
169
|
function extractTidPid(data) {
|
|
@@ -158,8 +182,8 @@ Plugin.init = async ({ router }) => {
|
|
|
158
182
|
controllers.renderAdminPage
|
|
159
183
|
);
|
|
160
184
|
|
|
161
|
-
// AJAX save endpoint (used by admin.js
|
|
162
|
-
router.post('/admin/plugins/discord-onekite/save',
|
|
185
|
+
// AJAX save endpoint for ACP (used by admin.js)
|
|
186
|
+
router.post('/api/admin/plugins/discord-onekite/save',
|
|
163
187
|
middleware.admin.checkPrivileges,
|
|
164
188
|
async (req, res) => {
|
|
165
189
|
try {
|
|
@@ -196,9 +220,11 @@ Plugin.onTopicPost = async (data) => {
|
|
|
196
220
|
|
|
197
221
|
const built = await buildPayload({ tid, isReply: false });
|
|
198
222
|
if (!built) return;
|
|
223
|
+
|
|
199
224
|
if (!cidAllowed(built.topicData.cid, settings.cids)) return;
|
|
200
225
|
|
|
201
|
-
|
|
226
|
+
// Send content + embed (content ensures clickable link always)
|
|
227
|
+
await sendDiscord(settings.webhookUrl, { content: built.content, embeds: [built.embed] }, built.content);
|
|
202
228
|
};
|
|
203
229
|
|
|
204
230
|
Plugin.onTopicReply = async (data) => {
|
|
@@ -211,9 +237,12 @@ Plugin.onTopicReply = async (data) => {
|
|
|
211
237
|
|
|
212
238
|
const built = await buildPayload({ tid, pid, isReply: true });
|
|
213
239
|
if (!built) return;
|
|
240
|
+
|
|
241
|
+
if (built.topicData?.mainPid && String(built.topicData.mainPid) === String(pid)) return;
|
|
242
|
+
|
|
214
243
|
if (!cidAllowed(built.topicData.cid, settings.cids)) return;
|
|
215
244
|
|
|
216
|
-
await sendDiscord(settings.webhookUrl, { content: built.content, embeds: [built.embed] });
|
|
245
|
+
await sendDiscord(settings.webhookUrl, { content: built.content, embeds: [built.embed] }, built.content);
|
|
217
246
|
};
|
|
218
247
|
|
|
219
248
|
module.exports = Plugin;
|
package/package.json
CHANGED
package/static/lib/admin.js
CHANGED
|
@@ -21,7 +21,6 @@ define('admin/plugins/discord-onekite', ['api'], function (api) {
|
|
|
21
21
|
cids: getMultiSelectValues('#cids'),
|
|
22
22
|
};
|
|
23
23
|
|
|
24
|
-
// api.post prefixes /api automatically, so server route must be /admin/...
|
|
25
24
|
api.post('/admin/plugins/discord-onekite/save', payload).then(function () {
|
|
26
25
|
if (window.app && typeof app.alertSuccess === 'function') {
|
|
27
26
|
app.alertSuccess('Paramètres enregistrés !');
|
|
@@ -1,13 +1,8 @@
|
|
|
1
1
|
<div class="acp-page-container">
|
|
2
|
-
<
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
</div>
|
|
7
|
-
<button id="save" class="btn btn-primary">
|
|
8
|
-
<i class="fa fa-save"></i> Enregistrer
|
|
9
|
-
</button>
|
|
10
|
-
</div>
|
|
2
|
+
<h4>Discord Onekite</h4>
|
|
3
|
+
<p class="text-muted">
|
|
4
|
+
Notifications Discord via webhook.
|
|
5
|
+
</p>
|
|
11
6
|
|
|
12
7
|
<form role="form" class="discord-onekite-settings">
|
|
13
8
|
<div class="mb-3">
|
|
@@ -33,5 +28,7 @@
|
|
|
33
28
|
Si aucune catégorie n’est sélectionnée : <strong>toutes les catégories</strong> seront notifiées.
|
|
34
29
|
</p>
|
|
35
30
|
</div>
|
|
31
|
+
|
|
32
|
+
<!-- IMPORT admin/partials/save_button.tpl -->
|
|
36
33
|
</form>
|
|
37
34
|
</div>
|