toykity Claude Opus 4.7 commited on
Commit
69a6a62
·
1 Parent(s): ddcfdbb

update startup patches

Browse files

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

Files changed (1) hide show
  1. var/docker/start.sh +332 -65
var/docker/start.sh CHANGED
@@ -3,35 +3,6 @@ set -e
3
 
4
  echo "=== Postiz HF Space Startup ==="
5
 
6
- # Run endpoint connectivity check (diagnostic)
7
- bash /app/endpoint-check.sh || true
8
-
9
- # Start cloudflared access tcp proxy for PostgreSQL (if configured)
10
- if [ -n "$TUNNEL_SERVICE_TOKEN_ID" ] && [ -n "$CF_TUNNEL_HOSTNAME" ]; then
11
- echo "Starting cloudflared access tcp proxy -> $CF_TUNNEL_HOSTNAME (PG)"
12
- cloudflared access tcp \
13
- --hostname "$CF_TUNNEL_HOSTNAME" \
14
- --url localhost:5432 &
15
- for i in $(seq 1 30); do
16
- (echo > /dev/tcp/localhost/5432) 2>/dev/null && break
17
- sleep 1
18
- done
19
- echo "cloudflared PostgreSQL proxy ready"
20
- fi
21
-
22
- # Start cloudflared access tcp proxy for Redis (if configured)
23
- if [ -n "$TUNNEL_SERVICE_TOKEN_ID" ] && [ -n "$CF_REDIS_HOSTNAME" ]; then
24
- echo "Starting cloudflared access tcp proxy -> $CF_REDIS_HOSTNAME (Redis)"
25
- cloudflared access tcp \
26
- --hostname "$CF_REDIS_HOSTNAME" \
27
- --url localhost:6379 &
28
- for i in $(seq 1 30); do
29
- (echo > /dev/tcp/localhost/6379) 2>/dev/null && break
30
- sleep 1
31
- done
32
- echo "cloudflared Redis proxy ready"
33
- fi
34
-
35
  # Patch compiled temporal.module.js to support mTLS client certificates
36
  # Field names must match @temporalio/common TLSConfig:
37
  # serverNameOverride, serverRootCACertificate, clientCertPair: { crt, key }
@@ -86,7 +57,6 @@ fi
86
  # ============================================================
87
 
88
  # Patch 1: temporal.module.js (orchestrator only)
89
- # Replace the socialIntegrationList workers array with a single main worker
90
  WORKER_TARGET="$PATCH_DIR/apps/orchestrator/dist/libraries/nestjs-libraries/src/temporal/temporal.module.js"
91
  if [ -f "$WORKER_TARGET" ]; then
92
  echo "Patching $WORKER_TARGET for worker consolidation..."
@@ -176,7 +146,7 @@ for DISCORD_DIST_DIR in "$PATCH_DIR/apps/backend/dist" "$PATCH_DIR/apps/orchestr
176
  node -e "
177
  const fs = require('fs');
178
  let code = fs.readFileSync('$DISCORD_TARGET', 'utf8');
