الدمج من جهة الخادم

يستعين الناشرون في المقام الأول بالتكامل من جهة الخادم لإدارة القرّاء وأذوناتهم. يستخدم الناشرون بشكل أساسي السمة UpdateReaderEntitlements لتعديل سجلّ Google لاستحقاق معرّف المنتج في المعرّف المقدَّم من الناشر (PPID).

إعداد Google Cloud

تشمل عملية إعداد ربط الاشتراكات في Google Cloud مكوّنَين رئيسيَين:

  1. تمكين واجهة برمجة التطبيقات لمشروع معين
  2. إنشاء حساب خدمة للوصول إلى واجهة برمجة التطبيقات

تفعيل Subscription Linking API

لاستخدام حساب خدمة وإدارة أذونات القارئ، يجب أن يتم تفعيل واجهة برمجة التطبيقات Subscription Linking API في مشروع Google Cloud وحساب خدمة OAuth الذي تم إعداده بشكل صحيح. لتفعيل Subscription Linking API لمشروع ما، انتقِل إلى القائمة -> APIs & Services -> Library (المكتبة) وابحث عن Subscription Linking، أو انتقِل إلى الصفحة مباشرةً:


https://console.cloud.google.com/apis/library?project=gcp_project_id

api

الشكل 1. الانتقال إلى مكتبة واجهة برمجة التطبيقات وتفعيل واجهة برمجة التطبيقات لمشروع على Google Cloud

إنشاء حساب خدمة

يتم استخدام حسابات الخدمة للسماح بالوصول من تطبيقك إلى SUBSCRIPTION Linking API.

  1. أنشئ حساب خدمة داخل وحدة تحكم المشروع.
  2. أنشِئ بيانات اعتماد لحساب الخدمة وخزِّن ملف credentials.json في موقع آمن يمكن لتطبيقك الوصول إليه.
  3. امنح دور "إدارة الهوية وإمكانية الوصول" "مشرف ربط الاشتراكات" لحساب الخدمة الذي أنشأته. للتحكُّم الدقيق في إمكانات حساب الخدمة، يمكنك تعيين الدور المناسب من الجدول التالي.
الإمكانية / الدور المشرف على ربط الاشتراكات مُشاهد ربط الاشتراكات مُشاهد أذونات ربط الاشتراكات
الحصول على أذونات وصول القرّاء
جذب قرّاء
تعديل أذونات وصول القرّاء
حذف القرّاء

استخدام حسابات الخدمة مع Subscription Linking API

يمكنك استخدام حسابات الخدمة لمصادقة عمليات إرسال الطلبات إلى واجهة برمجة التطبيقات Subscription Linking، إما من خلال مكتبة عميل googleapis أو من خلال توقيع الطلبات باستخدام REST API. تعالج مكتبات العملاء تلقائيًا طلب access_token المناسب، بينما تتطلب واجهة برمجة تطبيقات REST استرداد id_token ثم استبداله بـ access_token.

تستخدم كل من مكتبة العميل التالية وأمثلة واجهة برمجة التطبيقات REST نقطة النهاية getReader(). للحصول على عرض توضيحي مباشر لجميع طُرق واجهة برمجة التطبيقات، يمكنك الاطّلاع على الموقع الإلكتروني للعرض التوضيحي لربط الاشتراكات، أو الرمز الخاص به.

نموذج طلب من خلال مكتبة عميل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

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
}