How can i upload a media file to my google drive using google api? - google-api

Hey im trying to upload certain media files to my google drive using google api services can someone please tell me how can i do it, in my previous question i have given the code for getservice and clientservice you could refer to that thankyou

Uploading a file to Google drive is reasonably strait forward.
authorize the user.
create the file metadata
upload the file data itself
I have serval tutorials on this topic and a YouTube video This should get you started.
How to upload a file to Google Drive with C# .net
using Google.Apis.Auth.OAuth2;
using Google.Apis.Drive.v3;
using Google.Apis.Services;
using Google.Apis.Upload;
Console.WriteLine("Hello, World!");
// Installed file credentials from google developer console.
const string credentialsJson = #"C:\Development\FreeLance\GoogleSamples\Credentials\credentials.json";
// used to store authorization credentials.
var userName = "user";
// scope of authorization needed from the user
var scopes = new[] { DriveService.Scope.Drive };
// file to upload
var filePath = #"C:\Development\FreeLance\GoogleSamples\Data\image.png";
var fileName = Path.GetFileName(filePath);
var folderToUploadTo = "1hwRZWAi-OznYGL51Yx9BJmDp5Ayips16";
var credential = GoogleWebAuthorizationBroker.AuthorizeAsync(GoogleClientSecrets.FromFile(credentialsJson).Secrets,
scopes,
userName,
CancellationToken.None).Result;
// Create the Drive service.
var service = new DriveService(new BaseClientService.Initializer()
{
HttpClientInitializer = credential,
ApplicationName = "Daimto Drive upload Quickstart"
});
// Upload file photo.jpg on drive.
var fileMetadata = new Google.Apis.Drive.v3.Data.File()
{
Name = fileName,
Parents = new List<string>() { folderToUploadTo }
};
var fsSource = File.OpenRead(filePath);
// Create a new file, with metadatafileName and stream.
var request = service.Files.Create(fileMetadata, fsSource, "image/jpeg");
request.Fields = "id";
var results = await request.UploadAsync(CancellationToken.None);
if (results.Status == UploadStatus.Failed)
{
Console.WriteLine($"Error uploading file: {results.Exception.Message}");
}
// the file id of the new file we created
var fileId = request.ResponseBody?.Id;
Console.WriteLine($"fileId {fileId}");
Console.ReadLine();

Related

Google My Business API: issue obtaining Reviews

What's been done so far:
The Prerequisites and Basic Setup steps have been followed, and our
account has been granted access to "Google My Business API". (The
dashboard says "Activation status: Enabled")
In the APIs section of
google, a Service Account has been created under the Google Project
with the role of Editor.
In the My Business section of google i can
see our 6 published/verified Locations.
When our website uses the Service Account to interrogate the "List all reviews" api method, the exception back is "Google.GoogleApiException: 'Parameter validation failed for "parent"'"
A bit more about our code: Its asp.net and using a "Google.Apis.MyBusiness.v4" nuget package generated from https://github.com/googleapis/google-api-dotnet-client/issues/1352#issuecomment-475167066. I have downloaded the JWT file from the google dashboard, and the credential and business service objects are constructed as follows:
var scopes = new List<string>()
{
"https://www.googleapis.com/auth/plus.business.manage",
};
var stream = new FileStream("key.json", FileMode.Open, FileAccess.Read);
var credential = GoogleCredential.FromStream(stream);
credential = credential.CreateScoped(scopes);
var initializer = new BaseClientService.Initializer()
{
HttpClientInitializer = credential,
ApplicationName = "Google Reviews",
};
var service = new MyBusinessService(initializer);
And the Reviews api call where the exception happens
var reviewsListRequest = service.Accounts.Locations.Reviews.List("our location name here");
var listReviewsResponse = reviewsListRequest.Execute();
So the question is what isn't set up correctly and causing that exception?
Example:
var reviewsListRequest = service.Accounts.Locations.Get("accounts/accountnumber")
^^ WILL WORK
var reviewsListRequest = service.Accounts.Locations.Get("accountnumber");
^^ WILL NOT WORK

How to let user click to open the CSV file in browser C# BotFramework SDK3

