status = ready, sends each to DOHOO's schedule endpoints, and writes back scheduled plus the post ID. Your team plans in a spreadsheet; publishing happens on autopilot.Plan note: Direct REST API workflows require Business or Agency.
A spreadsheet is still the best collaborative content calendar: everyone can edit it, comment on it, and see the month at a glance. The only thing it can't do is publish. Fix that.
Step 1 — Structure the Sheet
| A: media_url | B: caption | C: platforms | D: date | E: time | F: timezone | G: status | H: result |
|---|---|---|---|---|---|---|---|
| https://.../v1.mp4 | Launch day 🚀 | tiktok,instagram,youtube | 2026-07-15 | 19:00 | America/New_York | ready | |
| https://.../v2.mp4 | Behind the scenes | instagram,facebook | 2026-07-16 | 12:30 | America/New_York | ready |
Rules that keep the automation robust:
media_urlmust be a direct HTTPS file link (Drive links must be set to public direct-download)timezoneis an IANA name — DOHOO interprets the time as local wall-clock in that zonestatusis the trigger column: the workflow only touchesreadyrows, so drafts stay safe
Step 2 — Connect the Sheet to DOHOO (n8n, no code)
The workflow is four nodes:
- Schedule Trigger — every 15 minutes
- Google Sheets → Get Rows — filter
status = ready - HTTP Request → DOHOO — for each platform in column C:
- first
a download step followed by POST /api/upload/presigned-url and the S3 PUTwith the row'smedia_url(server fetches the file, returns a permanentfileUrl) - then the platform's schedule call with
scheduledAt = "{date}T{time}:00"and the row'stimezone - Google Sheets → Update Row — set
status = scheduled, write the returned post ID into H
Full node-by-node setup: Automate Social Media with n8n.
Step 3 — Close the Loop with Status Write-Back
Add a second small workflow that runs daily: query DOHOO's scheduled posts with status: "all", match post IDs against column H, and write published or failed: <errorMessage> back to the row. Your spreadsheet becomes not just a calendar but a truthful publishing log — including explicit failure reasons, which no manual process gives you.
Apps Script Alternative (No n8n)
If you'd rather stay inside Google Workspace, a time-driven Apps Script trigger does the same job:
function publishReadyRows() {
const sheet = SpreadsheetApp.getActiveSheet();
const rows = sheet.getDataRange().getValues();
rows.forEach((r, i) => {
if (r[6] !== "ready") return;
const resp = UrlFetchApp.fetch("https://dohoo.ai/api/...", { // endpoint per docs.dohoo.ai
method: "post",
headers: { "X-API-Key": PropertiesService.getScriptProperties().getProperty("DOHOO_KEY") },
contentType: "application/json",
payload: JSON.stringify({ /* row → schedule params */ })
});
sheet.getRange(i + 1, 7).setValue("scheduled");
});
}
FAQ
Can several people manage the calendar together?
Yes — that's the point. Anyone edits the Sheet; only rows flipped to ready ever get scheduled.
What about per-platform captions?
Add columns like caption_x (≤280 chars) and caption_instagram (≤2200) and map each in the workflow.
How do I know a row actually published?
The write-back loop stamps published or failed with the exact error message from DOHOO — no silent gaps in the feed.
Airtable instead of Sheets?
Same pattern with a nicer database layer — see Airtable to Social Media.