@revopsglobal/linkedin-poster
v0.2.2
Published
RevOps Global LinkedIn poster. Local service that executes approved LinkedIn engagements from the RGOS queue.
Downloads
441
Readme
@revopsglobal/linkedin-poster
Local service that executes approved LinkedIn engagements from the RGOS queue. Runs as a macOS LaunchAgent and polls the RGOS queue every 15 seconds for items assigned to you.
Install
Prerequisites (one-time):
brew install node # or https://nodejs.org
npm install -g agent-browser
npm install -g @revopsglobal/linkedin-posterConfigure and start:
rgos-poster setupsetup walks you through logging in to RGOS, fetches your sender config from the poster-bootstrap edge function, creates a dedicated Chrome profile isolated from your daily browsing, prompts you to log in to LinkedIn there, and installs a LaunchAgent so the poster auto-starts on every login.
Commands
| Command | What it does |
|---------|--------------|
| rgos-poster setup | First-time install. Bootstraps config, creates dedicated Chrome profile, installs LaunchAgent. Safe to re-run (reloads LaunchAgent). |
| rgos-poster start | Run the poster in the foreground. Useful for debugging. |
| rgos-poster status | Hit the poster's /health endpoint and print the result. |
| rgos-poster logs | Tail the poster log file. |
| rgos-poster relogin | Re-open the dedicated Chrome profile to re-authenticate LinkedIn when the session expires. |
| rgos-poster uninstall | Stop the LaunchAgent, remove config and plist. Chrome profile is preserved. |
How it works
rgos-poster setupcalls theposter-bootstrapSupabase edge function with your RGOS session token. The edge function verifies you're an active sender inteam_membersand returns your port, sender identity, and Supabase credentials.- Secrets (
SUPABASE_SERVICE_ROLE_KEY,SLACK_WEBHOOK_URL) are stored in the macOS keychain under servicergos-poster. The LaunchAgent plist and~/.rgos-poster.envcarry only non-secret config (port, sender name, profile path). The poster hydrates secrets from the keychain at boot. - The LaunchAgent runs
src/poster.cjson every login with your sender env. poster.cjsstarts an HTTP server on your assigned port (Greg: 3747, Rachit: 3748, Kristina: 3749) and polls thelinkedin_engagement_queuetable every 15 seconds.- When an approved item matches your
sender_id, the poster drives your dedicated Chrome profile viaagent-browserto execute the LinkedIn action, then writes the result back to Supabase.
Troubleshooting
LinkedIn session expired. The poster detects this on every poll and sends a Slack alert (with a 30-minute cooldown). Run rgos-poster relogin to re-authenticate.
Port conflict. Each sender has a dedicated port. If rgos-poster status reports ECONNREFUSED, the poster probably crashed on startup. Check rgos-poster logs.
"LI_SENDER_NAME env var is required". Your LaunchAgent plist is missing env vars. Re-run rgos-poster setup.
agent-browser not found. Install globally: npm install -g agent-browser.
Chrome profile lock. The dedicated profile is isolated (~/Library/Application Support/rgos-linkedin-poster/Chrome/) and should never conflict with your main Chrome. If you see lock errors, quit all Chrome instances (killall "Google Chrome") and retry.
Uninstall
rgos-poster uninstall
npm uninstall -g @revopsglobal/linkedin-posterUpgrading from 0.1.x
Versions 0.1.x wrote SUPABASE_SERVICE_ROLE_KEY and SLACK_WEBHOOK_URL directly into ~/Library/LaunchAgents/com.revopsglobal.linkedin-poster-*.plist. Starting in 0.2.0 they live in the macOS keychain.
npm install -g @revopsglobal/linkedin-poster
rgos-poster setup # detects legacy secrets, migrates them, rewrites plistTo verify:
grep -E 'SUPABASE_SERVICE_ROLE_KEY|SLACK_WEBHOOK_URL' \
~/Library/LaunchAgents/com.revopsglobal.linkedin-poster-*.plist
# should return no matches
security find-generic-password -s rgos-poster -a SUPABASE_SERVICE_ROLE_KEY -w
security find-generic-password -s rgos-poster -a SLACK_WEBHOOK_URL -w
# both should print a valueIf you were running 0.1.x, rotate the old key in Supabase and the Slack webhook after upgrading — assume the plaintext copies have been backed up.
