Skip to content

Instantly share code, notes, and snippets.

@ronoaldo
Last active November 29, 2022 18:01
Show Gist options
  • Save ronoaldo/9ca1efa85f083ef5ed2f to your computer and use it in GitHub Desktop.
Save ronoaldo/9ca1efa85f083ef5ed2f to your computer and use it in GitHub Desktop.
Google Apps Script RSS Feed Generator
// O título do Feed
var FEED_TITLE = 'Meu Feed RSS';
// Descrição do Feed
var FEED_DESC = 'Esse é o meu Feed RSS';
// URL do Feed - O padrão aqui é usar a URL do próprio script
var FEED_URL = ScriptApp.getService().getUrl();
// O ID da planilha que vai alimentar o FEED
var SHEET_ID = 'ID DA PLANILHA AQUI';
function doGet(e) {
// Setup
var ss = SpreadsheetApp.openById(SHEET_ID);
data = ss.getSheetByName('Feed').getDataRange().getValues(),
xml = '<?xml version="1.0" encoding="UTF-8"?>';
xml += '<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">';
xml += '<channel><title>' + FEED_TITLE + '</title>';
xml += '<description>' + FEED_DESC + '</description>';
xml += '<link>' + FEED_URL + '</link>';
xml += '<atom:link href="' + FEED_URL + '" rel="self" type="application/rss+xml" />';
// Lookup items from spreadsheet
for (var i=1; i < data.length; i++) {
var title = data[i][0],
link = data[i][1],
desc = data[i][2],
pubDate = data[i][3];
xml += '<item>';
xml += '<title>' + title + '</title>';
xml += '<link>' + link + '</link>';
xml += '<description>' + desc + '</description>';
xml += '<pubDate>' + new Date(pubDate).toUTCString() + '</pubDate>';
xml += '<guid>' + makeGUID(i) + '</guid>';
xml += '</item>';
}
xml += '</channel></rss>';
var response = ContentService.createTextOutput(xml)
response.setMimeType(ContentService.MimeType.RSS);
return response
}
function makeGUID(pos) {
if (FEED_URL.indexOf('?') > 0) {
return FEED_URL += '&guid=' + pos;
}
return FEED_URL + '?guid=' + pos;
}
@ronoaldo
Copy link
Author

Como usar:

  1. Crie uma planilha do Google Drive com as colunas (nesta ordem): Title, Link, Description, Publish Date. Publish Date tem que ser reconhecido como data na planilha.
  2. Clique em Tools -> Script Editor e abra um novo script em branco.
  3. Copie e cole o conteúdo do gist no arquivo Code.gs
  4. Edite as variáveis do começo so script. Em especial, troque o ID da planilha senão não vai funcionar.
  5. Salve o script e execute a função doGet() para autorizar o script a abrir a planilha.
  6. Publique como web app, lembre-se de por acessível para qualquer usuário não autenticado (mais detalhes aqui: https://developers.google.com/apps-script/guides/web)

A URL do script publicado é o seu FEED.

@ronoaldo
Copy link
Author

ronoaldo commented Mar 22, 2021

Hi, I just tested it on a new Google Sheets project and it worked fine:

Made the sheet public so you can go to File -> Make a copy and adapt the script to your needs:

https://docs.google.com/spreadsheets/d/13sAItB5-D5XWY836-nwQw3Ibwb9OT8U0-cYlqSmFBbA/edit?usp=sharing

Hope this helps!

@zebrastribe
Copy link

zebrastribe commented Sep 1, 2021

Hi Ronoaldo
Great script I have a few issues tho.

  1. I added this function because it seems like RSS-feed will break on some characters:
    function escapeXml(unsafe) {
    return unsafe.replace(/[<>&'"]/g, function (c) {
    switch (c) {
    case '<': return '<';
    case '>': return '>';
    case '&': return '&';
    case ''': return ''';
    case '"': return '"';
    }
    });
    }

  2. Also the RSS feed only works in chrome? in firefox it will just download a file called "echo" with the feed inside.
    Edit: It seems like Firefox has dropped support for RSS feed all together... so it was not a problem with the script

@ronoaldo
Copy link
Author

ronoaldo commented Sep 4, 2021

Hi! I'm glad you liked it :) Thanks for the patch, but it seems to replace each character with itself? Can you elaborate a bit on that?

@zebrastribe
Copy link

Skærmbillede 2021-09-08 kl  14 39 31
looks funny :)
githubs auto correction at work...
function escapeXml(unsafe) { return unsafe.replace(/[<>&'"]/g, function (c) { switch (c) { case '<': return '&lt;'; case '>': return '&gt;'; case '&': return '&amp;'; case '\'': return '&apos;'; case '"': return '&quot;'; } }); }

@ancmto
Copy link

ancmto commented Nov 28, 2022

Muito interessante seu Script, parabéns.

