如何使用 Google App Script 从 Youtube 搜索中创建 RSS 提要?

Posted

技术标签:

【中文标题】如何使用 Google App Script 从 Youtube 搜索中创建 RSS 提要?【英文标题】:How can I make an RSS feed from Youtube search using Google App Script? 【发布时间】:2015-08-09 18:54:46 【问题描述】:

自从 Youtube 关闭了使用其最新版本 API 进行搜索的 RSS 提要,我一直在尝试使用 Google App Script 重新创建它们。这是我目前所拥有的(基于 this tutorial 将 twitter 小部件转换为 RSS):

function getSearches(a)
  try
    var rss,title,link;

    title="Youtube RSS Feed";
    link="http://www.youtube.com";

    var d=ScriptApp.getService().getUrl()+"?"+a;
    rss='<?xml version="1.0"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">';
    rss+='<channel><title>'+title+'</title>';
    rss+='<link>'+link+'</link>';
    rss+='<atom:link href="'+d+'" rel="self" type="application/rss+xml" />';
    rss+='<description>Youtube RSS feed updated on '+new Date()+'.</description>';

    var results = YouTube.Search.list('id, snippet', 
      q: a,
      maxResults: 50,
      order: 'date'
    );

    for(var i = 0; i < results.items.length; i++)
      var item = results.items[i];
      rss += "<item>";
      rss += "<title>" + item.snippet.title + "</title>";
      rss += "<link>http://www.youtube.com/watch?v=" + item.id.videoId + "</link>";
      rss += "<description>" + item.snippet.description + "</description>";
      rss += "<pubDate>" + Utilities.formatDate(new Date(item.snippet.publishedAt), "EDT", "EEE, dd MMM yyyy HH:mm:ss Z") + "</pubDate>";
      rss += "<guid>http://www.youtube.com/watch?v=" + item.id.videoId + "</guid>";
      rss += "</item>";
    
    rss+="</channel></rss>";
    Logger.log(rss)
    return rss
  
  catch(e)
    return"Something went wrong. Please retry after few minutes"
  


function doGet(e)
  //var a = e.queryString();
  var a = getSearches("search term");

  return ContentService.createTextOutput(a).setMimeType(ContentService.MimeType.RSS);

当我将其发布为 Web 应用程序并对其进行测试时,生成的页面看起来不错。我可以单击链接,它们会将我带到正确的视频。但是,当我尝试订阅提要(在我的情况下使用 Inoreader)时,它说没有找到提要。如果我直接在我的阅读器(同样是 Inoreader)中订阅网络应用程序 url,它似乎可以工作;但所有条目都链接到网络应用程序,而不是 youtube,并在单击时从 Google 应用程序脚本返回错误。

理想情况下,我希望网络应用能够接受任何搜索词并返回要通过 https://script.google.com/macros/s/LONG_KEY/exec?SEARCH_TERM 订阅的提要,类似于上面链接的 twitter RSS 功能。有没有人在这样的事情上取得过任何成功或可以给我指点?

【问题讨论】:

您是否设置了对应用程序的访问权限?当您单击底部的Deploy as Webapp 时,会有一个部分显示Who has access to the app 我经常会运行另一个浏览器,但我还没有登录谷歌进行测试,这样我就知道访问级别是正确的。除此之外,如果您的提要相同,它应该可以工作。 我相信我已经正确设置了一切。我已授权该应用程序。在权限下,我以自己的身份执行应用程序,“任何人,甚至匿名”都可以访问该应用程序。 【参考方案1】:

如何使用 Google 应用脚本从 Youtube 搜索中创建 RSS 提要:

在GitHub获取我的脚本的最新版本

