nodebb-plugin-onekite-discord 1.0.12 → 1.0.14

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.
Files changed (3) hide show
  1. package/library.js +35 -57
  2. package/package.json +1 -1
  3. package/plugin.json +1 -1
package/library.js CHANGED
@@ -2,37 +2,49 @@
2
2
 
3
3
 
4
4
 
5
+
6
+
5
7
  /**
6
- * Extract links from text in several formats NodeBB may produce.
7
- * Returns array of { text, url }.
8
- *
9
- * Supported inputs:
10
- * - Markdown: [text](url)
11
- * - HTML: <a href="url">text</a>
12
- * - NodeBB rendered: text(url) or text (url)
13
- * - Bare URLs: https://... or http://... or www.example.com
14
- *
15
- * Note: We'll output masked links in embed fields, where Discord supports them.
8
+ * Flatten any link-like markup to plain URLs so Discord auto-linkifies them.
9
+ * Supported:
10
+ * - [text](url)
11
+ * - <a href="url">text</a>
12
+ * - text(url) / text (url)
13
+ * - bare URLs and www.*
16
14
  */
17
- function extractDiscordLinks(str) {
18
- if (!str || typeof str !== 'string') return [];
19
-
20
- const links = [];
21
- const seen = new Set();
15
+ function flattenLinksToUrls(str) {
16
+ if (!str || typeof str !== 'string') return str;
22
17
 
23
18
  const normalizeUrl = (u) => {
24
- if (!u) return null;
19
+ if (!u) return u;
25
20
  let url = String(u).trim();
26
21
  url = url.replace(/^<(.+)>$/, '$1');
27
22
  url = url.replace(/^https:\//i, 'https://');
28
23
  url = url.replace(/^http:\//i, 'http://');
29
24
  if (/^www\./i.test(url)) url = 'https://' + url;
30
- // Very small sanity check
31
- if (!/^https?:\/\//i.test(url)) return null;
32
25
  return url;
33
- fields: linkFields,
34
26
  };
35
27
 
28
+ // HTML links -> URL
29
+ str = str.replace(/<a\s+[^>]*href=["']([^"']+)["'][^>]*>.*?<\/a>/gi, (_m, href) => {
30
+ return normalizeUrl(href);
31
+ });
32
+
33
+ // Markdown [text](url) -> URL
34
+ str = str.replace(/\[([^\]]+)\]\(([^)]+)\)/g, (_m, _text, url) => {
35
+ return normalizeUrl(url);
36
+ });
37
+
38
+ // text(url) or text (url) -> URL
39
+ str = str.replace(/([^\n\r()]{1,200}?)\s*\((https?:\/\/[^)\s]+|www\.[^)\\s]+)\)/g, (_m, _text, url) => {
40
+ return normalizeUrl(url);
41
+ });
42
+
43
+ return str;
44
+ }
45
+
46
+ ;
47
+
36
48
  const push = (text, url) => {
37
49
  const u = normalizeUrl(url);
38
50
  if (!u) return;
@@ -73,46 +85,12 @@ function extractDiscordLinks(str) {
73
85
  return links;
74
86
  }
75
87
 
76
- /**
77
- * Remove/flatten link markup from text for embed.description readability.
78
- * - [text](url) -> text
79
- * - <a href="url">text</a> -> text
80
- * - text(url) -> text
81
- * - leaves bare URLs as-is (optional), but we can also remove them if desired.
82
- */
83
- function stripLinkMarkup(str) {
84
- if (!str || typeof str !== 'string') return str;
85
-
86
- // HTML links -> text
87
- str = str.replace(/<a\s+[^>]*href=["'][^"']+["'][^>]*>(.*?)<\/a>/gi, (_m, text) => text);
88
-
89
- // Markdown masked -> text
90
- str = str.replace(/\[([^\]]+)\]\(([^)]+)\)/g, (_m, text) => text);
91
-
92
- // NodeBB rendered -> text
93
- str = str.replace(/([^\n\r()]{1,200}?)\s*\((https?:\/\/[^)\s]+|www\.[^)\s]+)\)/g, (_m, text) => String(text).trim());
88
+ ?)\s*\((https?:\/\/[^)\s]+|www\.[^)\s]+)\)/g, (_m, text) => String(text).trim());
94
89
 
95
90
  return str;
96
91
  }
97
92
 
98
- /**
99
- * Normalize links for Discord embeds.
100
- * Discord does NOT support masked links in embed descriptions.
101
- * NodeBB may already render links as: texte(url)
102
- * We always output a plain URL so Discord auto-linkifies it.
103
- */
104
- function formatDiscordLinks(str) {
105
- if (!str || typeof str !== 'string') return str;
106
-
107
- const normalizeUrl = (u) => {
108
- if (!u) return u;
109
- let url = String(u).trim();
110
- url = url.replace(/^<(.+)>$/, '$1');
111
- url = url.replace(/^https:\//i, 'https://');
112
- url = url.replace(/^http:\//i, 'http://');
113
- if (/^www\./i.test(url)) url = 'https://' + url;
114
- return url;
115
- };
93
+ ;
116
94
 
117
95
  // HTML <a href="...">...</a> -> URL
118
96
  str = str.replace(/<a\s+[^>]*href=["']([^"']+)["'][^>]*>.*?<\/a>/gi, (_m, href) => {
@@ -353,7 +331,7 @@ for (let i = 0; i < extractedLinks.length && linkFields.length < maxFields; i +=
353
331
  const embedTitle = `${replyIcon}${safeTitle} – ${username}`.slice(0, 256);
354
332
 
355
333
  // Embed title becomes clickable via embed.url
356
- return { topicData, content: '', embed: { title: embedTitle, url: targetUrl, description: stripLinkMarkup(excerpt || '') } };
334
+ return { topicData, content: '', embed: { title: embedTitle, url: targetUrl, description: flattenLinksToUrls(excerpt || ''), fields: linkFields } };
357
335
  }
358
336
 
359
337
  function extractTidPid(data) {
@@ -416,4 +394,4 @@ Plugin.onTopicReply = async (data) => {
416
394
  await sendDiscord(settings.webhookUrl, { content: built.content, embeds: [built.embed] });
417
395
  };
418
396
 
419
- module.exports = Plugin;
397
+ module.exports = Plugin;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nodebb-plugin-onekite-discord",
3
- "version": "1.0.12",
3
+ "version": "1.0.14",
4
4
  "description": "Discord webhook notifier for Onekite (NodeBB v4.x only)",
5
5
  "main": "library.js",
6
6
  "license": "MIT",
package/plugin.json CHANGED
@@ -31,5 +31,5 @@
31
31
  "acpScripts": [
32
32
  "public/admin.js"
33
33
  ],
34
- "version": "1.0.12"
34
+ "version": "1.0.14"
35
35
  }