Get list of named ranges using googlesheets api v4 in c# - google-sheets-api

I need to be able to get a list of all named ranges in a spreadsheet, but can't figure out how to do this.
I've found the following code but its not c# - how do I do the same thing in c#?
Code that does what I need but not in c#
function getNamedRanges2(spreadsheetId) {
var ss = SpreadsheetApp.openById(spreadsheetId);
var sheetIdToName = {};
ss.getSheets().forEach(function(e) {
sheetIdToName[e.getSheetId()] = e.getSheetName();
});
var result = {};
Sheets.Spreadsheets.get(spreadsheetId, {fields: "namedRanges"})
.namedRanges.forEach(function(e) {
var sheetName = sheetIdToName[e.range.sheetId.toString()];
var a1notation = ss.getSheetByName(sheetName).getRange(
e.range.startRowIndex + 1,
e.range.startColumnIndex + 1,
e.range.endRowIndex - e.range.startRowIndex,
e.range.endColumnIndex - e.range.startColumnIndex
).getA1Notation();
result[e.name] = sheetName + "!" + a1notation;
});
return result;
}
function main() {
var spreadsheetId = "### spreadsheet ID ###";
var result = getNamedRanges2(spreadsheetId);
Logger.log(JSON.stringify(result));
}

Based on the Quickstart for Sheets API and the C# sample code for Method: spreadsheets.get2, you can combine the two code snippets as following, in order to retrieve named ranges:
using Google.Apis.Auth.OAuth2;
using Google.Apis.Sheets.v4;
using Google.Apis.Sheets.v4.Data;
using Google.Apis.Services;
using Google.Apis.Util.Store;
using System;
using System.Collections.Generic;
using System.IO;
using System.Threading;
using Newtonsoft.Json;
using Data = Google.Apis.Sheets.v4.Data;
namespace SheetsQuickstart
{
class Program
{
// If modifying these scopes, delete your previously saved credentials
// at ~/.credentials/sheets.googleapis.com-dotnet-quickstart.json
static string[] Scopes = { SheetsService.Scope.SpreadsheetsReadonly };
static string ApplicationName = "Google Sheets API .NET Quickstart";
static void Main(string[] args)
{
UserCredential credential;
using (var stream =
new FileStream("credentials.json", FileMode.Open, FileAccess.Read))
{
// The file token.json stores the user's access and refresh tokens, and is created
// automatically when the authorization flow completes for the first time.
string credPath = "token.json";
credential = GoogleWebAuthorizationBroker.AuthorizeAsync(
GoogleClientSecrets.Load(stream).Secrets,
Scopes,
"user",
CancellationToken.None,
new FileDataStore(credPath, true)).Result;
Console.WriteLine("Credential file saved to: " + credPath);
}
// Create Google Sheets API service.
var service = new SheetsService(new BaseClientService.Initializer()
{
HttpClientInitializer = credential,
ApplicationName = ApplicationName,
});
// The spreadsheet to request.
string spreadsheetId = "YOUR SPREADSHEET ID";
// TODO: Update placeholder value.
SpreadsheetsResource.GetRequest request = service.Spreadsheets.Get(spreadsheetId);
request.Fields = "namedRanges";
// To execute asynchronously in an async method, replace `request.Execute()` as shown:
Data.Spreadsheet response = request.Execute();
// TODO: Change code below to process the `response` object:
Console.WriteLine(JsonConvert.SerializeObject(response));
}
}
}
The response will contain only the named ranges when request.Fields = "namedRanges"; is specified.

Related

google oauth 2 authorization when using their indexing api

