Menyinkronkan Hak Istimewa Pengguna (Integrasi sisi server)

Penayang terutama menggunakan integrasi sisi server untuk mengelola pembaca dan hak mereka. Pada dasarnya, penayang menggunakan UpdateReaderEntitlements untuk memperbarui data hak ID Produk Google untuk PPID.

Penyiapan Google Cloud

Mengonfigurasi Penautan Langganan di Google Cloud mencakup dua komponen utama:

  1. Mengaktifkan API untuk project tertentu
  2. Membuat akun layanan untuk mengakses API

Mengaktifkan Subscription Linking API

Untuk menggunakan akun layanan dan mengelola hak pembaca, project Google Cloud harus mengaktifkan Subscription Linking API, dan akun layanan OAuth yang dikonfigurasi dengan benar. Untuk mengaktifkan Subscription Linking API untuk project, buka menu -> API & Layanan -> Library, lalu telusuri Subscription Linking, atau buka halaman secara langsung:


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

api

Gambar 1. Membuka Library API, dan mengaktifkan API untuk project Google Cloud.

Membuat Akun Layanan

Akun layanan digunakan untuk mengizinkan akses dari aplikasi Anda ke Subscription Linking API.

  1. Buat akun layanan dalam konsol project Anda.
  2. Buat kredensial untuk akun layanan, dan simpan file credentials.json di lokasi aman yang dapat diakses oleh aplikasi Anda.
  3. Berikan peran IAM "Subscription Linking Admin" ke akun layanan yang Anda buat. Untuk kontrol terperinci atas kemampuan akun layanan, Anda dapat menetapkan peran yang sesuai dari tabel berikut.
Kemampuan / Peran Subscription Linking Admin Subscription Linking Viewer Subscription Linking Entitlements Viewer
Mendapatkan hak pembaca
Mendapatkan pembaca
Memperbarui hak pembaca
Menghapus pembaca

Menggunakan akun layanan dengan Subscription Linking API

Gunakan akun layanan untuk mengautentikasi panggilan ke Subscription Linking API, baik dengan library klien googleapis atau dengan menandatangani permintaan dengan REST API. Library klien secara otomatis menangani permintaan access_token yang sesuai, sedangkan REST API memerlukan pengambilan id_token, lalu menukarnya dengan access_token.

Contoh library klien dan REST API berikut menggunakan endpoint getReader(). Untuk demonstrasi langsung semua metode API, lihat situs Demo Penautan Langganan, atau kodenya.

Contoh permintaan dengan library klien googleapis node.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}/entitlements`,
    requestBody
  });
};

Menandatangani permintaan REST API secara manual

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
}