T-HUB/apps/api/package.json
hacklab c96704fb6b feat: wire the Instagram connector into connect and publishing
The Instagram connector existed but was never registered, so Channels showed
it as "provider unavailable" and publishing could not resolve it.

- Register createInstagramConnector in the connections registry and the
  publishing registry; add the connector-runtime publishing policy
  (idempotency "none": media_publish has no key, never replay).
- The Facebook app credentials identify the Hub, not a collective: read them
  only from INSTAGRAM_CLIENT_ID / INSTAGRAM_CLIENT_SECRET. Drop the
  clientId/clientSecret connect fields and stop copying the app secret into
  each connection's vault entry. The provider is connectable only when both
  are set (connectEnabled + connectNote).
- Fail the connect when several Instagram accounts are granted instead of
  silently publishing as the first Page's account.
- Fix the connector package's pre-existing lint errors (it now ships in api).
- Tests: contract cases for env-only credentials and the multi-account
  refusal; connections integration case for provider gating and the
  Facebook dialog redirect.
- docs/oauth-connect.md: Instagram setup, callback URI and limits.

Not in this change: publishing images needs a public plaintext JPEG URL that
Meta downloads, and storage is client-side encrypted, so presigned S3 URLs
cannot serve it. Until a short-lived media endpoint exists, publishing to
Instagram fails with an explicit error. Token refresh via ig_refresh_token
on graph.facebook.com also needs checking against Facebook Login tokens.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-15 14:15:03 +02:00

48 lines
1.6 KiB
JSON

{
"name": "@tactical-media-broadcast-hub/api",
"private": true,
"version": "0.1.0",
"scripts": {
"dev": "tsx watch src/main.ts",
"build": "tsc -p tsconfig.json",
"lint": "eslint src",
"typecheck": "tsc -p tsconfig.json --noEmit",
"test": "vitest run",
"migrate": "tsx src/db/migrate.cli.ts"
},
"dependencies": {
"@tactical-media-broadcast-hub/connector-sdk": "workspace:*",
"@tactical-media-broadcast-hub/connector-telegram": "workspace:*",
"@tactical-media-broadcast-hub/connector-instagram": "workspace:*",
"@tactical-media-broadcast-hub/core": "workspace:*",
"@aws-sdk/client-s3": "^3.1146.0",
"@aws-sdk/s3-request-presigner": "^3.1146.0",
"@nestjs/common": "^10.4.1",
"@nestjs/core": "^10.4.1",
"@nestjs/platform-express": "^10.4.1",
"@opentelemetry/api": "^1.9.1",
"@opentelemetry/auto-instrumentations-node": "^0.80.0",
"@opentelemetry/exporter-trace-otlp-http": "^0.222.0",
"@opentelemetry/sdk-node": "^0.222.0",
"jose": "^6.2.12",
"pg": "^8.23.1",
"pino": "^9.3.2",
"reflect-metadata": "^0.2.2",
"rxjs": "^7.8.1",
"@tactical-media-broadcast-hub/publishing-execution": "workspace:*",
"@tactical-media-broadcast-hub/connector-runtime": "workspace:*",
"@tactical-media-broadcast-hub/connector-mastodon": "workspace:*",
"@temporalio/client": "1.24.0"
},
"devDependencies": {
"@tactical-media-broadcast-hub/connector-mock-livestream": "workspace:^",
"@types/express": "^4.17.21",
"@types/node": "^22.5.0",
"@types/pg": "^8.23.1",
"tsx": "^4.17.0",
"vitest": "^2.0.5"
},
"engines": {
"node": ">=22.13.0"
}
}