YouTube API v3 keeps asking for authorisation every time - php

I am using the YouTube api v3 to retrieve a list of videos using the example at https://developers.google.com/youtube/v3/code_samples/php#retrieve_my_uploads
I open the page, the app asks for authorisation. I click the link to authorise, select my gmail account and I get the listing.
The problem is when i go back to the app even only a few seconds later, I have to authorise the app again.
I thought once the app was authorised you could exchange a token for a refresh token.
Is there anywhere that shows some code how to get a refresh token as the documentation or any reference to it online is very poor.
I really need some help getting this working as i've been trying for the last couple weeks and getting nowhere.

I have a long-winded answer, but it should be a big help. I had the same issue with the poor documentation and I am also trying to get a list of videos from a playlist for my project. The API v3 just magically started working for me after struggling for the past couple days, here is what I did.
First was actually getting the API key. I'm sure you've been in the Google Developers Console by now, but just in case here is what to do for this step:
Create a project in Google Developers Console
Enable the YouTube Data API v3 API
Under "Credentials", if you had the same issue as me, you can create a new Client ID but not an API key.
This is a major problem because you need an API key to make simple data requests without authorization, e.g., getting a list of videos from a playlist. To get an API key, go back to the "APIs" section, click on "YouTube Data API v3", and here is the screen with the loading indicator that never loads anything. However you can click on "Quota" here and it takes you to the older version of the Developers Console.
From this older version, you can go to "API Access" and add your Simple API Access keys (the API keys work on this older version, but not on the new version of Developers Console). I could be wrong about this but I think "Create new Server key..." is for server-side languages like PHP, and "Create new Browser key..." is for client-side languages like Javascript. There are also buttons for Android and iOS keys, but I assume you don't need those. Anyway, I'm using cURL in PHP and the Server key worked for me, I have it set to allow any referrers while my project is still in development.
Once you get your Key for server apps under Simple API Access, it might be a while before any requests using the key actually work. For me, my script didn't work for about 4-5 hours (I think Google is having real issues with their servers this week, which is also why I had to "trick" it into giving me an API key. And it's probably why the "Credentials" page doesn't load anything).
Now use the tool on https://developers.google.com/apis-explorer/#p/youtube/v3/youtube.playlists.list to help create your GET request. Enter "snippet" in the part field and an integer for maxResults if necessary. Then get the ID of a playlist from the URL on Youtube. For example, Conan's "Clueless Gamer" series is https://www.youtube.com/playlist?list=PLVL8S3lUHf0RqD7TZ6hohWk8Sd3asaqnY, so the ID is PLVL8S3lUHf0RqD7TZ6hohWk8Sd3asaqnY. Then click Execute.
Now it will give you the GET Request, something like
GET https://www.googleapis.com/youtube/v3/playlists?part=snippet&id=PLVL8S3lUHf0RqD7TZ6hohWk8Sd3asaqnY&maxResults=20&key={YOUR_API_KEY}
X-JavaScript-User-Agent: Google APIs Explorer
Just take the URL after the word GET and replace {YOUR_API_KEY} with your API key.
Now you can use this URL in a cURL request, like so, where $request_url is the URL from above with your API key in it:
//http://codular.com/curl-with-php
// Get cURL resource
$curl = curl_init();
// Set some options - we are passing in a useragent too here
curl_setopt_array($curl, array(
CURLOPT_RETURNTRANSFER => 1,
CURLOPT_URL => $request_url,
CURLOPT_USERAGENT => 'Codular Sample cURL Request'
));
// Send the request & save response to $resp
$resp = curl_exec($curl);
// Close request to clear up some resources
curl_close($curl);
Now $resp will hold a JSON string that you can parse through and get the data for that playlist's videos. I'll leave the JSON parsing up to you, but that's how you get data similar to the old gdata way in v2. And no authentication :)
It might report an error back that your API key isn't authorized, in which case you'll need to wait several hours. Again, I think Google has been having real server issues lately so be patient; it's not your script that doesn't work, it's Google ;)
I will note that
$resp = file_get_contents($request_url);
seems to work as well, but I honestly don't know which method is "better" between cURL and file_get_contents().