As the title, I want to let user click to open a file in browser which is created by Bot. I'm using webChat.
The code is what I have tried.
In botframework-emulator, if I click the link, the CSV file will open in the browser.
But in the webChat, it will request user to download, not open in the browser.
var aaa = await GetCSVAttachmentAsync(replymes.ServiceUrl, replymes.Conversation.Id);
foreach(var aa in aaa)
replymes.Attachments.Add(aa);
await context.PostAsync(replymes);
private async Task<IList<Attachment>> GetCSVAttachmentAsync(string serviceUrl, string conversationId)
{
string str = "this is a text CSV";
byte[] array = Encoding.GetEncoding("shift_jis").GetBytes(str);
using (var connector = new ConnectorClient(new Uri(serviceUrl)))
{
var attachments = new Attachments(connector);
var response = await attachments.Client.Conversations.UploadAttachmentAsync(
conversationId,
new AttachmentData
{
Name = "userinfo.csv",
OriginalBase64 = array,
Type = "text/csv"
});
message.Add(new Attachment
{
Name = "userinfo.html",
ContentType = "text/html",
ContentUrl = response.Id
});
return message;
}
}
To solve this problem, I also tried storageV2. But it seems the URI can't be accessed directly.
I still couldn't figure it out without creating a real file.
But instead of using storage V2, I can solve the problem. The thought is as below.
Let the bot create a file.
Upload it to Storage V2 using static website
Send the static website to user.

Download embedded images from google document

I'm trying to download embedded images in a google document using their Drive API and WebClient. A few of the images works just fine, and that is pure images. The others responds with a redirect to the login page instead of the file, so i suppose it has something to do with the credentials (I'm not setting any credetials to my WebClient right now). The images that fail looks like they are called drawings instead of images. Can that be the issue here?
The links that breaks looks like this:
https://docs.google.com/a/irissystem.se/drawings/image?id=HERE_IS_AN_UNIQUE_ID&rev=1&h=81&w=28&ac=1
Is there a way to download images like this using the HttpClient of DriveService-class or a way to apply my credentials from my DriveService to my WebClient instance?
The code below is used to parse the document and download the images.
foreach (HtmlNode img in doc.DocumentNode.SelectNodes("//img")) {
HtmlAttribute src = img.Attributes["src"];
using (WebClient webClient = new WebClient()) {
byte[] data = webClient.DownloadData(src.Value);
using (MemoryStream imagestream = new MemoryStream(data)) {
byte[] imagebinary = imagestream.ToArray();
Images.Add(src.Value, imagebinary);
}
}
}
UPDATE
Thanks to the comment below, i started thinking about the HttpClient and download stream and it turned out to be a good solution. The code below uses my Google DataService (authenticated and done) to download the embedded file as a stream. This works for both drawings and images, so it is a all round solution.
public byte[] GetFileByUrl(string Url, string ExportType = "text/plain") {
var stream = Service.HttpClient.GetStreamAsync(Url);
var result = stream.Result;
using (System.IO.MemoryStream ms = new System.IO.MemoryStream()) {
result.CopyTo(ms);
return ms.ToArray();
}
}
The code for auth looks like this
ServiceAccountCredential credential = new ServiceAccountCredential(
new ServiceAccountCredential.Initializer(SERVICE_ACCOUNT_EMAIL)
{
User = "xxx#xxx.com",
Scopes = new[] { DriveService.Scope.Drive }
}.FromCertificate(certificate));
Service = new DriveService(new BaseClientService.Initializer()
{
HttpClientInitializer = credential,
ApplicationName = "xxx",
});

Google AUTH API Application Type, how important is it?

I've been doing a lot tinkering around with the authentication stuff using the .NET libraries provided by Google.
We have both a desktop and web-app side, and what we want to achieve is to authenticate ONCE, either on the desktop or the web side, and store the refresh token, and reuse it both on the web side and the desktop side.
So the situation is like so, on the desktop side, when there's no saved existing AccessToken's and RefreshToken's, we will ask the user to authenticate via this code:
using (var stream = new FileStream("client_secrets_desktop.json", FileMode.Open, FileAccess.Read))
{
credential = await GoogleWebAuthorizationBroker.AuthorizeAsync(GoogleClientSecrets.Load(stream).Secrets,
new[] { GmailService.Scope.GmailReadonly, GmailService.Scope.GmailCompose },
"someemail#gmail.com", CancellationToken.None);
}
In this case the Client ID and Secret is of an Application type Installed Application.
On the web-application side, if there's also no refresh token yet then I'm using DotNetOpenAuth to trigger the authentication, here's the code snippet:
const string clientID = "someclientid";
const string clientSecret = "somesecret";
const string redirectUri = "http://localhost/Home/oauth2callback";
AuthorizationServerDescription server = new AuthorizationServerDescription
{
AuthorizationEndpoint = new Uri("https://accounts.google.com/o/oauth2/auth"),
TokenEndpoint = new Uri("https://accounts.google.com/o/oauth2/token"),
ProtocolVersion = ProtocolVersion.V20
};
public ActionResult AuthenticateMe()
{
List<string> scope = new List<string>
{
GmailService.Scope.GmailCompose,
GmailService.Scope.GmailReadonly,
GmailService.Scope.GmailModify
};
WebServerClient consumer = new WebServerClient(server, clientID, clientSecret);
// Here redirect to authorization site occurs
OutgoingWebResponse response = consumer.PrepareRequestUserAuthorization(
scope, new Uri(redirectUri));
response.Headers["Location"] += "&access_type=offline&approval_prompt=force";
return response.AsActionResult();
}
public void oauth2callback()
{
WebServerClient consumer = new WebServerClient(server, clientID, clientSecret);
consumer.ClientCredentialApplicator =
ClientCredentialApplicator.PostParameter(clientSecret);
IAuthorizationState grantedAccess = consumer.ProcessUserAuthorization(null);
string accessToken = grantedAccess.AccessToken;
}
Here is where I want to confirm my suspicions.
When there is a RefreshToken that exists, we use the following code snippet to call the Gmail API's
UserCredential uc = new UserCredential(flow, "someemail#gmail.com", new TokenResponse()
{
AccessToken = "lastaccesstoken",
TokenType = "Bearer",
RefreshToken = "supersecretrefreshtoken"
});
var refreshState = await uc.RefreshTokenAsync(CancellationToken.None);
var svc = new GmailService(new BaseClientService.Initializer()
{
HttpClientInitializer = uc,
ApplicationName = "Gmail Test",
});
Here's the thing I noticed is that, for me to be able to use the refresh token to refresh from either the desktop or the web side, the refresh token needs to be generated through the same client ID/secret combination. I've tested it and it seems like it's fine if we use Installed application as the application type for the Client ID for both the desktop and the web, but my question I guess is, these application type's for the client IDs, do they matter so much?
Am I doing anything wrong to do it this way?
Thanks in advance

