Youtube API Subscription.ContentDetails.NewItemCount returning zero if querying myself but return different value from Google API Explorer - youtube-api

When using the youtube API to get the list of my subscriptions and all the related details I get a number of information from the snippet and contentDetails part of the response object.
When I call the service from my script the contentDetails.newItemCount always return zero, this should indicate the number of new videos on the channel since last time I've opened the channel. The contentDetails.totalItemCount (total number of videos for the channel) is accurate instead.
In contrast if I run the same query through the google api explorer, the same variable contains the correct information and not zero.
The call I make from my PHP script is exactly the same as the one run on the google api explorer so I can't explain or understand why I'm getting different results. The code I use is roughly the following
$this->_youtube = new Google_Service_YouTube($this->_connector->_googleClient);
$params = array('mine' => true,'maxResults'=>25,'order'=>'alphabetical');
$part = 'snippet,contentDetails';
$response = $this->_youtube->subscriptions->listSubscriptions(
$part,
$params
);
foreach ($response['items'] as $item) {
$this->_mysubscriptions[] = array(
'channelId'=>$item['snippet']['resourceId']['channelId'],
'title'=>$item['snippet']['title'],
'description'=>$item['snippet']['description'],
'thumb_default'=>$item['snippet']['thumbnails']['default']['url'],
'thumb_medium'=>$item['snippet']['thumbnails']['medium']['url'],
'thumb_high'=>$item['snippet']['thumbnails']['high']['url'],
'subscribedOn'=>$this->cleanDate($item['snippet']['publishedAt']),
'totalVideos'=>$item['contentDetails']['totalItemCount'],
'newVideos'=>$item['contentDetails']['newItemCount']);
}
This is how the object returned looks like (just removed few IDs from the response) from the google API explorer, while when I run it through my code I get the same data but the newItemCount is zero.
{
"kind": "youtube#subscription",
"snippet": {
"publishedAt": "2016-09-14T12:48:00.000Z",
"title": "Muselk",
"description": "\"Memes win games\" - Youtube.com/mrmuselk",
"resourceId": {
"kind": "youtube#channel",
"channelId": "UCd534c_ehOvrLVL2v7Nl61w"
},
"thumbnails": {
"default": {
"url": "https://yt3.ggpht.com/-iWlz7dePNz0/AAAAAAAAAAI/AAAAAAAAAAA/smtPKh-RLTU/s88-c-k-no-mo-rj-c0xffffff/photo.jpg"
},
"medium": {
"url": "https://yt3.ggpht.com/-iWlz7dePNz0/AAAAAAAAAAI/AAAAAAAAAAA/smtPKh-RLTU/s240-c-k-no-mo-rj-c0xffffff/photo.jpg"
},
"high": {
"url": "https://yt3.ggpht.com/-iWlz7dePNz0/AAAAAAAAAAI/AAAAAAAAAAA/smtPKh-RLTU/s240-c-k-no-mo-rj-c0xffffff/photo.jpg"
}
}
},
"contentDetails": {
"totalItemCount": 792,
"newItemCount": 4,
"activityType": "all"
}
I've looked through the revision history but can't find any reference of modifications made to this specific property of the contentDetails object
There is a bug filed with google on this property but it refers to a different behaviour.
Wondering if this happens to other as well, or if somebody can give some hints on how this works or don't.

Related

How To Convert "created_timestamp" Value To A Valid Date In Python

I'm currently working on a Twitter bot that automatically reply messages, I'm doing this by using tweepy (the official python twitter library)
I need to filter messages based on the created time as I don't want to reply same message twice. Now the problem is that the API endpoint returns created_timestamp as string representation of positive integers.
Below is an example of data returned as per the doc
{
"next_cursor": "AB345dkfC",
"events": [
{ "id": "110", "created_timestamp": "1639919665615", ... },
{ "id": "109", "created_timestamp": "1639865141987", ... },
{ "id": "108", "created_timestamp": "1639827437833", ... },
{ "id": "107", "created_timestamp": "1639825389806", ... },
{ "id": "106", "created_timestamp": "1639825389796", ... },
{ "id": "105", "created_timestamp": "1639825389768", ... },
...
]
}
My question is "How do I convert the created_timestamp to a valid date using python" ?.
You might play with timestamps on this resource
And in your case could use methods like:
timestamp = int('timestamp_string')
datetime.fromtimestamp(timestamp, tz=None)
date.fromtimestamp(timestamp)
From the datetime standard library. But integers after the first line are already well comparable if the task is to distinguish differences between the timestamps.

Twitter API 2.0 - Unable to fetch user.fields

I am using API version 2.0 and unable to fetch the user.fields results. All other parameters seem to be returning results correctly. I'm following this documentation.
url = "https://api.twitter.com/2/tweets/search/all"
query_params = {
"query": "APPL",
"max_results": "10",
"tweet.fields": "created_at,lang,text,author_id",
"user.fields": "name,username,created_at,location",
"expansions": "referenced_tweets.id.author_id",
}
response = requests.request("GET", url, headers=headers, params=query_params).json()
Sample result:
{
'author_id': '1251347502013521925',
'text': 'All conspiracy. But watch for bad news on Apple. Such a vulnerable stocktechnically for the biggest market cap # $2.1T ( Thanks Jay). This is the glue for the bulls. But, they stopped innovating when Steve died, built a fancy office and split the stock. $appl',
'lang': 'en',
'created_at': '2021-06-05T02:33:48.000Z',
'id': '1401004298738311168',
'referenced_tweets': [{
'type': 'retweeted',
'id': '1401004298738311168'
}]
}
As you can see, the following information is not returned: name, username, and location.
Any idea how to retrieve this info?
Your query does actually return the correct data. I tested this myself.
A full example response will be structured like this:
{
"data": [
{
"created_at": "2021-06-05T02:33:48.000Z",
"lang": "en",
"id": "1401004298738311168",
"text": "All conspiracy. But watch for bad news on Apple. Such a vulnerable stocktechnically for the biggest market cap # $2.1T ( Thanks Jay). This is the glue for the bulls. But, they stopped innovating when Steve died, built a fancy office and split the stock. $appl",
"author_id": "1251347502013521925",
"referenced_tweets": [
{
"type": "retweeted",
"id": "1401004298738311168"
}
]
}
],
"includes": {
"users": [
{
"name": "Gary Casper",
"id": "1251347502013521925",
"username": "Hisel1979",
"created_at": "2020-07-11T13:39:58.000Z"
}
]
}
}
The sample result you provided comes from within the data object. However, the expanded object data will be nested in the includes object (in your case name, username, and location). The corresponding user object can be referenced via the author_id field.

What is the difference between ContentDetails.RegionRestriction and ContentDetails.CountryRestriction in the Youtube API V3?

Below I have my simple request that retrieves contentDetails for a specific video.
var youTubeService = new YouTubeService(new BaseClientService.Initializer()
{
ApiKey = "your-apikey",
ApplicationName = "DIGITAL.CLI"
});
var channelsListRequest = new VideosResource.ListRequest(youTubeService, "contentDetails");
channelsListRequest.Id = "FakBv-xNTeU";
var response = channelsListRequest.Execute();
Console.WriteLine(JsonConvert.SerializeObject(response));
In the response I get a list of regions where the video is blocked, but there is also a section that isn't in the response called countryRestrictions.
{
"etag": "8Dlzw_juiiGAkJUxdgfegatGe34",
"items": [
{
"contentDetails": {
"caption": "false",
"contentRating": {},
"definition": "hd",
"dimension": "2d",
"duration": "PT1M37S",
"licensedContent": true,
"projection": "rectangular",
"regionRestriction": {
"blocked": [
"US",
"FM",
"MP",
"VI",
"GU",
"MH",
"PR",
"PW",
"AS",
"UM"
]
}
},
"etag": "-DZJdN2PuXnNfuceW0s7RVa4Y9I",
"id": "FakBv-xNTeU",
"kind": "youtube#video"
}
],
"kind": "youtube#videoListResponse",
"pageInfo": {
"resultsPerPage": 1,
"totalResults": 1
}}
So this video has regionRestrictions, but no country restrictions. Is countryRestrictions still in use? The client library documentation of VideoConntentDetails has the same description for both of them.
And as a bonus question, if the allowed list contains items, then does that mean that all countries not in the allowed list are blocked?
According to the client library documentation of VideoContentDetailsRegionRestriction, this model class is deprecated; thus the client library property regionRestriction is deprecated too.
The client library is mapping its property countryRestriction from the YouTube Data API's property contentDetails.regionRestriction.
According to the official specification of the YouTube Data API's Videos resource, there's no property countryRestriction that this kind of API resource contains.
The answer to your second question is: yes, all countries not in the allowed list are blocked (the emphasis below is mine):
contentDetails.regionRestriction.allowed[] (list)
A list of region codes that identify countries where the video is viewable. If this property is present and a country is not listed in its value, then the video is blocked from appearing in that country. If this property is present and contains an empty list, the video is blocked in all countries.

No videos in the mostPopular chart for certain video categories

I'm trying to get a list of the most popular videos for certain video categories, however some categories return an empty list of videos despite the response being successful.
For example, the News & Politics category (ID 25):
I get the same response when making this request from my app. The category ID is valid and correct (as obtained from /youtube/v3/videoCategories). Changing the regionCode doesn't make a difference.
It's really important for the functionality of my app that a list of popular/recent/noteworthy videos for particular categories are shown. If there's no way to get the above request to return some videos, is there some kind of workaround that would return appropriate videos for the troublesome categories?
This looks like a bug to me
I tested it in the apis-explorer
Testing request 1:
Without category. test here scroll down there are some with nr 25
Request
GET https://www.googleapis.com/youtube/v3/videos?part=snippet&chart=mostPopular&maxResults=50&regionCode=us&fields=items%2Fsnippet%2FcategoryId&key={YOUR_API_KEY}
Response
{
"kind": "youtube#videoListResponse",
"etag": "\"RmznBCICv9YtgWaaa_nWDIH1_GM/ewwRz0VbTYpp2EGbOkvZ5M_1mbo\"",
"pageInfo": {
"totalResults": 0,
"resultsPerPage": 50
},
"items": [
"snippet": {
"categoryId": "25"
}
......
]
}
but as soon as you add the catagori id it returns 0
Test 2 fun results
A fun thing i found in my testing is if i add a category id of 10 link
GET https://www.googleapis.com/youtube/v3/videos?part=snippet&chart=mostPopular&maxResults=50&regionCode=us&videoCategoryId=10&fields=items%2Fsnippet%2FcategoryId&key={YOUR_API_KEY}
it returns others as well.
{
"items": [
{
"snippet": {
"categoryId": "24"
}
},
{
"snippet": {
"categoryId": "10"
}
},
{
"snippet": {
"categoryId": "10"
}
I would submit a bug report. issue forum

Youtube ContentID getting ownership info through the API using AppsScript

I am trying to get get ownership information against AssetIDs through the Youtube ContentID API.
I can see the data that I need through the API Explorer but cant seem to drill down the data using dot notation.
Here is the output from the API explorer:
{
"kind": "youtubePartner#asset",
"id": "A146063471697194",
"type": "music_video",
"ownership": {
"kind": "youtubePartner#rightsOwnership",
"general": [
{
"ratio": 100,
"owner": "Indmusic",
"type": "exclude"
}
]
},
"ownershipEffective": {
"kind": "youtubePartner#rightsOwnership",
"general": [
{
"ratio": 100,
"owner": "Indmusic",
"type": "exclude"
}
]
}
}
When accessing the "owner" I receive undefined instead of the listed value.
var url2 = _.sprintf('https://www.googleapis.com/youtube/partner/v1/assets/%s?fetchMetadata=effective&fetchOwnership=effective&key=%s',id,API_KEY);
var result2 = JSON.parse(UrlFetchApp.fetch(url2, getUrlFetchOptions()).getContentText());
Logger.log(result2.ownership.general.owner);
returns undefined
I have tried both ownershipEffective and ownership and they are both undefined.
I can log data from result2.ownership.general but nothing below that.
You can tell that general is an array by the [brackets] in:
"general": [
{
"ratio": 100,
"owner": "Indmusic",
"type": "exclude"
}
]
Try:
Logger.log(result2.ownership.general[0].owner);
general, having been declared an array, requires a position [0] even though there is only 1 item in the array.

Resources