RSS σε 66 κοινωνικά δίκτυα: Facebook, Instagram, X, LinkedIn, Telegram και άλλα Blog Συνεργατικό Πρόγραμμα Επικοινωνία
Σύνδεση Ξεκινήστε δωρεάν
Updated: 2026-10-31
Google Apps Script RSS Feed: Turn a Sheet Into XML

Short answer: With Google Apps Script you can turn a Google Sheet into an RSS feed without a server. Write a doGet function that reads the rows of the sheet, escapes the text, builds the XML with absolute links and RFC 822 dates, and returns it with the RSS mime type. Deploy the script as a web app that anyone can open, copy the address, check it with a validator and give it to an auto-poster. Every row that you mark as published then becomes a post on your social networks.

Many small teams keep their content plan in a spreadsheet: a row for each article, a column for the title, one for the summary, one for the date and one for the status. A spreadsheet is easy for editors, and it needs no hosting. What it lacks is a feed, which is what auto-posters, readers and other tools expect. Google Apps Script closes the gap. It is a JavaScript environment that runs inside your Google account, can read a sheet and can publish a script as a small web address. This guide builds the feed step by step, explains the limits of the platform honestly and ends with a test routine.

Prepare the sheet

Create a sheet with one row per post and fixed column headings in the first row. The script will depend on the order of the columns, so decide it once and keep it.

ColumnContentRule
A: slugThe permanent part of the addressLowercase words with hyphens, never edited after publishing
B: titleThe headline of the postPlain text
C: summaryOne or two complete sentencesNo half sentences
D: publishedDate and time of publicationA real date cell, not text
E: statusThe word Published for live rowsAnything else keeps the row out

Format column D as a date with a time, because two posts on the same day need a clear order. The status column is a simple safety switch: an editor can prepare a row in advance and set it to Published only when the page on the website is live. That prevents the most common problem with spreadsheet feeds, which is an item that points to a page that does not exist yet. If you want to go the other way and post from a sheet without writing code, see how to auto-post from Google Sheets to social media.

Write the doGet function

Open the script editor from the sheet, through the extensions menu, and write one function. A web app calls the function named doGet whenever somebody requests its address.

const SHEET_ID = "paste-the-id-of-your-sheet-here";
const SITE = "https://example.com";

function doGet() {
  const rows = SpreadsheetApp.openById(SHEET_ID)
    .getSheetByName("Posts")
    .getDataRange()
    .getValues()
    .slice(1);

  const now = new Date();
  const posts = rows
    .filter((r) => r[4] === "Published" && r[3] instanceof Date && r[3] <= now)
    .sort((a, b) => b[3] - a[3])
    .slice(0, 20);

  const xml = render(posts);
  return ContentService.createTextOutput(xml)
    .setMimeType(ContentService.MimeType.RSS);
}

The function skips the heading row, keeps only rows with the status Published and a real date in the past, sorts them with the newest first and keeps twenty. Twenty items are enough for a reader or an auto-poster, and a short file is fetched quickly. The mime type tells the receiving program that the output is a feed and not a web page.

Build the XML safely

Text from a sheet can contain ampersands, angle brackets and quotation marks, and any of them can break an XML document. Escape every value before it goes into the template.

