Google plus language programming using people.list - c#

as a new researcher I am trying to get information about relations among people on G+. I want to get other's circle list for some research purpose. It seems that the G+ API offers a web version to use people.list with a OAuth2 token. My question is, does people.list support programming language such as c#, java? I tried with c# but it seems to be blocked by the server.
Is there is a way to apply people.list in c#,java etc? If yes, are there some samples? Or someone provide some open codes to fullfill similar functions?
thanks very much.
the following is my related c# code:
var provider = new NativeApplicationClient(GoogleAuthenticationServer.Description)
{
ClientIdentifier = credentials.ClientId,
ClientSecret = credentials.ClientSecret
};
var auth = new OAuth2Authenticator<NativeApplicationClient>(provider, GetAuthorization);
var servicelist = new PlusService(new BaseClientService.Initializer()
{
Authenticator = auth
});
string userId = "********************";
PeopleResource.ListRequest circle = servicelist.People.List(userId, new PeopleResource.Collection());
circle.MaxResults = 5;
PeopleFeed danielfeed = circle.Fetch();
private static IAuthorizationState GetAuthorization(NativeApplicationClient arg)
{
IAuthorizationState state = new AuthorizationState(new[] { TasksService.Scopes.Tasks.GetStringValue() });
state.Callback = new Uri(NativeApplicationClient.OutOfBandCallbackUrl);
Uri authUri = arg.RequestUserAuthorization(state);
Process.Start(authUri.ToString());
Console.Write(" Authorization Code: ");
string authCode = Console.ReadLine();
Console.WriteLine();
return arg.ProcessUserAuthorization(authCode, state);
}
}
The program goes wrong at "PeopleFeed danielfeed = circle.Fetch();" I think I have already passed the OAuth token to the people.list function by variable "auth". Can you give me some advices?

Google's People:list API's documentation is here. The entire API is RESTful, and does not block any language.
You can use C#, and just need to learn how to consume a REST API in C#. The C# class you will want to use is the HttpClient class. It is very well documented here and there are plenty of tutorials online, as well as here on SO.

Related

LibGit2Sharp: How to push a local repo commit to Azure DevOps remote repo using a Personal Access Token inside a custom HTTP authentication header?

