101 lines
7.8 KiB
Markdown
101 lines
7.8 KiB
Markdown
# Social Accounts
|
|
|
|
## Account Mapping
|
|
| Brand | Facebook Page | Facebook Page ID | Instagram Business Account | Instagram User ID | X/Twitter Account | Target Username |
|
|
| --- | --- | --- | --- | --- | --- | --- |
|
|
| QRMaster.net | QRMaster.net | 884792004727212 | QRMaster.net | 17841480094799114 | TIMO_QRMASTER | qrmaster |
|
|
| GreenLens Pro | GreenLens Pro | 1150261294842586 | GreenLens Pro | 17841422012320229 | greenlensproai | greenlens.pro |
|
|
|
|
|
|
## Brand Rules
|
|
- QRMaster-Posts dürfen **nur** auf `QRMaster.net`-Accounts posten.
|
|
- GreenLens-Posts dürfen **nur** auf `GreenLens Pro`-Accounts posten.
|
|
- Kein Crossposting zwischen Brands.
|
|
- Token niemals öffentlich teilen; nur Referenz in dieser Datei.
|
|
|
|
|
|
## Scripts
|
|
| Path | Purpose |
|
|
| --- | --- |
|
|
| `C:\Users\timo\Documents\meta_token_refresh.py` | Meta Long-Lived + Page Token Refresh |
|
|
| `C:\Users\timo\Documents\instagram_r2_carousel_post.py` | Instagram single-image/carousel über R2 |
|
|
| `C:\Users\timo\x-api-autopost\x_media_post.py` | X/Twitter for QRMaster |
|
|
| `C:\Users\timo\greenlens-x-autopost\` | X/Twitter for GreenLens |
|
|
|
|
|
|
## Token Files / Paths
|
|
| Path | Contains |
|
|
| --- | --- |
|
|
| `C:\Users\timo\Documents\meta_instagram_tokens.env` | Meta Facebook + Instagram long-lived/page tokens |
|
|
| `C:\Users\timo\Documents\r2_social_media.env` | R2 upload credentials for IG assets |
|
|
| `C:\Users\timo\Documents\instagram_r2_carousel_post.py` | uses both env files above |
|
|
| `C:\Users\timo\Documents\XApiAutopost\.env` | X/Twitter QRMaster creds |
|
|
| `C:\Users\timo\Documents\greenlens-x-autopost\.env` | X/Twitter GreenLens creds |
|
|
| `C:\Users\timo\Documents\greenlens\Greenlens\.env` | GreenLens TikTok + plant import admin creds |
|
|
|
|
## QRMaster TikTok Cron Credentials
|
|
- Source of truth: the server-side `.env` for the QRMaster app.
|
|
- Required variables: `TIKTOK_CLIENT_KEY`, `TIKTOK_CLIENT_SECRET`, `TIKTOK_REDIRECT_URI`.
|
|
- Optional helper: `TIKTOK_ADMIN_KEY` for guarding the `/api/tiktok/connect` start route.
|
|
- OAuth result: access/refresh tokens are stored in the database after `/api/tiktok/connect` and `/api/tiktok/callback`.
|
|
- Do not put TikTok access tokens in `.env`; the cron job reads them from the DB through the app flow.
|
|
- For cron posting, use the same QRMaster server environment that already contains `CRON_SECRET` / `INTERNAL_API_SECRET` for internal APIs.
|
|
|
|
## TikTok Connection Status + Credential Locations
|
|
- QRMaster TikTok OAuth is connected and tested live via `https://qrmaster.net/api/tiktok/callback`; the callback success screen returned `TikTok account connected. You can close this tab.`
|
|
- GreenLens TikTok OAuth is connected and tested live via `https://greenlenspro.com/api/tiktok/callback`; the callback success screen returned `TikTok account connected. You can close this tab.`
|
|
- QRMaster app credentials live in the QRMaster server-side `.env` and are wired through `QR-Master/docker-compose.yml` (`TIKTOK_CLIENT_KEY`, `TIKTOK_CLIENT_SECRET`, `TIKTOK_REDIRECT_URI`, `TIKTOK_ADMIN_KEY`).
|
|
- GreenLens app credentials live in `C:\Users\timo\Documents\greenlens\Greenlens\.env` / the corresponding server-side `.env` and are wired through `Greenlens/docker-compose.yml` (`TIKTOK_CLIENT_KEY`, `TIKTOK_CLIENT_SECRET`, `TIKTOK_REDIRECT_URI`, `PLANT_IMPORT_ADMIN_KEY`).
|
|
- Hermes scratch/test reference file for local operator checks: `C:\Users\timo\.hermes\.env`. Treat it as local helper state, not production source of truth.
|
|
|
|
## TikTok Posting Policy for Cron Jobs and Live Posting
|
|
- Default policy for **both** QRMaster and GreenLens: TikTok jobs should **upload/draft only**, never direct-post, unless Timo explicitly says otherwise.
|
|
- If Timo says only **"Go"**, interpret that as permission for TikTok **upload/draft only**. Timo finishes the final publish manually inside TikTok.
|
|
- QRMaster specifically should be treated as **upload-only**.
|
|
- GreenLens should also remain **upload-only by default** unless Timo explicitly asks for a different behavior.
|
|
- Do not treat a generic approval like "Go" as permission for automatic/direct TikTok publishing.
|
|
|
|
## TikTok Analytics (Display API, read-only)
|
|
- The requested scopes MUST exactly match what each app has approved in the TikTok Developer Portal — requesting an unapproved scope aborts the whole OAuth login with a generic "scope" error.
|
|
- Approved scopes per app (as of 2026-07-09):
|
|
- QRMaster: `user.info.basic, user.info.profile, user.info.stats, video.list, video.upload` (NO `video.publish` — upload/draft only).
|
|
- GreenLens Pro: `user.info.basic, video.upload, video.publish` (NO analytics scopes yet — a portal revision adding `user.info.stats` + `video.list` is required before GreenLens analytics works).
|
|
- Admin-key-protected live analytics endpoints (no data is stored, every call reads fresh from TikTok):
|
|
- QRMaster: `GET /api/tiktok/analytics?key=<TIKTOK_ADMIN_KEY>&max_videos=50`
|
|
- GreenLens: `GET /api/tiktok/analytics` (guarded by the plant import admin key)
|
|
- Response: account stats (followers, total likes, video count) plus per-video views/likes/comments/shares with computed `engagement_rate`, `posted_weekday_utc` and `posted_hour_utc`, and a summary block (totals, average/median views).
|
|
- After any scope change the account must re-authorize via `/api/tiktok/connect`, otherwise the stored token keeps the old permissions.
|
|
|
|
## TikTok Photo/Carousel Upload Notes
|
|
- Photo posts use `POST /v2/post/publish/content/init/` with `post_mode: MEDIA_UPLOAD` (draft in the creator's inbox, needs only `video.upload`). Valid post modes are only `MEDIA_UPLOAD` and `DIRECT_POST` — `DRAFT` is not a valid value.
|
|
- Photos are delivered via `source_info.photo_images` as public URLs (`PULL_FROM_URL`). TikTok only pulls from **verified domains** — verify the hosting domain (e.g. `greenlenspro.com` for MinIO storage URLs) under Content Posting API → "Verify domains" in the Developer Portal, otherwise the upload fails.
|
|
- QRMaster's only verified property is `qrmaster.net` (via `public/tiktokVwGRbyf2BbBLqUlFrnehtntSEU9Ihiok.txt`). The Cloudflare R2 public domain (`pub-*.r2.dev`, used for Instagram) is **not** verified — never pass R2 URLs to the TikTok photo API for QRMaster.
|
|
|
|
## QRMaster Social Asset Hosting (no-deploy image URLs)
|
|
- `POST https://qrmaster.net/api/social-assets` (header `x-admin-key: <TIKTOK_ADMIN_KEY>`) with JSON `{ "files": [{ "filename", "mimeType", "dataBase64" }] }` stores images in PostgreSQL and returns public `https://qrmaster.net/api/social-assets/<id>` URLs on the verified domain.
|
|
- `GET /api/social-assets/<id>` serves the file publicly (immutable cache); `GET /api/social-assets` (admin) lists the last 100 assets; `DELETE /api/social-assets/<id>` (admin) removes one.
|
|
- Allowed types: jpeg/png/webp/mp4, max 10 MB per file. Table `SocialAsset` is auto-created on first upload (`CREATE TABLE IF NOT EXISTS`, in line with the no-migrations policy).
|
|
- Typical carousel flow: upload slides here → pass the returned URLs as `photos` to `POST /api/tiktok/upload` → check via `/api/tiktok/upload/status?publish_id=...`. No app deploy needed per carousel.
|
|
|
|
## Refresh Behavior
|
|
- Meta user/page tokens werden automatisch refreshed durch `python C:\Users\timo\Documents\meta_token_refresh.py`.
|
|
- QRMaster Page-Auswahl erzwingt Page-ID `884792004727212`.
|
|
- GreenLens Page-Auswahl erzwingt Page-ID `1150261294842586`.
|
|
|
|
|
|
## Cron Jobs
|
|
| Job Name | Schedule | Deliver | Notes |
|
|
| --- | --- | --- | --- |
|
|
| `Weekly Meta Token Refresh` | Montag 09:00 | Telegram + Email | Refreshes Meta tokens |
|
|
|
|
> Social-package deliverables only after explicit `Go`.
|
|
|
|
|
|
## Publish Checklist
|
|
1) Brand wählen → nur passende Accounts zulassen.
|
|
2) Media vorbereiten: QRMaster → R2-Prefix `qrmaster/`, GreenLens → `greenlens/`.
|
|
3) Facebook: Page-ID + Page-Token verwenden.
|
|
4) Instagram: IG User ID + Page-Token über Container + `media_publish`.
|
|
5) X: zugehöriges Brand-Skript + zugehöriges `.env` verwenden.
|
|
6) Keine Token/Secrets loggen.
|