nodebb-plugin-facebook-post 1.0.47 → 1.0.48

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 CHANGED
@@ -220,7 +220,9 @@ async function publishFeedPost({ message, link, photoIds }) {
220
220
  const form = new URLSearchParams();
221
221
  form.append('message', String(message || ''));
222
222
  form.append('access_token', String(settings.fbPageAccessToken));
223
- if (link) form.append('link', String(link));
223
+ // N'envoyer `link` que s'il n'y a pas de photos : sinon Facebook affiche le
224
+ // preview du lien et ignore les photos attachées. Le lien est déjà dans le message.
225
+ if (link && !(Array.isArray(photoIds) && photoIds.length)) form.append('link', String(link));
224
226
  if (Array.isArray(photoIds) && photoIds.length) {
225
227
  photoIds.forEach((id, idx) => {
226
228
  form.append(`attached_media[${idx}]`, JSON.stringify({ media_fbid: id }));
@@ -486,6 +488,17 @@ Plugin.onPostSave = async function (hookData) {
486
488
  if (!(await userIsAllowed(ctx.post.uid))) return;
487
489
  if (!shouldProcessPost(ctx)) return;
488
490
 
491
+ // Si le topic est planifié, persister l'intention et ne pas publier maintenant.
492
+ // La publication aura lieu via onTopicScheduledPublish quand le topic sera rendu public.
493
+ if (bool(ctx.topic.scheduled)) {
494
+ const Posts = require.main.require('./src/posts');
495
+ if (bool(ctx.post.fbPostEnabled)) {
496
+ await Posts.setPostField(ctx.post.pid, 'fbPostEnabled', '1');
497
+ winston.info(`[facebook-post] topic planifié – intention sauvegardée pour pid=${ctx.post.pid}`);
498
+ }
499
+ return;
500
+ }
501
+
489
502
  const Posts = require.main.require('./src/posts');
490
503
 
491
504
  const fbAlready = await Posts.getPostField(ctx.post.pid, 'fbPostedId');
@@ -525,4 +538,67 @@ Plugin.onPostSave = async function (hookData) {
525
538
  }
526
539
  };
527
540
 
541
+ Plugin.onTopicScheduledPublish = async function (topicData) {
542
+ const winston = require.main.require('winston');
543
+ try {
544
+ await loadSettings();
545
+ if (!settings.enabled) return;
546
+ if (!settings.fbPageId || !settings.fbPageAccessToken) return;
547
+
548
+ const pid = topicData && topicData.mainPid;
549
+ if (!pid) return;
550
+
551
+ const Posts = require.main.require('./src/posts');
552
+
553
+ // Vérifier que l'utilisateur avait coché la case lors de la création
554
+ const fbEnabled = await Posts.getPostField(pid, 'fbPostEnabled');
555
+ if (!bool(fbEnabled)) return;
556
+
557
+ const ctx = await getPostContext({ pid });
558
+ if (!ctx) return;
559
+
560
+ // Le flag est lu depuis la DB, pas depuis l'objet éphémère
561
+ ctx.post.fbPostEnabled = true;
562
+
563
+ if (!(await userIsAllowed(ctx.post.uid))) return;
564
+ if (!shouldProcessPost(ctx)) return;
565
+
566
+ const fbAlready = await Posts.getPostField(pid, 'fbPostedId');
567
+ if (!fbAlready) {
568
+ try {
569
+ const fbId = await postToFacebook(ctx);
570
+ if (fbId) {
571
+ await Posts.setPostField(pid, 'fbPostedId', fbId);
572
+ await Posts.setPostField(pid, 'fbPostedAt', Date.now());
573
+ winston.info(`[facebook-post] facebook publié (planifié) pid=${pid} fbId=${fbId}`);
574
+ } else {
575
+ winston.warn(`[facebook-post] postToFacebook sans id pour pid=${pid} (planifié)`);
576
+ }
577
+ } catch (fbErr) {
578
+ const detail = fbErr?.response ? JSON.stringify(fbErr.response.data) : (fbErr?.message || fbErr);
579
+ winston.error(`[facebook-post] facebook erreur (planifié) pid=${pid}: ${detail}`);
580
+ }
581
+ }
582
+
583
+ const igAlready = await Posts.getPostField(pid, 'igPostedId');
584
+ if (!igAlready) {
585
+ try {
586
+ const igId = await postToInstagram(ctx);
587
+ if (igId) {
588
+ await Posts.setPostField(pid, 'igPostedId', igId);
589
+ await Posts.setPostField(pid, 'igPostedAt', Date.now());
590
+ winston.info(`[facebook-post] instagram publié (planifié) pid=${pid} igId=${igId}`);
591
+ }
592
+ } catch (igErr) {
593
+ const detail = igErr?.response ? JSON.stringify(igErr.response.data) : (igErr?.message || igErr);
594
+ winston.error(`[facebook-post] instagram erreur (planifié) pid=${pid}: ${detail}`);
595
+ }
596
+ }
597
+ } catch (e) {
598
+ const winston = require.main.require('winston');
599
+ const detail = e?.response ? JSON.stringify(e.response.data) : (e?.message || e);
600
+ winston.error(`[facebook-post] onTopicScheduledPublish erreur: ${detail}`);
601
+ }
602
+ };
603
+
528
604
  module.exports = Plugin;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nodebb-plugin-facebook-post",
3
- "version": "1.0.47",
3
+ "version": "1.0.48",
4
4
  "description": "Auto-post new NodeBB topics to a fixed Facebook Page (text + NodeBB uploads).",
5
5
  "main": "library.js",
6
6
  "dependencies": {
package/plugin.json CHANGED
@@ -19,6 +19,10 @@
19
19
  {
20
20
  "hook": "action:post.save",
21
21
  "method": "onPostSave"
22
+ },
23
+ {
24
+ "hook": "action:topic.scheduled.publish",
25
+ "method": "onTopicScheduledPublish"
22
26
  }
23
27
  ],
24
28
  "staticDirs": {