nodebb-plugin-onekite-calendar 1.0.15 → 1.0.20

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/lib/api.js CHANGED
@@ -12,6 +12,51 @@ const logger = require.main.require('./src/logger');
12
12
 
13
13
  const dbLayer = require('./db');
14
14
 
15
+ // Resolve group identifiers from ACP.
16
+ // Admins may enter a group *name* ("Test") or a *slug* ("onekite-ffvl-2026").
17
+ // Depending on NodeBB version and group type (system/custom), some core methods
18
+ // accept one or the other. We try both to be tolerant.
19
+ async function getMembersByGroupIdentifier(groupIdentifier) {
20
+ const id = String(groupIdentifier || '').trim();
21
+ if (!id) return [];
22
+
23
+ // First try direct.
24
+ let members = [];
25
+ try {
26
+ members = await groups.getMembers(id, 0, -1);
27
+ } catch (e) {
28
+ members = [];
29
+ }
30
+ if (Array.isArray(members) && members.length) return members;
31
+
32
+ // Then try slug -> groupName mapping when available.
33
+ if (typeof groups.getGroupNameByGroupSlug === 'function') {
34
+ let groupName = null;
35
+ try {
36
+ if (groups.getGroupNameByGroupSlug.length >= 2) {
37
+ groupName = await new Promise((resolve) => {
38
+ groups.getGroupNameByGroupSlug(id, (err, name) => resolve(err ? null : name));
39
+ });
40
+ } else {
41
+ groupName = await groups.getGroupNameByGroupSlug(id);
42
+ }
43
+ } catch (e) {
44
+ groupName = null;
45
+ }
46
+
47
+ if (groupName && String(groupName).trim() && String(groupName).trim() !== id) {
48
+ try {
49
+ members = await groups.getMembers(String(groupName).trim(), 0, -1);
50
+ } catch (e) {
51
+ members = [];
52
+ }
53
+ if (Array.isArray(members) && members.length) return members;
54
+ }
55
+ }
56
+
57
+ return Array.isArray(members) ? members : [];
58
+ }
59
+
15
60
  // Fast membership check without N calls to groups.isMember.
16
61
  // NodeBB's groups.getUserGroups([uid]) returns an array (per uid) of group objects.
17
62
  // We compare against both group slugs and names to be tolerant with older settings.
@@ -56,30 +101,50 @@ const discord = require('./discord');
56
101
  // We try the common forms. Any failure is logged for debugging.
57
102
  async function sendEmail(template, toEmail, subject, data) {
58
103
  if (!toEmail) return;
104
+
105
+ // Language can come from plugin settings or NodeBB config depending on version.
106
+ let lang = 'fr';
107
+ try {
108
+ const s = await meta.settings.get('calendar-onekite').catch(() => ({}));
109
+ lang = (s && s.defaultLang) || (meta && meta.config && (meta.config.defaultLang || meta.config.defaultLanguage)) || 'fr';
110
+ } catch (e) {
111
+ lang = (meta && meta.config && (meta.config.defaultLang || meta.config.defaultLanguage)) || 'fr';
112
+ }
113
+
114
+ // Subject is not a positional arg; it must be injected via params.subject.
115
+ const params = Object.assign({}, data || {}, subject ? { subject } : {});
116
+
117
+ // Prefer sendToEmail when available (most consistent across versions).
59
118
  try {
60
- // NodeBB core signature (historically):
61
- // Emailer.sendToEmail(template, email, language, params[, callback])
62
- // Subject is not a positional arg; it must be injected (either by NodeBB itself
63
- // or via filter:email.modify). We always pass it in params.subject.
64
- const language = (meta && meta.config && (meta.config.defaultLang || meta.config.defaultLanguage)) || 'fr';
65
- const params = Object.assign({}, data || {}, subject ? { subject } : {});
66
119
  if (typeof emailer.sendToEmail === 'function') {
67
- await emailer.sendToEmail(template, toEmail, language, params);
120
+ // NodeBB: sendToEmail(template, email, language, params)
121
+ if (emailer.sendToEmail.length >= 4) {
122
+ await emailer.sendToEmail(template, toEmail, lang, params);
123
+ } else {
124
+ // Older signature: sendToEmail(template, email, params)
125
+ await emailer.sendToEmail(template, toEmail, params);
126
+ }
68
127
  return;
69
128
  }
70
- // Fallback for older/unusual builds (rare)
129
+ } catch (err) {
130
+ // eslint-disable-next-line no-console
131
+ console.warn('[calendar-onekite] Failed to send email', { template, toEmail, err: String((err && err.message) || err) });
132
+ }
133
+
134
+ // Very old/unusual builds: try send() but only if it clearly accepts an email.
135
+ try {
71
136
  if (typeof emailer.send === 'function') {
72
137
  // Some builds accept (template, email, language, params)
73
138
  if (emailer.send.length >= 4) {
74
- await emailer.send(template, toEmail, language, params);
75
- return;
139
+ await emailer.send(template, toEmail, lang, params);
140
+ } else {
141
+ // Some builds accept (template, email, params)
142
+ await emailer.send(template, toEmail, params);
76
143
  }
77
- // Some builds accept (template, email, params)
78
- await emailer.send(template, toEmail, params);
79
144
  }
80
145
  } catch (err) {
81
146
  // eslint-disable-next-line no-console
82
- console.warn('[calendar-onekite] Failed to send email', { template, toEmail, err: String(err) });
147
+ console.warn('[calendar-onekite] Failed to send email', { template, toEmail, err: String((err && err.message) || err) });
83
148
  }
84
149
  }
85
150
 
@@ -710,7 +775,7 @@ api.createReservation = async function (req, res) {
710
775
  const requester = await user.getUserFields(uid, ['username', 'email']);
711
776
  const itemsLabel = (resv.itemNames || []).join(', ');
712
777
  for (const g of notifyGroups) {
713
- const members = await groups.getMembers(g, 0, -1);
778
+ const members = await getMembersByGroupIdentifier(g);
714
779
  const uids = Array.isArray(members) ? members : [];
715
780
 
716
781
  // Batch fetch user email/username when supported by this NodeBB version.
package/lib/scheduler.js CHANGED
@@ -59,28 +59,47 @@ async function processAwaitingPayment() {
59
59
 
60
60
  async function sendEmail(template, toEmail, subject, data) {
61
61
  if (!toEmail) return;
62
+
63
+ // Language can come from plugin settings or NodeBB config depending on version.
64
+ let lang = 'fr';
62
65
  try {
63
- // NodeBB core signature:
64
- // Emailer.sendToEmail(template, email, language, params[, callback])
65
- // Subject is NOT a positional argument; it must be provided in params.subject
66
- // and optionally copied into the final email by filter:email.modify.
67
- const language = (meta && meta.config && (meta.config.defaultLang || meta.config.defaultLanguage)) || 'fr';
68
- const params = Object.assign({}, data || {}, subject ? { subject } : {});
66
+ const s = await meta.settings.get('calendar-onekite').catch(() => ({}));
67
+ lang = (s && s.defaultLang) || (meta && meta.config && (meta.config.defaultLang || meta.config.defaultLanguage)) || 'fr';
68
+ } catch (e) {
69
+ lang = (meta && meta.config && (meta.config.defaultLang || meta.config.defaultLanguage)) || 'fr';
70
+ }
69
71
 
72
+ // Subject is NOT a positional argument; it must be provided in params.subject.
73
+ const params = Object.assign({}, data || {}, subject ? { subject } : {});
74
+
75
+ try {
70
76
  if (typeof emailer.sendToEmail === 'function') {
71
- await emailer.sendToEmail(template, toEmail, language, params);
77
+ // NodeBB: sendToEmail(template, email, language, params)
78
+ if (emailer.sendToEmail.length >= 4) {
79
+ await emailer.sendToEmail(template, toEmail, lang, params);
80
+ } else {
81
+ // Older signature: sendToEmail(template, email, params)
82
+ await emailer.sendToEmail(template, toEmail, params);
83
+ }
72
84
  return;
73
85
  }
86
+ } catch (err) {
87
+ // eslint-disable-next-line no-console
88
+ console.warn('[calendar-onekite] Failed to send email (scheduler)', {
89
+ template,
90
+ toEmail,
91
+ err: String((err && err.message) || err),
92
+ });
93
+ }
74
94
 
75
- // Fallbacks for older/unusual builds
95
+ // Very old/unusual builds: try send() but only if it clearly accepts an email.
96
+ try {
76
97
  if (typeof emailer.send === 'function') {
77
- // Some builds accept (template, email, language, params)
78
98
  if (emailer.send.length >= 4) {
79
- await emailer.send(template, toEmail, language, params);
80
- return;
99
+ await emailer.send(template, toEmail, lang, params);
100
+ } else {
101
+ await emailer.send(template, toEmail, params);
81
102
  }
82
- // Some builds accept (template, email, params)
83
- await emailer.send(template, toEmail, params);
84
103
  }
85
104
  } catch (err) {
86
105
  // eslint-disable-next-line no-console
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nodebb-plugin-onekite-calendar",
3
- "version": "1.0.15",
3
+ "version": "1.0.20",
4
4
  "description": "FullCalendar-based equipment reservation workflow with admin approval & HelloAsso payment for NodeBB",
5
5
  "main": "library.js",
6
6
  "license": "MIT",
package/plugin.json CHANGED
@@ -39,5 +39,5 @@
39
39
  "acpScripts": [
40
40
  "public/admin.js"
41
41
  ],
42
- "version": "1.0.15"
42
+ "version": "1.0.20"
43
43
  }