displaying details from youtube api c# - c#

trying to display playlist details from Youtube API, api is successfully working and picking up information, but I dont know how to display the information received other than console.writeLine, I want to be able to display in .net site and format it.Have already got information assigning to variables but dont know how to translate them over to viewable objects
Code as follows:
API Code:
/*
*/
using System;
using System.IO;
using System.Reflection;
using System.Threading;
using System.Threading.Tasks;
using Google.Apis.Auth.OAuth2;
using Google.Apis.Services;
using Google.Apis.Upload;
using Google.Apis.Util.Store;
using Google.Apis.YouTube.v3;
using Google.Apis.YouTube.v3.Data;
public class uploaded_videos
{
//adapted from youtube api code samples for .net
public async Task Run(Video_details vidDetails)
{
//Google API validation
UserCredential credential;
using (var stream = new FileStream(#"C:\Users\siobhan\Documents\Visual Studio 2015\WebSites\FYP_November\Client_id_googleApi.json", FileMode.Open, FileAccess.Read))
{
credential = await GoogleWebAuthorizationBroker.AuthorizeAsync(
GoogleClientSecrets.Load(stream).Secrets,
// This OAuth 2.0 access scope allows for read-only access to the authenticated
// user's account, but not other types of account access.
new[] { YouTubeService.Scope.YoutubeReadonly },
"user",
CancellationToken.None,
new FileDataStore(this.GetType().ToString())
);
}
var youtubeService = new YouTubeService(new BaseClientService.Initializer()
{
HttpClientInitializer = credential,
ApplicationName = this.GetType().ToString()
});
var channelsListRequest = youtubeService.Channels.List("contentDetails");
channelsListRequest.Mine = true;
// Retrieve the contentDetails part of the channel resource for the authenticated user's channel.
var channelsListResponse = await channelsListRequest.ExecuteAsync();
foreach (var channel in channelsListResponse.Items)
{
// From the API response, extract the playlist ID that identifies the list
// of videos uploaded to the authenticated user's channel.
var uploadsListId = channel.ContentDetails.RelatedPlaylists.Uploads;
Console.WriteLine("Videos in list {0}", uploadsListId);
var nextPageToken = "";
while (nextPageToken != null)
{
var playlistItemsListRequest = youtubeService.PlaylistItems.List("snippet");
playlistItemsListRequest.PlaylistId = uploadsListId;
playlistItemsListRequest.MaxResults = 50;
playlistItemsListRequest.PageToken = nextPageToken;
// Retrieve the list of videos uploaded to the authenticated user's channel.
var playlistItemsListResponse = await playlistItemsListRequest.ExecuteAsync();
foreach (var playlistItem in playlistItemsListResponse.Items)
{
// Print information about each video.
//Console.WriteLine("{0} ({1})",playlistItem.Snippet.Thumbnails, playlistItem.Snippet.Title, playlistItem.Snippet.ResourceId.VideoId);
playlistItem.Snippet.ResourceId.VideoId = vidDetails.vidId;
playlistItem.Snippet.Title= vidDetails.vidTitle;
//playlistItem.Snippet.Thumbnails.Standard = vidDetails.vidThumb;
}
nextPageToken = playlistItemsListResponse.NextPageToken;
}
}
}
}
ASP Class for website view:
public partial class ProfilePage : System.Web.UI.Page
{
protected async void Page_Load(object sender, EventArgs e) {
Video_details vidDetails = new Video_details();
uploaded_videos uploadedVids = new uploaded_videos();
await new uploaded_videos().Run(vidDetails);
vidDetails.vidId = lblVideo3.Text;
vidDetails.vidTitle = lblVideo2.Text;
//vidDetails.vidThumb = imgVid1....
}
}
Any help would be great!

Related

Microsoft Graph API authentication error(Error Description: /me request is only valid with delegated authentication flow)

We have a console application that uses Aspose email dll for sending mails and various other functionalities.
Since it uses basic authentication that is getting deprecated soon by microsoft so we are planning to have authentication using Microsoft Graph API.
So I have done below steps
1)Registered the app in Microsoft Azure active directory and gave permissions under Microsoft Graph. PFA(AzureAPP_permissions.png)
2)I added code for generating token using graph API and then tried fetching email,sending email using Aspose dll but every time it throws below error.
**Aspose.Email.AsposeBadServerResponceException: 'Server error Status: BadRequest
Description: /me request is only valid with delegated authentication flow.
Details:
POST: https://graph.microsoft.com/v1.0/me/mailFolders/inbox/messages
---------------------------------------**
Please help what is going wrong here
PFB the code part
Graph_code
using System;
using System.Collections.Generic;
using System.Configuration;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;
using Aspose.Email.Clients;
using Aspose.Email.Clients.Graph;
using Aspose.Email.Mapi;
using EASendMail;
namespace Email
{
internal class Graph_API
{
private static string _clientId = ConfigurationManager.AppSettings["ClientId"];
private static string _tenantId = ConfigurationManager.AppSettings["TenantId"];
private static string _secretValue = ConfigurationManager.AppSettings["SecretValue"];
static string _postString(string uri, string requestData)
{
HttpWebRequest httpRequest = WebRequest.Create(uri) as HttpWebRequest;
httpRequest.Method = "POST";
httpRequest.ContentType = "application/x-www-form-urlencoded";
using (Stream requestStream = httpRequest.GetRequestStream())
{
byte[] requestBuffer = Encoding.UTF8.GetBytes(requestData);
requestStream.Write(requestBuffer, 0, requestBuffer.Length);
requestStream.Close();
}
try
{
HttpWebResponse httpResponse = httpRequest.GetResponse() as HttpWebResponse;
var responseText = new StreamReader(httpResponse.GetResponseStream()).ReadToEnd();
Console.WriteLine(responseText);
return responseText;
}
catch (WebException ep)
{
if (ep.Status == WebExceptionStatus.ProtocolError)
{
var responseText = new StreamReader(ep.Response.GetResponseStream()).ReadToEnd();
Console.WriteLine(responseText);
}
throw ep;
}
}
public string GenerateToken()
{
string client_id = _clientId;
string client_secret = _secretValue;
string tenant = _tenantId;
string requestData =
string.Format("client_id={0}&client_secret={1}" + "&scope=https://graph.microsoft.com/.default&grant_type=client_credentials",
client_id, client_secret);
string tokenUri = string.Format("https://login.microsoftonline.com/{0}/oauth2/v2.0/token", tenant);
string responseText = _postString(tokenUri, requestData);
OAuthResponseParser parser = new OAuthResponseParser();
parser.Load(responseText);
var vv = parser.AccessToken;
return vv;
}
public void Generatemail()
{
interface_class bb = new interface_class();
IGraphClient client = GraphClient.GetClient(bb, _tenantId);
MapiMessage mm = new MapiMessage();
mm.Subject = "EMAILNET-39318 " + Guid.NewGuid().ToString();
mm.Body = "EMAILNET-39318 REST API v1.0 - Create Message";
mm.SetProperty(KnownPropertyList.DisplayTo, "xxx#outlook.com");
mm.SetProperty(KnownPropertyList.SenderName, "xxx#outlook.com");
mm.SetProperty(KnownPropertyList.SentRepresentingEmailAddress, "xxx#outlook.com");
// Create message in inbox folder
MapiMessage createdMessage = client.CreateMessage(Aspose.Email.Clients.Graph.KnownFolders.Inbox, mm);
}
public void FetchMail()
{
try
{
interface_class bb = new interface_class();
using (IGraphClient client = GraphClient.GetClient(bb, _tenantId))
{
FolderInfoCollection folderInfoCol1 = client.ListFolders();
FolderInfo inbox = null;
foreach (FolderInfo folderInfo in folderInfoCol1)
{
if (folderInfo.DisplayName.Equals("Inbox", StringComparison.InvariantCultureIgnoreCase))
{
inbox = folderInfo;
break;
}
}
MessageInfoCollection messageInfoCol = client.ListMessages(inbox.ItemId);
MessageInfo messageInfo = messageInfoCol[0];
MapiMessage message = client.FetchMessage(messageInfo.ItemId);
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
}
}
Itokenimplementor_class code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Aspose.Email.Clients;
using Aspose.Email.Clients.Graph;
namespace Email
{
internal class interface_class : ITokenProvider
{
Graph_API obj = new Graph_API();
DateTime expirationDate = DateTime.Today.AddDays(1);
public void Dispose()
{
throw new NotImplementedException();
}
public OAuthToken GetAccessToken()
{
string token = obj.GenerateToken();
return new OAuthToken(token, expirationDate);
}
public OAuthToken GetAccessToken(bool ignoreExistingToken)
{
throw new NotImplementedException();
}
}
}
https://graph.microsoft.com/v1.0/me/mailFolders/inbox/messages This endpoint is used to query inbox messages for a user right? Then who is /me here? And this is the issue.
In your code snippet, I noticed that you set the grant_type=client_credentials so you are using client credential flow. It's correct but pls note that you need to give application api permission. Application api permission is for client credential flow. And this api require Mail.ReadBasic.All, Mail.Read, Mail.ReadWrite permissions.
If you can generate access token successfully, you may decode the token the check if the roles claim contained correct permissions.
When you get a correct token, then pls use Get: /users/{id | userPrincipalName}/mailFolders/inbox/messages instead of /me. If you want to query emails for user1#yourtenant.onmicrosoft.com, then the url can be /users/user1#yourtenant.onmicrosoft.com/mailFolders/inbox/messages.
I also notice that you had GraphClient in your code. So you may also try my code below:
using Azure.Identity;
using Microsoft.Graph;
var scopes = new[] { "https://graph.microsoft.com/.default" };
var tenantId = "your_tenant_name.onmicrosoft.com";
var clientId = "azure_ad_app_client_id";
var clientSecret = "client_secret_for_the_azuread_app";
var clientSecretCredential = new ClientSecretCredential(
tenantId, clientId, clientSecret);
var graphClient = new GraphServiceClient(clientSecretCredential, scopes);
var messages = await graphClient.Users["user_id/PrincipalName"].Messages
.Request()
.GetAsync();

Is there any way to use Google Calendar API in C# (WPF) with an async method?

I am a beginer, this is the example from Google on how to officially implement the Google Calendar API using C#. The problem i have is that there is now way to use it with await/async, which means that my WPF application gets frozen when the requests gets made (?). I have looked on google for answers but could not find anything related to that specific issue.
using Google.Apis.Auth.OAuth2;
using Google.Apis.Calendar.v3;
using Google.Apis.Calendar.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 CalendarQuickstart
{
class Program
{
// If modifying these scopes, delete your previously saved credentials
// at ~/.credentials/calendar-dotnet-quickstart.json
static string[] Scopes = { CalendarService.Scope.CalendarReadonly };
static string ApplicationName = "Google Calendar 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 Calendar API service.
var service = new CalendarService(new BaseClientService.Initializer()
{
HttpClientInitializer = credential,
ApplicationName = ApplicationName,
});
// Define parameters of request.
EventsResource.ListRequest request = service.Events.List("primary");
request.TimeMin = DateTime.Now;
request.ShowDeleted = false;
request.SingleEvents = true;
request.MaxResults = 10;
request.OrderBy = EventsResource.ListRequest.OrderByEnum.StartTime;
// List events.
Events events = request.Execute();
Console.WriteLine("Upcoming events:");
if (events.Items != null && events.Items.Count > 0)
{
foreach (var eventItem in events.Items)
{
string when = eventItem.Start.DateTime.ToString();
if (String.IsNullOrEmpty(when))
{
when = eventItem.Start.Date;
}
Console.WriteLine("{0} ({1})", eventItem.Summary, when);
}
}
else
{
Console.WriteLine("No upcoming events found.");
}
Console.Read();
}
}
}
I would need to add await/async but of course it doesn't work event if i make the method async and make it return a task because service.Events.List does not implemet GetAwaiter:
EventsResource.ListRequest request = await service.Events.List("primary"); // this is what i would need
I guess the alternative would be to use the pure REST api but is there really no other way?
Turn Main into async, avoid .Result
static async Task Main(string[] args)
{
//...
credential = await GoogleWebAuthorizationBroker.AuthorizeAsync(
GoogleClientSecrets.Load(stream).Secrets,
Scopes,
"user",
CancellationToken.None,
new FileDataStore(credPath, true));
// ...
}
To turn regular sync method into awaitable operation you can try Task.Run()
EventsResource.ListRequest request = await Task.Run(() => service.Events.List("primary"));

How to get get multi language Title from Youtube Data API V3 and writing it into a csv File so that it is readable

I want to retrieve the Title and URL from given playlists and write it in to a local csv file, so it can be used in Microsoft excel. So far so good and no problems, I made a .Net console project with code from https://developers.google.com/youtube/v3/code_samples/dotnet.
The Titles in my play lists have various languages like german, hebrew, spanish and russian. To write the csv file I use the CsvHelper in c#. The problem is that the special non-english characters show up as unreadable characters in the csv file. Here my code for a german playlist, but it does not display the german special characters properly.
using System;
using System.IO;
using System.Reflection;
using System.Threading;
using System.Threading.Tasks;
using Google.Apis.Auth.OAuth2;
using Google.Apis.Services;
using Google.Apis.Upload;
using Google.Apis.Util.Store;
using Google.Apis.YouTube.v3;
using Google.Apis.YouTube.v3.Data;
using CsvHelper;
using CsvHelper.Configuration;
using System.Globalization;
namespace Youtube
{
internal class MyUploads
{
[STAThread]
static void Main(string[] args)
{
// Displays several properties of the neutral cultures.
Console.WriteLine("YouTube Data API: My Uploads");
Console.WriteLine("============================");
try
{
new MyUploads().Run().Wait();
}
catch (AggregateException ex)
{
foreach (var e in ex.InnerExceptions)
{
Console.WriteLine("Error: " + e.Message);
}
}
Console.WriteLine("Press any key to continue...");
Console.ReadKey();
}
private async Task Run()
{
UserCredential credential;
using (var stream = new FileStream("client_secrets.json", FileMode.Open, FileAccess.Read))
{
credential = await GoogleWebAuthorizationBroker.AuthorizeAsync(
GoogleClientSecrets.Load(stream).Secrets,
// This OAuth 2.0 access scope allows for read-only access to the authenticated
// user's account, but not other types of account access.
new[] { YouTubeService.Scope.YoutubeReadonly },
"user",
CancellationToken.None,
new FileDataStore(this.GetType().ToString())
);
}
var youtubeService = new YouTubeService(new BaseClientService.Initializer()
{
HttpClientInitializer = credential,
ApplicationName = this.GetType().ToString()
});
var channelsListRequest = youtubeService.Channels.List("contentDetails");
channelsListRequest.Mine = true;
// Retrieve the contentDetails part of the channel resource for the authenticated user's channel.
var channelsListResponse = await channelsListRequest.ExecuteAsync();
foreach (var channel in channelsListResponse.Items)
{
// From the API response, extract the playlist ID that identifies the list
// of videos uploaded to the authenticated user's channel.
var uploadsListId = "PLcHIqbEfi5uMC-GtxiSo0kFMF3bh6BQTo"; //eng "PLcHIqbEfi5uMsr-Lx0KT8mjJ-cnNYTzbW";
//channel.ContentDetails.RelatedPlaylists.Uploads;
Console.WriteLine("Videos in list {0}", uploadsListId);
System.Globalization.CultureInfo cultureInfo = new System.Globalization.CultureInfo("de-DE"); //en - GB
CsvConfiguration csvConfiguration = new CsvConfiguration(cultureInfo);
csvConfiguration.Delimiter = ";";
var writer = System.IO.File.CreateText("german_videos.csv");
var csvWriter = new CsvWriter(writer,csvConfiguration);
var nextPageToken = "";
csvWriter.WriteField("Title");
csvWriter.WriteField("URL");
csvWriter.NextRecord();
while (nextPageToken != null)
{
var playlistItemsListRequest = youtubeService.PlaylistItems.List("snippet");
playlistItemsListRequest.PlaylistId = uploadsListId;
playlistItemsListRequest.MaxResults = 50;
playlistItemsListRequest.PageToken = nextPageToken;
// Retrieve the list of videos uploaded to the authenticated user's channel.
var playlistItemsListResponse = await playlistItemsListRequest.ExecuteAsync();
foreach (var playlistItem in playlistItemsListResponse.Items)
{
// Print information about each video.
//Console.WriteLine("{0} ({1})", playlistItem.Snippet.Title, playlistItem.Snippet.ResourceId.VideoId);
csvWriter.WriteField(playlistItem.Snippet.Title);
csvWriter.WriteField("https://www.youtube.com/watch?v=" + playlistItem.Snippet.ResourceId.VideoId.ToString());
csvWriter.NextRecord();
}
nextPageToken = playlistItemsListResponse.NextPageToken;
}
csvWriter.Dispose();
writer.Dispose();
}
}
}
}
I solved the problem by writing to a SQL Express Database, defining the columns nvarchar. This solved the language problem.
using System;
using System.IO;
using System.Reflection;
using System.Threading;
using System.Threading.Tasks;
using Google.Apis.Auth.OAuth2;
using Google.Apis.Services;
using Google.Apis.Upload;
using Google.Apis.Util.Store;
using Google.Apis.YouTube.v3;
using Google.Apis.YouTube.v3.Data;
using CsvHelper;
using CsvHelper.Configuration;
using System.Globalization;
using System.Data.SqlClient;
using System.Configuration;
namespace Youtube
{
internal class MyUploads
{
[STAThread]
static void Main(string[] args)
{
// Displays several properties of the neutral cultures.
Console.WriteLine("YouTube Data API: My Uploads");
Console.WriteLine("============================");
try
{
//new MyUploads().Run().Wait();
new MyUploads().Run2("PLcHIqbEfi5uMC-GtxiSo0kFMF3bh6BQTo","german").Wait();
new MyUploads().Run2("PLcHIqbEfi5uMsr-Lx0KT8mjJ-cnNYTzbW", "english").Wait();
new MyUploads().Run2("PLcHIqbEfi5uMQfD84IXn-k1Jxv-LN8C6U", "spanish").Wait();
new MyUploads().Run2("PLcHIqbEfi5uMH2XkYIMeX490fAWir6S2b", "russian").Wait();
new MyUploads().Run2("PLcHIqbEfi5uOkN9p6wj941zDG1o4maX6Z", "hebrew").Wait();
}
catch (AggregateException ex)
{
foreach (var e in ex.InnerExceptions)
{
Console.WriteLine("Error: " + e.Message);
}
}
Console.WriteLine("Press any key to continue...");
Console.ReadKey();
}
private async Task Run2(string uploadsListId, string language)
{
UserCredential credential;
using (var stream = new FileStream("client_secrets.json", FileMode.Open, FileAccess.Read))
{
credential = await GoogleWebAuthorizationBroker.AuthorizeAsync(
GoogleClientSecrets.Load(stream).Secrets,
// This OAuth 2.0 access scope allows for read-only access to the authenticated
// user's account, but not other types of account access.
new[] { YouTubeService.Scope.YoutubeReadonly },
"user",
CancellationToken.None,
new FileDataStore(this.GetType().ToString())
);
}
var youtubeService = new YouTubeService(new BaseClientService.Initializer()
{
HttpClientInitializer = credential,
ApplicationName = this.GetType().ToString()
});
Console.WriteLine("Get Videos in list {0}", uploadsListId);
string constr = ConfigurationManager.ConnectionStrings["DefaultConnectionString"].ConnectionString;
SqlConnection con = new SqlConnection(constr);
con.Open();
var nextPageToken = "";
while (nextPageToken != null)
{
var playlistItemsListRequest = youtubeService.PlaylistItems.List("snippet");
playlistItemsListRequest.PlaylistId = uploadsListId;
playlistItemsListRequest.MaxResults = 50;
playlistItemsListRequest.PageToken = nextPageToken;
// Retrieve the list of videos uploaded to the authenticated user's channel.
var playlistItemsListResponse = await playlistItemsListRequest.ExecuteAsync();
foreach (var playlistItem in playlistItemsListResponse.Items)
{
// Print information about each video.
//Console.WriteLine("{0} ({1})", playlistItem.Snippet.Title, playlistItem.Snippet.ResourceId.VideoId);
SqlCommand command = new SqlCommand("INSERT INTO Videos VALUES(#playlistId,#VideoId, #Title, #Language, #position)", con);
command.Parameters.Add(new SqlParameter("playlistId", playlistItem.Snippet.PlaylistId));
command.Parameters.Add(new SqlParameter("VideoId", playlistItem.Snippet.ResourceId.VideoId));
command.Parameters.Add(new SqlParameter("Title", playlistItem.Snippet.Title));
command.Parameters.Add(new SqlParameter("Language", language));
command.Parameters.Add(new SqlParameter("position", playlistItem.Snippet.Position));
command.ExecuteNonQuery();
command.Dispose();
}
nextPageToken = playlistItemsListResponse.NextPageToken;
}
//clean up
con.Close();
con.Dispose();
}
}
}

How to set redirect uri of youtube data api

I followed the documentation and done everything mentioned there.
But when I run I get the code error: redirect_uri_mismatch.
It is not picking the redirected uri which is located inside client_secret.json.
I have not changed a single line from the sample code they have provided.
Instead of this solution, I have tried with simple https oauth process that works fine but with client library it is not working.
Code:
using System.IO;
using System.Reflection;
using System.Threading;
using System.Threading.Tasks;
using Google.Apis.Auth.OAuth2;
using Google.Apis.Services;
using Google.Apis.Upload;
using Google.Apis.Util.Store;
using Google.Apis.YouTube.v3;
using Google.Apis.YouTube.v3.Data;
namespace youtubeapiweb.Models
{
/// <summary>
/// YouTube Data API v3 sample: retrieve my uploads.
/// Relies on the Google APIs Client Library for .NET, v1.7.0 or higher.
/// See https://developers.google.com/api-client-library/dotnet/get_started
/// </summary>
internal class MyUploads
{
[STAThread]
public static void Main(string[] args)
{
Console.WriteLine("YouTube Data API: My Uploads");
Console.WriteLine("============================");
try
{
new MyUploads().Run().Wait();
}
catch (AggregateException ex)
{
foreach (var e in ex.InnerExceptions)
{
Console.WriteLine("Error: " + e.Message);
}
}
Console.WriteLine("Press any key to continue...");
Console.ReadKey();
}
private async Task Run()
{
UserCredential credential;
using (var stream = new FileStream(#"c:\users\noman nawaz\documents\visual studio 2015\Projects\youtubeapiweb\youtubeapiweb\Models\client_secret.json", FileMode.Open, FileAccess.Read))
{
credential = await GoogleWebAuthorizationBroker.AuthorizeAsync(
GoogleClientSecrets.Load(stream).Secrets,
// This OAuth 2.0 access scope allows for read-only access to the authenticated
// user's account, but not other types of account access.
new[] { YouTubeService.Scope.YoutubeReadonly },
"user",
CancellationToken.None,
new FileDataStore(this.GetType().ToString())
);
}
var youtubeService = new YouTubeService(new BaseClientService.Initializer()
{
HttpClientInitializer = credential,
ApplicationName = this.GetType().ToString()
});
var channelsListRequest = youtubeService.Channels.List("contentDetails");
channelsListRequest.Mine = true;
// Retrieve the contentDetails part of the channel resource for the authenticated user's channel.
var channelsListResponse = await channelsListRequest.ExecuteAsync();
foreach (var channel in channelsListResponse.Items)
{
// From the API response, extract the playlist ID that identifies the list
// of videos uploaded to the authenticated user's channel.
var uploadsListId = channel.ContentDetails.RelatedPlaylists.Uploads;
Console.WriteLine("Videos in list {0}", uploadsListId);
var nextPageToken = "";
while (nextPageToken != null)
{
var playlistItemsListRequest = youtubeService.PlaylistItems.List("snippet");
playlistItemsListRequest.PlaylistId = uploadsListId;
playlistItemsListRequest.MaxResults = 50;
playlistItemsListRequest.PageToken = nextPageToken;
// Retrieve the list of videos uploaded to the authenticated user's channel.
var playlistItemsListResponse = await playlistItemsListRequest.ExecuteAsync();
foreach (var playlistItem in playlistItemsListResponse.Items)
{
// Print information about each video.
Console.WriteLine("{0} ({1})", playlistItem.Snippet.Title, playlistItem.Snippet.ResourceId.VideoId);
}
nextPageToken = playlistItemsListResponse.NextPageToken;
}
}
}
}
}
The expected result would be the google auth screen where user has complete its authorization and the response sends back to redirected uri.

How to get all users from organization(orgUnit) using G Suite Admin SDK on C#?

How to get all users from organization(orgUnit) using G Suite Admin SDK on C#?
My code:
var request = _service.Users.List();
request.Customer = Customer;
request.Query = $"orgUnitPath={orgUnitPath}"; //orgUnitPath = "/01 Institute"
var result = request.Execute(); //get INVALID_OU_ID error
Did you try putting single quotes around your organisational unit path?
Something like that:
var request = _service.Users.List();
request.Customer = Customer;
request.Query = $"orgUnitPath='{orgUnitPath}'"; //orgUnitPath = '/01 Institute'
var result = request.Execute(); //get INVALID_OU_ID error
This is something that is not documented by Google but it should work.
You can try this code provided in the documentation.
using Google.Apis.Auth.OAuth2;
using Google.Apis.Admin.Directory.directory_v1;
using Google.Apis.Admin.Directory.directory_v1.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 DirectoryQuickstart
{
class Program
{
// If modifying these scopes, delete your previously saved credentials
// at ~/.credentials/admin-directory_v1-dotnet-quickstart.json
static string[] Scopes = { DirectoryService.Scope.AdminDirectoryUserReadonly };
static string ApplicationName = "Directory 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/admin-directory_v1-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 Directory API service.
var service = new DirectoryService(new BaseClientService.Initializer()
{
HttpClientInitializer = credential,
ApplicationName = ApplicationName,
});
// Define parameters of request.
UsersResource.ListRequest request = service.Users.List();
request.Customer = "my_customer";
request.MaxResults = 10;
request.OrderBy = UsersResource.ListRequest.OrderByEnum.Email;
// List users.
IList<User> users = request.Execute().UsersValue;
Console.WriteLine("Users:");
if (users != null && users.Count > 0)
{
foreach (var userItem in users)
{
Console.WriteLine("{0} ({1})", userItem.PrimaryEmail,
userItem.Name.FullName);
}
}
else
{
Console.WriteLine("No users found.");
}
Console.Read();
}
}
}
For further reference, you can refer to the documentation.
Additional information can be found as well in this SO post.

Categories