179
- code = code.replace(/https:\/\/discord\.com\/api\//g, 'https://discord.proxy.firela.io/api/');
180
  fs.writeFileSync('$DISCORD_TARGET', code);
181
  console.log('Discord proxy patched (API calls only)');
182
  "
@@ -184,8 +154,6 @@ console.log('Discord proxy patched (API calls only)');
184
  done
185
 
186
  # Patch threads.provider.js: route Threads API calls through reverse proxy
187
- # HF Spaces blocks connections to graph.threads.net (TypeError: fetch failed)
188
- # Must patch BOTH backend and orchestrator
189
  for THREADS_DIST_DIR in "$PATCH_DIR/apps/backend/dist" "$PATCH_DIR/apps/orchestrator/dist"; do
190
  THREADS_TARGET="$THREADS_DIST_DIR/libraries/nestjs-libraries/src/integrations/social/threads.provider.js"
191
  if [ -f "$THREADS_TARGET" ]; then
@@ -193,7 +161,7 @@ for THREADS_DIST_DIR in "$PATCH_DIR/apps/backend/dist" "$PATCH_DIR/apps/orchestr
193
  node -e "
194
  const fs = require('fs');
195
  let code = fs.readFileSync('$THREADS_TARGET', 'utf8');
196
- code = code.replace(/https:\/\/graph\.threads\.net/g, 'https://threads.proxy.firela.io');
197
  fs.writeFileSync('$THREADS_TARGET', code);
198
  console.log('Threads proxy patched');
199
  "
@@ -201,7 +169,6 @@ console.log('Threads proxy patched');
201
  done
202
 
203
  # Patch facebook.provider.js + instagram.provider.js: route through reverse proxy
204
- # HF Spaces blocks graph.facebook.com (used by Facebook Page + Instagram Business)
205
  for FB_DIST_DIR in "$PATCH_DIR/apps/backend/dist" "$PATCH_DIR/apps/orchestrator/dist"; do
206
  for FB_TARGET in \
207
  "$FB_DIST_DIR/libraries/nestjs-libraries/src/integrations/social/facebook.provider.js" \
@@ -211,7 +178,7 @@ for FB_DIST_DIR in "$PATCH_DIR/apps/backend/dist" "$PATCH_DIR/apps/orchestrator/
211
  node -e "
212
  const fs = require('fs');
213
  let code = fs.readFileSync('$FB_TARGET', 'utf8');
214
- code = code.replace(/https:\/\/graph\.facebook\.com/g, 'https://fb.proxy.firela.io');
215
  fs.writeFileSync('$FB_TARGET', code);
216
  console.log('Facebook proxy patched');
217
  "
@@ -220,7 +187,6 @@ console.log('Facebook proxy patched');
220
  done
221
 
222
  # Patch instagram.standalone.provider.js: route through reverse proxy
223
- # HF Spaces blocks both api.instagram.com and graph.instagram.com
224
  for IG_DIST_DIR in "$PATCH_DIR/apps/backend/dist" "$PATCH_DIR/apps/orchestrator/dist"; do
225
  IG_TARGET="$IG_DIST_DIR/libraries/nestjs-libraries/src/integrations/social/instagram.standalone.provider.js"
226
  if [ -f "$IG_TARGET" ]; then
@@ -228,8 +194,8 @@ for IG_DIST_DIR in "$PATCH_DIR/apps/backend/dist" "$PATCH_DIR/apps/orchestrator/
228
  node -e "
229
  const fs = require('fs');
230
  let code = fs.readFileSync('$IG_TARGET', 'utf8');
231
- code = code.replace(/https:\/\/api\.instagram\.com/g, 'https://ig-api.proxy.firela.io');
232
- code = code.replace(/https:\/\/graph\.instagram\.com/g, 'https://ig-graph.proxy.firela.io');
233
  fs.writeFileSync('$IG_TARGET', code);
234
  console.log('Instagram Standalone proxy patched');
235
  "
@@ -237,7 +203,6 @@ console.log('Instagram Standalone proxy patched');
237
  done
238
 
239
  # Patch hashnode.provider.js: route through reverse proxy
240
- # HF Spaces blocks gql.hashnode.com
241
  for HN_DIST_DIR in "$PATCH_DIR/apps/backend/dist" "$PATCH_DIR/apps/orchestrator/dist"; do
242
  HN_TARGET="$HN_DIST_DIR/libraries/nestjs-libraries/src/integrations/social/hashnode.provider.js"
243
  if [ -f "$HN_TARGET" ]; then
@@ -245,7 +210,7 @@ for HN_DIST_DIR in "$PATCH_DIR/apps/backend/dist" "$PATCH_DIR/apps/orchestrator/
245
  node -e "
246
  const fs = require('fs');
247
  let code = fs.readFileSync('$HN_TARGET', 'utf8');
248
- code = code.replace(/https:\/\/gql\.hashnode\.com/g, 'https://hashnode.proxy.firela.io');
249
  fs.writeFileSync('$HN_TARGET', code);
250
  console.log('Hashnode proxy patched');
251
  "
@@ -253,15 +218,13 @@ console.log('Hashnode proxy patched');
253
  done
254
 
255
  # Patch node-telegram-bot-api: route through reverse proxy
256
- # HF Spaces blocks api.telegram.org
257
- # Package lives at /app/node_modules/, not inside dist/
258
  TG_TARGET="$PATCH_DIR/node_modules/node-telegram-bot-api/src/telegram.js"
259
  if [ -f "$TG_TARGET" ]; then
260
  echo "Patching $TG_TARGET for Telegram proxy..."
261
  node -e "
262
  const fs = require('fs');
263
  let code = fs.readFileSync('$TG_TARGET', 'utf8');
264
- code = code.replace(/https:\/\/api\.telegram\.org/g, 'https://telegram.proxy.firela.io');
265
  fs.writeFileSync('$TG_TARGET', code);
266
  console.log('Telegram proxy patched');
267
  "
@@ -290,7 +253,6 @@ if (code.includes(oldUpload)) {
290
  fi
291
 
292
  # Patch integration.service.js to wrap uploadSimple in try-catch
293
- # so channel creation doesn't fail when avatar download fails
294
  INTEG_SVC_TARGET="$PATCH_DIR/apps/backend/dist/libraries/nestjs-libraries/src/database/prisma/integrations/integration.service.js"
295
  if [ -f "$INTEG_SVC_TARGET" ]; then
296
  echo "Patching $INTEG_SVC_TARGET for resilient picture upload..."
@@ -312,7 +274,7 @@ ISPATCH
312
  node /app/patches/integ-svc.js "$INTEG_SVC_TARGET"
313
  fi
314
 
315
- # Patch youtube.provider.js to remove youtubepartner scope (restricted, most users won't have it)
316
  mkdir -p /app/patches
317
  cat > /app/patches/yt-scope.js << 'YTPATCH'
318
  const fs = require('fs');
@@ -350,8 +312,6 @@ for YT_DIST_DIR in "$PATCH_DIR/apps/backend/dist" "$PATCH_DIR/apps/orchestrator/
350
  done
351
 
352
  # Write a global Node.js preload script to extend undici fetch timeout
353
- # HF Spaces has intermittent connectivity to external APIs (e.g. Discord)
354
- # Default undici connect timeout is 10s; we extend to 30s
355
  mkdir -p /app/patches
356
  cat > /app/patches/extend-timeout.js << 'PRELOAD'
357
  try {
@@ -370,7 +330,6 @@ PRELOAD
370
  echo "NODE_OPTIONS=--require /app/patches/extend-timeout.js" >> /app/.env
371
 
372
  # Patch posts.service.js in backend to log startWorkflow calls and errors
373
- # Discord workflow was silently not starting - need to see why
374
  POSTS_SVC_TARGET="$PATCH_DIR/apps/backend/dist/libraries/nestjs-libraries/src/database/prisma/posts/posts.service.js"
375
  if [ -f "$POSTS_SVC_TARGET" ]; then
376
  echo "Patching $POSTS_SVC_TARGET for startWorkflow logging..."
@@ -380,20 +339,11 @@ const fs = require('fs');
380
  const target = process.argv[2];
381
  let code = fs.readFileSync(target, 'utf8');
382
 
383
- // Find the pattern by looking for startWorkflow in createPost context
384
- // The compiled JS may use different variable names
385
- // Strategy: find ".startWorkflow(" calls that are followed by ".catch"
386
  const lines = code.split('\n');
387
  let patched = false;
388
  for (let i = 0; i < lines.length; i++) {
389
  if (lines[i].includes('.startWorkflow(') && !lines[i].includes('async startWorkflow')) {
390
- // Add logging before this line
391
  const indent = lines[i].match(/^(\s*)/)[1];
392
- // Extract the arguments pattern - log the call
393
- const logLine = indent + 'console.log("[startWorkflow] line:", JSON.stringify(' + lines[i].trim().replace('.startWorkflow(', '.startWorkflow.args || ').replace(/\.catch.*$/, '') + '));';
394
- // Simpler approach: just add a log line
395
- const logLine2 = indent + 'console.log("[startWorkflow] call found at line ' + i + ':", typeof post !== "undefined" ? post?.settings?.__type : "no-post-context");';
396
- // Even simpler: patch the .catch((err) => {}) to log errors
397
  if (lines[i].includes('.catch(')) {
398
  lines[i] = lines[i].replace('.catch((err) => {})', '.catch((err) => { console.error("[startWorkflow] FAILED:", err?.message || String(err)); })');
399
  if (lines[i] !== code.split('\n')[i]) {
@@ -401,7 +351,6 @@ for (let i = 0; i < lines.length; i++) {
401
  console.log('Patched .catch at line ' + i);
402
  }
403
  }
404
- // Also try the version without arrow function body
405
  if (lines[i].includes('.catch(() => {})') || lines[i].includes('.catch(()=>{})')) {
406
  lines[i] = lines[i].replace(/\.catch\(\(\) => \{\}\)/g, '.catch((err) => { console.error("[startWorkflow] FAILED:", err?.message || String(err)); })');
407
  lines[i] = lines[i].replace(/\.catch\(\(\)=>\{\}\)/g, '.catch((err) => { console.error("[startWorkflow] FAILED:", err?.message || String(err)); })');
@@ -411,11 +360,9 @@ for (let i = 0; i < lines.length; i++) {
411
  }
412
  }
413
 
414
- // Also add logging at the start of startWorkflow method itself
415
  const swStart = 'async startWorkflow(';
416
  const swIdx = code.indexOf(swStart);
417
  if (swIdx !== -1) {
418
- // Find the opening brace after the method signature
419
  const braceIdx = code.indexOf('{', swIdx);
420
  if (braceIdx !== -1) {
421
  const before = code.substring(0, braceIdx + 1);
@@ -431,12 +378,10 @@ if (patched) {
431
  fs.writeFileSync(target, lines.join('\n'));
432
  console.log('startWorkflow logging patched');
433
  } else {
434
- // Fallback: dump the context around startWorkflow for debugging
435
  console.log('No .catch patterns found, dumping startWorkflow context...');
436
  const idx = code.indexOf('async startWorkflow');
437
  if (idx !== -1) {
438
  console.log('startWorkflow method found at offset:', idx);
439
- // Find the method and the call sites
440
  const callSites = [];
441
  let pos = 0;
442
  while ((pos = code.indexOf('.startWorkflow(', pos)) !== -1) {
@@ -452,7 +397,6 @@ POSTSPATCH
452
  fi
453
 
454
  # Patch social.abstract.js in orchestrator to log raw errors from social providers
455
- # The default error handling swallows unknown X API errors as 'Unknown Error'
456
  for SA_DIST_DIR in "$PATCH_DIR/apps/orchestrator/dist" "$PATCH_DIR/apps/backend/dist"; do
457
  SA_TARGET="$SA_DIST_DIR/libraries/nestjs-libraries/src/integrations/social.abstract.js"
458
  if [ -f "$SA_TARGET" ]; then
@@ -460,7 +404,6 @@ for SA_DIST_DIR in "$PATCH_DIR/apps/orchestrator/dist" "$PATCH_DIR/apps/backend/
460
  node -e "
461
  const fs = require('fs');
462
  let code = fs.readFileSync('$SA_TARGET', 'utf8');
463
- // Add logging before the handleErrors call to capture raw error details
464
  const oldCatch = \"const handle = this.handleErrors(safeStringify(err), 200);\";
465
  const newCatch = \"console.error('[social-abstract] runInConcurrent error:', err?.message || err); console.error('[social-abstract] raw error body:', safeStringify(err)?.substring(0, 2000)); const handle = this.handleErrors(safeStringify(err), 200);\";
466
  if (code.includes(oldCatch)) {
@@ -474,6 +417,330 @@ if (code.includes(oldCatch)) {
474
  fi
475
  done
476
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
477
  echo "=== Patching complete, starting app ==="
478
 
479
  # Delegate to original entrypoint + CMD (nginx && pnpm run pm2)
 
3
 
4
  echo "=== Postiz HF Space Startup ==="
5
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6
  # Patch compiled temporal.module.js to support mTLS client certificates
7
  # Field names must match @temporalio/common TLSConfig:
8
  # serverNameOverride, serverRootCACertificate, clientCertPair: { crt, key }
 
57
  # ============================================================
58
 
59
  # Patch 1: temporal.module.js (orchestrator only)
 
60
  WORKER_TARGET="$PATCH_DIR/apps/orchestrator/dist/libraries/nestjs-libraries/src/temporal/temporal.module.js"
61
  if [ -f "$WORKER_TARGET" ]; then
62
  echo "Patching $WORKER_TARGET for worker consolidation..."
 
146
  node -e "
147
  const fs = require('fs');
148
  let code = fs.readFileSync('$DISCORD_TARGET', 'utf8');
149
+ code = code.replace(/https:\/\/discord\.com\/api\//g, 'https://discord-proxy.firela.io/api/');
150
  fs.writeFileSync('$DISCORD_TARGET', code);
151
  console.log('Discord proxy patched (API calls only)');
152
  "
 
154
  done
155
 
156
  # Patch threads.provider.js: route Threads API calls through reverse proxy
 
 
157
  for THREADS_DIST_DIR in "$PATCH_DIR/apps/backend/dist" "$PATCH_DIR/apps/orchestrator/dist"; do
158
  THREADS_TARGET="$THREADS_DIST_DIR/libraries/nestjs-libraries/src/integrations/social/threads.provider.js"
159
  if [ -f "$THREADS_TARGET" ]; then
 
161
  node -e "
162
  const fs = require('fs');
163
  let code = fs.readFileSync('$THREADS_TARGET', 'utf8');
164
+ code = code.replace(/https:\/\/graph\.threads\.net/g, 'https://threads-proxy.firela.io');
165
  fs.writeFileSync('$THREADS_TARGET', code);
166
  console.log('Threads proxy patched');
167
  "
 
169
  done
170
 
171
  # Patch facebook.provider.js + instagram.provider.js: route through reverse proxy
 
172
  for FB_DIST_DIR in "$PATCH_DIR/apps/backend/dist" "$PATCH_DIR/apps/orchestrator/dist"; do
173
  for FB_TARGET in \
174
  "$FB_DIST_DIR/libraries/nestjs-libraries/src/integrations/social/facebook.provider.js" \
 
178
  node -e "
179
  const fs = require('fs');
180
  let code = fs.readFileSync('$FB_TARGET', 'utf8');
181
+ code = code.replace(/https:\/\/graph\.facebook\.com/g, 'https://fb-proxy.firela.io');
182
  fs.writeFileSync('$FB_TARGET', code);
183
  console.log('Facebook proxy patched');
184
  "
 
187
  done
188
 
189
  # Patch instagram.standalone.provider.js: route through reverse proxy
 
190
  for IG_DIST_DIR in "$PATCH_DIR/apps/backend/dist" "$PATCH_DIR/apps/orchestrator/dist"; do
191
  IG_TARGET="$IG_DIST_DIR/libraries/nestjs-libraries/src/integrations/social/instagram.standalone.provider.js"
192
  if [ -f "$IG_TARGET" ]; then
 
194
  node -e "
195
  const fs = require('fs');
196
  let code = fs.readFileSync('$IG_TARGET', 'utf8');
197
+ code = code.replace(/https:\/\/api\.instagram\.com/g, 'https://ig-api-proxy.firela.io');
198
+ code = code.replace(/https:\/\/graph\.instagram\.com/g, 'https://ig-graph-proxy.firela.io');
199
  fs.writeFileSync('$IG_TARGET', code);
200
  console.log('Instagram Standalone proxy patched');
201
  "
 
203
  done
204
 
205
  # Patch hashnode.provider.js: route through reverse proxy
 
206
  for HN_DIST_DIR in "$PATCH_DIR/apps/backend/dist" "$PATCH_DIR/apps/orchestrator/dist"; do
207
  HN_TARGET="$HN_DIST_DIR/libraries/nestjs-libraries/src/integrations/social/hashnode.provider.js"
208
  if [ -f "$HN_TARGET" ]; then
 
210
  node -e "
211
  const fs = require('fs');
212
  let code = fs.readFileSync('$HN_TARGET', 'utf8');
213
+ code = code.replace(/https:\/\/gql\.hashnode\.com/g, 'https://hashnode-proxy.firela.io');
214
  fs.writeFileSync('$HN_TARGET', code);
215
  console.log('Hashnode proxy patched');
216
  "
 
218
  done
219
 
220
  # Patch node-telegram-bot-api: route through reverse proxy
 
 
221
  TG_TARGET="$PATCH_DIR/node_modules/node-telegram-bot-api/src/telegram.js"
222
  if [ -f "$TG_TARGET" ]; then
223
  echo "Patching $TG_TARGET for Telegram proxy..."
224
  node -e "
225
  const fs = require('fs');
226
  let code = fs.readFileSync('$TG_TARGET', 'utf8');
227
+ code = code.replace(/https:\/\/api\.telegram\.org/g, 'https://telegram-proxy.firela.io');
228
  fs.writeFileSync('$TG_TARGET', code);
229
  console.log('Telegram proxy patched');
230
  "
 
253
  fi
254
 
255
  # Patch integration.service.js to wrap uploadSimple in try-catch
 
256
  INTEG_SVC_TARGET="$PATCH_DIR/apps/backend/dist/libraries/nestjs-libraries/src/database/prisma/integrations/integration.service.js"
257
  if [ -f "$INTEG_SVC_TARGET" ]; then
258
  echo "Patching $INTEG_SVC_TARGET for resilient picture upload..."
 
274
  node /app/patches/integ-svc.js "$INTEG_SVC_TARGET"
275
  fi
276
 
277
+ # Patch youtube.provider.js to remove youtubepartner scope
278
  mkdir -p /app/patches
279
  cat > /app/patches/yt-scope.js << 'YTPATCH'
280
  const fs = require('fs');
 
312
  done
313
 
314
  # Write a global Node.js preload script to extend undici fetch timeout
 
 
315
  mkdir -p /app/patches
316
  cat > /app/patches/extend-timeout.js << 'PRELOAD'
317
  try {
 
330
  echo "NODE_OPTIONS=--require /app/patches/extend-timeout.js" >> /app/.env
331
 
332
  # Patch posts.service.js in backend to log startWorkflow calls and errors
 
333
  POSTS_SVC_TARGET="$PATCH_DIR/apps/backend/dist/libraries/nestjs-libraries/src/database/prisma/posts/posts.service.js"
334
  if [ -f "$POSTS_SVC_TARGET" ]; then
335
  echo "Patching $POSTS_SVC_TARGET for startWorkflow logging..."
 
339
  const target = process.argv[2];
340
  let code = fs.readFileSync(target, 'utf8');
341
 
 
 
 
342
  const lines = code.split('\n');
343
  let patched = false;
344
  for (let i = 0; i < lines.length; i++) {
345
  if (lines[i].includes('.startWorkflow(') && !lines[i].includes('async startWorkflow')) {
 
346
  const indent = lines[i].match(/^(\s*)/)[1];
 
 
 
 
 
347
  if (lines[i].includes('.catch(')) {
348
  lines[i] = lines[i].replace('.catch((err) => {})', '.catch((err) => { console.error("[startWorkflow] FAILED:", err?.message || String(err)); })');
349
  if (lines[i] !== code.split('\n')[i]) {
 
351
  console.log('Patched .catch at line ' + i);
352
  }
353
  }
 
354
  if (lines[i].includes('.catch(() => {})') || lines[i].includes('.catch(()=>{})')) {
355
  lines[i] = lines[i].replace(/\.catch\(\(\) => \{\}\)/g, '.catch((err) => { console.error("[startWorkflow] FAILED:", err?.message || String(err)); })');
356
  lines[i] = lines[i].replace(/\.catch\(\(\)=>\{\}\)/g, '.catch((err) => { console.error("[startWorkflow] FAILED:", err?.message || String(err)); })');
 
360
  }
361
  }
362
 
 
363
  const swStart = 'async startWorkflow(';
364
  const swIdx = code.indexOf(swStart);
365
  if (swIdx !== -1) {
 
366
  const braceIdx = code.indexOf('{', swIdx);
367
  if (braceIdx !== -1) {
368
  const before = code.substring(0, braceIdx + 1);
 
378
  fs.writeFileSync(target, lines.join('\n'));
379
  console.log('startWorkflow logging patched');
380
  } else {
 
381
  console.log('No .catch patterns found, dumping startWorkflow context...');
382
  const idx = code.indexOf('async startWorkflow');
383
  if (idx !== -1) {
384
  console.log('startWorkflow method found at offset:', idx);
 
385
  const callSites = [];
386
  let pos = 0;
387
  while ((pos = code.indexOf('.startWorkflow(', pos)) !== -1) {
 
397
  fi
398
 
399
  # Patch social.abstract.js in orchestrator to log raw errors from social providers
 
400
  for SA_DIST_DIR in "$PATCH_DIR/apps/orchestrator/dist" "$PATCH_DIR/apps/backend/dist"; do
401
  SA_TARGET="$SA_DIST_DIR/libraries/nestjs-libraries/src/integrations/social.abstract.js"
402
  if [ -f "$SA_TARGET" ]; then
 
404
  node -e "
405
  const fs = require('fs');
406
  let code = fs.readFileSync('$SA_TARGET', 'utf8');
 
407
  const oldCatch = \"const handle = this.handleErrors(safeStringify(err), 200);\";
408
  const newCatch = \"console.error('[social-abstract] runInConcurrent error:', err?.message || err); console.error('[social-abstract] raw error body:', safeStringify(err)?.substring(0, 2000)); const handle = this.handleErrors(safeStringify(err), 200);\";
409
  if (code.includes(oldCatch)) {
 
417
  fi
418
  done
419
 
420
+ # ============================================================
421
+ # Social platform reverse proxy patches
422
+ # All platforms: route API calls through Cloudflare-proxied domains
423
+ # to bypass HF Space outbound HTTPS blocking
424
+ # ============================================================
425
+
426
+ # --- LinkedIn (api.linkedin.com + www.linkedin.com for OAuth) ---
427
+ for LI_DIST_DIR in "$PATCH_DIR/apps/backend/dist" "$PATCH_DIR/apps/orchestrator/dist"; do
428
+ for LI_TARGET in \
429
+ "$LI_DIST_DIR/libraries/nestjs-libraries/src/integrations/social/linkedin.provider.js" \
430
+ "$LI_DIST_DIR/libraries/nestjs-libraries/src/integrations/social/linkedin.page.provider.js"; do
431
+ if [ -f "$LI_TARGET" ]; then
432
+ echo "Patching $LI_TARGET for LinkedIn proxy..."
433
+ node -e "
434
+ const fs = require('fs');
435
+ let code = fs.readFileSync('$LI_TARGET', 'utf8');
436
+ code = code.replace(/https:\/\/api\.linkedin\.com/g, 'https://linkedin-proxy.firela.io');
437
+ code = code.replace(/https:\/\/www\.linkedin\.com/g, 'https://linkedin-www-proxy.firela.io');
438
+ fs.writeFileSync('$LI_TARGET', code);
439
+ console.log('LinkedIn proxy patched');
440
+ "
441
+ fi
442
+ done
443
+ done
444
+
445
+ # --- Reddit (oauth.reddit.com + www.reddit.com for OAuth) ---
446
+ for RD_DIST_DIR in "$PATCH_DIR/apps/backend/dist" "$PATCH_DIR/apps/orchestrator/dist"; do
447
+ RD_TARGET="$RD_DIST_DIR/libraries/nestjs-libraries/src/integrations/social/reddit.provider.js"
448
+ if [ -f "$RD_TARGET" ]; then
449
+ echo "Patching $RD_TARGET for Reddit proxy..."
450
+ node -e "
451
+ const fs = require('fs');
452
+ let code = fs.readFileSync('$RD_TARGET', 'utf8');
453
+ code = code.replace(/https:\/\/oauth\.reddit\.com/g, 'https://reddit-proxy.firela.io');
454
+ code = code.replace(/https:\/\/www\.reddit\.com/g, 'https://reddit-www-proxy.firela.io');
455
+ fs.writeFileSync('$RD_TARGET', code);
456
+ console.log('Reddit proxy patched');
457
+ "
458
+ fi
459
+ done
460
+
461
+ # --- TikTok (open.tiktokapis.com) ---
462
+ for TK_DIST_DIR in "$PATCH_DIR/apps/backend/dist" "$PATCH_DIR/apps/orchestrator/dist"; do
463
+ TK_TARGET="$TK_DIST_DIR/libraries/nestjs-libraries/src/integrations/social/tiktok.provider.js"
464
+ if [ -f "$TK_TARGET" ]; then
465
+ echo "Patching $TK_TARGET for TikTok proxy..."
466
+ node -e "
467
+ const fs = require('fs');
468
+ let code = fs.readFileSync('$TK_TARGET', 'utf8');
469
+ code = code.replace(/https:\/\/open\.tiktokapis\.com/g, 'https://tiktok-proxy.firela.io');
470
+ fs.writeFileSync('$TK_TARGET', code);
471
+ console.log('TikTok proxy patched');
472
+ "
473
+ fi
474
+ done
475
+
476
+ # --- Pinterest (api.pinterest.com) ---
477
+ for PI_DIST_DIR in "$PATCH_DIR/apps/backend/dist" "$PATCH_DIR/apps/orchestrator/dist"; do
478
+ PI_TARGET="$PI_DIST_DIR/libraries/nestjs-libraries/src/integrations/social/pinterest.provider.js"
479
+ if [ -f "$PI_TARGET" ]; then
480
+ echo "Patching $PI_TARGET for Pinterest proxy..."
481
+ node -e "
482
+ const fs = require('fs');
483
+ let code = fs.readFileSync('$PI_TARGET', 'utf8');
484
+ code = code.replace(/https:\/\/api\.pinterest\.com/g, 'https://pinterest-proxy.firela.io');
485
+ fs.writeFileSync('$PI_TARGET', code);
486
+ console.log('Pinterest proxy patched');
487
+ "
488
+ fi
489
+ done
490
+
491
+ # --- Slack (slack.com) ---
492
+ for SL_DIST_DIR in "$PATCH_DIR/apps/backend/dist" "$PATCH_DIR/apps/orchestrator/dist"; do
493
+ SL_TARGET="$SL_DIST_DIR/libraries/nestjs-libraries/src/integrations/social/slack.provider.js"
494
+ if [ -f "$SL_TARGET" ]; then
495
+ echo "Patching $SL_TARGET for Slack proxy..."
496
+ node -e "
497
+ const fs = require('fs');
498
+ let code = fs.readFileSync('$SL_TARGET', 'utf8');
499
+ code = code.replace(/https:\/\/slack\.com/g, 'https://slack-proxy.firela.io');
500
+ fs.writeFileSync('$SL_TARGET', code);
501
+ console.log('Slack proxy patched');
502
+ "
503
+ fi
504
+ done
505
+
506
+ # --- Twitch (api.twitch.tv + id.twitch.tv for OAuth) ---
507
+ for TW_DIST_DIR in "$PATCH_DIR/apps/backend/dist" "$PATCH_DIR/apps/orchestrator/dist"; do
508
+ TW_TARGET="$TW_DIST_DIR/libraries/nestjs-libraries/src/integrations/social/twitch.provider.js"
509
+ if [ -f "$TW_TARGET" ]; then
510
+ echo "Patching $TW_TARGET for Twitch proxy..."
511
+ node -e "
512
+ const fs = require('fs');
513
+ let code = fs.readFileSync('$TW_TARGET', 'utf8');
514
+ code = code.replace(/https:\/\/api\.twitch\.tv/g, 'https://twitch-proxy.firela.io');
515
+ code = code.replace(/https:\/\/id\.twitch\.tv/g, 'https://twitch-id-proxy.firela.io');
516
+ fs.writeFileSync('$TW_TARGET', code);
517
+ console.log('Twitch proxy patched');
518
+ "
519
+ fi
520
+ done
521
+
522
+ # --- Kick (api.kick.com + id.kick.com for OAuth) ---
523
+ for KI_DIST_DIR in "$PATCH_DIR/apps/backend/dist" "$PATCH_DIR/apps/orchestrator/dist"; do
524
+ KI_TARGET="$KI_DIST_DIR/libraries/nestjs-libraries/src/integrations/social/kick.provider.js"
525
+ if [ -f "$KI_TARGET" ]; then
526
+ echo "Patching $KI_TARGET for Kick proxy..."
527
+ node -e "
528
+ const fs = require('fs');
529
+ let code = fs.readFileSync('$KI_TARGET', 'utf8');
530
+ code = code.replace(/https:\/\/api\.kick\.com/g, 'https://kick-proxy.firela.io');
531
+ code = code.replace(/https:\/\/id\.kick\.com/g, 'https://kick-id-proxy.firela.io');
532
+ fs.writeFileSync('$KI_TARGET', code);
533
+ console.log('Kick proxy patched');
534
+ "
535
+ fi
536
+ done
537
+
538
+ # --- Bluesky (bsky.social + video.bsky.app) ---
539
+ for BS_DIST_DIR in "$PATCH_DIR/apps/backend/dist" "$PATCH_DIR/apps/orchestrator/dist"; do
540
+ BS_TARGET="$BS_DIST_DIR/libraries/nestjs-libraries/src/integrations/social/bluesky.provider.js"
541
+ if [ -f "$BS_TARGET" ]; then
542
+ echo "Patching $BS_TARGET for Bluesky proxy..."
543
+ node -e "
544
+ const fs = require('fs');
545
+ let code = fs.readFileSync('$BS_TARGET', 'utf8');
546
+ code = code.replace(/https:\/\/bsky\.social/g, 'https://bluesky-proxy.firela.io');
547
+ code = code.replace(/https:\/\/video\.bsky\.app/g, 'https://bluesky-video-proxy.firela.io');
548
+ fs.writeFileSync('$BS_TARGET', code);
549
+ console.log('Bluesky proxy patched');
550
+ "
551
+ fi
552
+ done
553
+
554
+ # --- Dribbble (api.dribbble.com + dribbble.com + api-sandbox.pinterest.com) ---
555
+ for DR_DIST_DIR in "$PATCH_DIR/apps/backend/dist" "$PATCH_DIR/apps/orchestrator/dist"; do
556
+ DR_TARGET="$DR_DIST_DIR/libraries/nestjs-libraries/src/integrations/social/dribbble.provider.js"
557
+ if [ -f "$DR_TARGET" ]; then
558
+ echo "Patching $DR_TARGET for Dribbble proxy..."
559
+ node -e "
560
+ const fs = require('fs');
561
+ let code = fs.readFileSync('$DR_TARGET', 'utf8');
562
+ code = code.replace(/https:\/\/api\.dribbble\.com/g, 'https://dribbble-proxy.firela.io');
563
+ code = code.replace(/https:\/\/dribbble\.com/g, 'https://dribbble-www-proxy.firela.io');
564
+ code = code.replace(/https:\/\/api-sandbox\.pinterest\.com/g, 'https://dribbble-sandbox-proxy.firela.io');
565
+ fs.writeFileSync('$DR_TARGET', code);
566
+ console.log('Dribbble proxy patched');
567
+ "
568
+ fi
569
+ done
570
+
571
+ # --- Medium (api.medium.com) ---
572
+ for MD_DIST_DIR in "$PATCH_DIR/apps/backend/dist" "$PATCH_DIR/apps/orchestrator/dist"; do
573
+ MD_TARGET="$MD_DIST_DIR/libraries/nestjs-libraries/src/integrations/social/medium.provider.js"
574
+ if [ -f "$MD_TARGET" ]; then
575
+ echo "Patching $MD_TARGET for Medium proxy..."
576
+ node -e "
577
+ const fs = require('fs');
578
+ let code = fs.readFileSync('$MD_TARGET', 'utf8');
579
+ code = code.replace(/https:\/\/api\.medium\.com/g, 'https://medium-proxy.firela.io');
580
+ fs.writeFileSync('$MD_TARGET', code);
581
+ console.log('Medium proxy patched');
582
+ "
583
+ fi
584
+ done
585
+
586
+ # --- VK (api.vk.com + id.vk.com for OAuth) ---
587
+ for VK_DIST_DIR in "$PATCH_DIR/apps/backend/dist" "$PATCH_DIR/apps/orchestrator/dist"; do
588
+ VK_TARGET="$VK_DIST_DIR/libraries/nestjs-libraries/src/integrations/social/vk.provider.js"
589
+ if [ -f "$VK_TARGET" ]; then
590
+ echo "Patching $VK_TARGET for VK proxy..."
591
+ node -e "
592
+ const fs = require('fs');
593
+ let code = fs.readFileSync('$VK_TARGET', 'utf8');
594
+ code = code.replace(/https:\/\/api\.vk\.com/g, 'https://vk-proxy.firela.io');
595
+ code = code.replace(/https:\/\/id\.vk\.com/g, 'https://vk-id-proxy.firela.io');
596
+ fs.writeFileSync('$VK_TARGET', code);
597
+ console.log('VK proxy patched');
598
+ "
599
+ fi
600
+ done
601
+
602
+ # --- Farcaster/Neynar (api.neynar.com) ---
603
+ for FC_DIST_DIR in "$PATCH_DIR/apps/backend/dist" "$PATCH_DIR/apps/orchestrator/dist"; do
604
+ FC_TARGET="$FC_DIST_DIR/libraries/nestjs-libraries/src/integrations/social/farcaster.provider.js"
605
+ if [ -f "$FC_TARGET" ]; then
606
+ echo "Patching $FC_TARGET for Farcaster proxy..."
607
+ node -e "
608
+ const fs = require('fs');
609
+ let code = fs.readFileSync('$FC_TARGET', 'utf8');
610
+ code = code.replace(/https:\/\/api\.neynar\.com/g, 'https://farcaster-proxy.firela.io');
611
+ fs.writeFileSync('$FC_TARGET', code);
612
+ console.log('Farcaster proxy patched');
613
+ "
614
+ fi
615
+ done
616
+
617
+ # --- Dev.to (dev.to) ---
618
+ for DV_DIST_DIR in "$PATCH_DIR/apps/backend/dist" "$PATCH_DIR/apps/orchestrator/dist"; do
619
+ DV_TARGET="$DV_DIST_DIR/libraries/nestjs-libraries/src/integrations/social/dev.to.provider.js"
620
+ if [ -f "$DV_TARGET" ]; then
621
+ echo "Patching $DV_TARGET for Dev.to proxy..."
622
+ node -e "
623
+ const fs = require('fs');
624
+ let code = fs.readFileSync('$DV_TARGET', 'utf8');
625
+ code = code.replace(/https:\/\/dev\.to/g, 'https://devto-proxy.firela.io');
626
+ fs.writeFileSync('$DV_TARGET', code);
627
+ console.log('Dev.to proxy patched');
628
+ "
629
+ fi
630
+ done
631
+
632
+ # --- MeWe (mewe.com) ---
633
+ for MW_DIST_DIR in "$PATCH_DIR/apps/backend/dist" "$PATCH_DIR/apps/orchestrator/dist"; do
634
+ MW_TARGET="$MW_DIST_DIR/libraries/nestjs-libraries/src/integrations/social/mewe.provider.js"
635
+ if [ -f "$MW_TARGET" ]; then
636
+ echo "Patching $MW_TARGET for MeWe proxy..."
637
+ node -e "
638
+ const fs = require('fs');
639
+ let code = fs.readFileSync('$MW_TARGET', 'utf8');
640
+ code = code.replace(/https:\/\/mewe\.com/g, 'https://mewe-proxy.firela.io');
641
+ fs.writeFileSync('$MW_TARGET', code);
642
+ console.log('MeWe proxy patched');
643
+ "
644
+ fi
645
+ done
646
+
647
+ # --- Moltbook (www.moltbook.com) ---
648
+ for MB_DIST_DIR in "$PATCH_DIR/apps/backend/dist" "$PATCH_DIR/apps/orchestrator/dist"; do
649
+ MB_TARGET="$MB_DIST_DIR/libraries/nestjs-libraries/src/integrations/social/moltbook.provider.js"
650
+ if [ -f "$MB_TARGET" ]; then
651
+ echo "Patching $MB_TARGET for Moltbook proxy..."
652
+ node -e "
653
+ const fs = require('fs');
654
+ let code = fs.readFileSync('$MB_TARGET', 'utf8');
655
+ code = code.replace(/https:\/\/www\.moltbook\.com/g, 'https://moltbook-proxy.firela.io');
656
+ fs.writeFileSync('$MB_TARGET', code);
657
+ console.log('Moltbook proxy patched');
658
+ "
659
+ fi
660
+ done
661
+
662
+ # --- Whop (api.whop.com) ---
663
+ for WP_DIST_DIR in "$PATCH_DIR/apps/backend/dist" "$PATCH_DIR/apps/orchestrator/dist"; do
664
+ WP_TARGET="$WP_DIST_DIR/libraries/nestjs-libraries/src/integrations/social/whop.provider.js"
665
+ if [ -f "$WP_TARGET" ]; then
666
+ echo "Patching $WP_TARGET for Whop proxy..."
667
+ node -e "
668
+ const fs = require('fs');
669
+ let code = fs.readFileSync('$WP_TARGET', 'utf8');
670
+ code = code.replace(/https:\/\/api\.whop\.com/g, 'https://whop-proxy.firela.io');
671
+ fs.writeFileSync('$WP_TARGET', code);
672
+ console.log('Whop proxy patched');
673
+ "
674
+ fi
675
+ done
676
+
677
+ # --- Skool (api2.skool.com) ---
678
+ for SK_DIST_DIR in "$PATCH_DIR/apps/backend/dist" "$PATCH_DIR/apps/orchestrator/dist"; do
679
+ SK_TARGET="$SK_DIST_DIR/libraries/nestjs-libraries/src/integrations/social/skool.provider.js"
680
+ if [ -f "$SK_TARGET" ]; then
681
+ echo "Patching $SK_TARGET for Skool proxy..."
682
+ node -e "
683
+ const fs = require('fs');
684
+ let code = fs.readFileSync('$SK_TARGET', 'utf8');
685
+ code = code.replace(/https:\/\/api2\.skool\.com/g, 'https://skool-proxy.firela.io');
686
+ fs.writeFileSync('$SK_TARGET', code);
687
+ console.log('Skool proxy patched');
688
+ "
689
+ fi
690
+ done
691
+
692
+ # --- X/Twitter (api.x.com + upload.x.com via twitter-api-v2 package) ---
693
+ X_PKG="$PATCH_DIR/node_modules/twitter-api-v2/dist"
694
+ if [ -d "$X_PKG" ]; then
695
+ echo "Patching twitter-api-v2 package for X proxy..."
696
+ for X_FILE in "$X_PKG"/*.js; do
697
+ if [ -f "$X_FILE" ]; then
698
+ node -e "
699
+ const fs = require('fs');
700
+ let code = fs.readFileSync('$X_FILE', 'utf8');
701
+ let changed = false;
702
+ if (code.includes('api.x.com')) {
703
+ code = code.replace(/https:\/\/api\.x\.com/g, 'https://x-proxy.firela.io');
704
+ changed = true;
705
+ }
706
+ if (code.includes('upload.x.com')) {
707
+ code = code.replace(/https:\/\/upload\.x\.com/g, 'https://x-upload-proxy.firela.io');
708
+ changed = true;
709
+ }
710
+ if (changed) {
711
+ fs.writeFileSync('$X_FILE', code);
712
+ console.log('Patched:', '$X_FILE');
713
+ }
714
+ "
715
+ fi
716
+ done
717
+ fi
718
+
719
+ # --- YouTube/Google (www.googleapis.com + youtube.googleapis.com via googleapis package) ---
720
+ YT_PKG="$PATCH_DIR/node_modules/googleapis/build/src"
721
+ if [ -d "$YT_PKG" ]; then
722
+ echo "Patching googleapis package for YouTube/Google proxy..."
723
+ find "$YT_PKG" -name "*.js" | while read YT_FILE; do
724
+ node -e "
725
+ const fs = require('fs');
726
+ let code = fs.readFileSync('$YT_FILE', 'utf8');
727
+ let changed = false;
728
+ if (code.includes('youtube.googleapis.com')) {
729
+ code = code.replace(/https:\/\/youtube\.googleapis\.com/g, 'https://yt-proxy.firela.io');
730
+ changed = true;
731
+ }
732
+ if (code.includes('www.googleapis.com')) {
733
+ code = code.replace(/https:\/\/www\.googleapis\.com/g, 'https://googleapis-proxy.firela.io');
734
+ changed = true;
735
+ }
736
+ if (changed) {
737
+ fs.writeFileSync('$YT_FILE', code);
738
+ console.log('Patched:', '$YT_FILE');
739
+ }
740
+ "
741
+ done
742
+ fi
743
+
744
  echo "=== Patching complete, starting app ==="
745
 
746
  # Delegate to original entrypoint + CMD (nginx && pnpm run pm2)