I am trying to push a commit I made on my local repository to a remote counterpart, hosted on a private Azure DevOps server, using LibGit2Sharp programmatically.
As per the Azure documentation, the HTTPS OAuth enabled Personal Access Token needs to sent with the request in a custom Authentication header as 'Basic' with the Base64 encoded token:
var personalaccesstoken = "PATFROMWEB";
using (HttpClient client = new HttpClient()) {
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic",
Convert.ToBase64String(Encoding.ASCII.GetBytes($":{personalaccesstoken}")));
using (HttpResponseMessage response = client.GetAsync(
"https://dev.azure.com/{organization}/{project}/_apis/build/builds?api-version=5.0").Result) {
response.EnsureSuccessStatusCode();
}
}
The LibGit2Sharp.CloneOptions class has a FetchOptions field which in turn has a CustomHeaders array that can be used to inject the authentication header during the clone operation, like the following (as mentioned in this issue):
CloneOptions cloneOptions = new() {
CredentialsProvider = (url, usernameFromUrl, types) => new UsernamePasswordCredentials {
Username = $"{USERNAME}",
Password = $"{ACCESSTOKEN}"
},
FetchOptions = new FetchOptions {
CustomHeaders = new[] {
$"Authorization: Basic {encodedToken}"
}
}
};
Repository.Clone(AzureUrl, LocalDirectory, cloneOptions);
And the clone process succeeds (I tested it as well as checked the source code :) )
However, the LibGit2Sharp.PushOptions does not have any such mechanism to inject authentication headers. I am limited to the following code:
PushOptions pushOptions = new()
{
CredentialsProvider = (url, usernameFromUrl, types) => new UsernamePasswordCredentials
{
Username = $"{USERNAME}",
Password = $"{PASSWORD}"
}
};
This is making my push operation fail with the following message:
Too many redirects or authentication replays
I checked the source code for Repository.Network.Push() on Github.
public virtual void Push(Remote remote, IEnumerable<string> pushRefSpecs, PushOptions pushOptions)
{
Ensure.ArgumentNotNull(remote, "remote");
Ensure.ArgumentNotNull(pushRefSpecs, "pushRefSpecs");
// Return early if there is nothing to push.
if (!pushRefSpecs.Any())
{
return;
}
if (pushOptions == null)
{
pushOptions = new PushOptions();
}
// Load the remote.
using (RemoteHandle remoteHandle = Proxy.git_remote_lookup(repository.Handle, remote.Name, true))
{
var callbacks = new RemoteCallbacks(pushOptions);
GitRemoteCallbacks gitCallbacks = callbacks.GenerateCallbacks();
Proxy.git_remote_push(remoteHandle,
pushRefSpecs,
new GitPushOptions()
{
PackbuilderDegreeOfParallelism = pushOptions.PackbuilderDegreeOfParallelism,
RemoteCallbacks = gitCallbacks,
ProxyOptions = new GitProxyOptions { Version = 1 },
});
}
}
As we can see above, the Proxy.git_remote_push method call inside the Push() method is passing a new GitPushOptions object, which indeed seems to have a CustomHeaders field implemented. But it is not exposed to a consumer application and is being instantiated in the library code directly!
It is an absolute necessity for me to use the LibGit2Sharp API, and our end-to-end testing needs to be done on Azure DevOps repositories, so this issue is blocking me from progressing further.
My questions are:
Is it possible to use some other way to authenticate a push operation on Azure from LibGit2Sharp? Can we leverage the PushOptions.CredentialsProvider handler so that it is compatible with the auth-n method that Azure insists on?
Can we cache the credentials by calling Commands.Fetch by injecting the header in a FetchOptions object before carrying out the Push command? I tried it but it fails with the same error.
To address the issue, is there a modification required on the library to make it compatible with Azure Repos? If yes, then I can step up and contribute if someone could give me pointers on how the binding to the native code is made :)
I will provide an answer to my own question as we have fixed the problem.
The solution to this is really simple; I just needed to remove the CredentialsProvider delegate from the PushOptions object, that is:
var pushOptions = new PushOptions();
instead of,
PushOptions pushOptions = new()
{
CredentialsProvider = (url, usernameFromUrl, types) => new UsernamePasswordCredentials
{
Username = $"{USERNAME}",
Password = $"{PASSWORD}"
}
};
¯\(ツ)/¯
I don't know why it works, but it does. (Maybe some folks from Azure can clarify it to us.)
It turns out that this works on windows (push options with no credentials provider). Perhaps because somewhere a native call the OS resolves the credentials using some other means. But in Linux / container environment, the issue persists.
"There was a problem pushing the repo: remote authentication required but no callback set"
I think as you mentioned, minimally the CustomHeaders implementation must be exposed for this to work.
Image of error on console

Youtube API List channels other than Google