Took me ages to work this out as I couldn't find any examples on how to do this easily.
It turned out that I need to create a POST request to get an access code and refresh token and this was achieved with using Curlfrom the command line
url --data "code=AUHROISATON_CODE&client_id=CLIENT_ID.apps.googleusercontent.com&client_secret=CLINET_SECRET&redirect_uri=http://www.example.com&grant_type=authorization_code" https://accounts.google.com/o/oauth2/token
After a few errors such as 'Missing grant_type', 'Invalid code' it now works.
I revoked access to the app, ran the following GET request (taken from https://developers.google.com/accounts/docs/OAuth2WebServer#formingtheurl) to get the code and was able to use the code in the above Curl statement
https://accounts.google.com/o/oauth2/auth?
scope=https://www.googleapis.com/auth/youtube&
state=security_token%3D138r5719ru3e1%26url%3Dhttps://oa2cb.example.com/myHome&
redirect_uri=https%3A%2F%2Foauth2-login-demo.appspot.com%2Fcode&,
response_type=code&
client_id=812741506391.apps.googleusercontent.com&
approval_prompt=force

Related

Getting started with the YouTube Analytics API?

How can I "link" a person's youtube account to an account on my website? I am trying to get Analytics from videos, how much money they have made, etc. I know i am supposed to be using the YouTube Analytics API, but I see tons of different documentation and it gets SO confusing. Are there any PHP libraries I can use to get this data and to link the user's account to my web application? I am also confused on where I get an OAuth Key.
Here are some sites i have looked at:
1) Site One
2) Site Two
On site two, I looked at the examples, but nothing really helped me understand even how to start.
A lot of the relevant info you'll need can be found in this document:
https://developers.google.com/youtube/analytics/authentication
Basically, it outlines the following 4 steps:
1) Register your web app in the Google Cloud Console
This is needed so you can get a client secret and client ID, which your server-side PHP code will need in order to do the oAuth flow (and get the right scope to be able to query analytics data for the user that's authenticating). See here for more info on how to do this:
https://developers.google.com/youtube/analytics/registering_an_application
The most important things to do as your register your app are to turn on the YouTube Analytics API and create a new client ID for your web application.
2) When a user visits your page, you'll need some way (i.e. a login button, for example) to trigger the start of the oAuth flow. When this is triggered, you'll want to redirect the browser to this URL:
https://accounts.google.com/o/oauth2/auth?client_id=[YOUR CLIENT ID]&redirect_uri=[THE URL YOU WANT THE USER TO BE DIRECTED TO AFTER AUTHENTICATION]&scope=https://www.googleapis.com/auth/yt-analytics.readonly&response_type=code&access_type=offline
This will present them with a window asking them if they want to give permission to your app to read their analytics. Note that the client id parameter is the same that you received when you registered your app in step 1. That registration process also will require you to set the allowed redirect URIs, so here you must pass one you set in the registration.
3) The redirect URL will be requested, from step two, by Google's servers with a "code" parameter attched. So when it is requested, it should immediately do a POST to another URL (i.e. with cURL or something similar), that looks like this:
POST /o/oauth2/token HTTP/1.1
Host: accounts.google.com
Content-Type: application/x-www-form-urlencoded
code=[CODE THAT CAME IN AS A GET PARAMETER] &client_id=[YOUR CLIENT ID]&client_secret=[YOUR CLIENT SECRET]&redirect_uri=[THE REGISTERED REDIRECT URI]&grant_type=authorization_code
If you do it as a POST with cURL, then the response will be a JSON packet that has an access token and a refresh token.
4) Your php page can store these both (in your DB, for example), note that the user should be treated as logged in at this point, and you can use the access token in the header of all API requests send to the analytics API.
https://developers.google.com/youtube/analytics/authentication#OAuth2_Calling_a_Google_API
IT'll expire in an hour, so with each request you should be checking its age (i.e. when you stored it in the DB, you could store the expiry time, for example), and when you're getting close you can use the refresh token to get a new access token.
https://developers.google.com/youtube/analytics/authentication#OAuth2_Refreshing_a_Token
You can now redirect them to wherever your app needs them to be to start interfacing with the API.
Seems like a lot? It can be, but once you get the paradigm down it's pretty simple. And you asked about a client for PHP, and thankfully there is one:
https://github.com/google/google-api-php-client
It's got simple handlers for the whole oAuth2 flow, and also has a YouTube analytics service object that sets the access token automatically for you as it's making its various calls.