Reusing Google API credentials in GData API

I am trying to make a web application is ASP.NET MVC 5 with which I can authenticate a user with a Google Account and then read data from his/her spreadsheets stored in Google Drive/Google Sheets.
I am using Google API to authenticate a user. After a user is successfully authenticated, I get the credentials back from Google in an object which is of type Google.Apis.Auth.OAuth2.Web AuthResult.UserCredential
I can then successfully create a service to list files from Drive using code similar to
var driveService = new DriveService(new BaseClientService.Initializer
{
HttpClientInitializer = result.Credential,
ApplicationName = "ASP.NET MVC Sample"
});
Now, I want to use GData API to read content from spreadsheets in Drive. For this to work, I need to have a SpreadsheetsService object and then set it's RequestFactory parameter to an instance of GOAuth2RequestFactory and this in turn needs OAuth2 parameters to be specified in an instance of class OAuth2Parameters.
How can I reuse the credentials obtained using the Google Api in GData API?
I am already doing the thing you want to do,
Code for how I passed the GData tokens
Issue with OAuth2 authentication with google spreadsheet
i.e. I use a single OAuth2 access/refresh token set. Using the same tokens for both gdata calls & drive API calls.
This is the code that finally worked for me
public class AppFlowMetadata : FlowMetadata
{
private static readonly IAuthorizationCodeFlow flow =
new GoogleAuthorizationCodeFlow(new GoogleAuthorizationCodeFlow.Initializer
{
ClientSecrets = new ClientSecrets
{
ClientId = "randomstring.apps.googleusercontent.com",
ClientSecret = "shhhhhh!"
},
Scopes = new[] { DriveService.Scope.Drive, "https://spreadsheets.google.com/feeds", "https://docs.google.com/feeds", "https://www.googleapis.com/auth/userinfo.email", "https://www.googleapis.com/auth/userinfo.profile" },
DataStore = new FileDataStore("Drive.Api.Auth.Store")
});
public override string GetUserId(Controller controller)
{
var user = controller.Session["user"];
if (user == null)
{
user = Guid.NewGuid();
controller.Session["user"] = user;
}
return user.ToString();
}
public override IAuthorizationCodeFlow Flow { get { return flow; } }
}
And then, in the controller, OAuth2 parameters were copied to GData
var result = await new AuthorizationCodeMvcApp(this, new AppFlowMetadata()).
AuthorizeAsync(cancellationToken);
OAuth2Parameters parameters = new OAuth2Parameters();
parameters.ClientId = "somestring.apps.googleusercontent.com";
parameters.ClientSecret = "shhhhhh!";
parameters.Scope = result.Credential.Token.Scope;
parameters.AccessToken = result.Credential.Token.AccessToken;
parameters.RefreshToken = result.Credential.Token.RefreshToken;
GOAuth2RequestFactory requestFactory = new GOAuth2RequestFactory(null, "MySpreadsheetIntegration-v1", parameters);
SpreadsheetsService service = new SpreadsheetsService("MySpreadsheetIntegration-v1");
service.RequestFactory = requestFactory;

Resources