One-click social media publisher — start with Pinterest, grow beyond it.
PinFlow is a powerful, fully automated Chrome Extension built on Manifest V3. It empowers users to capture images and videos from any website via a right-click context menu and seamlessly publish them to Pinterest as newly created Pins — not just saved items.
🔬 How it was built — Pinterest has no public API for pin creation, so the extension's DOM contract was reverse-engineered from recorded HAR traffic (
PinFlow-Engineering-Spec.mddocuments selectors, flows and failure modes;CASE_STUDY.mdwalks through the build). Fragile selectors are handled with fallback chains + remote config, so Pinterest UI changes don't break the tool.
To ensure a smooth, uninterrupted experience and avoid bot detection, PinFlow mimics natural human interaction through a built-in Humanizer engine with jitter delays, simulated typing, and realistic mouse events — all while injecting metadata from reusable, custom profiles.
PinFlow started as a one-person tool to solve a frustrating daily workflow: publishing dozens of images to Pinterest manually was slow, repetitive, and error-prone.
But the real problem is bigger than Pinterest.
Every content creator, marketer, and store owner publishes the same image to multiple platforms — Pinterest, Instagram, Tumblr, Twitter/X, TikTok — one by one, manually, every single day. That's hours of wasted time every week.
The vision for PinFlow is to become a universal, headless, cross-platform publishing engine — where you right-click once (or schedule a batch), and your content reaches all your platforms simultaneously, with zero visible browser tabs and a single control panel.
- 🖱️ Context Menu Integration — Capture images and videos by simply right-clicking media on any webpage.
- 📌 Automated Pin Creation — Publishes items as "Created" Pins with destination URLs, fully automating the Pinterest pin-builder UI.
- 👤 Profile Management — Save and reuse multiple profiles to auto-fill Pin title, description, hashtags, and website link.
- 🧠 Humanized Automation — Custom
Humanizermodule simulates keystrokes, realistic typing delays, word pauses, and natural random-point mouse clicks to avoid bot detection. - 📦 Batch Upload Mode — Queue up to 10 images/videos and publish them sequentially with a single click.
- 🔒 Web Locks Queue Guard — Uses
navigator.locksto prevent race conditions when the queue is triggered multiple times. - ⚡ Dynamic Upload Detection —
MutationObserver-based wait replaces fixed timeouts — moves on exactly when Pinterest signals success, not a second before or after. - ✅ Publish Guardian — Multi-signal system monitors 4 independent DOM signals to confirm the server actually saved the Pin before closing the tab.
- 🎨 Board Selection — Automatically selects or creates a Pinterest board during the pin job.
- 🌐 Dynamic Remote Config — Pinterest's DOM selectors are hosted in a remote JSON file (GitHub Gist) and synced every 6 hours — no re-publishing to the Chrome Web Store needed when Pinterest updates its UI.
- 🍞 Shadow DOM Toast Notifications — CSS-isolated progress notifications injected into the source tab so they never conflict with host-page styles.
- 🔁 Fallback Selector Chains — Every field has a prioritized list of selectors. If Pinterest's A/B tests change the DOM, the next selector in the chain is tried automatically.
The next generation of PinFlow moves from a single-platform extension to a headless, multi-platform publishing powerhouse.
Add publishing automation for more social platforms using the same proven DOM-automation architecture:
| Platform | Status | Notes |
|---|---|---|
| ✅ Live | Full create-pin automation | |
| Tumblr | 🔜 Planned | Image + caption + tags |
| Twitter / X | 🔜 Planned | Image tweet with alt text |
| 🔜 Planned | Requires mobile-view workaround | |
| TikTok | 🔜 Planned | Photo mode support |
| 🔜 Planned | Post with image attachment | |
| Flickr | 🔜 Planned | Full metadata support |
| 🔜 Planned | Multi-subreddit batch posting | |
| 500px | 🔜 Planned | Photography community upload |
| Behance | 🔜 Planned | Portfolio-style publishing |
| Dribbble | 🔜 Planned | Portfolio-style publishing |
The biggest architectural challenge today: Chrome Extensions with content scripts require the target tab to be visible and active. If the tab is minimized or in the background, some DOM interactions fail silently.
The solution is to move the automation layer from the browser extension into a local Chromium Headless process:
- Run a dedicated Chromium instance in headless mode (via Puppeteer or Playwright)
- The extension becomes a scheduler and configuration manager — it collects the jobs, hands them to the headless process
- Headless Chromium runs all DOM automation invisibly, with no open visible windows
- The user can lock their screen, close their laptop lid — jobs still process
This eliminates the #1 user complaint: "My screen has to be on for it to work."
A full local web dashboard (served by the extension's background service worker) for:
- Visual queue management — drag-and-drop reorder, per-platform toggles per item
- Simultaneous multi-platform posting — one image, publish to all selected platforms in parallel
- Per-platform profile editor — different captions/hashtags/links per platform in one view
- Scheduling — set a publish time per item or per batch
- Analytics panel — see which items succeeded, failed, or are pending across all platforms
- Retry logic UI — one-click retry for failed items with detailed error logs
Beyond right-click, add more input sources:
- CSV / spreadsheet import — bulk-schedule hundreds of posts from a file
- RSS / sitemap monitor — auto-detect new content on a website and queue it
- Folder watcher — watch a local folder and publish new images automatically
- AI caption generation — generate platform-specific descriptions using a connected LLM
PinFlow is engineered with strict separation of concerns — no file handles logic from two layers:
| Layer | Technology | Role |
|---|---|---|
| Extension Standard | Chrome Manifest V3 | Permissions, CSP, lifecycle |
| Background | Service Worker | CORS-safe fetch, orchestration, context menu |
| Content Layer | Content Scripts | DOM automation on Pinterest only |
| Queue Guard | navigator.locks API |
Prevents parallel queue execution |
| UI | Vanilla HTML/JS/CSS | Lightweight popup, no framework |
| Storage | chrome.storage.local + Remote JSON |
Local-first with remote selector sync |
pinflow/
├── manifest.json # MV3 permissions and background declaration
├── background/
│ ├── service-worker.js # Entry point: context menu & orchestration
│ ├── fetcher.js # CORS-safe media fetcher → ArrayBuffer
│ ├── config-manager.js # Local/Remote config sync manager
│ ├── queue-manager.js # Sequential batch processor with lock guard
│ └── tab-manager.js # Pinterest tab lifecycle controller
├── content/
│ ├── pin-builder.js # Pinterest DOM automation (upload, fill, publish)
│ ├── humanizer.js # Simulated human typing, delays, click events
│ └── toast.js # Shadow DOM notifications on source tab
├── popup/
│ ├── popup.html # Extension UI
│ ├── popup.js # Profile CRUD & active state management
│ └── popup.css # UI styling
├── shared/
│ ├── constants.js # MSG_TYPES, STORAGE_KEYS
│ └── validator.js # Profile & remote config schema validation
└── remote/
└── config.schema.json # JSON schema for remote selector updates
- Clone or download this repository.
- Open Chrome → navigate to
chrome://extensions/. - Enable Developer mode (top-right toggle).
- Click Load unpacked.
- Select the project folder (the one containing
manifest.json). - The PinFlow icon appears in your extensions bar. ✅
- Click the PinFlow extension icon.
- Create a new profile: Title, Description, Hashtags, Website URL, Board Name.
- Set it as the Active Profile.
- Right-click any image or video on any webpage.
- Select "Pin to Pinterest 📌".
- A Toast notification tracks progress on your current tab. Pinterest opens in the background and publishes automatically.
- Right-click images and select "Add to Pin Queue 📋" to queue them up.
- Select "Publish Queue Now 🚀" from the context menu or the popup.
- PinFlow processes all jobs sequentially, one Pinterest tab, no conflicts.
PinFlow requests the minimum permissions required:
| Permission | Why |
|---|---|
contextMenus |
Add right-click options on images/videos |
storage |
Save profiles and config locally |
activeTab & tabs |
Open Pinterest tab, inject script, show toasts |
scripting |
Execute content script on pinterest.com |
alarms |
Schedule periodic remote config refresh |
<all_urls> host |
Service Worker fetches media from any site (CORS-safe) |
No data is ever sent to any external server other than Pinterest. All profiles and settings live in chrome.storage.local on your own machine.
- CASE_STUDY.md — A deep dive into the engineering challenges faced while building PinFlow, and how each one was solved.
Built for robust, automated social media publishing — starting with Pinterest, growing beyond.