How to make publishedAfter field working? - youtube-data-api

I'm trying to get videos of a particular channel using search/list API method. But looks like publishedAfter field doesn't work.
Example: https://www.googleapis.com/youtube/v3/search?part=snippet&channelId=UCgxTPTFbIbCWfTR9I2-5SeQ&maxResults=50&order=date&publishedAfter=2019-01-01T00:00:00Z&type=video&key=MYKEY
"totalResults": 1546,
...
{
"kind": "youtube#searchResult",
"etag": "\"XpPGQXPnxQJhLgs6enD_n8JR4Qk/ZrInvdAerhIEEIuhaU-Op01jNGQ\"",
"id": {
"kind": "youtube#video",
"videoId": "lkHUuL_qBKc"
},
"snippet": {
"publishedAt": "2018-10-05T16:45:52.000Z",
"channelId": "UCgxTPTFbIbCWfTR9I2-5SeQ",
"title": "🔥 Путин обманул. Квартира за 2 млрд. ГРУ",
...
There are less than 150 videos with publishedAt > 1st of January, but API returns 1546 videos and the results contain videos, that were published before 1st of January, the above example shows 5th of October, 2018. Looks like API ignores publishedAfter condition as well as order=date.
It's weird, but two days ago the same url with the same key gave correct results.
Is it possible to get correct search results?

It's not your fault. Right now, it's seems like a global problem.
Read here - https://support.google.com/youtube/thread/2494861?hl=en
My youtube app is broken too.

Related

How i can get list of popular youtube channels per each country?

How i can get list of popular youtube channels per each country?
this service find solution
https://www.channelcrawler.com/eng/results2/281574
I tried youtube api but i didn't find, anyone know solution?
As mentioned, is not possible to get this information using the YouTube API directly, even in the FAQ of the page you shared says:
The Channel Crawler was made to discover new YouTube channels, based on your search criteria.
and:
The Channel Crawler uses advanced data collection methods in order to collect channel information from YouTube and store it in the database. Basically, it just checks the liked videos and comment sections of channels that are already in the database, in order to add more channels to it. You can also manually add a channel.
Following the highlighted information, I have this idea and you can try it too:
Use the search endpoint for search channels in a specific country and in a specific videoCategory, then, with the channelId returned in the results of the search, use the channel endpoint for get their country1.
1 take into account that some channels doesn't have the country value; in this case, you have to set another criteria(s) for determine whether the channel matches with your requirements.
Example:
Use the search endpoint for search channels in country/region Pakistan and in the videoCategory Sports - test it here:
URL:
https://youtube.googleapis.com/youtube/v3/search?part=id%2Csnippet&order=videoCount&q=Sports&regionCode=PK&key=[YOUR_API_KEY]
The results of this request are as follows:
{
"kind": "youtube#searchListResponse",
"etag": "0C7hSI3oNXJt66PsERuviVQcLCo",
"nextPageToken": "CAUQAA", // Remember the nextPageToken for get the next results.
"regionCode": "PK", // Region queried.
"pageInfo": {
"totalResults": 1000000, // Look the amount of data you have to check, filter and debug.
"resultsPerPage": 5 // Set "maxResults" parameter to "50" for get more results per page.
},
"items": [
{
"kind": "youtube#searchResult",
"etag": "iSwEnBs_yV6lOIBubmRXVwjjujQ",
"id": {
"kind": "youtube#channel", // Make sure that this item is actually an channel.
"channelId": "UCo2TvjBHS1BtyIkeGGTMe6w"
},
"snippet": {
"publishedAt": "2018-07-28T18:34:04Z",
"channelId": "UCo2TvjBHS1BtyIkeGGTMe6w", // Use this value for the "channel" endpoint.
"title": "ONTime Sports",
"description": "قناة اون تايم سبورت واحدة من مجم...",
"thumbnails": { [thumbnails here...] },
"channelTitle": "ONTime Sports",
"liveBroadcastContent": "upcoming",
"publishTime": "2018-07-28T18:34:04Z"
}
},
[other results here...]
]
}
Use channel endpoint for get the channel detailed information - in this case, their country - test it here:
URL - using the channelId UCo2TvjBHS1BtyIkeGGTMe6w - obtained from the previous search results:
https://youtube.googleapis.com/youtube/v3/channels?part=id%2Csnippet&id=UCo2TvjBHS1BtyIkeGGTMe6w&key=[YOUR_API_KEY]
The results of this request are as follows:
{
"kind": "youtube#channelListResponse",
"etag": "8BfUXxlAEBLe7lBmih1JXUwZ394",
"pageInfo": {
"totalResults": 1,
"resultsPerPage": 5
},
"items": [
{
"kind": "youtube#channel",
"etag": "AFk5NCl9393ui58WyRf7WljoatE",
"id": "UCo2TvjBHS1BtyIkeGGTMe6w",
"snippet": {
"title": "ONTime Sports",
"description": "large description here...",
"customUrl": "ontimesportseg",
"publishedAt": "2018-07-28T18:34:04Z",
"thumbnails": {[thumbnails here]},
"localized": {
"title": "ONTime Sports",
"description": "large description here..."
},
"country": "EG" // This is the regionCode of the country this channels has provided.
}
}
]
}
Here, you can see that the value "country" for this channel is "EG" = Egypt2.
Then, repeat these steps with all countries and videoCategory for each country.
Considerations:
As I tested, the type parameter in search is not working as one might expect, in this case (for get channels only), use the order=viewCount combination of parameter=value. Even with this combination, make sure to check that the value of the kind attribute is: youtube#channel. Also, I search the videoCategory using its name, no its id - as it should be -, but, the API is not perfect, that's why I used the name of the videoCategory.
Even specifiyng the region parameter with a valid country, you might get results that are either from another countries or doesn't have the country attribute and value at all = and that's due the channel's popularity in the given country and public channel information. A simple example could be: ESPN, they probably have a YouTube channel for each country, but, their main channel is the most popular in all countries, so, in this case, you'll get the ESPN channel in english and that might differ from your expected results. You have to work with what YouTube provides.
As you notice, there are too many channels/results to debug, so, make sure to provide more filters and set your queries/search criteria and (once you get the desired results), store the valid results in a database or similar.
If you know specific channels that you know are popular in a given country, but, when you query that channel using the YouTube Data API, it doesn't bring the country value, you have to save that channel manually in your database and/or collect more information for automatically set if a channel is from a given country - this point is very related to my point # 2.

YouTube API returns wrong video duration

I'm using the YouTube API to get the duration of videos. However, the API response does not correspond to video length.
Example:
https://www.youtube.com/watch?v=g5xNzUA5Qf8
Length on YouTube 3:33
Screen shot of video on YouTube
Duration in YouTube API: 1 day, 2 hours 34 minutes and 17 seconds
{
"kind": "youtube#video",
"etag": "tWwii1RezGsoNlQtpFjI00I5gog",
"id": "g5xNzUA5Qf8",
"contentDetails": {
"duration": "P1DT2H34M17S",
"dimension": "2d",
"definition": "sd",
"caption": "false",
"licensedContent": false,
"contentRating": {},
"projection": "rectangular"
}
}
Other example:
https://www.youtube.com/watch?v=KZeXI0iHsAA
3 minutes vs 1 hour
Is this a YouTube API bug, or is there something I don't understand?
I didn't find anyone reporting a similar problem.
It seems that one more time YouTube Data API v3 doesn't work as documented.
I would recommend you to use my open-source YouTube operationnal API at https://yt.lemnoslife.com/videos?part=contentDetails&id=g5xNzUA5Qf8
It will return you the correct duration in seconds and not in the ISO 8601 format (if you really need this format please leave a comment).

Filter video list by tag

Goal
Get videos, ordered by date, and filtered by tag from a specific YouTube channel. I need only the videos that have that unique tag. I understand I can get the latest uploaded videos, then one by one query YouTube API for each video and determine if it has the tags I need. But I find that too lengthy and wonder if there's a single API request than can handle that filter for me.
Tried
Reading this API documentation I understood the snippet was supposed to have a snippet.tags:
snippet.tags[]
list
A list of keyword tags associated with the video. Tags may contain spaces. The property value has a maximum length of 500 characters. Note the following rules regarding the way the character limit is calculated:
The property value is a list, and commas between items in the list count toward the limit.
If a tag contains a space, the API server handles the tag value as though it were wrapped in quotation marks, and the quotation marks count toward the character limit. So, for the purposes of character limits, the tag Foo-Baz contains seven characters, but the tag Foo Baz contains nine characters.
Using the following (search/list)
https://www.googleapis.com/youtube/v3/search?part=snippet&channelId=CHANNEL_ID&maxResults=10&order=date&type=video&key=MY_GOOGLE_CONSOLE_KEY
I get:
{
"kind": "youtube#searchResult",
"etag": "\"cbz3lIQ2N25AfwNr-BdxUVxJ_QY/MO86DiShKKJ483oXkFJdDmvBd5M\"",
"id": {
"kind": "youtube#video",
"videoId": "jMywJTXhkVs"
},
"snippet": {
"publishedAt": "2017-09-16T15:28:40.000Z",
"channelId": "UC4GRKWUEhUvsCqD-yNQpxQw",
"title": "Real Time - Gesture Drawing 7 (5.10 mins time)",
"description": "Join me in gesture drawing practice from photo reference. :) References (in order of drawing) - Thank you to SenshiStock (https://senshistock.deviantart.com/) ...",
"thumbnails": {
"default": {
"url": "https://i.ytimg.com/vi/jMywJTXhkVs/default.jpg",
"width": 120,
"height": 90
},
"medium": {
"url": "https://i.ytimg.com/vi/jMywJTXhkVs/mqdefault.jpg",
"width": 320,
"height": 180
},
"high": {
"url": "https://i.ytimg.com/vi/jMywJTXhkVs/hqdefault.jpg",
"width": 480,
"height": 360
}
},
"channelTitle": "Chayemor",
"liveBroadcastContent": "none"
}
}
The snippet only includes publishedAt, channelId, title, and description, certainly no tags.
Looking into /search/list documentation I see that it has another parameter that I might be able to use:
q
string
The q parameter specifies the query term to search for.
Your request can also use the Boolean NOT (-) and OR (|) operators to
exclude videos or to find videos that are associated with one of
several search terms. For example, to search for videos matching
either "boating" or "sailing", set the q parameter value to
boating|sailing. Similarly, to search for videos matching either
"boating" or "sailing" but not "fishing", set the q parameter value to
boating|sailing -fishing. Note that the pipe character must be
URL-escaped when it is sent in your API request. The URL-escaped value
for the pipe character is %7C.
So I use the tag "sketching" that I know is set in various videos. (A way to determine if a single video's tags is through https://www.googleapis.com/youtube/v3/videos?key=GOOGLE_KEY&fields=items(snippet(title,description,tags))&part=snippet&id=video_id )
https://www.googleapis.com/youtube/v3/search?q=%22sketching%22&part=snippet&channelId=CHANNEL_ID&maxResults=25&order=date&type=video&key=GOOGLE_KEY
That yields this:
{
"kind": "youtube#searchListResponse",
"etag": "\"cbz3lIQ2N25AfwNr-BdxUVxJ_QY/hPC7YXbOHVWNEk_6UiC5Jzdh5Zs\"",
"regionCode": "ES",
"pageInfo": {
"totalResults": 10,
"resultsPerPage": 25
},
"items": []
}
Nothing else. It says there are 10 results, but I don't see them, I do't know what they are. I tried sending the request without the "" but it returned the same result. Messing around I saw that when searching within a channel's videos from YouTube (as a browser client, through GUI, not API), it uses the parameter 'query'. So out of not having any more ideas I decided to substitute q for query.
https://www.googleapis.com/youtube/v3/search?query=sketching&part=snippet&channelId=UC4GRKWUEhUvsCqD-yNQpxQw&maxResults=25&order=date&type=video&key=GOOGLE_KEY
That query did yield results, but not of those videos who had that unique tag, but rather any video that had that tag or that word used in the title or description.
{
"kind": "youtube#searchListResponse",
"etag": "\"cbz3lIQ2N25AfwNr-BdxUVxJ_QY/xjWZRnm0X7B_csQX4KEu9nv_qdQ\"",
"regionCode": "ES",
"pageInfo": {
"totalResults": 24,
"resultsPerPage": 25
},
"items": [ ... ]
}
Any suggestions?

YouTube API v3 returns no items

A week ago I started using the YouTube API v3, and have been able to retrieve 13 items from the API using this URL:
https://www.googleapis.com/youtube/v3/search?key={MyKey}&channelId={AChannelId}&part=snippet,id&order=date&maxResults=5
Today I used this exact same call/URL and now it returns:
// 20140828161458
// https://www.googleapis.com/youtube/v3/search?key={MyKey}&channelId={AChannelId}&>part=snippet,id&order=date&maxResults=5
{
"kind": "youtube#searchListResponse",
"etag": "\"gLjvtM18QUCicnbwPLo7vn_YIlg/Z7muB3yLsIIdSeQTKlRVObzSk8M\"",
"pageInfo": {
"totalResults": 0,
"resultsPerPage": 5
},
"items": [
]
}
So no items are being returned, eventhough there should be 13. I used another channelId to make sure the problem wasn't in the channelId, but it also returned nothing.
I have checked the Google blog, but there was no mention of a change. Anyone have an idea what could be wrong?

Pull public event data from Google Calendar

I may be over thinking this a bit. On my web site, I would like to user certain data from my public google calendar. My plan is to pull it on the server side so I can do things like process it, cache it and format it the way I want.
I've been looking at using the Google Api libraries, but I can't get past any of the authorization hurdles. A service account sounds like what I really want, but I'm having trouble wrapping my head around how that works in this situation.
The old GDATA apis would be ok, but I'm not very keen on using them because they look fairly deprecated at this point by the newer libraries.
Since it is all public data, I'm hoping there is a simpler way to get to the event data that I'm looking for.
In case it matters, my site is Asp.Net (MVC).
Update
Ok, I was definitely way over thinking it. See my answer.
Now that RSS has been removed from Google Calendar, I've been in search of an easy replacement. I dug around and found the following in the Google Calendar API that seems to do the trick: calendar.events.list
Calendar Events List in Google API Explorer is a good place to get started with the different parameters and options - and it'll build you an example request string. You can see that I specified a minimum time of 2/5/2016, sort it by the start time, and show deleted events.
GET https://www.googleapis.com/calendar/v3/calendars/[CALENDAR ID HERE]/events?
orderBy=startTime&showDeleted=true&singleEvents=true&
timeMin=2016-02-05T00%3A00%3A00Z&key={YOUR_API_KEY}
Results are in JSON so you can parse it in your favorite programming language, ASP.NET or whatever. Result looks like:
{
"kind": "calendar#events",
"etag": "\"123456789123456\"",
"summary": "My Public Calendar",
"updated": "2016-01-29T14:38:29.392Z",
"timeZone": "America/New_York",
"accessRole": "reader",
"defaultReminders": [ ],
"items": [ {
"kind": "calendar#event",
"etag": "\"9876543210987654\"",
"id": "sfdljgsdkjgheakrht4sfdjfscd",
"status": "confirmed",
"htmlLink": "https://www.google.com/calendar/event?eid=sdgtukhysrih489759sdkjfhwseihty7934hyt94hdorujt3q95uy689u9yhfdgnbiwe5hy",
"created": "2015-07-06T16:21:59.000Z",
"updated": "2015-07-06T16:21:59.329Z",
"summary": "In-Service Day",
"location": "Maui, HI",
"creator": {
"email": "abra#cadabra.com",
"displayName": "Joe Abra"
},
"organizer": {
"email": "cadabra.com_sejhrgtuiwerghwi4hruh#group.calendar.google.com",
"displayName": "My Public Calendar",
"self": true
},
"start": {
"date": "2016-02-08"
},
"end": {
"date": "2016-02-09"
},
"transparency": "transparent",
"iCalUID": "isdt56y784g78ty86tgsfdgh#google.com",
"sequence": 0
},
{
...
}]
}
One good answer to this (the one I'm going with) is to simply use the calendar's public address to get the data. This is an option that I had forgotten about and it works fine for this particular situation.
You can find the url for the data if you go to the settings for a particular calendar and pick the format you want (I went with xml for this situation.)
The data that you get out of this service is very human-reader optimized, but I can make it work for what I'm doing.

Resources