How to get YouTube channel name and URL after authenticating - google-api

Once I have authenticated a user - such as in the code below - how can I find out their channel name and URL of channel?
I'm using the YouTube data api v3 with .NET library:
UserCredential credential;
using (var stream = new FileStream("client_secrets.json", FileMode.Open, FileAccess.Read))
{
credential = await GoogleWebAuthorizationBroker.AuthorizeAsync(
GoogleClientSecrets.Load(stream).Secrets,
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()
});

Finally worked out how to do it. Once you get the token back from the authentication do this:
var channelsListRequest = _youTubeService.Channels.List("id,snippet");
channelsListRequest.Mine = true;
var channelsListResponse = channelsListRequest.Execute();
if ( (null != channelsListResponse) &&
(null != channelsListResponse.Items) &&
(channelsListResponse.Items.Count > 0) )
{
Channel userChannel = channelsListResponse.Items[0];
string youtubeUserID = userChannel.Id;
string ytChannelURL = "https://www.youtube.com/channel/" + userChannel.Id;
string name = userChannel.Snippet.Title;
}
Phew!

Related

How to update data through Api in Xamarin

I do the update command through the API. Everything seems fine. However, the data is not up to date. When I debug there is no error.
public async Task UpdateViewRatingStore(bool value)
{
var url = baseUrl + userget;
HttpClient client = new HttpClient();
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", mytokenlogin);
string jsonStr = await client.GetStringAsync(url);
var res = JsonConvert.DeserializeObject<Customer>(jsonStr);
var checkunredrating = res.RatingStores;
if (checkunredrating != null)
{
foreach (var r in checkunredrating)
{
r.ID = r.ID;
r.StoreID = r.StoreID;
r.RatingStores = r.RatingStores;
r.CommentStore = r.CommentStore;
r.UserRating = r.UserRating;
r.CreateDay = r.CreateDay;
r.Display = r.Display;
r.ViewStorer = value;
var urlput = baseUrlStoreRating + r.ID;
var stringContent = new StringContent(JsonConvert.SerializeObject(res.RatingStores), Encoding.UTF8, "application/json");
await client.PutAsync(urlput, stringContent);
}
}
}
However when I check in the database it is still not updated. I tested it manually on swagger and Posman was fine. Where did I go wrong? Ask for help. Thank you
you are trying to update a single object, but passing the entire collection every time
instead, try this
foreach (var r in checkunredrating)
{
// you only need to update the changed values
r.ViewStorer = value;
var urlput = baseUrlStoreRating + r.ID;
// only send the current object you are updating
var stringContent = new StringContent(JsonConvert.SerializeObject(r), Encoding.UTF8, "application/json");
await client.PutAsync(urlput, stringContent);
}

Using Google.Apis.Core for .NET Core, why can't i see a list of photos in my Google Photos when I specify spaces="photos"?

Sample code goes like this:
static string[] Scopes = { DriveService.Scope.Drive, DriveService.Scope.DrivePhotosReadonly };
static string ApplicationName = "Quickstart";
UserCredential credential;
using (var stream = new FileStream("credentials.json", FileMode.Open, FileAccess.Read))
{
string credPath = "token.json";
credential = GoogleWebAuthorizationBroker.AuthorizeAsync(
GoogleClientSecrets.Load(stream).Secrets,
Scopes,
"user",
CancellationToken.None,
new FileDataStore(credPath, true)).Result;
}
// 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.Spaces = "photos";
listRequest.PageSize = 100;
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();
I enable the Google Drive API through the Google Console and get the credentials.json file. When I run this using listRequest.Spaces = "drive" then I can see all of my drive files, but I cannot see any photos when I make it "photos".
What other sort of undocumented magic needs to be in place here for this to work?
Thanks.
Google Drive and Google Photos have been disconnected, the space "photos" has been deprecated.
However, there is a Google Photos API that allows you to list your photos.

Async and Await didn't work on web api

