I am new to Asp.net and does any one have a working solution to pulling data from google analytics into my webapplication, I have obtained the following code but it gives me an IO error.
Here is my method:
public void Main()
{
//This is the API url which we're storing to a string
string scope = AnalyticsService.Scopes.AnalyticsReadonly.GetStringValue();
//For whatever reason, this is labelled wrong. It is the email address
//that you have added as a user to your Analytics account
string clientId = "xxxxxxxx#gmail.com";
//This is the physical path to the file we downloaded earlier
//To demonstrate this, I've kept the full path to my key file.
//Obviously, you will need to change this to match where you've
//stored yours.
string keyFile = #"C:\Users\Jacob\Documents\Adwords and analytics\katoona\793c6491a4ad1118dda49d6bf6824a975edd485a-privatekey.p12";
//The password Google gives you, probably the same as the one below
string keyPassword = "notasecret";
//Store the authentication description
AuthorizationServerDescription desc = GoogleAuthenticationServer.Description;
//Create a certificate object to use when authenticating
X509Certificate2 key = new X509Certificate2(keyFile, keyPassword, X509KeyStorageFlags.Exportable);
//Now, we will log in and authenticate, passing in the description
//and key from above, then setting the accountId and scope
AssertionFlowClient client = new AssertionFlowClient(desc, key)
{
ServiceAccountId = clientId,
Scope = scope
};
//Finally, complete the authentication process
//NOTE: This is the first change from the update above
OAuth2Authenticator<AssertionFlowClient> auth =
new OAuth2Authenticator<AssertionFlowClient>(client, AssertionFlowClient.GetState);
//First, create a new service object
//NOTE: this is the second change from the update
//above. Thanks to James for pointing this out
AnalyticsService gas = new AnalyticsService(new BaseClientService.Initializer() { Authenticator = auth });
//Create our query
//The Data.Ga.Get needs the parameters:
//Analytics account id, starting with ga:
//Start date in format YYYY-MM-DD
//End date in format YYYY-MM-DD
//A string specifying the metrics
DataResource.GaResource.GetRequest r = gas.Data.Ga.Get("ga:9475327", "2013-09-09", "2013-09-23", "ga:visitors");
//Specify some addition query parameters
r.Dimensions = "ga:visitorType";
r.Sort = "-ga:visitors";
r.MaxResults = 5;
//Execute and fetch the results of our query
try
{
//Write the column headers
GaData d = r.Execute();
foreach (var h in d.ColumnHeaders)
{
ListBox1.Items.Add(h.Name);
}
//Write the data
foreach (var row in d.Rows)
{
ListBox1.Items.Add(row[0] + " ------ " + row[1]);
}
}
catch (Exception webEx)
{
throw;
}
Giving the exact error received would help - then we can see whether it's an OAuth problem or a problem with what you're sending to query the GA data API.
Also, start by using the Google Analytics Query Explorer to construct and test your query before converting it to C# code.
Related
I have a .Net Standard client application running on UWP.
My client application contacts the server that generates a sas key like so:
var myPrivateStorageAccount = CloudStorageAccount.Parse(mystorageAccountKey);
var myPrivateTableClient = myPrivateStorageAccount.CreateCloudTableClient();
SharedAccessTablePolicy pol = new SharedAccessTablePolicy()
{
SharedAccessExpiryTime = DateTime.UtcNow.AddMinutes(59),
Permissions = SharedAccessTablePermissions.Query | SharedAccessTablePermissions.Add
};
CloudTable myPrivateTable = myPrivateTableClient.GetTableReference(tableName);
String sas = myPrivateTable.GetSharedAccessSignature(pol);
return sas;
My client application then runs the following:
StorageCredentials creds = new StorageCredentials(sas);
this.tableClient = new CloudTableClient(tableServiceURI, creds);
this.table = tableClient.GetTableReference(tableName);
TableQuery<DynamicTableEntity> projectionQuery = new TableQuery<DynamicTableEntity>().Select(new string[] { "DocumentName" }).Where(TableQuery.GenerateFilterCondition("PartitionKey", QueryComparisons.Equal, cc));
var res = await table.ExecuteQuerySegmentedAsync<DynamicTableEntity>(projectionQuery, null);
and gets the following error:
Server failed to authenticate the request. Make sure the value of
Authorization header is formed correctly including the signature. sr
is mandatory. Cannot be empty
but as this is tablestorage I dont think sr is required
and my SAS key looks fine to me:
?sv=2018-03-28&tn=MyTable&sig=RandomSig151235341543&st=2019-01-17T12%3A00%3A28Z&se=2019-01-17T12%3A59%3A28Z&sp=ra
so whats the problem here?
Ok so this is kind of stupid but I will post anyway.
I was sending the request to:
https://myaccount.blob.core.windows.net/
and should have been sending the request to:
https://myaccount.table.core.windows.net/
I have been using the code bellow on two different web applications on two different servers for months and they both randomly stopped working this week with a 400 bad request "An exception of type 'DotNetOpenAuth.Messaging.ProtocolException' occurred in Google.Apis.dll but was not handled in user code
Additional information: Error occurred while sending a direct message or getting the response."
//Retreive total hits and hits in last 30 days from google analytic
//This is the API url which we're storing to a string
string scope = AnalyticsService.Scopes.AnalyticsReadonly.GetStringValue();
//For whatever reason, this is labelled wrong. It is the email address
//that you have added as a user to your Analytics account
string clientId = "*******#developer.gserviceaccount.com";
//This is the physical path to the file we downloaded earlier
//To demonstrate this, I've kept the full path to my key file.
//Obviously, you will need to change this to match where you've
//stored yours.
string keyFile = #"C:\key\*******.p12";
//The password Google gives you, probably the same as the one below
string keyPassword = "notasecret";
//Store the authentication description
AuthorizationServerDescription desc = GoogleAuthenticationServer.Description;
//Create a certificate object to use when authenticating
X509Certificate2 key = new X509Certificate2(keyFile, keyPassword, X509KeyStorageFlags.Exportable);
//Now, we will log in and authenticate, passing in the description
//and key from above, then setting the accountId and scope
AssertionFlowClient client = new AssertionFlowClient(desc, key)
{
ServiceAccountId = clientId,
Scope = scope
};
//Finally, complete the authentication process
//NOTE: This is the first change from the update above
OAuth2Authenticator<AssertionFlowClient> auth =
new OAuth2Authenticator<AssertionFlowClient>(client, AssertionFlowClient.GetState);
//First, create a new service object
//NOTE: this is the second change from the update
//above. Thanks to James for pointing this out
AnalyticsService gas = new AnalyticsService(new BaseClientService.Initializer() { Authenticator = auth });
//Create our query
//The Data.Ga.Get needs the parameters:
//Analytics account id, starting with ga:
//Start date in format YYYY-MM-DD
//End date in format YYYY-MM-DD
//A string specifying the metrics
DataResource.GaResource.GetRequest r =
gas.Data.Ga.Get(googleID, "2005-01-01", DateTime.Now.ToString("yyyy-MM-dd"), "ga:totalEvents");
//Specify some addition query parameters
r.Filters = "ga:eventCategory==appStart;ga:eventAction==user";
//Execute and fetch the results of our query
GaData d = r.Execute();
It randomly started working again on both applications on both servers without me changing anything.
I have an AngularJS + C#.NET OnePage Application Website. The goal is to retrieve a JSON from a private Google Spreadsheet that I own with C# (not with AngularJS). I read various Google Sheets Documentation and API, OAuth 2.0 etc. and tried some examples, but none of them seem to work for me. I see there are different ways to access and retrieve data from a Google Spreadsheet, still, they don't work for my case.
Can anyone help me?
Thank you.
Edit: I managed to get a token by creating an Other Application type under Google Developers Console=>Credentials=>Create Client ID. Here's the C# Console Application:
using System;
using Google.GData.Client;
using Google.GData.Spreadsheets;
namespace MySpreadsheetIntegration
{
class Program
{
static void Main(string[] args)
{
////////////////////////////////////////////////////////////////////////////
// STEP 1: Configure how to perform OAuth 2.0
////////////////////////////////////////////////////////////////////////////
// TODO: Update the following information with that obtained from
// https://code.google.com/apis/console. After registering
// your application, these will be provided for you.
string CLIENT_ID = "12345678.apps.googleusercontent.com";
// This is the OAuth 2.0 Client Secret retrieved
// above. Be sure to store this value securely. Leaking this
// value would enable others to act on behalf of your application!
string CLIENT_SECRET = "Gc0230jdsah01jqpowpgff";
// Space separated list of scopes for which to request access.
string SCOPE = "https://spreadsheets.google.com/feeds https://docs.google.com/feeds";
// This is the Redirect URI for installed applications.
// If you are building a web application, you have to set your
// Redirect URI at https://code.google.com/apis/console.
string REDIRECT_URI = "urn:ietf:wg:oauth:2.0:oob";
////////////////////////////////////////////////////////////////////////////
// STEP 2: Set up the OAuth 2.0 object
////////////////////////////////////////////////////////////////////////////
// OAuth2Parameters holds all the parameters related to OAuth 2.0.
OAuth2Parameters parameters = new OAuth2Parameters();
// Set your OAuth 2.0 Client Id (which you can register at
// https://code.google.com/apis/console).
parameters.ClientId = CLIENT_ID;
// Set your OAuth 2.0 Client Secret, which can be obtained at
// https://code.google.com/apis/console.
parameters.ClientSecret = CLIENT_SECRET;
// Set your Redirect URI, which can be registered at
// https://code.google.com/apis/console.
parameters.RedirectUri = REDIRECT_URI;
////////////////////////////////////////////////////////////////////////////
// STEP 3: Get the Authorization URL
////////////////////////////////////////////////////////////////////////////
// Set the scope for this particular service.
parameters.Scope = SCOPE;
// Get the authorization url. The user of your application must visit
// this url in order to authorize with Google. If you are building a
// browser-based application, you can redirect the user to the authorization
// url.
string authorizationUrl = OAuthUtil.CreateOAuth2AuthorizationUrl(parameters);
Console.WriteLine(authorizationUrl);
Console.WriteLine("Please visit the URL above to authorize your OAuth "
+ "request token. Once that is complete, type in your access code to "
+ "continue...");
parameters.AccessCode = Console.ReadLine();
////////////////////////////////////////////////////////////////////////////
// STEP 4: Get the Access Token
////////////////////////////////////////////////////////////////////////////
// Once the user authorizes with Google, the request token can be exchanged
// for a long-lived access token. If you are building a browser-based
// application, you should parse the incoming request token from the url and
// set it in OAuthParameters before calling GetAccessToken().
OAuthUtil.GetAccessToken(parameters);
string accessToken = parameters.AccessToken;
Console.WriteLine("OAuth Access Token: " + accessToken);
////////////////////////////////////////////////////////////////////////////
// STEP 5: Make an OAuth authorized request to Google
////////////////////////////////////////////////////////////////////////////
// Initialize the variables needed to make the request
GOAuth2RequestFactory requestFactory =
new GOAuth2RequestFactory(null, "MySpreadsheetIntegration-v1", parameters);
SpreadsheetsService service = new SpreadsheetsService("MySpreadsheetIntegration-v1");
service.RequestFactory = requestFactory;
Console.ReadLine();
}
}
}
With this code I have to copy the link I get and paste it in a browser in order to get a token. Is there a way to get this token directly in my app without the need to copy the link manually?
I found another working solution where you don't have to open a browser window which is similar to the solution with the p12-key above.
First, create in the Google Developer Console under Create Credentials a Service account key.
Then, you have to choose a service account type, you can choose App Engine Default Service account and you can download a json file that contains the private key.
With this file, you can create programmatically Google credentials (where "sheets-test.json" is the downloaded json file):
var credential = GoogleCredential.FromStream(new FileStream("Sheets-test.json", FileMode.Open)).CreateScoped(Scopes);
Give the service user (you can find it in the json file in the client_email field) access to your spreadsheet.
Here is the full code that enables you to append a value to the first free row in a spreadsheet, I modified the google .NET quickstart project:
using System;
using System.Collections.Generic;
using System.IO;
using Google.Apis.Auth.OAuth2;
using Google.Apis.Services;
using Google.Apis.Sheets.v4;
using Google.Apis.Sheets.v4.Data;
namespace SheetApiTest
{
public class SheetApiWithGoogleCredentials
{
static string[] Scopes = { SheetsService.Scope.Spreadsheets };
static string ApplicationName = "Google Sheets API .NET Quickstart";
public void AppendData()
{
// the downloaded jsonn file with private key
var credential = GoogleCredential.FromStream(new FileStream("Sheets-test.json", FileMode.Open)).CreateScoped(Scopes);
var service = new SheetsService(new BaseClientService.Initializer()
{
HttpClientInitializer = credential,
ApplicationName = ApplicationName,
});
// spreadsheet id - your own spreadsheet id
var spreadsheetId = "11AwV7d1pEPq4x-rx9WeZHNwGJa0ehfRhh760";
var valueRange = new ValueRange { Values = new List<IList<object>> { new List<object>() } };
valueRange.Values[0].Add(DateTime.Now.ToLongTimeString());
// insert here the name of your spreadsheet table
var rangeToWrite = "Tabellenblatt1";
var appendRequest = service.Spreadsheets.Values.Append(valueRange, spreadsheetId, rangeToWrite);
appendRequest.ValueInputOption = SpreadsheetsResource.ValuesResource.AppendRequest.ValueInputOptionEnum.USERENTERED;
var appendReponse = appendRequest.Execute();
}
}
}
There is a way for server-to-server communication using certificate instead of copy/paste the provided by Google AccessCode for the communication to be established.
First you will need to get your certificate from Google Console.
If you haven't already created a project do so and give it a name. Then:
Go to "Credentials" section (found on the left menu) and
Click on the button "Create Credentials" and choose "Service account key"
Choose the service account to be "App Engine default service account" and
Choose the "key type" to be "p.12" which is the certificate type.
Image for reference:
After these steps are completed, the certificate will be automatically downloaded. Upload it in some folder in your project and use it as shown below.
Note: for the sake of simplicity the code is placed in the controller.
public async Task<ActionResult> ServerAuth()
{
ViewBag.Message = "Server to server authentication";
List<string> records = new List<string>();
const string ServiceAccountEmail = "your-account#appspot.gserviceaccount.com";
string fullKeyPath = HttpContext.Server.MapPath("~/Key/MyProjectKey.p12"); // The certificate generated by Google and uploaded in the project.
var certificate = new X509Certificate2(fullKeyPath, "notasecret", X509KeyStorageFlags.Exportable); // "notasecret" is the password for the certificate
var serviceAccountCredentialInitializer = new ServiceAccountCredential.Initializer(ServiceAccountEmail)
{
Scopes = new[] { "https://spreadsheets.google.com/feeds", "http://spreadsheets.google.com/feeds/spreadsheets/private/full" }
}.FromCertificate(certificate);
var credential = new ServiceAccountCredential(serviceAccountCredentialInitializer);
if (!await credential.RequestAccessTokenAsync(System.Threading.CancellationToken.None))
{
throw new InvalidOperationException("Access token request failed.");
}
var requestFactory = new GDataRequestFactory(null);
requestFactory.CustomHeaders.Add("Authorization: Bearer " + credential.Token.AccessToken);
var service = new SpreadsheetsService(null) { RequestFactory = requestFactory };
SpreadsheetQuery query = new SpreadsheetQuery();
query.Title = "Test Sheet"; // The exact name of the sheet you want to read
query.Exact = true;
var feed = service.Query(query);
foreach (SpreadsheetEntry entry in feed.Entries)
{
foreach (WorksheetEntry worksheet in entry.Worksheets.Entries.Cast<WorksheetEntry>())
{
CellQuery cellQuery = new CellQuery(worksheet.CellFeedLink);
CellFeed cellFeed = service.Query(cellQuery);
foreach (CellEntry cell in cellFeed.Entries)
{
records.Add(cell.InputValue);
}
}
}
return View(records);
}
I'm suddenly starting to get the following exception when attempting to authenticate and access a spreadsheet on Google drive:
Unhandled Exception: Google.GData.Client.GDataRequestException:
Execution of aut hentication request returned unexpected
result: 404
at Google.GData.Client.Utilities.getAuthException(TokenCollection tokens,
Htt pWebResponse response)
at Google.GData.Client.Utilities.QueryClientLoginToken(GDataCredentials
gc, S tring serviceName, String applicationName, Boolean
fUseKeepAlive, IWebProxy prox yServer, Uri
clientLoginHandler)
at Google.GData.Client.GDataGAuthRequest.QueryAuthToken(GDataCredentials
gc)
at Google.GData.Client.GDataGAuthRequest.EnsureCredentials()
at Google.GData.Client.GDataRequest.EnsureWebRequest()
at Google.GData.Client.GDataGAuthRequest.EnsureWebRequest()
at Google.GData.Client.GDataRequest.Execute()
at Google.GData.Client.GDataGAuthRequest.Execute(Int32 retryCounter)
at Google.GData.Client.GDataGAuthRequest.Execute()
at Google.GData.Client.Service.Query(Uri queryUri, DateTime ifModifiedSince, String etag, Int64& contentLength)
at Google.GData.Client.Service.Query(FeedQuery feedQuery)
at Google.GData.Documents.DocumentsService.Query(DocumentsListQuery
feedQuery )
at GoogleLogger.GoogleService.getLastXECLogRows(String folderName, String fileName, Int32 rows)
This is in code that has been running for two years without any problems. I first thought that I may have lost access permissions on my production system but Google drive loads fine in my web browser. Tried it on several other systems and am getting the very same.
Did they change something in the Google API today? This can't be coincidence!
Google has retired their older authentication API. OAuth 2.0 should be used instead.
I spent too much time to figure out how to use newer Auth API with older GData API grabbing bits and pieces of information here and there from the Internet.
I decided to share all the the details with screenshots to save your time.
Go to https://console.developers.google.com/project
Hit Create Project button
Create project. Type in some name.
Go to API & Auth > Credentials and hit Create new Client ID button. It will create JSON key for you automatically - ignore that.
Hit Generate new P12 key
File download will start automatically. Remember the password, you will need it to open the file you just downloaded.
Rename downloaded file to Key.p12 and add it to your solution. Make sure you set Build Action and Copy to Output Directory accordingly.
Install Google API Auth using Nuget. Type the following in the Package Manager Console
Install-Package Google.Apis.Auth
Copy service account email address that was generated in Step #4.
Grant appropriate permission to this user in your Google Spreadsheet.
Use the following code to query the spreadsheet. Replace email and Google spreadsheet URL address in the code below.
const string ServiceAccountEmail = "452351479-q41ce1720qd9l94s8847mhc0toao1fed#developer.gserviceaccount.com";
var certificate = new X509Certificate2("Key.p12", "notasecret", X509KeyStorageFlags.Exportable);
var serviceAccountCredentialInitializer =
new ServiceAccountCredential.Initializer(ServiceAccountEmail)
{
Scopes = new[] { "https://spreadsheets.google.com/feeds" }
}.FromCertificate(certificate);
var credential = new ServiceAccountCredential(serviceAccountCredentialInitializer);
if (!credential.RequestAccessTokenAsync(System.Threading.CancellationToken.None).Result)
throw new InvalidOperationException("Access token request failed.");
var requestFactory = new GDataRequestFactory(null);
requestFactory.CustomHeaders.Add("Authorization: Bearer " + credential.Token.AccessToken);
var service = new SpreadsheetsService(null) { RequestFactory = requestFactory };
var query = new ListQuery("https://spreadsheets.google.com/feeds/list/0ApZkobM61WIrdGRYshh345523VNsLWc/1/private/full");
var feed = service.Query(query);
var rows = feed.Entries
.Cast<ListEntry>()
.Select(arg =>
new
{
Field0 = arg.Elements[0].Value,
Field1 = arg.Elements[1].Value
})
.ToList();
I've managed to solve this by using this solution with Service Account with oAuth2.0
Accessing older GData APIs (Spreadsheet API) using OAuth 2 and a service account
The solution:
1. Create Project and Google Service Account in https://console.developers.google.com/project
Generate your p12 key.
Allow APIs in Developer console you want to use (basically we are going to use old API, so you can skip this step, but just in case)
Use the code below (.NET Framework 4.5!)
Also don't forget to grant "youraccount#developer.gserviceaccount.com" access to your spreadsheet document as you grant permissions for usual users by pressing Share.
Code:
using System.Security.Cryptography.X509Certificates;
using Google.GData.Client;
using Google.GData.Extensions;
using Google.GData.Spreadsheets;
using Google.Apis.Auth.OAuth2;
string keyFilePath = #"C:\key.p12"; // found in developer console
string serviceAccountEmail = "youraccount#developer.gserviceaccount.com"; // found in developer console
var certificate = new X509Certificate2(keyFilePath, "notasecret", X509KeyStorageFlags.Exportable);
ServiceAccountCredential credential = new ServiceAccountCredential(new ServiceAccountCredential.Initializer(serviceAccountEmail) //create credential using certificate
{
Scopes = new[] { "https://spreadsheets.google.com/feeds/" } //this scopr is for spreadsheets, check google scope FAQ for others
}.FromCertificate(certificate));
credential.RequestAccessTokenAsync(System.Threading.CancellationToken.None).Wait(); //request token
var requestFactory = new GDataRequestFactory("Some Name");
requestFactory.CustomHeaders.Add(string.Format("Authorization: Bearer {0}", credential.Token.AccessToken));
SpreadsheetsService myService = new SpreadsheetsService("You App Name"); //create your old service
myService.RequestFactory = requestFactory; //add new request factory to your old service
SpreadsheetQuery query = new SpreadsheetQuery(); //do the job as you done it before
SpreadsheetFeed feed = myService.Query(query);
Alright, I figured it out. Step by step instructions as follows - also see the code I provided below. FYI, this runs in .Net 3.5 and unlike the solution offered previously there are no new dependencies. You should be up and running in no time.
If you haven't yet create your OAuth 2.0 credentials - I assume you already know how to get those but here:
a) Log into your Google developer console: http://console.developers.google.com
b) Create a project
c) Create your credentials - use 'installed application'
d) add the APIs that you need - I think Drive API is definitely required. I also added Drive SDK just in case.
Copy the code below into VS and edit the first Main() method with your client key and secret key.
Run the app and copy both the new access token and the refresh token. Put those and your remaining credentials into the second Main() method below.
You now should be able to run the second Main() method (just reverse the naming). From now on that will be all you need - there is no need to re-run the first Main() method.
BTW, the first Main() method below was found here: https://developers.google.com/google-apps/spreadsheets/authorize
I did however add the missing token type as well the access type. Those are needed, so use the code below:
using System;
using Google.GData.Client;
using Google.GData.Spreadsheets;
using Google.GData.Documents;
using System.Configuration;
using System.Collections.Specialized;
namespace GoogleSpreadsheet
{
class GoogleOAutho2
{
private static String folderName = "crazy.ivan";
static void Main(string[] args)
{
////////////////////////////////////////////////////////////////////////////
// STEP 1: Configure how to perform OAuth 2.0
////////////////////////////////////////////////////////////////////////////
// TODO: Update the following information with that obtained from
// https://code.google.com/apis/console. After registering
// your application, these will be provided for you.
string CLIENT_ID = "your_client_id";
// This is the OAuth 2.0 Client Secret retrieved
// above. Be sure to store this value securely. Leaking this
// value would enable others to act on behalf of your application!
string CLIENT_SECRET = "your_secret_key"
// Space separated list of scopes for which to request access.
string SCOPE = "https://www.googleapis.com/auth/drive https://spreadsheets.google.com/feeds https://docs.google.com/feeds";
// This is the Redirect URI for installed applications.
// If you are building a web application, you have to set your
// Redirect URI at https://code.google.com/apis/console.
string REDIRECT_URI = "urn:ietf:wg:oauth:2.0:oob";
string TOKEN_TYPE = "refresh";
////////////////////////////////////////////////////////////////////////////
// STEP 2: Set up the OAuth 2.0 object
////////////////////////////////////////////////////////////////////////////
// OAuth2Parameters holds all the parameters related to OAuth 2.0.
OAuth2Parameters parameters = new OAuth2Parameters();
// Set your OAuth 2.0 Client Id (which you can register at
// https://code.google.com/apis/console).
parameters.ClientId = CLIENT_ID;
// Set your OAuth 2.0 Client Secret, which can be obtained at
// https://code.google.com/apis/console.
parameters.ClientSecret = CLIENT_SECRET;
// Set your Redirect URI, which can be registered at
// https://code.google.com/apis/console.
parameters.RedirectUri = REDIRECT_URI;
////////////////////////////////////////////////////////////////////////////
// STEP 3: Get the Authorization URL
////////////////////////////////////////////////////////////////////////////
// Set the scope for this particular service.
parameters.Scope = SCOPE;
parameters.AccessType = "offline"; // IMPORTANT and was missing in the original
parameters.TokenType = TOKEN_TYPE; // IMPORTANT and was missing in the original
// Get the authorization url. The user of your application must visit
// this url in order to authorize with Google. If you are building a
// browser-based application, you can redirect the user to the authorization
// url.
string authorizationUrl = OAuthUtil.CreateOAuth2AuthorizationUrl(parameters);
Console.WriteLine(authorizationUrl);
Console.WriteLine("Please visit the URL above to authorize your OAuth "
+ "request token. Once that is complete, type in your access code to "
+ "continue...");
parameters.AccessCode = Console.ReadLine();
////////////////////////////////////////////////////////////////////////////
// STEP 4: Get the Access Token
////////////////////////////////////////////////////////////////////////////
// Once the user authorizes with Google, the request token can be exchanged
// for a long-lived access token. If you are building a browser-based
// application, you should parse the incoming request token from the url and
// set it in OAuthParameters before calling GetAccessToken().
OAuthUtil.GetAccessToken(parameters);
string accessToken = parameters.AccessToken;
string refreshToken = parameters.RefreshToken;
Console.WriteLine("OAuth Access Token: " + accessToken + "\n");
Console.WriteLine("OAuth Refresh Token: " + refreshToken + "\n");
////////////////////////////////////////////////////////////////////////////
// STEP 5: Make an OAuth authorized request to Google
////////////////////////////////////////////////////////////////////////////
// Initialize the variables needed to make the request
GOAuth2RequestFactory requestFactory =
new GOAuth2RequestFactory(null, "MySpreadsheetIntegration-v1", parameters);
SpreadsheetsService service = new SpreadsheetsService("MySpreadsheetIntegration-v1");
service.RequestFactory = requestFactory;
// Make the request to Google
// See other portions of this guide for code to put here...
// Instantiate a SpreadsheetQuery object to retrieve spreadsheets.
Google.GData.Spreadsheets.SpreadsheetQuery query = new Google.GData.Spreadsheets.SpreadsheetQuery();
// Make a request to the API and get all spreadsheets.
SpreadsheetFeed feed = service.Query(query);
// Iterate through all of the spreadsheets returned
foreach (SpreadsheetEntry entry in feed.Entries)
{
// Print the title of this spreadsheet to the screen
Console.WriteLine(entry.Title.Text);
}
Console.ReadLine();
}
// once you copied your access and refresh tokens
// then you can run this method directly from now on...
static void MainX(string[] args)
{
GOAuth2RequestFactory requestFactory = RefreshAuthenticate();
SpreadsheetsService service = new SpreadsheetsService("MySpreadsheetIntegration-v1");
service.RequestFactory = requestFactory;
// Instantiate a SpreadsheetQuery object to retrieve spreadsheets.
Google.GData.Spreadsheets.SpreadsheetQuery query = new Google.GData.Spreadsheets.SpreadsheetQuery();
// Make a request to the API and get all spreadsheets.
SpreadsheetFeed feed = service.Query(query);
// Iterate through all of the spreadsheets returned
foreach (SpreadsheetEntry entry in feed.Entries)
{
// Print the title of this spreadsheet to the screen
Console.WriteLine(entry.Title.Text);
}
Console.ReadLine();
public static GOAuth2RequestFactory RefreshAuthenticate() {
OAuth2Parameters parameters = new OAuth2Parameters(){
RefreshToken = "the_refresh_token_you_copied_from_the_CLI_running_the_first_method";
AccessToken = "the_access_token_you_copied_from_the_CLI_running_the_first_method";
ClientId = "your_client_id";
ClientSecret = "your_dirty_little_secret";
Scope = "https://www.googleapis.com/auth/drive https://spreadsheets.google.com/feeds",
AccessType = "offline",
TokenType = "refresh"
};
string authUrl = OAuthUtil.CreateOAuth2AuthorizationUrl(parameters);
return new GOAuth2RequestFactory(null, "evilspeculator", parameters);
}
}
}
Hope that works for you guys - best of luck!
Andrew I was wondering how you got the google.apis.auth.oauth2 dll. Im trying to impliment your fix and I cant find the correct way to install the library.
I feel like I may be able to get this to work after I have that part.
I am using Google Contacts Api. I am not sure whether I can send an Auth Token as a parameter.
string _token = _google.Token;
RequestSettings requestSettings = new RequestSettings("AppName",_token);
ContactsRequest contactsRequest = new ContactsRequest(requestSettings);
// Get the feed
Feed<Contact> feed = contactsRequest.GetContacts();
I get 401 Unauthorised as a response for this code, but if I send the username and password as parameters, I am able to get a response.
Whoops, sorry, I didn't quite get it right the first time. I'm using this code in a real app, I just do things a bit different in my code because I'm constantly refreshing tokens.
In any case, here's the proper logic:
// get this information from Google's API Console after registering your app
var parameters = new OAuth2Parameters
{
ClientId = #"",
ClientSecret = #"",
RedirectUri = #"",
Scope = #"https://www.google.com/m8/feeds/",
};
// generate the authorization url
string url = OAuthUtil.CreateOAuth2AuthorizationUrl(parameters);
// now use the url to authorize the app in the browser and get the access code
(...)
// get this information from Google's API Console after registering your app
parameters.AccessCode = #"<from previous step>";
// get an access token
OAuthUtil.GetAccessToken(parameters);
// setup connection to contacts service
var contacts = new ContactsRequest(new RequestSettings("<appname>", parameters));
// get each contact
foreach (var contact in contacts.GetContacts().Entries)
{
System.Diagnostics.Debug.WriteLine(contact.ContactEntry.Name.FullName);
}
FYI, after you call GetAccessToken() against your access code, your parameters data structure will include the AccessToken and RefreshToken fields. If you STORE these two values, you can set them in the parameters structure in subsequent calls (allowing you to skip asking for authorization in the future) and instead of calling GetAccessToken() simply call RefreshAccessToken(parameters) and you'll always have access to the contacts. Make sense? Here, take a look:
// get this information from Google's API Console after registering your app
var parameters = new OAuth2Parameters
{
ClientId = #"",
ClientSecret = #"",
RedirectUri = #"",
Scope = #"https://www.google.com/m8/feeds/",
AccessCode = "",
AccessToken = "", /* use the value returned from the old call to GetAccessToken here */
RefreshToken = "", /* use the value returned from the old call to GetAccessToken here */
};
// get an access token
OAuthUtil.RefreshAccessToken(parameters);
// setup connection to contacts service
var contacts = new ContactsRequest(new RequestSettings("<appname>", parameters));
// get each contact
foreach (var contact in contacts.GetContacts().Entries)
{
System.Diagnostics.Debug.WriteLine(contact.ContactEntry.Name.FullName);
}
Edit:
// generate the authorization url
string url = OAuthUtil.CreateOAuth2AuthorizationUrl(parameters);
// now use the url to authorize the app in the browser and get the access code
(...)
// get this information from Google's API Console after registering your app
var parameters = new OAuth2Parameters
{
ClientId = #"",
ClientSecret = #"",
RedirectUri = #"",
Scope = #"https://www.google.com/m8/feeds/",
AccessCode = #"<from previous step>",
};
// get an access token
OAuthUtil.GetAccessToken(parameters);
// setup connection to contacts service
var contacts = new ContactsRequest(new RequestSettings("<appname>", parameters));
// get each contact
foreach (var contact in contacts.GetContacts().Entries)
{
System.Diagnostics.Debug.WriteLine(contact.ContactEntry.Name.FullName);
}