Integracja po stronie serwera

Wydawcy używają integracji po stronie serwera głównie do zarządzania czytelnikami zezwoleń. Do aktualizacji wydawcy używają głównie usługi UpdateReaderEntitlements Dokument Google dotyczący upoważnienia do korzystania z identyfikatora produktu w przypadku identyfikatora PPID.

Konfiguracja Google Cloud

Konfigurowanie łączenia subskrypcji w Google Cloud obejmuje 2 główne elementy:

  1. Włączanie interfejsu API w danym projekcie
  2. Tworzenie konta usługi umożliwiającego dostęp do interfejsu API

Włączanie interfejsu Subscription link API

Aby używać konta usługi i zarządzać uprawnieniami czytelników, projekt musi mieć włączony interfejs Subscription Grouping API oraz prawidłowo skonfigurowane konto usługi OAuth. Aby włączyć interfejs Subscription link API w przypadku usługi przejdź z menu -> Interfejsy API Usługi -> Biblioteka i wyszukiwanie Subscription Linking lub bezpośrednio wejdź na stronę:


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

api

Rysunek 1. Przejście do biblioteki interfejsów API i włączenie interfejsu API dla usługi Google Projekt w chmurze.

Utwórz konto usługi

Konta usługi są używane do zezwalania na dostęp z aplikacji do Subskrypcja łączenia interfejsu API.

  1. Utwórz konto usługi w obrębie konta usługi konsoli.
  2. Utwórz dane logowania dla konta usługi i zapisz je. credentials.json w bezpiecznej lokalizacji dostępnej dla Twojej aplikacji.
  3. Przypisywanie roli uprawnień „Administrator połączeń subskrypcji” do utworzone przez Ciebie konto usługi. W celu szczegółowej kontroli nad możliwościami funkcji konta usługi, możesz przypisać odpowiednią rolę z tej tabeli.
Kompetencje / rola Administrator połączeń subskrypcji Wyświetlający połączenia subskrypcji Wyświetlający uprawnienia połączeń subskrypcji
Uzyskaj uprawnienia czytelników
Zdobywanie czytelników
Zaktualizuj uprawnienia czytelników
Usuń czytelników

Używanie kont usługi z interfejsem Subscription Grouping API

używać kont usługi do uwierzytelniania wywołań interfejsu Subscription Grouping API; za pomocą biblioteki klienta Jamboard lub podpisywania żądań za pomocą interfejsu API typu REST. Biblioteki klienta automatycznie obsługują żądania odpowiedni access_token, a interfejs API REST wymaga pobrania parametru id_token i zamienić go na access_token.

Oba te klienty w przykładach biblioteki i interfejsu API REST używają punktu końcowego getReader(). Na żywo wszystkich metod interfejsu API znajdziesz w dokumentacji, Wersja demonstracyjna łączenia subskrypcji lub jej kod.

Przykładowe żądanie z biblioteką klienta 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}`,
  });
};

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
  });
};

Ręczne podpisywanie żądań do interfejsu 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
}