ناشران در درجه اول از ادغام سمت سرور برای مدیریت خوانندگان و حقوق آنها استفاده می کنند. در درجه اول، ناشران از UpdateReaderEntitlements
برای بهروزرسانی سابقه Google در مورد حق شناسه محصول برای یک PPID استفاده میکنند.
راه اندازی Google Cloud
پیکربندی پیوند اشتراک در Google Cloud شامل دو جزء اصلی است:
- فعال کردن API برای یک پروژه معین
- ایجاد یک حساب کاربری برای دسترسی به api
API پیوند اشتراک را فعال کنید
برای استفاده از یک حساب سرویس و مدیریت حقوق خواننده، یک پروژه Google Cloud باید هم API پیوند اشتراک را فعال کرده و هم یک حساب سرویس OAuth به درستی پیکربندی شده باشد. برای فعال کردن API پیوند اشتراک برای یک پروژه، از منو -> APIs & Services -> Library پیمایش کنید و Subscription Linking
را جستجو کنید، یا مستقیماً از صفحه بازدید کنید:
https://console.cloud.google.com/apis/library?project=gcp_project_id
شکل 1. پیمایش به کتابخانه API و فعال کردن API برای پروژه Google Cloud.
یک حساب خدمات ایجاد کنید
حسابهای سرویس برای اجازه دسترسی از برنامه شما به API پیوند اشتراک استفاده میشوند.
- یک حساب سرویس در کنسول پروژه خود ایجاد کنید .
- اعتبارنامه ها را برای حساب سرویس ایجاد کنید و فایل
credentials.json
را در مکانی امن و قابل دسترسی برای برنامه خود ذخیره کنید. - نقش IAM "Subscription Linking Admin" را به حساب سرویسی که ایجاد کردید اعطا کنید . برای کنترل دقیق بر روی قابلیت های اکانت سرویس، می توانید نقش مناسب را از جدول زیر اختصاص دهید.
قابلیت / نقش | مدیریت پیوند اشتراک | مشاهده کننده پیوند اشتراک | مشاهده کننده حقوق پیوند اشتراک |
---|---|---|---|
حقوق خواننده را دریافت کنید | |||
خوانندگان را دریافت کنید | |||
به روز رسانی حقوق خواننده | |||
خوانندگان را حذف کنید |
از حسابهای سرویس با API پیوند اشتراک استفاده کنید
برای احراز هویت تماسها به 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;
}