-1

When I run the following JavaScript through Google Apps script with more then 100 keywords.

function youTubeSearchResults() {
  // 1. Retrieve values from column "A".
  const sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
  const values = sheet.getRange("A2:A" + sheet.getLastRow()).getDisplayValues().filter(([a]) => a);

  // 2. Retrieve your current values.
  const modifyResults = values.flatMap(([keywords]) => {
    const searchResults = YouTube.Search.list("id, snippet", { q: keywords, maxResults: 10, type: "video", order: "viewCount", videoDuration: "short", order: "date" });
    const fSearchResults = searchResults.items.filter(function (sr) { return sr.id.kind === "youtube#video" });
    return fSearchResults.map(function (sr) { return [keywords, sr.id.videoId, `https://www.youtube.com/watch?v=${sr.id.videoId}`, sr.snippet.title, sr.snippet.publishedAt, sr.snippet.channelTitle, sr.snippet.channelId, `https://www.youtube.com/channel/${sr.snippet.channelId}`, sr.snippet.thumbnails.high.url] });
  });

  // 3. Retrieve viewCounts and subscriberCounts.
  const { videoIds, channelIds } = modifyResults.reduce((o, r) => {
    o.videoIds.push(r[1]);
    o.channelIds.push(r[6]);
    return o;
  }, { videoIds: [], channelIds: [] });
  const limit = 50;
  const { viewCounts, subscriberCounts } = [...Array(Math.ceil(videoIds.length / limit))].reduce((obj, _) => {
    const vIds = videoIds.splice(0, limit);
    const cIds = channelIds.splice(0, limit);
    const res1 = YouTube.Videos.list(["statistics"], { id: vIds, maxResults: limit }).items.map(({ statistics: { viewCount } }) => viewCount);
    const obj2 = YouTube.Channels.list(["statistics"], { id: cIds, maxResults: limit }).items.reduce((o, { id, statistics: { subscriberCount } }) => (o[id] = subscriberCount, o), {});
    const res2 = cIds.map(e => obj2[e] || null);
    obj.viewCounts = [...obj.viewCounts, ...res1];
    obj.subscriberCounts = [...obj.subscriberCounts, ...res2];
    return obj;
  }, { viewCounts: [], subscriberCounts: [] });
  const ar = [viewCounts, subscriberCounts];
  const rr = ar[0].map((_, c) => ar.map(r => r[c]));

  // 4. Merge data.
  const res = modifyResults.map((r, i) => [...r, ...rr[i]]);

  // 5. Put values on Spreadsheet.
  sheet.getRange(2, 2, res.length, res[0].length).setValues(res);
}

it gives me that error

GoogleJsonResponseException: API call to youtube.videos.list failed with error: 
The request cannot be completed because you have exceeded your <a href="/youtube/v3/getting-started#quota">quota</a>.
reduce.viewCounts @code.gs:23
youTubeSearchResults @code.gs:20 

I know YouTube have data call limits for example you can call the results of not more then 50 video ids at one time but if you have 1000 video ids in your sheet you can run then loop for first 50 then next so on. Is it anything like that I can do with search results too.

Please help me understand how can I fix this issue.

tamey
  • 3
  • 3
  • The YT API has a hard limit of 1000 request units, where usually 1 entitiy in the response = 1 unit. To increase this hard limit you need to have your project assessed and audited by YT, details here: https://developers.google.com/youtube/v3/guides/quota_and_compliance_audits. Hint: you are very unlikely to pass this audit. – Rory McCrossan Sep 25 '22 at 18:25
  • Isn't it 10000 units? – Kos Sep 25 '22 at 19:50
  • Does this answer your question? [The request cannot be completed because you have exceeded your quota](https://stackoverflow.com/questions/58469228/the-request-cannot-be-completed-because-you-have-exceeded-your-quota) – Kos Sep 25 '22 at 20:06
  • @Kos [It's indeed 10,000 quota units](https://developers.google.com/youtube/v3/getting-started#quota). You can see each endpoint quota cost [here](https://developers.google.com/youtube/v3/determine_quota_cost). – Benjamin Loison Sep 25 '22 at 20:24

1 Answers1

0

Note that the endpoint the most expensive in your script is the Search: list one which costs 100 of your 10,000 quota (you can have a look to other endpoint costs here).

You may be interested in the standalone quota-free solution that consists in reverse-engineering the YouTube UI search feature.

Otherwise a temporary solution to Google audit consists in using my no-key service.

With my no-key service:

const searchResults = YouTube.Search.list("id, snippet", { q: keywords, maxResults: 10, type: "video", order: "viewCount", videoDuration: "short", order: "date" });

would become:

const searchResults = JSON.parse(UrlFetchApp.fetch(`https://yt.lemnoslife.com/noKey/search?part=snippet&q=${keywords}&maxResults=10&type=video&order=viewCount&videoDuration=short`).getContentText())

As part=id doesn't add more data to the response and AFAIK using two order isn't supported by YouTube Data API v3.

Benjamin Loison
  • 3,782
  • 4
  • 16
  • 33
  • I tried to use your website for search query (https://yt.lemnoslife.com/search?part=id,snippet&q=accident) but I am unable to get results in following order, Date (Today) ,Type (Video), Duration (Short), Relevance (View Count) – tamey Sep 26 '22 at 06:41
  • You are using my YouTube operational API not the no-key service, use https://yt.lemnoslife.com/noKey/search?part=id,snippet&q=accident instead – Benjamin Loison Sep 26 '22 at 10:50
  • Thank you for your guidance, Can you please help me to understand how can i get this data [link](https://yt.lemnoslife.com/noKey/search?part=id,snippet&q=accident&order=viewCount&order=date&type=video&videoDuration=short&publishedAfter=2022-09-26T00:00:00Z) in google sheets. I need "videoid" "Title" "video Views' "subscriber count" "Channel Name" "img url" "published date". – tamey Sep 26 '22 at 16:29
  • [I modified accordingly my answer](https://stackoverflow.com/posts/73847671/revisions) to help you use my no-key service in your Google Apps Script. – Benjamin Loison Sep 26 '22 at 17:16
  • The results fetched by using your link works perfect for me but the only problem I don't have any programming background that's why I am unable to get desired results in google sheets. can you please guide me what is the solution. I spend last 6 hours to find a solution but no success. – tamey Sep 26 '22 at 23:26
  • As described in [your question](https://stackoverflow.com/q/73846826/7123660), your only error is related to quota. With [my solution](https://stackoverflow.com/a/73847671/7123660) you solved it, to apply my solution you just have to replace a code snippet by another as I described so you don't need any programming background. If it doesn't work, just share the error message/undesired behavior you got. – Benjamin Loison Sep 27 '22 at 05:49
  • Thank you so much for the support, For now I think I figured it out. – tamey Sep 27 '22 at 09:33