I am trying to use await on my async method but it didn't work. I input 2 array of parameters when calling the post method, only the last one is inserted
to database(I use Elasticsearch as database so when the _id is the same the document will replaced by the new one). and I found out when insert is not done yet the program is already run to query the database and the result is 0 so it's insert again instead of update.
I already add await on my program but it didn't work out. Can anyone help me with this problem? Thanks
here is my code
// POST api/values
[HttpPost]
public async Task<AvatarModel.AvatarResponse> Post(MultiLanguageTemp[] LangTemp)
{
//process param to multilanguage model
AvatarModel.AvatarResponse Resp = new AvatarModel.AvatarResponse();
try
{
for (int i = 0; i < LangTemp.Length; i++)
{
string Type = LangTemp[i].Type;
if ("ErrorCode".Equals(Type))
{
}
else
{
string GetLabelId = LangTemp[i].LabelId;
string GetTranslation = LangTemp[i].Translation;
MultiLanguage Lang = new MultiLanguage();
Lang.Type = LangTemp[i].Type;
Lang.Site = LangTemp[i].Site;
Lang.Language = LangTemp[i].LangId;
Lang.Source = LangTemp[i].Source;
Lang.TranslationList = new Dictionary<string, string>();
Lang.TranslationList.Clear();
Lang.TranslationList.Add(GetLabelId, GetTranslation);
//search elasticsearch first using id TYPE+SITE+LANG_ID+SOURCE
string ESResponse = await GetMultiLangAsync(Lang);
JObject GetResp = JObject.Parse(ESResponse);
//get elasticsearch Hits count
JToken GetHitsTotal = GetResp.SelectToken("hits.total");
int Hits = int.Parse(GetHitsTotal.ToString());
// if id exist then do update else do insert
if (Hits > 0)
{
string ResponseUpdate = await UpdateMultiLangAsync(GetLabelId, GetTranslation,Lang);
if (!ResponseUpdate.ToString().ToUpper().Contains("ERROR"))
{
Resp.Result = "0000000";
Resp.Message = "Update MultiLanguage Info is Success";
}
else
{
Resp.Result = "9000003";
Resp.Message = "Update MultiLanguage Info into ES failed";
}
}
else
{
//tasks.Add(InsertMultiLangAsync(Lang));
//insert new document into elasticsearch
string InsertESResponse = await InsertMultiLangAsync(Lang);
if (!InsertESResponse.ToUpper().Contains("ERROR"))
{
Resp.Result = "0000000";
Resp.Message = "Insert MultiLanguage Info is Success";
}
else
{
Resp.Result = "9000003";
Resp.Message = "Insert MultiLanguage Info into ES failed";
}
}
}
}
}
catch (Exception E)
{
Resp.Result = "9000005";
Resp.Message = E.Message.ToString();
}
return Resp;
}
public async Task<string> GetMultiLangAsync(MultiLanguage Lang)
{
var Client = new HttpClient();
Client.BaseAddress = new Uri("http://localhost:9200/multilanguage/MultiLangInfo/");
Client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
var Query = "{\"query\": {\"match\": {\"_id\":\"" + Lang.Type + Lang.Site + Lang.Language + Lang.Source + "\"}}}";
var StringContent = new StringContent(Query, Encoding.UTF8, "application/json");
var Response = Client.PostAsync("_search", StringContent).Result.Content.ReadAsStringAsync();
//JObject GetResp = JObject.Parse(Response.Result);
return await Response;
}
public async Task<string> InsertMultiLangAsync(MultiLanguage Lang)
{
var Client = new HttpClient();
Client.BaseAddress = new Uri("http://localhost:9200/multilanguage/");
Client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
var JsonTextMultiLang = JsonConvert.SerializeObject(Lang, Formatting.None, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore });
var StringContent = new StringContent(JsonTextMultiLang, Encoding.UTF8, "application/json");
var ResponseInsert = Client.PostAsync("MultiLangInfo/" + Lang.Type + Lang.Site + Lang.Language + Lang.Source, StringContent).Result.Content.ReadAsStringAsync();
return await ResponseInsert;
}
public async Task<string> UpdateMultiLangAsync(string GetLabelId,string GetTranslation, MultiLanguage Lang)
{
var UpdateES = "{\"doc\":{\"TranslationList\":{\"" + GetLabelId + "\":\"" + GetTranslation + "\"}},\"detect_noop\":true}";
var Client = new HttpClient();
Client.BaseAddress = new Uri("http://localhost:9200/multilanguage/MultiLangInfo/" + Lang.Type + Lang.Site + Lang.Language + Lang.Source + "/");
Client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
var StringContent = new StringContent(UpdateES, Encoding.UTF8, "application/json");
var ResponseUpdate = Client.PostAsync("_update", StringContent).Result.Content.ReadAsStringAsync();
return await ResponseUpdate;
}
Here is my insight.
Based on the details you provided, you have a long-running task that would eventually create/update a record in your database. Now, the problem you encounter is the second http request you send is not waiting for the first one to finish even though you are using async/await pattern. Well, this is not how it works. Regardless of what you do, whether you block the thread or not, there is thread pooling and distinct http calls will have their own thread. So using async/await would not affect that at all. For the most part, you're using async/await correctly. However, what you're trying to achieve is not done by async/await. You might want to try a messaging system to queue all the requests. In that case, you can't put clients on hold, You'd generate a request id and send it to them immediately and process the request asynchronously in time.