Você tem algum outro modelo, mas que sirva pra gerar um arquivo XML?

@ronoaldo
Copy link
Author

@ancmto o atual já produz um XML 😄 - ele apenas formata como um XML que segue o padrão do RSS ... Você pode compor tags diversas a partir da mesma lógica e gerar o XML no formato desejado. Daria para fazer um pouco de "mágica" detectando o nome das colunas a partir do Script Service e usar este nomo como nome de cada tag do XML gerado.

@ronoaldo
Copy link
Author

Mas onde ele gera os arquivo?

@ancmto no meu script a ideia é gerar o XML do RSS como parte da resposta de uma requisição web, através da publicação do script como web app. Assim dá para adicionar a URL do web app em um leitor de RSS que então irá consumir os dados gerados pelo script. Em resumo, neste meu trecho específico não é gerado um arquivo.

Desculpe a ignorância, sou novo nisso.

Estou usando um outro código para gerar o XML, mas que gera o arquivo final dentro de um documento do DOCS.

 var doc = DocumentApp.openByUrl('https://docs.google.com/document/d/1ggag_FjtTUqO4eMvH7N2iM0kHxQo84v3Dv3eSM2SImU/edit');
  var header = doc.getHeader();
  if (header)
    header.clear();
  var footer = doc.getFooter();
  if (footer)
    footer.clear();
  var body = doc.getBody(); 
  body.setText(xml.toString())
  
  

Você pode usar o script em um outro formato sim, para gerar um documento, mas aí teria que extrair a geração do XML de dentro da função doGet(e) do meu script, pois nesse cenário a parte do response não se aplica. O trecho que você compartilhou na mensagem acima seria algo na linha de geração como um documento do Docs. Outra abordagem seria gerar o arquivo diretamente dentro do drive.

Eu não tenho nenhum exemplo de código desta parte, mas seria algo como obter um File do Google Drive, e em seguida gravar os bytes do XML nele. O DriveApp já tem uma função que recebe a string gerada, então seria algo assim (não testei isso!):

var xml = createXmlFromSheet();
var file = DriveApp.createFile("meuarquivo.xml", xml.toString(), "text/xml");
console.log(`Arquivo gerado em ${file.getDownloadUrl()}`);

Boa sorte!

@ancmto
Copy link

ancmto commented Nov 29, 2022

Legal.... Mas já estou conseguindo fazer o que eu preciso, com o código que você mandou... Eu acho que tinha entendido o passa a passo, mas fui com calma, e está sendo bem fácil... Agora só estou organizando as informações da planilha.

Depois vou experimentar essa opção com a geração do arquivo no Drive.

Obrigado!

@ronoaldo
Copy link
Author

ronoaldo commented Nov 29, 2022

@ancmto acabei conseguindo um exemplo. Faz uma cópia desta planilha e aí ao abrir sua cópia vai aparecer o menu XML depois do menu Ajuda no sheets. Ao rodar o script, ele irá gerar um arquivo persons.xml no seu drive. A primeira vez irá pedir permissão.

https://docs.google.com/spreadsheets/d/1p6aGoF1D968qA114vMGvq9sxHfF4adQ2EY8X5A3IH7U/edit?usp=sharing

Se preferir, crie sua própria planilha e nela crie uma aba chamada "Persons". As colunas/linhas serão convertidas em um XML automaticamente. Adicione este script na planilha:

function xmlFromSheet() {
  // Setup
  var ss = SpreadsheetApp.getActive(),
      data = ss.getSheetByName('Persons').getDataRange().getValues(),
      xml = '<?xml version="1.0" encoding="UTF-8"?>';
  
  headers = data[0];

  xml += "<persons>";

  // Lookup items from spreadsheet
  for (var i=1; i < data.length; i++) {
    // For each column create a tag with the header name
    var row = data[i];

    xml += "<person>";
    for (var j=0; j<row.length; j++) {
      var tag = headers[j];

      xml += `<${tag}>${row[j]}</${tag}>`;
    }
    xml += "</person>"
  }

  xml += "</persons>";

  return xml;
}

function sheetToXML() {
  var xml = xmlFromSheet();
  var file = DriveApp.createFile("persons.xml", xml.toString(), "text/xml");
  console.log(`File created at ${file.getDownloadUrl()}`);
}

function onOpen() {
  var ui = SpreadsheetApp.getUi();
  ui.createMenu("XML").addItem("Convert to XML", "sheetToXML").addToUi();
}

@ancmto
Copy link

ancmto commented Nov 29, 2022

Eu fiz a inserção desse código, mas não funcionou.

var xml = createXmlFromSheet();
var file = DriveApp.createFile("meuarquivo.xml", xml.toString(), "text/xml");
console.log(Arquivo gerado em ${file.getDownloadUrl()});

Captura de ecrã 2022-11-29, às 20 00 49

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment