[object Object]

← back to Marketing Command Center

fix(linkedin): blank media title default + video-wins when both media refs given (Cody-verified)

37441d3224a8ef7d1844b485947906b669552099 · 2026-07-30 15:34:02 -0700 · Steve

- linkedin/index.js: media.title defaults to '' not the literal 'video'/'image' (junk on public posts).
- channels/index.js: postLinkedIn isVideo = !!videoUrl so a video isn't silently dropped when a thumbnail image is also passed.
- NOTE: Cody's 'uploadedPartIds should be uploadPartId' finding was VERIFIED FALSE against LinkedIn's Videos API docs (uploadedPartIds ARE the PUT ETags) — no change made there.

Files touched

Diff

commit 37441d3224a8ef7d1844b485947906b669552099
Author: Steve <steve@designerwallcoverings.com>
Date:   Thu Jul 30 15:34:02 2026 -0700

    fix(linkedin): blank media title default + video-wins when both media refs given (Cody-verified)
    
    - linkedin/index.js: media.title defaults to '' not the literal 'video'/'image' (junk on public posts).
    - channels/index.js: postLinkedIn isVideo = !!videoUrl so a video isn't silently dropped when a thumbnail image is also passed.
    - NOTE: Cody's 'uploadedPartIds should be uploadPartId' finding was VERIFIED FALSE against LinkedIn's Videos API docs (uploadedPartIds ARE the PUT ETags) — no change made there.
---
 modules/channels/index.js | 4 ++--
 modules/linkedin/index.js | 2 +-
 package.json              | 2 +-
 3 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/modules/channels/index.js b/modules/channels/index.js
index 3a18d4d..ba848d1 100644
--- a/modules/channels/index.js
+++ b/modules/channels/index.js
@@ -660,8 +660,8 @@ async function postLinkedIn(content) {
   // videoUrl → native VIDEO upload (videos endpoint + multipart PUT + finalize);
   // mediaUrl → single-PUT IMAGE upload. Routing image vs video must match the
   // media kind or LinkedIn rejects it (initializeUpload endpoints are distinct).
-  const isVideo = !!content.videoUrl && !content.mediaUrl;
-  const src = content.mediaUrl || content.videoUrl;
+  const isVideo = !!content.videoUrl;                 // video wins if both video + image refs are supplied
+  const src = isVideo ? content.videoUrl : content.mediaUrl;
   if (src) {
     const media = await fetch(src);
     if (!media.ok) return [{ ok: false, error: `couldn't fetch media (${media.status})` }];
diff --git a/modules/linkedin/index.js b/modules/linkedin/index.js
index 8dd709d..99640f3 100644
--- a/modules/linkedin/index.js
+++ b/modules/linkedin/index.js
@@ -90,7 +90,7 @@ async function liPost({ text, media }) {
   if (media && (media.video || media.image)) {
     const kind = media.video ? 'video' : 'image';
     const urn = await liUploadMedia({ token, author, kind, ref: media.video || media.image });
-    content = { media: { title: media.title || (kind === 'video' ? 'video' : 'image'), id: urn } };
+    content = { media: { title: media.title || '', id: urn } }; // blank title, not the literal media-kind word
   } else if (media && media.url) {
     content = { article: { source: media.url, title: media.title || '', description: media.description || '' } };
   }
diff --git a/package.json b/package.json
index 5ff3b70..d0bb84f 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
 {
   "name": "marketing-command-center",
-  "version": "1.8.0",
+  "version": "1.8.1",
   "description": "DW Marketing Command Center — Constant Contact, marketing calendar, suggested copy, on-demand layouts",
   "main": "server.js",
   "scripts": {

← 60ffd0e chore: lint+refactor, fix channels postLinkedIn video routin  ·  back to Marketing Command Center  ·  auto-save: 2026-07-30T15:49:17 (1 files) — package-lock.json eb62709 →