const ENT = {
  "&": "&" + "amp;",
  "<": "&" + "lt;",
  ">": "&" + "gt;",
  '"': "&" + "quot;",
  "'": "&" + "apos;",
};
const esc = (s) => String(s == null ? "" : s).replace(/[&<>"']/g, (c) => ENT[c]);

function render(posts) {
  const newest = posts.length ? posts[0][3] : new Date(0);
  const items = posts.map((r) => {
    const url = SITE + "/blog/" + r[0] + "/";
    return "<item>" +
      "<title>" + esc(r[1]) + "</title>" +
      "<link>" + esc(url) + "</link>" +
      "<guid isPermaLink=\"true\">" + esc(url) + "</guid>" +
      "<pubDate>" + r[3].toUTCString() + "</pubDate>" +
      "<description>" + esc(r[2]) + "</description>" +
      "</item>";
  }).join("");
  return "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" +
    "<rss version=\"2.0\"><channel>" +
    "<title>Example Journal</title>" +
    "<link>" + SITE + "</link>" +
    "<description>News and guides from Example Journal.</description>" +
    "<lastBuildDate>" + newest.toUTCString() + "</lastBuildDate>" +
    items + "</channel></rss>";
}

Several details are deliberate. The date method of the language writes the format that the RSS specification expects, and the modern script runtime supports it. The channel date comes from the newest post and not from the clock, so that the file does not change when nothing was published. The identifier of each item is its permanent address, built from the slug in column A and a fixed site constant, so every link is absolute. Check the first item against the real page on your website, because the address that the feed writes must be the address that opens.

Deploy the script as a web app

Use the deploy menu, choose a new deployment of the type web app, run it as yourself and allow access to anyone. The word anyone is important: if only signed-in users may open it, the auto-poster receives a login page instead of a feed. After you confirm, Google shows an address that ends with exec. That address is your feed. The first time, you will be asked to authorise the script to read your sheet, which is normal.

  • Open the address in a private window to check that it works without your login.
  • The browser may show the XML or offer to download it; both are fine.
  • Every code change needs a new version in the deployment settings. Saving the file is not enough, because the address serves the version that was deployed.

The address of the test deployment, which ends with dev, runs the latest saved code but only for you. Never give that one to an auto-poster, because it requires your login.

Know the limits of the platform

Apps Script is convenient, but it is not a web server, and an honest guide must say what it cannot do.

  • No custom headers. You cannot set an ETag or a cache lifetime, so clients cannot skip an unchanged file with a conditional request.
  • A redirect. The address of a web app answers with a redirect to another Google domain before it delivers the content. Most feed readers and auto-posters follow redirects, but test yours.
  • Quotas and speed. A script has daily limits on execution time and requests, and a cold start may take a second or two. A feed that is polled every few minutes is far below the limits for a normal account.
  • A long address. The address is not pretty and belongs to Google. You can put a redirect from your own domain in front of it, but do not hide the real address from yourself.

For a small feed these limits are acceptable. If you need conditional requests, a custom domain or heavy traffic, move the same logic to a small server or a serverless function, as shown in the AWS Lambda feed guide και the Cloudflare Workers feed guide.

Cache the result

Reading a sheet takes time, and a popular feed may be requested often. The script cache service can keep the finished XML for a few minutes, so that most requests are answered without touching the sheet.

function doGet() {
  const cache = CacheService.getScriptCache();
  let xml = cache.get("feed");
  if (!xml) {
    xml = render(loadPosts());
    cache.put("feed", xml, 300);
  }
  return ContentService.createTextOutput(xml)
    .setMimeType(ContentService.MimeType.RSS);
}

The function loadPosts stands for the reading and filtering code shown earlier. The cache holds values up to a limited size, so a feed of twenty short items fits easily, and a lifetime of five minutes means that a new row appears quickly. If you edit a row and want the change to appear at once, you can remove the cached value from the editor.

Dates, drafts and old rows

Because the sheet is edited by hand, the dates need extra care. A date typed as text is not a date, and the script ignores it, which is the safe behaviour. A row with a date in the future stays out until that moment, but the feed is built on request, so the post appears within minutes after the time has passed. If you import old rows, give them their original dates, because a feed full of items with today’s date makes an auto-poster share your whole archive in one afternoon. For the effect of old dates see the guide to feed order and backdated posts.

Test the feed

Request the address with curl, following the redirect, and look at the result instead of assuming that it is right.

curl -sL "https://script.google.com/macros/s/PASTE-YOUR-ID/exec" | head -20
curl -sIL "https://script.google.com/macros/s/PASTE-YOUR-ID/exec"
  • The first line of the body is an XML declaration, followed by an rss element.
  • Every link starts with your real domain and uses https.
  • Each item has a title, a link, a date and a description.
  • The newest row with the status Published comes first.
  • Paste the address into the W3C Feed Validation Service and fix every error.

A longer routine is in the feed validation guide, and a shorter one in debugging a feed with curl.

Common mistakes to avoid

  • Access limited to signed-in users. The auto-poster receives a login page.
  • Forgetting a new version. The address keeps serving the old code.
  • Dates typed as text. The row is silently skipped.
  • Editing slugs. A new address means a repeated post.
  • Marking a row Published too early. The feed links to a page that does not exist yet.
  • Unescaped text. One ampersand in a title breaks the whole document.

How PostRSS works with an Apps Script feed

PostRSS has been publishing RSS and Atom feeds to social networks since 2014. Paste the address of your feed, connect your accounts and choose how each post is built from the title, the description or the page title. PostRSS checks the feed as often as every minute and shares each new entry, with its image and link, to the channels you choose among 66 supported networks, messengers, team chats and blogs, including LinkedIn, X, Bluesky, Mastodon and Telegram. Keyword filters, UTM parameters and posting windows let you tune each channel. See the PostRSS features page and the plan limits on the pricing page. More developer guides are under the Technical Guide tag.

Σχετική ανάγνωση

The bottom line

A spreadsheet can be a perfectly good source for a feed. Keep the columns fixed, use a real date and a status column as a safety switch, escape the text, build absolute links from the slug, return the RSS mime type and deploy the script as a web app that anyone can open. Remember the limits: no custom headers, a redirect and quotas. Test the live address with curl and a validator, then connect it to an auto-poster, and every row you publish reaches your readers and your social channels.

FAQ

Can Google Apps Script return an RSS feed?

Yes. A doGet function can return text output with the RSS mime type, and a web app deployment gives the function a public address.

Does the feed work without logging in?

Yes, if the deployment allows access for anyone. Test the address in a private window to be sure.

Why does my feed show old content after I changed the code?

The web app address serves the version that was deployed. Create a new version in the deployment settings after every change.

Can I set an ETag or cache headers?

Not in a script web app. You can cache the result inside the script, but the response headers cannot be customised, so conditional requests are not available.

Can PostRSS read a feed served by Apps Script?

Yes. PostRSS reads any valid RSS or Atom address that is reachable without a login. Paste the address, connect your channels and new rows are shared as soon as they appear.

New guides, once a month

What changed in the networks, what broke, and how to fix it before it costs you reach.

We send a confirmation e-mail first. Unsubscribe any time.

Περισσότερα εργαλεία από την ομάδα μας

Από την Internet Solutions, την ομάδα πίσω από το PostRSS. Κάθε προϊόν σάς εξοικονομεί χρόνο με τον δικό του τρόπο.

Live chat με AI για ιστότοπους Talkmio Ο ιστότοπός σας απαντά στους επισκέπτες 24/7 με βάση το δικό σας περιεχόμενο, στη γλώσσα τους. Δωρεάν πρόγραμμα · χωρίς κάρτα Βοηθός AI Ask Mio Συνομιλία, κώδικας, σχεδιασμός, γραφή και έρευνα. Το Mio επιλέγει το καλύτερο μοντέλο για κάθε εργασία. Δωρεάν πρόγραμμα Αυτόματος πιλότος AI για blog και social AI Blog Autopilot Η AI γράφει άρθρα SEO 2.000–3.000 λέξεων και κοινοποιεί το καθένα σε 60 κοινωνικά δίκτυα. Τα 3 πρώτα άρθρα δωρεάν Έλεγχος υγείας ιστότοπου Έλεγχος AI ιστοτόπου SEO, ταχύτητα, SSL, ασφάλεια και ρυθμίσεις email σε μία αναφορά, με σειρά προτεραιότητας. Ο πρώτος έλεγχος δωρεάν Σε βάθος ανίχνευση SEO Έλεγχος SEO AI ιστοτόπου Πλήρης ανίχνευση SEO σε 7 τομείς, μαζί με την ορατότητα στην αναζήτηση AI, με διορθώσεις ταξινομημένες κατά αντίκτυπο. Ο πρώτος έλεγχος δωρεάν RSS και ροές προϊόντων Δημιουργός RSS Feed Δημιουργήστε RSS από οποιαδήποτε σελίδα, καθώς και ροές προϊόντων για Google και Meta που ενημερώνονται μόνες τους. Δωρεάν πρόγραμμα Ανάπτυξη ιστότοπων και SEO Internet Solutions Ιστότοποι, ηλεκτρονικά καταστήματα και εξατομικευμένα συστήματα, που σχεδιάζει, κατασκευάζει και υποστηρίζει η ομάδα μας. Από το 2011