パブリッシャーは主に、読者とその利用資格を管理するためにサーバーサイドの統合を使用します。パブリッシャーは、主に UpdateReaderEntitlements
を使用して、PPID のプロダクト ID 利用資格に関する Google の記録を更新します。
Google Cloud の設定
Google Cloud で定期購読のリンクを構成する作業は、主に 2 つのコンポーネントで構成されます。
- 特定のプロジェクトに対して API を有効にする
- API にアクセスするためのサービス アカウントを作成する
Subscription Linking API を有効にする
サービス アカウントを使用して読者の利用資格を管理するには、Google Cloud プロジェクトで Subscription Linking API を有効にして、OAuth サービス アカウントを適切に構成する必要があります。プロジェクトの Subscription Linking API を有効にするには、メニュー -> [API とサービス] -> [ライブラリ] に移動して Subscription Linking
を検索するか、ページに直接アクセスしてください。
https://console.cloud.google.com/apis/library?project=gcp_project_id
図 1. API ライブラリに移動し、Google Cloud プロジェクトに対して API を有効にする。
サービス アカウントを作成する
サービス アカウントは、アプリケーションから Subscription Linking API へのアクセスを許可するために使用されます。
- プロジェクトのコンソールでサービス アカウントを作成します。
- サービス アカウントの認証情報を作成し、アプリケーションにアクセスできる安全な場所に
credentials.json
ファイルを保存します。 - 作成したサービス アカウントに「サブスクリプション リンク管理者」の IAM ロールを付与します。サービス アカウントの機能をきめ細かく制御するには、次の表から適切なロールを割り当てることができます。
権限 / 役割 | サブスクリプション リンク管理者 | サブスクリプション リンク閲覧者 | サブスクリプション リンク権限の閲覧者 |
---|---|---|---|
読者の利用資格を取得する | |||
読者を獲得 | |||
読者の利用資格を更新する | |||
読者を削除 |
Subscription Linking API でサービス アカウントを使用する
サービス アカウントを使用して、Subscription Linking API の呼び出しを認証します。認証するには、googleapis クライアント ライブラリを使用するか、REST API でリクエストに署名します。クライアント ライブラリは適切な access_token
のリクエストを自動的に処理しますが、REST API では id_token
を取得して access_token
と交換する必要があります。
以下に示すクライアント ライブラリと REST API の例は、どちらも getReader()
エンドポイントを使用します。すべての API メソッドのライブデモについては、定期購入リンクのデモサイト、またはサイトのコードをご覧ください。
Node.js googleapis クライアント ライブラリを使用したリクエストの例
import {readerrevenuesubscriptionlinking_v1, Auth} from 'googleapis'
const subscriptionLinking = readerrevenuesubscriptionlinking_v1.Readerrevenuesubscriptionlinking
class SubscriptionLinking {
constructor() {
this.auth = new Auth.GoogleAuth({
keyFile: process.env.KEY_FILE,
scopes: [
'https://www.googleapis.com/auth/readerrevenue.subscriptionlinking.manage'
],
})
}
init() {
return new subscriptionLinking(
{version: 'v1', auth: this.auth})
}
}
const api = new SubscriptionLinking()
const client = api.init()
async function getReader (ppid) {
const publicationId = process.env.PUBLICATION_ID
return await client.publications.readers.get({
name: `publications/${publicationId}/readers/${ppid}`,
})
}
REST API リクエストへの手動署名
import fetch from 'node-fetch'
import jwt from 'jsonwebtoken'
function getSignedJwt() {
/*
Either store the credentials string in an environmental variable
Or implement logic to fetch it.
*/
const key_file = process.env.CREDENTIALS_STRING
const issueDate = new Date()
const expireMinutes = 60
const offsetInSeconds = issueDate.getTimezoneOffset() * 60000
const expireDate = new Date(issueDate.getTime() + (expireMinutes * 60000))
const iat = Math.floor((issueDate.getTime() + offsetInSeconds) / 1000)
const exp = Math.floor((expireDate.getTime() + offsetInSeconds) / 1000)
const token = {
iss: key_file.client_email,
iat,
exp,
aud: 'https://oauth2.googleapis.com/token',
scope:'https://www.googleapis.com/auth/readerrevenue.subscriptionlinking.manage',
}
return jwt.sign(token, key_file.private_key, {
algorithm: 'RS256',
keyid: key_file.private_key_id,
})
}
async function getAccessToken(signedJwt) {
let body = new URLSearchParams();
body.set('grant_type', 'urn:ietf:params:oauth:grant-type:jwt-bearer')
body.set('assertion', signedJwt)
const request = await fetch('https://oauth2.googleapis.com/token', {
method: 'POST',
headers: {'Content-Type': 'application/x-www-form-urlencoded'},
body
})
const accessResponse = await accessFetch.json()
return accessResponse.access_token
}
async function getReader(ppid) {
const publicationId = process.env.PUBLICATION_ID
const base_url = 'https://readerrevenuesubscriptionlinking.googleapis.com/v1'
const endpoint = `${base_url}/publications/${publicationId}/readers/${ppid}`
const signedJwt = await getSignedJwt()
const accessToken = await getAccessToken(signedJwt)
const reader = await fetch(endpoint, {
method: 'GET',
headers: {
Authorization: `Bearer ${accessToken}`,
},
}).then((response) => {
return response.json()
})
return reader
}