Yayıncılar, okuyucuları ve haklarıyla ilgili bilgileri yönetmek için öncelikle sunucu tarafı entegrasyonu kullanır. Yayıncılar, öncelikle Google'ın bir PPID için ürün kimliği hakkıyla ilgili kaydını güncellemek amacıyla UpdateReaderEntitlements
kullanır.
Google Cloud kurulumu
Google Cloud'da abonelik bağlamayı yapılandırmanın iki ana bileşeni vardır:
- Belirli bir proje için API'yi etkinleştirme
- API'ye erişmek için hizmet hesabı oluşturma
Abonelik Bağlama API'yi etkinleştirme
Hizmet hesabı kullanmak ve okuyucunun haklarından yararlanmak için Google Cloud projesinde hem Abonelik Bağlantısı API'sinin etkinleştirilmesi hem de düzgün yapılandırılmış bir OAuth hizmet hesabının bulunması gerekir. Bir proje için Subscription Linking API'yi etkinleştirmek üzere menü -> API'ler ve Hizmetler -> Kitaplık'a gidin ve Subscription Linking
'yi arayın veya sayfayı doğrudan ziyaret edin:
https://console.cloud.google.com/apis/library?project=gcp_project_id
Şekil 1. API kitaplığına gitme ve bir Google Cloud projesi için API'yi etkinleştirme.
Hizmet hesabı oluşturma
Hizmet hesapları, uygulamanızdan Subscription Linking API'ye erişime izin vermek için kullanılır.
- Projenizin konsolunda bir hizmet hesabı oluşturun.
- Hizmet hesabı için kimlik bilgileri oluşturun ve
credentials.json
dosyasını uygulamanızın erişebileceği güvenli bir konumda depolayın. - Oluşturduğunuz hizmet hesabına "Abonelik Bağlama Yöneticisi" IAM rolünü verin. Hizmet hesabının özellikleri üzerinde ayrıntılı kontrol sahibi olmak için aşağıdaki tablodan uygun rolü atayabilirsiniz.
Yetenek / rol | Abonelik Bağlama Yöneticisi | Abonelik Bağlama Görüntüleyicisi | Abonelik Bağlama Yararlanma Hakları Görüntüleyicisi |
---|---|---|---|
Okuyucu ayrıcalıklarını alma | |||
Okuyucu edinme | |||
Okuyucuların yararlanma haklarını güncelleme | |||
Okuyucuları silme |
Abonelik Bağlantısı API'si ile hizmet hesaplarını kullanma
Abonelik Bağlama API'sine yapılan çağrıların kimliğini hizmet hesaplarıyla doğrulamak için googleapis istemci kitaplığını (access_token
isteklerini otomatik olarak işleyen) kullanın veya istekleri doğrudan REST API ile imzalayın. REST API'yi kullanıyorsanız önce bir access_token
(Google Kimlik Doğrulama kitaplığı veya hizmet hesabı JWT'si aracılığıyla) elde etmeniz ve ardından Authorization
başlığına eklemeniz gerekir.
Aşağıdaki istemci kitaplığı ve REST API örneklerinde getReader()
, getReaderEntitlements()
, updateReaderEntitlements()
ve deleteReader()
'in nasıl çağrılacağıyla ilgili örnek kodlar verilmiştir.
İstemci kitaplığı
Bu bölümde, Node.js'de googleapis istemci kitaplığının nasıl kullanılacağı açıklanmaktadır.
Örnek istek
Auth.GoogleAuth
yapıcısında keyFile
alanı için hizmet hesabı anahtarınızın yolunu ayarlayın.
Kuruluş politikanız nedeniyle bir hizmet hesabı anahtarını dışa aktaramıyorsanız hesap varsayılan kimlik bilgisi (ADC) yöntemini kullanabilirsiniz. ADC yöntemini kullanırsanız ADC'nin kimlik bilgilerini kendi başına aradığından keyFile
alanını sağlamanız gerekmez.
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 subscriptionLinkingApi = new SubscriptionLinking();
const client = subscriptionLinkingApi.init();
/**
* Retrieves details for a specific reader associated with the publication.
* @async
* @param {string} ppid - The Publisher Provided ID (ppid) for the reader.
* @return {Promise<object>} A promise that resolves with the reader's details
* from the API.
*/
async function getReader(ppid) {
const publicationId = process.env.PUBLICATION_ID;
return await client.publications.readers.get({
name: `publications/${publicationId}/readers/${ppid}`,
});
};
/**
* Updates the entitlements for a specific reader.
* @async
* @param {string} ppid - The Publisher Provided ID (ppid) for the reader whose
* entitlements are being updated.
* @return {Promise<object>} A promise that resolves with the result of the
* updated entitlements object.
*/
async function updateReaderEntitlements(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
});
};
/**
* Retrieves the current entitlements for a specific reader.
* @async
* @param {string} ppid - The Publisher Provided ID (ppid) for the reader.
* @return {Promise<object>} A promise that resolves with the reader's entitlements object.
*/
async function getReaderEntitlements(ppid) {
const publicationId = process.env.PUBLICATION_ID;
return await client.publications.readers.getEntitlements({
name: `publications/${publicationId}/readers/${ppid}/entitlements`
});
};
/**
* Deletes a specific Subscription Linkikng reader record associated with the publication.
* @async
* @param {string} ppid - The Publisher Provided ID (ppid) for the reader to be deleted.
* @param {boolean=} forceDelete - If true, delete the user even if their
* entitelements are not empty
* @return {Promise<object>} A promise that resolves upon successful deletion
* with an empty object ({})
*/
async function deleteReader(ppid, forceDelete = false) {
const publicationId = process.env.PUBLICATION_ID;
return await client.publications.readers.delete({
name: `publications/${publicationId}/readers/${ppid}`
force: forceDelete
});
};
REST API
REST API uç noktalarını çağırmak istiyorsanız Authorization
başlığına ayarlanacak accessToken
değerini almak için bu yöntemlerden birini kullanabilirsiniz.
1. GoogleAuth
kitaplığını kullanma
credentials
anahtarı için hizmet hesabı anahtarı veya hesap varsayılan kimlik bilgisi (ADC) kullanabilirsiniz.
ADC yöntemini kullanırsanız ADC kendi başına kimlik bilgilerini arayacağı için credentials
alanını sağlamanız gerekmez.
import { GoogleAuth } from 'google-auth-library';
import credentialJson from 'path_to_your_json_file' with { type: 'json' };
const auth = new GoogleAuth({
credentials: credential_json,
scopes: [
'https://www.googleapis.com/auth/readerrevenue.subscriptionlinking.manage'
]
});
async function getAccessToken() {
const accessToken = await auth.getAccessToken();
return accessToken;
}
2. Hizmet Hesabı JWT'si kullanarak access_token
oluşturma
import fetch from 'node-fetch';
import jwt from 'jsonwebtoken';
function getSignedJwt() {
/*
Either store the service account 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 response = await fetch('https://oauth2.googleapis.com/token', {
method: 'POST',
headers: {'Content-Type': 'application/x-www-form-urlencoded'},
body
})
const accessResponse = await response.json();
return accessResponse.access_token;
}
Google Auth kitaplığıyla REST API çağrıları için örnek kod
import { GoogleAuth } from 'google-auth-library';
import fetch from 'node-fetch'
import credentialJson from 'path_to_your_json_file' with { type: 'json' };
const BASE_SUBSCRIPTION_LINIING_API_URL='https://readerrevenuesubscriptionlinking.googleapis.com/v1';
const publicationId = process.env.PUBLICATION_ID
const auth = new GoogleAuth({
credentials: credentialJson,
scopes: [
'https://www.googleapis.com/auth/readerrevenue.subscriptionlinking.manage'
]
});
async function getAccessToken() {
const accessToken = await auth.getAccessToken();
return accessToken;
}
/**
* Retrieves details for a specific reader associated with the publication.
* @async
* @param {string} ppid - The Publisher Provided ID (ppid) for the reader.
* @return {object} reader json for the given ppid
*/
async function getReader(ppid) {
const endpoint = `${BASE_SUBSCRIPTION_LINIING_API_URL}/publications/${publicationId}/readers/${ppid}`;
const accessToken = await getAccessToken();
const response = await fetch(endpoint, {
method: 'GET',
headers: {
Authorization: `Bearer ${accessToken}`,
},
});
const reader = await response.json();
return reader;
}
/**
* Updates the entitlements for a specific reader.
* @async
* @param {string} ppid - The Publisher Provided ID (ppid) for the reader.
* @return {object} the updated entitlements object in json.
*/
async function updateReaderEntitlements(ppid) {
const endpoint = `${BASE_SUBSCRIPTION_LINIING_API_URL}/publications/${publicationId}/readers/${ppid}/entitlements`;
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'
}]
};
const response = await fetch(endpoint, {
method: 'PATCH',
headers: {
Authorization: `Bearer ${accessToken}`,
'Content-Type': 'application/json',
},
body: JSON.stringify(requestBody)
})
const updatedEntitlements = await response.json();
return updatedEntitlements;
}
/**
* Retrieves the current entitlements for a specific reader.
* @async
* @param {string} ppid - The Publisher Provided ID (ppid) for the reader.
* @return {object} the reader's entitlements object in json.
*/
async function getReaderEntitlements(ppid) {
const endpoint = `${BASE_SUBSCRIPTION_LINIING_API_URL}/publications/${publicationId}/readers/${ppid}/entitlements`;
const accessToken = await getAccessToken();
const response = await fetch(endpoint, {
method: 'GET',
headers: {
Authorization: `Bearer ${accessToken}`,
},
});
const entitlements = await response.json();
return entitlements;
}
/**
* Deletes a specific Subscription Linkikng reader record associated with the publication.
* @async
* @param {string} ppid - The Publisher Provided ID (ppid) for the reader.
* @param {boolean=} forceDelete - If true, delete the user even if their
* entitelements are not empty
* @return {object} returns an empty object ({}) if the delete operation is successful
*/
async function deleteReader(ppid, forceDelete = false) {
const endpoint = `${BASE_SUBSCRIPTION_LINIING_API_URL}/publications/${publicationId}/readers/${ppid}?force=${forceDelete}`;
const response = await fetch(endpoint, {
method: 'DELETE',
headers: {
Authorization: `Bearer ${accessToken}`,
}
});
const result = await response.json();
return result;
}