function getSearchRSS(query)
  let results = YouTube.Search.list('id, snippet', 
    q: query,
    maxResults: 50,
    order: 'date'
  );

  let encoded_query = encodeURIComponent(query)
  let rss_url = ScriptApp.getService().getUrl() + "?" + encoded_query;

  let channel = XmlService.createElement("channel")
    .addContent(XmlService.createElement("title").addContent(XmlService.createText("Youtube Search RSS Feed: " + query)))
    .addContent(XmlService.createElement("link").addContent(XmlService.createText("https://www.youtube.com/results?search_query=" + encoded_query)))
    .addContent(XmlService.createElement("description").addContent(XmlService.createText("Youtube Search RSS feed for search query '" + query + "' updated on " + (new Date()))))
    .addContent(XmlService.createElement("link", XmlService.getNamespace("atom", "http://www.w3.org/2005/Atom")).setAttribute("rel", "self").setAttribute("href", rss_url));

  for(let i = 0; i < results.items.length; ++i)
    let video = results.items[i];
    let yt_url = "https://www.youtube.com/watch?v=" + video.id.videoId;
    channel.addContent(XmlService.createElement("item")
      .addContent(
        XmlService.createElement("title").addContent(XmlService.createText(video.snippet.title))
      ).addContent(
        XmlService.createElement("link").addContent(XmlService.createText(yt_url))
      ).addContent(
        XmlService.createElement("description").addContent(XmlService.createText(video.snippet.description))
      ).addContent(
        XmlService.createElement("pubDate").addContent(XmlService.createText(Utilities.formatDate(new Date(video.snippet.publishedAt), "EDT", "EEE, dd MMM yyyy HH:mm:ss Z")))
      ).addContent(
        XmlService.createElement("guid").addContent(XmlService.createText(yt_url))
      ))
  


  return XmlService.getPrettyFormat().format(XmlService.createDocument(
        XmlService.createElement("rss").setAttribute("version", "2.0").addContent(channel)
      ));


function doGet(req) 
  let query = decodeURIComponent(req.queryString);
  return ContentService.createTextOutput(getSearchRSS(query))
    .setMimeType(ContentService.MimeType.RSS)

如何使用这个脚本:

部署:

    在https://script.google.com/ 上创建脚本 将代码粘贴到新脚本 资源 -> 高级 Google 服务 -> 启用 YouTube 数据 API 发布 -> 作为网络应用程序 抓取生成的 URL,在 URL 末尾添加搜索查询,并在其前面加上“?”标记。 完成。

代码的每次更改都需要您在部署窗口中添加新的项目版本:

例如:

部署选项卡中的 URL:https://script.google.com/macros/s/BLABLABLA/exec

我希望生成的搜索查询:#hot16challenge2

此查询的 URL 编码版本:%23hot16challenge2

基于此查询以 RSS 响应的最终 URL:

https://script.google.com/macros/s/BLABLABLA/exec?%23hot16challenge2

【讨论】:

我收到ReferenceError: YouTube is not defined (line 2, file "Code") @AndréLevy 您是否按照说明进行操作?您似乎尚未启用 YouTube 数据 API。【参考方案2】:

所以看来我的问题是发布的网络应用程序的版本。我不知道不增加版本会缓存应用程序,就像它在该版本下首次发布时一样。我注意到在测试应用程序时出现了代码更改;但是在查看已发布的 url 输出时,它们不存在。

文件 > 管理版本允许我增加版本号,然后更改开始显示,我能够订阅源。

【讨论】:

以上是关于如何使用 Google App Script 从 Youtube 搜索中创建 RSS 提要?的主要内容,如果未能解决你的问题,请参考以下文章

在Google-App-Script for Google云端硬盘中如果标题包含某个字词,如何将某些文件从root移动到某个文件夹?

如何从 Google App Script 中的文件运行保存的 Big Query 脚本? [关闭]

如何向 Google Apps Script Web App 发送有效的 HTTP 请求?

如何在 Google App Script 中使用参数调用 MySQL 存储过程?

Google App Script:从范围选择中删除空白行以进行排序

如何收听Telegram Bot错误? (Google App Script + Webhooks)