nodebb-plugin-facebook-post 1.0.26 → 1.0.29
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/library.js +3 -43
- package/package.json +1 -1
- package/static/lib/composer.js +7 -83
package/library.js
CHANGED
|
@@ -14,7 +14,6 @@ const DEFAULT_SETTINGS = {
|
|
|
14
14
|
categoriesWhitelist: '',
|
|
15
15
|
minimumReputation: 0,
|
|
16
16
|
maxImages: 4,
|
|
17
|
-
enablePlaceTagging: true,
|
|
18
17
|
};
|
|
19
18
|
|
|
20
19
|
function bool(v) {
|
|
@@ -51,7 +50,6 @@ async function loadSettings() {
|
|
|
51
50
|
settings.excerptMaxLen = int(settings.excerptMaxLen, DEFAULT_SETTINGS.excerptMaxLen);
|
|
52
51
|
settings.minimumReputation = int(settings.minimumReputation, 0);
|
|
53
52
|
settings.maxImages = int(settings.maxImages, DEFAULT_SETTINGS.maxImages);
|
|
54
|
-
settings.enablePlaceTagging = bool(settings.enablePlaceTagging);
|
|
55
53
|
settings.categoriesWhitelist = trimStr(settings.categoriesWhitelist);
|
|
56
54
|
|
|
57
55
|
const env = readEnv();
|
|
@@ -192,14 +190,13 @@ async function uploadPhotoToFacebook(urlAbs) {
|
|
|
192
190
|
return resp.data && resp.data.id;
|
|
193
191
|
}
|
|
194
192
|
|
|
195
|
-
async function publishFeedPost({ message, link, photoIds
|
|
193
|
+
async function publishFeedPost({ message, link, photoIds }) {
|
|
196
194
|
const endpoint = `https://graph.facebook.com/${settings.fbGraphVersion}/${settings.fbPageId}/feed`;
|
|
197
195
|
|
|
198
196
|
const form = new URLSearchParams();
|
|
199
197
|
form.append('message', String(message || ''));
|
|
200
198
|
form.append('access_token', String(settings.fbPageAccessToken));
|
|
201
199
|
if (link) form.append('link', String(link));
|
|
202
|
-
if (placeId) form.append('place', String(placeId));
|
|
203
200
|
if (Array.isArray(photoIds) && photoIds.length) {
|
|
204
201
|
photoIds.forEach((id, idx) => {
|
|
205
202
|
form.append(`attached_media[${idx}]`, JSON.stringify({ media_fbid: id }));
|
|
@@ -225,8 +222,6 @@ async function postToFacebook(ctx) {
|
|
|
225
222
|
.filter(isForumHosted)
|
|
226
223
|
.slice(0, Math.max(0, settings.maxImages));
|
|
227
224
|
|
|
228
|
-
const placeId = (settings.enablePlaceTagging && trimStr(ctx.post.fbPlaceId)) || null;
|
|
229
|
-
|
|
230
225
|
const lines = [`\uD83D\uDCDD ${topicTitle}`];
|
|
231
226
|
if (excerpt) lines.push(excerpt);
|
|
232
227
|
lines.push(`\uD83D\uDD17 ${link}`);
|
|
@@ -240,7 +235,7 @@ async function postToFacebook(ctx) {
|
|
|
240
235
|
if (id) photoIds.push(id);
|
|
241
236
|
}
|
|
242
237
|
|
|
243
|
-
return publishFeedPost({ message, link, photoIds
|
|
238
|
+
return publishFeedPost({ message, link, photoIds });
|
|
244
239
|
}
|
|
245
240
|
|
|
246
241
|
const Plugin = {};
|
|
@@ -294,42 +289,7 @@ Plugin.init = async function (params) {
|
|
|
294
289
|
}
|
|
295
290
|
});
|
|
296
291
|
|
|
297
|
-
|
|
298
|
-
const winston = require.main.require('winston');
|
|
299
|
-
res.set('Cache-Control', 'no-store');
|
|
300
|
-
try {
|
|
301
|
-
await loadSettings();
|
|
302
|
-
if (!settings.fbPageAccessToken) return res.json({ results: [] });
|
|
303
|
-
const q = trimStr(req.query.q);
|
|
304
|
-
if (q.length < 2) return res.json({ results: [] });
|
|
305
|
-
|
|
306
|
-
const resp = await axios.get(
|
|
307
|
-
`https://graph.facebook.com/${settings.fbGraphVersion}/search`,
|
|
308
|
-
{
|
|
309
|
-
params: {
|
|
310
|
-
type: 'place',
|
|
311
|
-
q,
|
|
312
|
-
fields: 'id,name,location',
|
|
313
|
-
access_token: settings.fbPageAccessToken,
|
|
314
|
-
limit: 7,
|
|
315
|
-
},
|
|
316
|
-
timeout: 8000,
|
|
317
|
-
}
|
|
318
|
-
);
|
|
319
|
-
const data = (resp.data && resp.data.data) || [];
|
|
320
|
-
winston.info(`[facebook-post] search-place: q="${q}" → ${data.length} résultat(s)`);
|
|
321
|
-
const results = data.map(p => ({
|
|
322
|
-
id: p.id,
|
|
323
|
-
name: p.name,
|
|
324
|
-
city: (p.location && (p.location.city || p.location.country)) || '',
|
|
325
|
-
}));
|
|
326
|
-
return res.json({ results });
|
|
327
|
-
} catch (e) {
|
|
328
|
-
const detail = e?.response?.data ? JSON.stringify(e.response.data) : e?.message;
|
|
329
|
-
winston.warn(`[facebook-post] search-place erreur: ${detail}`);
|
|
330
|
-
return res.json({ results: [] });
|
|
331
|
-
}
|
|
332
|
-
});
|
|
292
|
+
|
|
333
293
|
};
|
|
334
294
|
|
|
335
295
|
Plugin.addAdminNavigation = async function (header) {
|
package/package.json
CHANGED
package/static/lib/composer.js
CHANGED
|
@@ -24,21 +24,6 @@
|
|
|
24
24
|
<input type="checkbox" class="form-check-input" id="fbPostEnabled" data-fbpost-enabled>
|
|
25
25
|
<label class="form-check-label" for="fbPostEnabled">Publier ce nouveau topic sur Facebook (et Insta si activé)</label>
|
|
26
26
|
</div>
|
|
27
|
-
|
|
28
|
-
<div class="mb-2" data-fbpost-place-wrap style="display:none;">
|
|
29
|
-
<label class="form-label" style="font-size:12px;opacity:.8;">
|
|
30
|
-
Lieu – optionnel
|
|
31
|
-
</label>
|
|
32
|
-
<div style="position:relative;">
|
|
33
|
-
<input type="text" class="form-control" data-fbpost-place-query
|
|
34
|
-
placeholder="Rechercher un lieu (ville, adresse…)" autocomplete="off">
|
|
35
|
-
<ul data-fbpost-place-results
|
|
36
|
-
style="display:none;position:absolute;z-index:9999;background:#fff;
|
|
37
|
-
border:1px solid #ccc;border-radius:4px;list-style:none;
|
|
38
|
-
margin:0;padding:0;width:100%;max-height:200px;overflow-y:auto;"></ul>
|
|
39
|
-
</div>
|
|
40
|
-
<input type="hidden" data-fbpost-place-id>
|
|
41
|
-
</div>
|
|
42
27
|
</div>
|
|
43
28
|
`;
|
|
44
29
|
|
|
@@ -54,75 +39,14 @@
|
|
|
54
39
|
else $composer.prepend(html);
|
|
55
40
|
}
|
|
56
41
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
$placeWrap.toggle($enabled.is(':checked'));
|
|
62
|
-
});
|
|
63
|
-
|
|
64
|
-
let _placeTimer = null;
|
|
65
|
-
const $query = $composer.find('[data-fbpost-place-query]');
|
|
66
|
-
const $results = $composer.find('[data-fbpost-place-results]');
|
|
67
|
-
const $placeId = $composer.find('[data-fbpost-place-id]');
|
|
68
|
-
|
|
69
|
-
function clearPlace() {
|
|
70
|
-
$placeId.val('');
|
|
71
|
-
}
|
|
72
|
-
function selectPlace(id, name, city) {
|
|
73
|
-
$placeId.val(id);
|
|
74
|
-
$query.val(name + (city ? ' – ' + city : ''));
|
|
75
|
-
$results.hide().empty();
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
$query.on('input', function () {
|
|
79
|
-
clearPlace();
|
|
80
|
-
clearTimeout(_placeTimer);
|
|
81
|
-
const q = $query.val().trim();
|
|
82
|
-
if (q.length < 2) { $results.hide().empty(); return; }
|
|
83
|
-
_placeTimer = setTimeout(async function () {
|
|
84
|
-
try {
|
|
85
|
-
const res = await fetch('/api/facebook-post/search-place?q=' + encodeURIComponent(q), {
|
|
86
|
-
credentials: 'same-origin', cache: 'no-store',
|
|
87
|
-
});
|
|
88
|
-
if (!res.ok) return;
|
|
89
|
-
const json = await res.json();
|
|
90
|
-
$results.empty();
|
|
91
|
-
if (!json.results || !json.results.length) { $results.hide(); return; }
|
|
92
|
-
json.results.forEach(function (p) {
|
|
93
|
-
const label = p.name + (p.city ? ' – ' + p.city : '');
|
|
94
|
-
$('<li>')
|
|
95
|
-
.text(label)
|
|
96
|
-
.css({ padding: '6px 10px', cursor: 'pointer' })
|
|
97
|
-
.on('mousedown', function (e) {
|
|
98
|
-
e.preventDefault();
|
|
99
|
-
selectPlace(p.id, p.name, p.city);
|
|
100
|
-
})
|
|
101
|
-
.appendTo($results);
|
|
102
|
-
});
|
|
103
|
-
$results.show();
|
|
104
|
-
} catch { /* ignore */ }
|
|
105
|
-
}, 350);
|
|
106
|
-
});
|
|
107
|
-
|
|
108
|
-
$query.on('blur', function () {
|
|
109
|
-
setTimeout(function () { $results.hide(); }, 200);
|
|
110
|
-
});
|
|
111
|
-
$query.on('focus', function () {
|
|
112
|
-
if ($results.children().length) $results.show();
|
|
113
|
-
});
|
|
114
|
-
|
|
115
|
-
$(window).off('filter:composer.submit.fbpost')
|
|
116
|
-
.on('filter:composer.submit.fbpost', function (ev2, submitData) {
|
|
42
|
+
// NodeBB 4.x fires 'action:composer.submit' with { composerData } (the object
|
|
43
|
+
// sent to the socket). Modifying composerData by reference is enough.
|
|
44
|
+
$(window).off('action:composer.submit.fbpost')
|
|
45
|
+
.on('action:composer.submit.fbpost', function (ev2, data) {
|
|
117
46
|
const enabled = $enabled.is(':checked');
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
if (enabled) {
|
|
122
|
-
const placeId = $composer.find('[data-fbpost-place-id]').val();
|
|
123
|
-
if (placeId) submitData.fbPlaceId = placeId;
|
|
124
|
-
}
|
|
125
|
-
return submitData;
|
|
47
|
+
const postData = (data && data.composerData) || (data && data.postData) || data;
|
|
48
|
+
if (!postData || typeof postData !== 'object') return;
|
|
49
|
+
postData.fbPostEnabled = enabled;
|
|
126
50
|
});
|
|
127
51
|
}
|
|
128
52
|
|