Setting a groups cover image using the Facebook Graph API

I've been visiting this forum for years, but this is my first ever question. Any help would be appreciated!
I am writing a web service to pass groups from one application into Facebook and invite the authorised people into them and set a nice pretty cover photo that is generated and stored within the application.
The group creation works splendidly after a fair old bit of head scratching, however, when I try to set the cover image, I am getting a rather useful error message back as below.
OAuth "Facebook Platform" "unknown_error" "An unknown error has occurred."
It's a PHP application on Code Igniter. According to Facebook's delightfully accurate API documentation, this is a simple matter of a cUrl post to 'graph.facebook.com/$groupId' passing the same auth token I just used to create the group and perform the invites and a single JSON encoded parameter of 'cover_url' => $urlOfImage .
A simple task in theory, however, I have spent all day today and a significant chunk of yesterday trying to get this to work without much success.
I have tried posting the image as a Curl object as is necessary in other areas of the Facebook API, and it appears to be trying giving me an error that the image is generating a 404 error (it isn't, when I checked the access logs, it was never requested).
Please be someone out there who has had some success with this.
This has now been fixed by Facebook

How do I use Twitter's API to fetch tweets from someone's timeline ? (problems with authentication !)

So I'm trying to get the latest tweets posted by a user using a PHP script (and caching the results into a text file). I'm using the request https://api.twitter.com/1/statuses/user_timeline.json?count=5&screen_name=google and it's been working fine as a public client, but in order to get better control over my API hit limit I need to authenticate my requests.
I've tried the method shown at https://dev.twitter.com/docs/auth/application-only-auth , but after I successfully connect I get the error "Your credentials do not allow access to this resource" (why ?). So I've tried to use the OAuth method (which looks frighteningly complicated for a hobbyist like me), and downloaded the TwitterOAuth library. But I'm still having trouble connecting ! I put my credentials in the config.php file, but I have no idea where to go from there. The documentation seems to be hinting that I need to manually login to Twitter to authorize the application's connection token... or something. Apparently I need to redirect to some callback URL (what even ?!) and get a short-term connection to enable a long-term connection password which I have to store for later ? What is this madness ?
I was initially under the impression that I could just fetch data from Twitter's RSS feeds but those can't be accessed from scripts for some reason (unlike the Google News RSS feed which fetches just fine). It seems I've gotten myself into something much more complicated than what I signed for. Isn't there an easier (and saner) way of doing this ? Or is nothing decidedly simple ?
I apologize for being such an easily-confused dullard, but my head is spinning.
Thanks !
Edit : after digging around some more I decided to just use PHP curl to fetch the raw page, and then do some Xpath voodoo to get the tweets and the time they were posted at. Of course, this is CPU-intensive, far from stable, and probably not a practice that pleases the folks at Twitter; it also only returns the last 20 tweets (which is thankfully enough for my needs).
However, Cormac Driver's response below about Temboo is certainly a method I'll be investigating next time I need to do something like that.
Temboo provides a simple way of using OAuth to authenticate with Twitter. The process is broken down into two steps:
InitializeOauth. This step returns a Twitter authorization URL that Twitter account holders can visit to grant access to your script.
FinalizeOauth. This step returns the access token that your script will need to make authenticated requests to the Twitter API on behalf of the user.
Full details on how to do this with PHP here: https://www.temboo.com/library/Library/Twitter/OAuth/
You can see an example of how Temboo handles OAuth for Facebook on this page. The PHP source code is provided, and it's almost identical to the code you'll need to do the same thing for Twitter.
(Full disclosure: I work at Temboo)

Unable to identify issue with Ajax call to Yii API getting no response headers

Overview
I'm currently working on a jQuery/HTML5 project that displays web performance data with a series of charts using an internal API to retrieve the data. The API is powered by Yii, but I am not working on it, so i cannot change or experiment with it myself.
Basically I am hoping someone can help identify if the API is the root cause of the problem or if it's a problem with the Ajax in my jQuery being incorrect.
A small explanation of the process my application goes through...
Application loads, uses user details to authenticate with API. Receives API Key from API.
After the key has been retrieved, several calls are made to retrieve data from the APi to display as the web performance data.
At set intervals, a generic is called to the database to check that the API Key has expired or not.
If the key has expired, it makes another request to the API for a new API Key as stated in step 1. If there are any problems with gaining an API key, this is when the user gets kicked off.
Restart cycle excluding getting the data.
Problem
All Ajax calls are made to the are crossdomain as both the project and the API are on separate sub domains. These are done using JSONP and a jQuery callback.
The problem I am having is that when I need to authenticate if the key is valid or not, if it is no longer valid, the API returns a 401 error which my Ajax does not register. If i view the API URL in Firefox, I can see the returned Json data, wrapped in a callback, but when I check firebug it says there is a request, but no response.
Basically when the API returns data that is not 200 OK, it doesn't send a response header at all.
However I have manually called the API using cUrl in terminal, and have received a response header, as well as in Google Chrome.
If someone could tell me if this is a well known issue with Firefox/jQuery or if this is a problem with the Yii API I would very much appreciate it.
Try adding this before your ajax call:
jQuery.support.cors = true; // force cross-site scripting in IE

List all Google Apps Profiles on PHP Site

I am trying to get a list of all Google Apps users of a domain onto a public PHP website (without visitors of the site needing to login or do anything). I have a basic understanding of what needs to happen but can't quite piece it all together. It can't be as hard as it seems to me... could it?
Authentication and Authorization:
I'm pretty sure it needs to use OAuth 2.0 ... but am unsure whether it needs 2 legged or 3 legged. I got another section of the site working with ClientLogin but that won't pull in Google Apps profiles, only user's first and last names (I need the other profile fields). I have set up the API access within the account and have that side of things all set (I believe).
I have found this page, which shows how to construct a URL request to get all Profiles (in every language except PHP of course) but don't understand how to implement this.
http://code.google.com/googleapps/domain/profiles/developers_guide.html
I also tried this example but it just gives me a 401 after I enter the credentials. http://gdatatips.blogspot.com/2008/11/2-legged-oauth-in-php.html
I don't know which frameworks or includes are needed to accomplish this either. I have tried zend, OAuth.php and a whole bunch of other bootstraps... but keep getting lost as to what each is doing.
If someone could help me by outlining:
Which files/framework I need to upload and include as a bootstrap
What variables within those files I need to update with the Google credentials
How I integrate the Google Profiles "Retrieve all Profiles" request with PHP
An ELI5 (explain it like i'm 5) overview would be very much appreciated... I'm sorry for my apparent incompetence, but I have been reading articles for nearly a week and have not gotten anywhere.
Thank you in advance for any help provided.
Good question.
You'll need to implement the Google OAuth 2.0 process as it's described here (experimental?), because someone (you) will need to give your app the initial permissions to access Google Apps API. Steps are:
Register your domain with google (don't remember the link)
Redirect/send browser to an authentication url: https://accounts.google.com/o/oauth2/auth, with the appropriate request params (see the first link). You'll need access_type=offline, your scope would be https://apps-apis.google.com/a/feeds/user/
Get a code back, then exchange for a refresh_token, an access_token, and a value specifying when the access_token will expire. Store these in a database
Whenever you need to make an API call, check if your access_token has expired or not, and refresh when necessary, which is what the refresh_token is for. The refresh_token is valid as long as you don't revoke the access you gave to the app.
OAuth Playground helps a lot. Good luck.

Categories