我正在尝试使用 Google Drive API 创建文件副本,然后使用 Docs API 进行查找和替换。除了问题是新创建的文件归我在我的 https://console.cloud.google.com/ 帐户中创建的服务帐户所有,我已经能够使其全部正常工作。这是我所拥有的:
internal class DriveHelper
{
public DriveService Service { get; set; }
const string APPLICATION_NAME = "sound-booth-scheduler";
static readonly string[] Scopes = { DriveService.Scope.Drive };
internal DriveHelper()
{
InitializeService();
}
private void InitializeService()
{
var credential = GetCredentialsFromFile();
Service = new DriveService(new BaseClientService.Initializer()
{
HttpClientInitializer = credential,
ApplicationName = APPLICATION_NAME
});
}
private GoogleCredential GetCredentialsFromFile()
{
GoogleCredential credential;
using var stream = new FileStream("client_secrets.json", FileMode.Open, FileAccess.Read);
credential = GoogleCredential.FromStream(stream).CreateScoped(Scopes);
return credential;
}
}
DriveHelper driveHelper = new DriveHelper();
var templateFileRequest = driveHelper.Service.Files.Get("<file id>");
templateFileRequest.Fields = "owners, parents";
var templateFile = templateFileRequest.Execute();
var copyRequest = driveHelper.Service.Files.Copy(new File(), "<file id>");
copyRequest.Fields = "owners, parents, id";
var copiedFile = copyRequest.Execute();
复制请求执行时没有任何错误,但是
copiedFile
有服务帐户的父级,所以当我在浏览器中查看我的 Google 云端硬盘时看不到它。我尝试使用以下代码设置父级,但会导致错误:
var updateRequest = driveHelper.Service.Files.Update(new File(), copiedFile.Id);
updateRequest.AddParents = templateFile.Parents.First();
updateRequest.RemoveParents = String.Join(",", copiedFile.Parents);
var updatedCopiedFile = updateRequest.Execute();
如何使用 API 复制文件并将我的用户帐户(拥有服务帐户的人)设置为文档的所有者?
我的问题是,即使我没有 G Suite 帐户,我仍在使用服务帐户。我切换到使用 OAuth 身份验证,并且文件副本按预期工作。这是我的代码的主要部分,以防它对其他人有帮助:
var secrets = GoogleClientSecrets.FromFile("client_secret_oath.json");
var userCredentials = GoogleWebAuthorizationBroker.AuthorizeAsync(
secrets.Secrets,
_Scopes,
"user",
CancellationToken.None,
new FileDataStore("token_send.json", true)
)
.Result;
var driveService = new DriveService(new BaseClientService.Initializer()
{
HttpClientInitializer = userCredentials,
ApplicationName = APPLICATION_NAME
});
//copy the file
var copyRequest = driveService.Files.Copy(new DriveData.File(), "<fileid>");
copyRequest.Fields = "id";
var copiedFile = copyRequest.Execute();
//rename the file
copiedFile = driveService.Files.Get(copiedFile.Id).Execute();
string fileId = copiedFile.Id;
copiedFile.Id = null;
copiedFile.Name = copiedFile.Name + "_Test";
var updateRequest = driveService.Files.Update(copiedFile, fileId);
var renamedFile = updateRequest.Execute();
共享和更改文件的所有权
您需要手动与 Gmail 或 Workspace 帐户共享文件。
取决于您使用的 Drive API 版本。你需要使用:
权限:创建
或
权限:插入
这将允许您创建一个选项,将服务帐户拥有的文件直接共享给另一个有权访问 Drive UI 的用户。
还有关于如何使用 Drive V3 的“权限”的指南以及您可以实施的示例代码。
由于组织可能存在共享限制,您需要确保查看有关 Gmail 和 Workspace 帐户之间所有权转移的工作方式的步骤,实施示例代码时的关键是确保
role=owner
和transferOwnsership=true
.
参考
这是 cas4 代码的简短版本。
string[] scopes = { DriveService.Scope.Drive };
UserCredential credential;
using (var stream = new FileStream(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "credentials.json"), FileMode.Open, FileAccess.Read)) {
string credPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "token.json");
credential = GoogleWebAuthorizationBroker.AuthorizeAsync(
GoogleClientSecrets.FromStream(stream).Secrets,
scopes,
"user",
CancellationToken.None,
new FileDataStore(credPath, true)).Result;
}
var driveService = new DriveService(new BaseClientService.Initializer {
HttpClientInitializer = credential,
ApplicationName = "My Application Name",
});
// Copy the file
var copyRequest = driveService.Files.Copy(new File(), templateId);
var copiedFile = await copyRequest.ExecuteAsync();
// Rename the file
string copiedFileId = copiedFile.Id;
copiedFile.Id = null; // Must clear Id as that property is not writable.
copiedFile.Name = "New Name";
var updateRequest = driveService.Files.Update(copiedFile, copiedFileId);
var renamedFile = await updateRequest.ExecuteAsync();