يستخدم الناشرون بشكل أساسي الدمج من جهة الخادم لإدارة القرّاء
المعلومات والواجبات. يستخدم الناشرون UpdateReaderEntitlements
بشكل أساسي للتحديث
سجلّ Google الخاص باستحقاق استخدام معرّف المنتج للمعرّف المقدَّم من الناشر (PPID)
إعداد Google Cloud
يشتمل إعداد ميزة "ربط الاشتراكات" في Google Cloud على مكوّنَين رئيسيَّين:
- تمكين واجهة برمجة التطبيقات لمشروع معين
- إنشاء حساب خدمة للوصول إلى واجهة برمجة التطبيقات
تفعيل واجهة Subscription Linking API
لاستخدام حساب خدمة وإدارة أذونات القارئ، يجب إنشاء حساب على Google Cloud
أن يتضمن المشروع كلاً من Subscription Linking API مفعَّلًا وأن
حساب خدمة OAuth المهيأ. لتفعيل واجهة Subscription Linking API
المشروع، انتقل من القائمة -> واجهات برمجة التطبيقات الخدمات -> المكتبة والبحث عن
Subscription Linking
، أو زيارة الصفحة مباشرةً:
https://console.cloud.google.com/apis/library?project=gcp_project_id
الشكل 1. الانتقال إلى مكتبة واجهة برمجة التطبيقات وتفعيل واجهة برمجة التطبيقات المشروع على السحابة الإلكترونية.
إنشاء حساب للخدمة
يتم استخدام حسابات الخدمة للسماح بالوصول من تطبيقك إلى Subscription Linking API
- إنشاء حساب خدمة ضمن حساب مشروعك وحدة التحكم.
- إنشاء بيانات اعتماد لحساب الخدمة وتخزينه
ملف
credentials.json
في مكان آمن يمكن لتطبيقك الوصول إليه. - منح دور "إدارة الهوية وإمكانية الوصول" "مشرف ربط الاشتراكات" إلى حساب الخدمة الذي أنشأته. للتحكّم بدقة في إمكانات يمكنك تعيين الدور المناسب من الجدول التالي.
الإمكانات / الدور | مشرف ربط الاشتراكات | عارض ربط الاشتراكات | عارِض أذونات ربط الاشتراكات |
---|---|---|---|
الحصول على أذونات القرّاء | |||
الحصول على قرّاء | |||
تعديل أذونات القرّاء | |||
حذف القرّاء |
استخدام حسابات الخدمة من خلال Subscription Linking API
استخدام حسابات الخدمة للمصادقة على الطلبات المرسَلة إلى Subscription Linking API
إما من خلال مكتبة برامج Chrome أو من خلال توقيع الطلبات
باستخدام REST API. تعالج مكتبات العملاء تلقائيًا طلب
access_token
مناسب، بينما تتطلب واجهة برمجة تطبيقات REST استرداد id_token
ثم استبدِلها مقابل access_token
.
كل من العميل التالي
ومكتبة REST API تستخدم نقطة النهاية getReader()
. بث مباشر
شرحًا لجميع طرق واجهة برمجة التطبيقات، راجع
الموقع الإلكتروني للعرض التوضيحي لربط الاشتراكات أو الرمز الخاص به
نموذج طلب باستخدام مكتبة برامج googleapis.js
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}`,
});
};
async function updateEntitlements(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}`,
requestBody
});
};
التوقيع يدويًا على طلبات واجهة برمجة التطبيقات 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
}