I'm trying to make sense of the google indexing api but their documentation is horrible. I've gone through setting up the service account and downloading the json file along with the remaining prerequisites. The next step is to get an access token to authenticate.
I'm in a .net environment but they don't give an example for that. I did find some example of using a .net library to do it here, but after the following code I'm not sure what service would be created to then make the call to the indexing api. I don't see a google.apis.indexing library in the nuget package manager.
UserCredential credential;
using (var stream = new FileStream("client_secrets.json", FileMode.Open, FileAccess.Read))
{
credential = await GoogleWebAuthorizationBroker.AuthorizeAsync(
GoogleClientSecrets.Load(stream).Secrets,
new[] { "https://www.googleapis.com/auth/indexing" },
"user", CancellationToken.None, new FileDataStore("IndexingStore"));
}
In their example code it looks like just a simple json post. I tried that but of course it doesn't work because I'm not authenticated. I'm just not sure how to tie all of this together in a .net environment.
You're right, Google's documentation for this is either not there or is terrible. Even their own docs have broken or unfinished pages in them and in one of them you're pointed to a nuget package that doesn't exist. It is possible to get this to work though by cobbling together other Auth examples on SA and then following the Java indexing documentation.
First, you'll need to use nuget package manager to add the main api package and the auth package:
Google.Apis
Google.Apis.Auth
Then try the following:
using System;
using System.Configuration;
using System.IO;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using Google.Apis.Auth.OAuth2;
using Google.Apis.Http;
using Newtonsoft.Json;
namespace MyProject.Common.GoogleForJobs
{
public class GoogleJobsClient
{
public async Task<HttpResponseMessage> AddOrUpdateJob(string jobUrl)
{
return await PostJobToGoogle(jobUrl, "URL_UPDATED");
}
public async Task<HttpResponseMessage> CloseJob(string jobUrl)
{
return await PostJobToGoogle(jobUrl, "URL_DELETED");
}
private static GoogleCredential GetGoogleCredential()
{
var path = ConfigurationManager.AppSettings["GoogleForJobsJsonFile"];
GoogleCredential credential;
using (var stream = new FileStream(path, FileMode.Open, FileAccess.Read))
{
credential = GoogleCredential.FromStream(stream)
.CreateScoped(new[] { "https://www.googleapis.com/auth/indexing" });
}
return credential;
}
private async Task<HttpResponseMessage> PostJobToGoogle(string jobUrl, string action)
{
var googleCredential = GetGoogleCredential();
var serviceAccountCredential = (ServiceAccountCredential) googleCredential.UnderlyingCredential;
const string googleApiUrl = "https://indexing.googleapis.com/v3/urlNotifications:publish";
var requestBody = new
{
url = jobUrl,
type = action
};
var httpClientHandler = new HttpClientHandler();
var configurableMessageHandler = new ConfigurableMessageHandler(httpClientHandler);
var configurableHttpClient = new ConfigurableHttpClient(configurableMessageHandler);
serviceAccountCredential.Initialize(configurableHttpClient);
HttpContent content = new StringContent(JsonConvert.SerializeObject(requestBody), Encoding.UTF8, "application/json");
var response = await configurableHttpClient.PostAsync(new Uri(googleApiUrl), content);
return response;
}
}
}
You can then just call it like this
var googleJobsClient = new GoogleJobsClient();
var result = await googleJobsClient.AddOrUpdateJob(url_of_vacancy);
Or if you're not inside an async method
var googleJobsClient = new GoogleJobsClient();
var result = googleJobsClient.AddOrUpdateJob(url_of_vacancy).Result;

How to use the continuationtoken in TFS 2015 Object Model: GetBuildsAsync?

