对数据传输存储桶的访问权限通过 Google Ad Manager 中的用户角色进行管理。获得必要的用户角色权限后,您就可以使用自己选择的方法访问数据传输文件。
跳转到本文的某个部分:
关于此权限的用户角色
若要访问存储桶,您需担任一个已启用“查看数据传输存储桶”权限的角色。
若要更改用户角色,您需担任广告资源网的管理员,或者拥有“在‘管理’标签页中修改用户、角色和小组”权限。请注意,一个用户一次只能与 1 个角色关联。
如需了解详情,请参阅管理用户角色成员资格。
查看角色名下的此权限
您可以查看用户现任的角色,并酌情添加或移除此权限。
- 登录 Google Ad Manager。
- 依次点击管理和访问与授权。
- 再点击角色和角色名称。
- 在“报告”下,找到“查看数据传输存储桶”权限。
- (可选)如需为角色启用此权限,请选中相应复选框。
访问存储桶的方法
Google Cloud Storage 是一款独立的 Google 产品,供 Ad Manager 用作数据传输报表和批量上传的受众群体 Cookie ID 的数据存储区。
您可通过 3 种方法访问 Ad Manager 云存储桶。下文按照从易到难的顺序列出了这些方法:
- 通过网页:访问
https://console.developers.google.com/storage/gdfp-[Ad Manager 广告联盟代码]
。 - gsutil 是一个基于 Python 的命令行工具,可提供与 Unix 类似的命令,用于与相应的存储桶互动。存储桶身份验证的抽象化和处理都是自动进行的。
- Google Cloud Storage API 是一种用于操控存储桶的全功能 API,可通过 JSON 或 XML RESTful 网络界面使用。API 客户端库可用于许多常用的编程环境,包括 Java、JavaScript、Python 和 Objective-C。如果您需要以编程方式操控存储桶,从而与 Google App Engine 应用或 Java Web 应用进行集成,则这种方法最有效。
本文提供了有关 Google Cloud Storage API 的详情。由于通过网络和 gsutil 进行访问的可行性更强,因此我们首推这两种方法。Google Cloud Storage 开发者网站中充分介绍了这两种方法。
使用 Google Cloud Storage API
如果您已确定 API 访问权限最符合您的需求,我们建议您配置一个 Google Cloud Storage 服务账号。
配置 Google Cloud Storage 服务账号
通过 API 访问存储桶时,最好配置一个服务账号,而不是在用户环境中运行。服务账号会使用私钥(而不是动态生成的 OAuth 令牌)进行身份验证,这便简化了应用开发工作。如需配置服务账号,请执行以下操作:
-
创建一个新项目(或选择一个现有项目)作为应用的父级项目,然后点击进入该项目。
-
(可选)如果您打算将文件从 Ad Manager 存储桶复制到您自己的 Google Cloud Storage 账号,请点击结算和设置,以便向您的项目添加结算来源。
-
新建一个客户端 ID:
-
依次点击 API 和服务以及凭据。
-
点击新建客户端 ID。
-
选择服务账号作为应用类型,然后点击创建客户端 ID。
-
系统生成的电子邮件地址会采用如下格式:
[unique-id]@developer.gserviceagccount.com
。将服务账号用户添加到您的 Ad Manager 广告资源网,并确保其担任的角色具有“查看数据传输存储桶”权限。 -
点击生成新的 P12 密钥。该文件会自动保存到您的计算机中。您可在自己开发的应用中使用此密钥来访问 API,如下文中的代码示例所示。
-
- 拥有“查看数据传输存储桶”权限的用户将能够访问您的 Ad Manager 存储桶。
Google 提供了 Google Cloud Storage 的代码示例和库。下面的 Java 示例用于读取 Ad Manager 云端存储桶中的某个文件。该示例显示了您在设置服务账号时配置的组件可能会对代码产生哪些影响:
-
项目名称:Google Cloud Storage 项目的名称。
-
服务账号电子邮件地址:您生成的电子邮件地址。
-
.p12 密钥文件:您下载的文件。
-
存储桶名称:当您启用使用 Ad Manager 云端存储桶的功能时,Google 会向您提供此名称。
import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; import java.security.GeneralSecurityException; import java.util.Collections; import com.google.api.client.googleapis.auth.oauth2.GoogleCredential; import com.google.api.client.googleapis.javanet.GoogleNetHttpTransport; import com.google.api.client.http.HttpTransport; import com.google.api.client.json.jackson2.JacksonFactory; import com.google.api.services.storage.Storage; import com.google.api.services.storage.model.StorageObject; public class GcsApiTest { /** * 名下创建了服务账号的项目的名称。 * * 此信息显示在 Google Developers Console 下。 */ private static final String PROJECT_NAME = "project name"; /** * 服务账号的开发者电子邮件地址。 * * 此电子邮件在您在 Google Developers Console 中 * 创建服务账号客户端 ID 后生成,您可以从“凭据” * 页面检索此电子邮件。 */ private static final String SERVICE_ACCOUNT_EMAIL = "service account email address"; /** * 用于存储操作的存储桶。 * * 您的客户经理向您提供了此存储桶的名称。 * 它的名称类似于“gdfp-12345678”或 *“gdfp_cookieupload_12345678”,这取决于您使用的 Ad Manager 插件。 */ private static final String BUCKET_NAME = "bucket name"; /** * Google Cloud Storage OAuth 2.0 读/写范围。这应该 * 对应于您的“查看数据传输存储桶”权限所蕴含的访问权限, * 而且您无法请求获取 * 未通过此权限授予的访问权限。 */ private static final String STORAGE_SCOPE = "https://googleapis.com/auth/devstorage.read_write"; /** * 提供该存储桶访问权限的 key.p12 文件的路径。 * * 此文件在您创建服务客户端 ID 时生成。* 如果您没有此文件,则需要从Google Developers Console * 生成新的客户端 p12 密钥。 */ private static final String KEY_P12 = "path to .p12 key file"; /** HTTP 传输。*/ private HttpTransport httpTransport; private Storage storage; // constructor, sets up credentials and storage objects public GcsApiTest() { File p12File = new File(KEY_P12); try { httpTransport = GoogleNetHttpTransport.newTrustedTransport(); GoogleCredential credential = new GoogleCredential.Builder() .setTransport(httpTransport) .setJsonFactory(JacksonFactory.getDefaultInstance()) .setServiceAccountId(SERVICE_ACCOUNT_EMAIL) .setServiceAccountScopes( Collections.singleton(STORAGE_SCOPE)) .setServiceAccountPrivateKeyFromP12File(p12File).build(); storage = new Storage.Builder(httpTransport, JacksonFactory.getDefaultInstance(), credential) .setApplicationName(PROJECT_NAME).build(); } catch (GeneralSecurityException | IOException e1) { e1.printStackTrace(); System.exit(1); } } /** * 用于返回存储桶中第一个文件的名称的方法。 * * @返回该文件的名称,如果存储桶为空,则返回 null * @引发 IOException */ public String GetFirstFile() throws IOException { Storage.Objects.List listObjects = storage.objects().list(BUCKET_NAME); listObjects.setMaxResults(5L); com.google.api.services.storage.model.Objects objects = listObjects .execute(); // empty bucket? if (null == objects.getItems() || objects.getItems().isEmpty()) { System.out.println("Bucket \"" + BUCKET_NAME + "\" empty or invalid."); return null; } StorageObject object = objects.getItems().get(0); System.out.println("First object in bucket: \"" + object.getName() + "\"."); return object.getName(); } /** * 用于从存储桶下载指定文件的方法 * * @参数文件名 * 应下载的文件的名称。 * @引发 IOException */ public void DownloadFile(String filename) throws IOException { Storage.Objects.Get getObject = storage.objects().get(BUCKET_NAME, filename); OutputStream os = new FileOutputStream(filename, true); getObject.getMediaHttpDownloader().setDirectDownloadEnabled(true); getObject.executeMediaAndDownloadTo(os); System.out.println("File \"" + filename + "\" downloaded."); } /** * 用于执行不同测试的主方法。 * * @形参 实参 */ public static void main(String[] args) { GcsApiTest gcsApiTest = new GcsApiTest(); try { String filename = gcsApiTest.GetFirstFile(); gcsApiTest.DownloadFile(filename); } catch (IOException e) { System.out.println(e.getMessage()); } } }
限制和并发连接数
尽管没有预定义的并发连接数限制,但为了避免滥用行为,Google 对数据传输提取请求数设定了限制。