here is the code to fetch username and password from the xml file but it does't fetch the the data?

Here is the code to fetch username and password from the xml file but it does't fetch the the data?
private var myXML: XML = new XML();
private function connect(event: Event): void {
var str1: String = username.text.toString();
trace(str1);
var str2: String = password.text.toString();
trace(str2);
var str3: String = myXML.authentication.username;
Alert.show(str3);
var str4: String = myXML.authentication.password;
if (str1 == str3 && str2 == str4) {
Alert.show("sucessfully Connected")
} else {
Alert.show("invalid username password");
}
}
Where you are assigning data for myXML and what is your xml?
var settingFile:File;
var stream:FileStream;
var resultXML:XML;
settingFile = settingFile.resolvePath("setting.xml");
stream = new FileStream;
if(settingFile.exists)
{
stream.open(settingFile,FileMode.READ);
resultXML = XML(stream.readUTFBytes(stream.bytesAvailable));
stream.close();
var xmlDoc:XMLDocument = new XMLDocument(resultXML.toString());
var decoder:SimpleXMLDecoder = new SimpleXMLDecoder(true);
var resultObj:Object = decoder.decodeXML(xmlDoc);
}
from that resultObj u can access the username and password
if you are using FlexApplication then convert the xml file to xmlDocument and decode it. then from the decoded object you can get the username and password.
var xmlDoc:XMLDocument = new XMLDocument(myXML.toString());
var decoder:SimpleXMLDecoder = new SimpleXMLDecoder(true);
var resultObj:Object = decoder.decodeXML(xmlDoc);
you can try like this.
private var myXML: XML = new XML();
private function connect(event: Event): void {
var xmlDoc:XMLDocument = new XMLDocument(myXML.toString());
var decoder:SimpleXMLDecoder = new SimpleXMLDecoder(true);
var resultObj:Object = decoder.decodeXML(xmlDoc);
var str1: String = username.text.toString();
trace(str1);
var str2: String = password.text.toString();
trace(str2);
var str3: String = resultObj.authentication.username;
Alert.show(str3);
var str4: String = resultObj.authentication.password;
if (str1 == str3 && str2 == str4) {
Alert.show("sucessfully Connected")
} else {
Alert.show("invalid username password");
}
}
Why don't you try to load the XML file suing the URL loader and capture the COMPLETE event to fetch the data?

LinqToTwitter generate exception when i try to send privatemessage

i try to send private message to followers of a user who is already authenticated with my_app, here is the code :
var authent = new MvcAuthorizer
{
Credentials = new SessionStateCredentials()
{
ConsumerKey = this.client.ConsumerKey,
ConsumerSecret = this.client.ConsumerSecret,
OAuthToken = identity.Token.Token
}
};
var twitterCtx = new TwitterContext(authent);
list_friend.ToList().ForEach(x => twitterCtx.NewDirectMessage(x.InvitedFriendID, messageWithPlaceHolders.Replace("[FRIEND_NAME]", x.Name)));
list_friend is the list of followers of the user who is authenticated.
Pleaaaase i need your help.
the solution is to use the InMemoryCrendentials rather than SessionStateCredentials and add the token secret to crendential, and after we should add DateTime.Now to the message because twitter don't allow duplicate message, here is the code off the solution it work well :
var authent = new MvcAuthorizer
{
Credentials = new InMemoryCredentials()
{
ConsumerKey = this.client.ConsumerKey,
ConsumerSecret = this.client.ConsumerSecret,
OAuthToken = identity.Token.Token,
AccessToken = identity.Token.Secret
}
};
var twitterCtx = new TwitterContext(authent);
list_friend.ToList().ForEach(x => twitterCtx.NewDirectMessage(x.SocialId, messageWithPlaceHolders.Replace("[FRIEND_NAME]", x.Name) +DateTime.Now.ToString()));
Thanks

Resources