I am sitting hours and cannot find the answer for issue I have. I am using latest Youtube API for .NET
The problem I wanna solve is to take information - mostly id from any channel for Youtube channel I give the name.
var youtubeService = new YouTubeService(new BaseClientService.Initializer()
{
ApiKey = "key",
ApplicationName = "appName"
});
var asd = youtubeService.Channels.List(new Repeatable<string>(new List<string> { "snippet,contentDetails,statistics" }));
asd.ForUsername = "Mauzer";
var dsa = await asd.ExecuteAsync();
To achieve that I am using ForUsername property. However the result of call does not always return the result.
For example if I type "Google" as Username it return the Google`s channel. However it doesn't work for all channels I can find exploring Youtube.
Anyone is familiar and know what I am missing?

Calling MailChimp API v3.0 with .Net

I'm trying to access our MailChimp account via the new 3.0 REST API. I've done the following:
using(var http = new HttpClient())
{
var creds = Convert.ToBase64String(Encoding.ASCII.GetBytes("username:mailchimpapikey-us1"));
http.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", creds);
string content = await http.GetStringAsync(#"https://us1.api.mailchimp.com/3.0/lists");
Console.WriteLine(content);
}
However, when I run this code, I get a 401 error with the following json details:
{"type":"http://kb.mailchimp.com/api/error-docs/401-api-key-invalid","title":"API Key Invalid","status":401,"detail":"Your API key may be invalid, or you've attempted to access the wrong datacenter.","instance":"a9fe4028-519e-41d6-9f77-d2caee4d4683"}
The datacenter I'm using in my URI (us1 in this example) matches the dc on my API key. My API key works if I use the MailChimp SDK so I know my key isn't invalid. Also, using Fiddler, I can see that the MailChimp SDK is calling the same dc as I'm doing in my URI.
Any Ideas as to why I am having trouble Authenticating?
EDIT
As noted in the question, I'm asking specifically about accessing the new 3.0 REST API. I'm trying to do this directly as opposed to using a third party wrapper.
The new API is composed of http calls so it should be pretty straight forward. I'm simply having trouble with the authentication piece.
So I was able to finally chat with a super tech support person at MailChimp.
The MailChimp docs state the following
The easiest way to authenticate is using HTTP Basic Auth. Enter any string
as the username and supply your API Key as the password.
Your HTTP library should have built-in support for basic authorization.
Their documentation is a bit misleading. Typically the Auth header for Basic Auth would look like what I was sending:
Authorization: Basic xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
where the row of x would represent the base64 encoded username:password.
However, talking with the support tech, the actual implementation they use is:
Authorization: username keyid
No base64 encoding, no Basic keyword. Username doesn't even have to be your username.
So, here is the working code:
using(var http = new HttpClient())
{
http.DefaultRequestHeaders.Authorization =
new AuthenticationHeaderValue("Basic", mailchimpapikey-us1);
string content = await http.GetStringAsync(#"https://us1.api.mailchimp.com/3.0/lists");
Console.WriteLine(content);
}
EDIT
Note the comments. TooMuchPete was correct in that the normal HTTP Basic Auth headers do work. Apparently I was hitting some old code or something on the MailChimp side.
I'm leaving the post as a reference for anyone who is trying to call the new 3.0 API.
I wrote an article on a simple way up adding subscribers to a list using:
Dim mailchimp As New ZmailChimp
Dim ListId$ = "9b2e63f0b9" 'List Sage' List
Dim email$ = "samsmith20#anymail.com" '"sam19#postcodelite.com"
Dim fieldListOnAdd = "FNAME,Sam,LNAME,Smith,MTYPE,User,MID,631637"
Dim fieldListOnUpdate = "FNAME,Sam,LNAME,Smith,MID,631637" 'Don't change MTYPE
'Put on 'Sage One' and 'Sage 50' group
Dim groupList = "407da9f47d,05086211ba"
With mailchimp
.API$ = "46cMailChimpAPIKeyd1de-us14" 'MailChimp API key
.dataCenter$ = "us14" 'Last 4 letters of API key
.password$ = "Password!"
MsgBox(.addSubscriber(ListId$, email, fieldListOnAdd, fieldListOnUpdate, groupList))
End With
mailchimp = Nothing
see:http://www.codeproject.com/Tips/1140339/Mail-Chimp-Add-Update-e-mail-to-List-and-Subscribe
this may save someone some time
Mailchimp Ecommerce
var mcorder = new Standup.Ecomm.MailChimpManager(ConfigurationManager.AppSettings["MailChimpApiKey"]);
var orders = new MailOrder();
orders.CampaignId = ConfigurationManager.AppSettings["MailChimpCampaignId"];
orders.EmailId = ConfigurationManager.AppSettings["MailChimpEmailId"];
orders.Id = orderNumber;
orders.StoreId = "abcde";
orders.StoreName = "E-Commerce Store";
orders.Total = Convert.ToDouble(orderTotal);
orders.Tax = Convert.ToDouble(tax);
orders.Items = new List<MailOrderItem>();
foreach (var orderItem in orderItemList)
{
var item = new MailOrderItem();
item.ProductId = orderItem.OrderNumber;
item.ProductName = orderItem.Title;
item.SKU = orderItem.Sku;
item.CategoryId = 0;
item.CategoryName = " ";
item.Quantity = orderItem.Quantity;
item.Cost = Convert.ToDouble(orderItem.ProductCost);
orders.Items.Add(item);
}
mcorder.AddOrder(orders);

Facebook permission error

public Form1()
{
InitializeComponent();
// The application key of the Facebook application used
fbService.ApplicationKey = "XXXXXXXXXXX";
// Add all needed permissions
List<Enums.ExtendedPermissions> perms = new List<Enums.ExtendedPermissions>
{
Enums.ExtendedPermissions.none
};
fbService.ConnectToFacebook(perms); //error here (The given key was not present in the dictionary.)
}
I mention the error where I get the error , as am new to facebook api and specially new to c# any explained answer is appriciated
Thank you
Use the static method on FacebookClient like this:
FacebookClient.SetDefaultHttpWebRequestFactory(uri => {
var request = new HttpWebRequestWrapper((HttpWebRequest)WebRequest.Create(uri));
request.Proxy = ......; // normal .net IWebProxy
return request;
});
See this answer also: Facebook SDK Proxy setting C#

Google+ API: How can I use RefreshTokens to avoid requesting access every time my app launches?

I'm trying to use the Google+ API to access info for the authenticated user. I've copied some code from one of the samples, which works fine (below), however I'm having trouble making it work in a way I can reuse the token across app-launches.
I tried capturing the "RefreshToken" property and using provider.RefreshToken() (amongst other things) and always get a 400 Bad Request response.
Does anyone know how to make this work, or know where I can find some samples? The Google Code site doesn't seem to cover this :-(
class Program
{
private const string Scope = "https://www.googleapis.com/auth/plus.me";
static void Main(string[] args)
{
var provider = new NativeApplicationClient(GoogleAuthenticationServer.Description);
provider.ClientIdentifier = "BLAH";
provider.ClientSecret = "BLAH";
var auth = new OAuth2Authenticator<NativeApplicationClient>(provider, GetAuthentication);
var plus = new PlusService(auth);
plus.Key = "BLAH";
var me = plus.People.Get("me").Fetch();
Console.WriteLine(me.DisplayName);
}
private static IAuthorizationState GetAuthentication(NativeApplicationClient arg)
{
// Get the auth URL:
IAuthorizationState state = new AuthorizationState(new[] { Scope });
state.Callback = new Uri(NativeApplicationClient.OutOfBandCallbackUrl);
Uri authUri = arg.RequestUserAuthorization(state);
// Request authorization from the user (by opening a browser window):
Process.Start(authUri.ToString());
Console.Write(" Authorization Code: ");
string authCode = Console.ReadLine();
Console.WriteLine();
// Retrieve the access token by using the authorization code:
return arg.ProcessUserAuthorization(authCode, state);
}
}
Here is an example. Make sure you add a string setting called RefreshToken and reference System.Security or find another way to safely store the refresh token.
private static byte[] aditionalEntropy = { 1, 2, 3, 4, 5 };
private static IAuthorizationState GetAuthorization(NativeApplicationClient arg)
{
// Get the auth URL:
IAuthorizationState state = new AuthorizationState(new[] { PlusService.Scopes.PlusMe.GetStringValue() });
state.Callback = new Uri(NativeApplicationClient.OutOfBandCallbackUrl);
string refreshToken = LoadRefreshToken();
if (!String.IsNullOrWhiteSpace(refreshToken))
{
state.RefreshToken = refreshToken;
if (arg.RefreshToken(state))
return state;
}
Uri authUri = arg.RequestUserAuthorization(state);
// Request authorization from the user (by opening a browser window):
Process.Start(authUri.ToString());
Console.Write(" Authorization Code: ");
string authCode = Console.ReadLine();
Console.WriteLine();
// Retrieve the access token by using the authorization code:
var result = arg.ProcessUserAuthorization(authCode, state);
StoreRefreshToken(state);
return result;
}
private static string LoadRefreshToken()
{
return Encoding.Unicode.GetString(ProtectedData.Unprotect(Convert.FromBase64String(Properties.Settings.Default.RefreshToken), aditionalEntropy, DataProtectionScope.CurrentUser));
}
private static void StoreRefreshToken(IAuthorizationState state)
{
Properties.Settings.Default.RefreshToken = Convert.ToBase64String(ProtectedData.Protect(Encoding.Unicode.GetBytes(state.RefreshToken), aditionalEntropy, DataProtectionScope.CurrentUser));
Properties.Settings.Default.Save();
}
The general idea is as follows:
You redirect the user to Google's Authorization Endpoint.
You obtain a short-lived Authorization Code.
You immediately exchange the Authorization Code for a long-lived Access Token using Google's Token Endpoint. The Access Token comes with an expiry date and a Refresh Token.
You make requests to Google's API using the Access Token.
You can reuse the Access Token for as many requests as you like until it expires. Then you can use the Refresh Token to request a new Access Token (which comes with a new expiry date and a new Refresh Token).
See also:
The OAuth 2.0 Authorization Protocol
Google's OAuth 2.0 documentation
I also had problems with getting "offline" authentication to work (i.e. acquiring authentication with a refresh token), and got HTTP-response 400 Bad request with a code similar to the OP's code. However, I got it to work with the line client.ClientCredentialApplicator = ClientCredentialApplicator.PostParameter(this.clientSecret); in the Authenticate-method. This is essential to get a working code -- I think this line forces the clientSecret to be sent as a POST-parameter to the server (instead of as a HTTP Basic Auth-parameter).
This solution assumes that you've already got a client ID, a client secret and a refresh-token. Note that you don't need to enter an access-token in the code. (A short-lived access-code is acquired "under the hood" from the Google server when sending the long-lived refresh-token with the line client.RefreshAuthorization(state);. This access-token is stored as part of the auth-variable, from where it is used to authorize the API-calls "under the hood".)
A code example that works for me with Google API v3 for accessing my Google Calendar:
class SomeClass
{
private string clientID = "XXXXXXXXX.apps.googleusercontent.com";
private string clientSecret = "MY_CLIENT_SECRET";
private string refreshToken = "MY_REFRESH_TOKEN";
private string primaryCal = "MY_GMAIL_ADDRESS";
private void button2_Click_1(object sender, EventArgs e)
{
try
{
NativeApplicationClient client = new NativeApplicationClient(GoogleAuthenticationServer.Description, this.clientID, this.clientSecret);
OAuth2Authenticator<NativeApplicationClient> auth = new OAuth2Authenticator<NativeApplicationClient>(client, Authenticate);
// Authenticated and ready for API calls...
// EITHER Calendar API calls (tested):
CalendarService cal = new CalendarService(auth);
EventsResource.ListRequest listrequest = cal.Events.List(this.primaryCal);
Google.Apis.Calendar.v3.Data.Events events = listrequest.Fetch();
// iterate the events and show them here.
// OR Plus API calls (not tested) - copied from OP's code:
var plus = new PlusService(auth);
plus.Key = "BLAH"; // don't know what this line does.
var me = plus.People.Get("me").Fetch();
Console.WriteLine(me.DisplayName);
// OR some other API calls...
}
catch (Exception ex)
{
Console.WriteLine("Error while communicating with Google servers. Try again(?). The error was:\r\n" + ex.Message + "\r\n\r\nInner exception:\r\n" + ex.InnerException.Message);
}
}
private IAuthorizationState Authenticate(NativeApplicationClient client)
{
IAuthorizationState state = new AuthorizationState(new string[] { }) { RefreshToken = this.refreshToken };
// IMPORTANT - does not work without:
client.ClientCredentialApplicator = ClientCredentialApplicator.PostParameter(this.clientSecret);
client.RefreshAuthorization(state);
return state;
}
}
The OAuth 2.0 spec is not yet finished, and there is a smattering of spec implementations out there across the various clients and services that cause these errors to appear. Mostly likely you're doing everything right, but the DotNetOpenAuth version you're using implements a different draft of OAuth 2.0 than Google is currently implementing. Neither part is "right", since the spec isn't yet finalized, but it makes compatibility something of a nightmare.
You can check that the DotNetOpenAuth version you're using is the latest (in case that helps, which it might), but ultimately you may need to either sit tight until the specs are finalized and everyone implements them correctly, or read the Google docs yourself (which presumably describe their version of OAuth 2.0) and implement one that specifically targets their draft version.
I would recommend looking at the "SampleHelper" project in the Samples solution of the Google .NET Client API:
Samples/SampleHelper/AuthorizationMgr.cs
This file shows both how to use Windows Protected Data to store a Refresh token, and it also shows how to use a Local Loopback Server and different techniques to capture the Access code instead of having the user enter it manually.
One of the samples in the library which use this method of authorization can be found below:
Samples/Tasks.CreateTasks/Program.cs

Categories