# Launchpad: posting to X and LinkedIn (copy what you need into .env) # Where the app and the API are reached. Both platforms send people back to # {API_URL}/api/social/{x,linkedin}/callback after they connect an account, so API_URL must be reachable from the # internet (when running locally, an https tunnel such as ngrok: API_URL=https://.ngrok-free.app). FRONTEND_URL=http://localhost:5173 API_URL=http://localhost:8000 # X: developer.x.com > your app > Keys and tokens > "OAuth 2.0 Client ID and Client Secret" # (not the API Key / Bearer Token). Then User authentication settings: # App permissions: Read and write. Type of app: Web App (confidential client). # Callback URI: {API_URL}/api/social/x/callback # Scopes asked for: tweet.read tweet.write users.read offline.access media.write # (media.write posts images and videos; accounts connected before it was added are asked to reconnect) # X is switched off for now (LinkedIn only). Set to true to bring it back. X_ENABLED=false X_CLIENT_ID= X_CLIENT_SECRET= # LinkedIn: linkedin.com/developers > your app > Auth > "Client ID" and "Primary Client Secret" # Products: "Sign In with LinkedIn using OpenID Connect" and "Share on LinkedIn". # Auth > Authorized redirect URLs: {API_URL}/api/social/linkedin/callback # Scopes asked for: openid profile w_member_social # LinkedIn tokens last about 60 days; then the account shows Reconnect. LINKEDIN_CLIENT_ID= LINKEDIN_CLIENT_SECRET= # Connections: X tokens are refreshed automatically (every 10 minutes the worker checks them, and every 6 hours asks # each platform whether the connection still works). When a connection goes down, its scheduled posts are paused and # never attempted; reconnecting the same account resumes the ones still ahead. # Encrypts the stored social tokens (a Fernet key). Empty: derived from JWT_SECRET. # Make one with: python -c "from cryptography.fernet import Fernet; print(Fernet.generate_key().decode())" SOCIAL_TOKEN_KEY=