Integrazione lato server

Gli editori usano principalmente l'integrazione lato server per gestire i lettori e i loro diritti. Gli editori usano principalmente UpdateReaderEntitlements per aggiornare il record di Google del diritto di un ID prodotto relativo a un PPID.

Configurazione di Google Cloud

La configurazione di Subscription Linking in Google Cloud include due componenti principali:

  1. Attivazione dell'API per un progetto specifico
  2. Creazione di un account di servizio per accedere all'API

Attivare l'API Subscription Linking

Per utilizzare un account di servizio e gestire i diritti di un lettore, un progetto Google Cloud deve avere sia l'API Subscription Linking attiva sia un account di servizio OAuth configurato correttamente. Per attivare l'API Subscription Linking per un progetto, vai al menu -> API e servizi -> Libreria e cerca Subscription Linking oppure visita direttamente la pagina:


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

API

Figura 1. Accesso alla libreria API e attivazione dell'API per un progetto Google Cloud.

Creare un account di servizio

Gli account di servizio vengono utilizzati per consentire l'accesso dalla tua applicazione all'API Subscription Linking.

  1. Crea un account di servizio nella console del progetto.
  2. Crea le credenziali per l'account di servizio e salva il file credentials.json in una posizione sicura accessibile alla tua applicazione.
  3. Concedi il ruolo IAM "Amministratore collegamento abbonamenti" all'account di servizio che hai creato. Per un controllo granulare sulle capacità dell'account di servizio, puoi assegnare il ruolo appropriato dalla tabella seguente.
Funzionalità / Ruolo Amministratore collegamento abbonamenti Visualizzatore collegamento abbonamenti Visualizzatore diritti collegamento abbonamenti
Ottieni diritti lettore
Ottieni lettori
Aggiorna diritti lettore
Elimina lettori

Usare gli account di servizio con l'API Subscription Linking

Usa gli account di servizio per autenticare le chiamate all'API Subscription Linking, con la libreria client googleapis o firmando le richieste con l'API REST. Le librerie client gestiscono automaticamente la richiesta dell'oggetto access_token appropriato, mentre l'API REST richiede il recupero di un id_token da scambiare con un access_token.

Entrambi i seguenti esempi di libreria client e API REST utilizzano l'endpoint getReader(). Per una dimostrazione dal vivo di tutti i metodi dell'API, visita il sito Subscription Linking Demo o il relativo codice.

Esempio di richiesta con la libreria client 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}`,
    requestBody
  });
};

Firmare manualmente le richieste API 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
}