I am using the following code
BuildHttpClient service = new BuildHttpClient(tfsCollectionUri,
new Microsoft.VisualStudio.Services.Common.VssCredentials(true));
var asyncResult = service.GetBuildsAsync(project: tfsTeamProject);
var queryResult = asyncResult.Result;
This returns only the first 199 builds.
Looks like in need to use the continuationtoken but am not sure how to do this. The docs say that the REST API will return the token. I am using the Object Model, and am looking for how to retrieve the token!
I am using Microsoft.TeamFoundationServer.Client v 14.102.0; Microsoft.TeamFoundationServer.ExtendedClient v 14.102.0, Microsoft.VisualStudio.Service.Client v 14.102.0 and Microsoft.VisualStudio.Services.InteractiveClient v 14.102.0
Question
How do I use the continuation token **when using the TFS Object model?
The continuationToken is in the response header after the first call to the API:
x-ms-continuationtoken: xxxx
It can not be retrieved from .net client library. You have to use the rest api to retrieve the header information. Here is an example for your reference:
using System;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading.Tasks;
namespace GetBuilds
{
class Program
{
public static void Main()
{
Task t = GetBuilds();
Task.WaitAll(new Task[] { t });
}
private static async Task GetBuilds()
{
try
{
var username = "xxxxx";
var password = "******";
using (var client = new HttpClient())
{
client.DefaultRequestHeaders.Accept.Add(
new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/json"));
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic",
Convert.ToBase64String(
System.Text.ASCIIEncoding.ASCII.GetBytes(
string.Format("{0}:{1}", username, password))));
using (HttpResponseMessage response = client.GetAsync(
"http://tfs2015:8080/tfs/DefaultCollection/teamproject/_apis/build/builds?api-version=2.2").Result)
{
response.EnsureSuccessStatusCode();
string responseBody = await response.Content.ReadAsStringAsync();
Console.WriteLine(responseBody);
}
}
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
}
}
}
You have to use 'GetBuildsAsync2', which returns an IPagedList. You can retrieve the ContinuationToken from the IPagedList:
// Iterate to get the full set of builds
string continuationToken = null;
List<Build> builds = new List<Build>();
do
{
IPagedList<Build> buildsPage = service.GetBuildsAsync2(tfsTeamProject, continuationToken: continuationToken).Result;
//add the builds
builds.AddRange(buildsPage);
//get the continuationToken for the next loop
continuationToken = buildsPage.ContinuationToken;
}
while (continuationToken != null);

List of folder not shared with me, Google Drive API

In my application, I want to list all folder that exist in my drive, but I don't know how to do it. I want to list folder just in "My Drive" not in "Shared with me".
Here is my code :
Dim fold = Service.Files.List()
fold.Q = "mimeType = 'application/vnd.google-apps.folder' and trashed = false and 'me' in owners "
But I have an exception: Invalid Query [400]
You can refer to this documentation.
Also, the includeTeamDriveItems was already set to false as a default value. From here, you will be able to set if you want to include team drives in the result.
Try the code from the quickstart.
using Google.Apis.Auth.OAuth2;
using Google.Apis.Drive.v3;
using Google.Apis.Drive.v3.Data;
using Google.Apis.Services;
using Google.Apis.Util.Store;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace DriveQuickstart
{
class Program
{
// If modifying these scopes, delete your previously saved credentials
// at ~/.credentials/drive-dotnet-quickstart.json
static string[] Scopes = { DriveService.Scope.DriveReadonly };
static string ApplicationName = "Drive API .NET Quickstart";
static void Main(string[] args)
{
UserCredential credential;
using (var stream =
new FileStream("client_secret.json", FileMode.Open, FileAccess.Read))
{
string credPath = System.Environment.GetFolderPath(
System.Environment.SpecialFolder.Personal);
credPath = Path.Combine(credPath, ".credentials/drive-dotnet-quickstart.json");
credential = GoogleWebAuthorizationBroker.AuthorizeAsync(
GoogleClientSecrets.Load(stream).Secrets,
Scopes,
"user",
CancellationToken.None,
new FileDataStore(credPath, true)).Result;
Console.WriteLine("Credential file saved to: " + credPath);
}
// Create Drive API service.
var service = new DriveService(new BaseClientService.Initializer()
{
HttpClientInitializer = credential,
ApplicationName = ApplicationName,
});
// Define parameters of request.
FilesResource.ListRequest listRequest = service.Files.List();
listRequest.PageSize = 10;
listRequest.Fields = "nextPageToken, files(id, name)";
// List files.
IList<Google.Apis.Drive.v3.Data.File> files = listRequest.Execute()
.Files;
Console.WriteLine("Files:");
if (files != null && files.Count > 0)
{
foreach (var file in files)
{
Console.WriteLine("{0} ({1})", file.Name, file.Id);
}
}
else
{
Console.WriteLine("No files found.");
}
Console.Read();
}
}
}
Regarding your error, I think you are trying to use search parameters specific for two different versions, Drive v3 API and Drive v2 API
You can refer to this SO post for further information.

TFS API to create a TFS Group and set permissions?

Hello I'm trying to use TFS API to create a new group, for it I have this code:
var teamProjects = this.VersionControlServer.GetAllTeamProjects(false);
foreach (var teamProject in teamProjects)
{
var result = _gss.CreateApplicationGroup(teamProject.ArtifactUri.AbsoluteUri, "NewGroup","TestDescription");
//NOW I WANT TO SET THE PERMISSIONS FOR THIS GROUP
}
As I need to set the permission "Edit project-level information" for this group I tried lot of methods and different approaches, but anything seems to solve my need. This for example:
var ProjectSecurityToken = AuthorizationSecurityConstants.ProjectSecurityPrefix + teamProject.ArtifactUri.AbsoluteUri;
var groupACL = securityNamespace.QueryAccessControlList(ProjectSecurityToken, new[] {list[4].Descriptor}, false);
securityNamespace.SetAccessControlEntry(ProjectSecurityToken, new Microsoft.TeamFoundation.Framework.Client.AccessControlEntry(list[4].Descriptor, 115, 0), true);
I had hard-coded "list[4]" because it was the group I just created, I need some help to see what is wrong in my code. I get no error message and it doesn't work as well.
I can get the permissions been set via following code:
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.TeamFoundation.Client;
using Microsoft.TeamFoundation.Server;
using Microsoft.TeamFoundation.VersionControl.Client;
using Microsoft.TeamFoundation.Framework.Client;
namespace API
{
class Program
{
static void Main(string[] args)
{
string project = "http://xxx.xxx.xxx.xxx:8080/tfs";
TfsTeamProjectCollection tpc = new TfsTeamProjectCollection(new Uri(project));
var tps = tpc.GetService<VersionControlServer>();
var ttt = tps.GetTeamProject("ProjectName");
ISecurityService securityService = tpc.GetService<ISecurityService>();
System.Collections.ObjectModel.ReadOnlyCollection<SecurityNamespace> securityNamespaces = securityService.GetSecurityNamespaces();
IGroupSecurityService gss = tpc.GetService<IGroupSecurityService>();
Identity SIDS = gss.ReadIdentity(SearchFactor.AccountName, "GroupName", QueryMembership.Expanded);//GourName format: [ProjectName]\\GourpName
IdentityDescriptor id = new IdentityDescriptor("Microsoft.TeamFoundation.Identity", SIDS.Sid);
List<SecurityNamespace> securityList = securityNamespaces.ToList<SecurityNamespace>();
string securityToken;
foreach (SecurityNamespace sn in securityList)
{
if (sn.Description.DisplayName == "Project")
{
securityToken = "$PROJECT:" + ttt.ArtifactUri.AbsoluteUri;
sn.SetPermissions(securityToken, id, 115, 0, true);
}
}
}
}
}

TwitterSettings.OAuthVersion

i don't understand that : GetRequestToken is not working in TweetSharp on Windows Phone
My code :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Navigation;
using Microsoft.Phone.Controls;
using Microsoft.Phone.Shell;
using PhoneApp2.Resources;
using TweetSharp;
namespace PhoneApp2
{
public partial class MainPage : PhoneApplicationPage
{
private const string consumerKey = "zvBvaKjEQRwGqu9ECaNfop0pr";
private const string consumerSecret = "SgEqsMRcIrEYNrtXhvtYdnx7qBA9EITzswneyjf8wRorDvSAvn";
private TwitterService myclient;
private OAuthRequestToken requestToken;
private bool userAuthenticated = false;
// Constructeur
public MainPage()
{
InitializeComponent();
myclient = new TwitterService(consumerKey, consumerSecret);
}
private void Button_Click(object sender, RoutedEventArgs e)
{
//If user is already logged in, just send the tweet, otherwise get the RequestToken
if (userAuthenticated)
//send the Tweet, this is just a placeholder, we will add the actual code later
Dispatcher.BeginInvoke(() => { MessageBox.Show("Placeholder for tweet sending"); });
else
myclient.GetRequestToken(processRequestToken);
}
private void processRequestToken(OAuthRequestToken token, TwitterResponse response)
{
if (token == null)
Dispatcher.BeginInvoke(() => { MessageBox.Show("Error getting request token"); });
else
{
requestToken = token;
Dispatcher.BeginInvoke(() =>
{
Browser.Visibility = System.Windows.Visibility.Visible;
Browser.Navigate(myclient.GetAuthorizationUri(requestToken));
});
}
}
}
}
and visual studio 2013 create an error on myclient.GetRequestToken(processRequestToken); ...
how can incorporate your solution with hammock on my code?
I had this identical error last week (doing this app) The solution was to implement the Hammock Library instead of tweet sharp. Also in the post tweet example change the version from 1 to 1.1
This is the Nokia Developer Documentation I followed to implement logging in
This is the Nokia Developer Documentation I followed to implement posting a tweet
REMEMBER CHANGE THE VERSION TO 1.1 LIKE THIS
From this
var credentials = new OAuthCredentials
{
Type = OAuthType.ProtectedResource,
SignatureMethod = OAuthSignatureMethod.HmacSha1,
ParameterHandling = OAuthParameterHandling.HttpAuthorizationHeader,
ConsumerKey = AppSettings.consumerKey,
ConsumerSecret = AppSettings.consumerKeySecret,
Token = this.accessToken,
TokenSecret = this.accessTokenSecret,
Version = "1.0"
};
var restClient = new RestClient
{
Authority = "http://api.twitter.com",
HasElevatedPermissions = true
};
var restRequest = new RestRequest
{
Credentials = credentials,
Path = "/1/statuses/update.json",
Method = WebMethod.Post
};
restRequest.AddParameter("status", txtTweetContent.Text);
restClient.BeginRequest(restRequest, new RestCallback(PostTweetRequestCallback));
To This
var credentials = new OAuthCredentials
{
Type = OAuthType.ProtectedResource,
SignatureMethod = OAuthSignatureMethod.HmacSha1,
ParameterHandling = OAuthParameterHandling.HttpAuthorizationHeader,
ConsumerKey = AppSettings.consumerKey,
ConsumerSecret = AppSettings.consumerKeySecret,
Token = this.accessToken,
TokenSecret = this.accessTokenSecret,
Version = "1.0"
};
var restClient = new RestClient
{
Authority = "http://api.twitter.com",
HasElevatedPermissions = true
};
var restRequest = new RestRequest
{
Credentials = credentials,
Path = "/1.1/statuses/update.json",
Method = WebMethod.Post
};
restRequest.AddParameter("status", txtTweetContent.Text);
restClient.BeginRequest(restRequest, new RestCallback(PostTweetRequestCallback));