How-to Guide

How to Post to Social Media from Google Sheets

Quick Answer: Structure a Sheet with columns for media URL, caption, platforms, date/time and timezone. An n8n REST workflow reads rows where 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_url must be a direct HTTPS file link (Drive links must be set to public direct-download)
  • timezone is an IANA name — DOHOO interprets the time as local wall-clock in that zone
  • status is the trigger column: the workflow only touches ready rows, so drafts stay safe

Step 2 — Connect the Sheet to DOHOO (n8n, no code)

The workflow is four nodes:

  1. Schedule Trigger — every 15 minutes
  2. Google Sheets → Get Rows — filter status = ready
  3. HTTP Request → DOHOO — for each platform in column C:
  4. first a download step followed by POST /api/upload/presigned-url and the S3 PUT with the row's media_url (server fetches the file, returns a permanent fileUrl)
  5. then the platform's schedule call with scheduledAt = "{date}T{time}:00" and the row's timezone
  6. 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.

Publish to all 8 platforms in one step — no silent failures.

View DOHOO plans