ผู้เผยแพร่โฆษณาใช้การผสานรวมฝั่งเซิร์ฟเวอร์เป็นหลักในการจัดการผู้อ่านและสิทธิ์ของผู้อ่าน โดยทั่วไปแล้ว ผู้เผยแพร่โฆษณาจะใช้ UpdateReaderEntitlements
เพื่ออัปเดตระเบียนสิทธิ์การใช้รหัสผลิตภัณฑ์ของ Google สำหรับ PPID
การตั้งค่า 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 และเปิดใช้ API สําหรับโปรเจ็กต์ Google Cloud
สร้างบัญชีบริการ
ระบบจะใช้บัญชีบริการเพื่ออนุญาตให้แอปพลิเคชันเข้าถึง Subscription Linking API
- สร้างบัญชีบริการภายในคอนโซลของโปรเจ็กต์
- สร้างข้อมูลเข้าสู่ระบบสําหรับบัญชีบริการ และจัดเก็บไฟล์
credentials.json
ไว้ในตําแหน่งปลอดภัยที่แอปพลิเคชันเข้าถึงได้ - มอบบทบาท IAM "ผู้ดูแลการลิงก์การสมัครใช้บริการ" ให้กับบัญชีบริการที่คุณสร้างขึ้น หากต้องการควบคุมความสามารถของบัญชีบริการอย่างละเอียด คุณสามารถมอบหมายบทบาทที่เหมาะสมจากตารางต่อไปนี้
ความสามารถ / บทบาท | ผู้ดูแลการลิงก์การสมัครใช้บริการ | ผู้ดูการลิงก์การสมัครใช้บริการ | ผู้ดูการให้สิทธิ์การลิงก์การสมัครใช้บริการ |
---|---|---|---|
รับการให้สิทธิ์ผู้อ่าน | |||
ดึงดูดผู้อ่าน | |||
อัปเดตการให้สิทธิ์แก่ผู้อ่าน | |||
ลบผู้อ่าน |
ใช้บัญชีบริการกับ Subscription Linking API
หากต้องการตรวจสอบสิทธิ์การเรียก Subscription Linking API ด้วยบัญชีบริการ ให้ใช้ไลบรารีไคลเอ็นต์ googleapis (ซึ่งจัดการคําขอ access_token
โดยอัตโนมัติ) หรือลงชื่อขอกับ REST API โดยตรง หากใช้ REST API ก่อนอื่นคุณต้องได้รับ access_token
(ผ่านไลบรารี Google Auth หรือใช้ JWT ของบัญชีบริการ) แล้วใส่ไว้ในส่วนหัว Authorization
ทั้งตัวอย่างไลบรารีไคลเอ็นต์และ REST API ต่อไปนี้มีโค้ดตัวอย่างสำหรับวิธีเรียก getReader()
,
getReaderEntitlements()
, updateReaderEntitlements()
และ
deleteReader()
ไลบรารีของไคลเอ็นต์
ส่วนนี้จะอธิบายวิธีใช้ไลบรารีไคลเอ็นต์ googleapis ใน Node.js
ตัวอย่างคำขอ
สําหรับช่อง keyFile
ในคอนสตรคเตอร์ Auth.GoogleAuth
ให้ตั้งค่าเส้นทางไปยังคีย์บัญชีบริการ
หากส่งออกคีย์บัญชีบริการไม่ได้เนื่องจากนโยบายขององค์กร คุณจะใช้วิธีการข้อมูลเข้าสู่ระบบเริ่มต้นของบัญชี (ADC) ได้ หากใช้วิธีการ ADC คุณไม่จําเป็นต้องระบุkeyFile
ช่อง เนื่องจาก ADC จะค้นหาข้อมูลเข้าสู่ระบบด้วยตัวเอง
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 subscriptionLinkingApi = new SubscriptionLinking();
const client = subscriptionLinkingApi.init();
/**
* Retrieves details for a specific reader associated with the publication.
* @async
* @param {string} ppid - The Publisher Provided ID (ppid) for the reader.
* @return {Promise<object>} A promise that resolves with the reader's details
* from the API.
*/
async function getReader(ppid) {
const publicationId = process.env.PUBLICATION_ID;
return await client.publications.readers.get({
name: `publications/${publicationId}/readers/${ppid}`,
});
};
/**
* Updates the entitlements for a specific reader.
* @async
* @param {string} ppid - The Publisher Provided ID (ppid) for the reader whose
* entitlements are being updated.
* @return {Promise<object>} A promise that resolves with the result of the
* updated entitlements object.
*/
async function updateReaderEntitlements(ppid) {
const publicationId = process.env.PUBLICATION_ID;
const requestBody = {
/*
Refer to
https://developers.google.com/news/subscribe/subscription-linking/appendix/glossary#entitlements_object
*/
entitlements : [{
product_id: `${publicationId}:basic`,
subscription_token: 'abc1234',
detail: 'This is our basic plan',
expire_time: '2025-10-21T03:05:08.200564Z'
}]
};
return await client.publications.readers.updateEntitlements({
name: `publications/${publicationId}/readers/${ppid}/entitlements`,
requestBody
});
};
/**
* Retrieves the current entitlements for a specific reader.
* @async
* @param {string} ppid - The Publisher Provided ID (ppid) for the reader.
* @return {Promise<object>} A promise that resolves with the reader's entitlements object.
*/
async function getReaderEntitlements(ppid) {
const publicationId = process.env.PUBLICATION_ID;
return await client.publications.readers.getEntitlements({
name: `publications/${publicationId}/readers/${ppid}/entitlements`
});
};
/**
* Deletes a specific Subscription Linkikng reader record associated with the publication.
* @async
* @param {string} ppid - The Publisher Provided ID (ppid) for the reader to be deleted.
* @param {boolean=} forceDelete - If true, delete the user even if their
* entitelements are not empty
* @return {Promise<object>} A promise that resolves upon successful deletion
* with an empty object ({})
*/
async function deleteReader(ppid, forceDelete = false) {
const publicationId = process.env.PUBLICATION_ID;
return await client.publications.readers.delete({
name: `publications/${publicationId}/readers/${ppid}`
force: forceDelete
});
};
REST API
หากต้องการเรียกใช้ปลายทาง REST API คุณสามารถใช้วิธีการใดก็ได้เพื่อรับ accessToken
เพื่อตั้งค่าส่วนหัว Authorization
1. ใช้ไลบรารี GoogleAuth
สำหรับคีย์ credentials
คุณสามารถใช้คีย์บัญชีบริการหรือข้อมูลเข้าสู่ระบบเริ่มต้นของบัญชี (ADC)
หากใช้วิธีการ ADC คุณไม่จําเป็นต้องระบุช่อง credentials
เนื่องจาก ADC จะค้นหาข้อมูลเข้าสู่ระบบด้วยตนเอง
import { GoogleAuth } from 'google-auth-library';
import credentialJson from 'path_to_your_json_file' with { type: 'json' };
const auth = new GoogleAuth({
credentials: credential_json,
scopes: [
'https://www.googleapis.com/auth/readerrevenue.subscriptionlinking.manage'
]
});
async function getAccessToken() {
const accessToken = await auth.getAccessToken();
return accessToken;
}
2. สร้าง access_token
โดยใช้ JWT ของบัญชีบริการ
import fetch from 'node-fetch';
import jwt from 'jsonwebtoken';
function getSignedJwt() {
/*
Either store the service account 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 response = await fetch('https://oauth2.googleapis.com/token', {
method: 'POST',
headers: {'Content-Type': 'application/x-www-form-urlencoded'},
body
})
const accessResponse = await response.json();
return accessResponse.access_token;
}
ตัวอย่างโค้ดสําหรับการเรียก REST API ด้วยไลบรารี Google Auth
import { GoogleAuth } from 'google-auth-library';
import fetch from 'node-fetch'
import credentialJson from 'path_to_your_json_file' with { type: 'json' };
const BASE_SUBSCRIPTION_LINIING_API_URL='https://readerrevenuesubscriptionlinking.googleapis.com/v1';
const publicationId = process.env.PUBLICATION_ID
const auth = new GoogleAuth({
credentials: credentialJson,
scopes: [
'https://www.googleapis.com/auth/readerrevenue.subscriptionlinking.manage'
]
});
async function getAccessToken() {
const accessToken = await auth.getAccessToken();
return accessToken;
}
/**
* Retrieves details for a specific reader associated with the publication.
* @async
* @param {string} ppid - The Publisher Provided ID (ppid) for the reader.
* @return {object} reader json for the given ppid
*/
async function getReader(ppid) {
const endpoint = `${BASE_SUBSCRIPTION_LINIING_API_URL}/publications/${publicationId}/readers/${ppid}`;
const accessToken = await getAccessToken();
const response = await fetch(endpoint, {
method: 'GET',
headers: {
Authorization: `Bearer ${accessToken}`,
},
});
const reader = await response.json();
return reader;
}
/**
* Updates the entitlements for a specific reader.
* @async
* @param {string} ppid - The Publisher Provided ID (ppid) for the reader.
* @return {object} the updated entitlements object in json.
*/
async function updateReaderEntitlements(ppid) {
const endpoint = `${BASE_SUBSCRIPTION_LINIING_API_URL}/publications/${publicationId}/readers/${ppid}/entitlements`;
const requestBody = {
/*
Refer to
https://developers.google.com/news/subscribe/subscription-linking/appendix/glossary#entitlements_object
*/
entitlements : [{
product_id: `${publicationId}:basic`,
subscription_token: 'abc1234',
detail: 'This is our basic plan',
expire_time: '2025-10-21T03:05:08.200564Z'
}]
};
const response = await fetch(endpoint, {
method: 'PATCH',
headers: {
Authorization: `Bearer ${accessToken}`,
'Content-Type': 'application/json',
},
body: JSON.stringify(requestBody)
})
const updatedEntitlements = await response.json();
return updatedEntitlements;
}
/**
* Retrieves the current entitlements for a specific reader.
* @async
* @param {string} ppid - The Publisher Provided ID (ppid) for the reader.
* @return {object} the reader's entitlements object in json.
*/
async function getReaderEntitlements(ppid) {
const endpoint = `${BASE_SUBSCRIPTION_LINIING_API_URL}/publications/${publicationId}/readers/${ppid}/entitlements`;
const accessToken = await getAccessToken();
const response = await fetch(endpoint, {
method: 'GET',
headers: {
Authorization: `Bearer ${accessToken}`,
},
});
const entitlements = await response.json();
return entitlements;
}
/**
* Deletes a specific Subscription Linkikng reader record associated with the publication.
* @async
* @param {string} ppid - The Publisher Provided ID (ppid) for the reader.
* @param {boolean=} forceDelete - If true, delete the user even if their
* entitelements are not empty
* @return {object} returns an empty object ({}) if the delete operation is successful
*/
async function deleteReader(ppid, forceDelete = false) {
const endpoint = `${BASE_SUBSCRIPTION_LINIING_API_URL}/publications/${publicationId}/readers/${ppid}?force=${forceDelete}`;
const response = await fetch(endpoint, {
method: 'DELETE',
headers: {
Authorization: `Bearer ${accessToken}`,
}
});
const result = await response.json();
return result;
}