Syncronization using Polling
A polling strategy is bad for both our systems and your API Quotas because it generates a high volume of futile requests.
A better approach is to use our Webhooks to keep your system updated. Check them out!
In this use case, we suppose that you have a system that you want to keep in sync with the Fatture in Cloud API, in particular retrieving the list of the products from our API and storing them in some way. In this example, we'll adopt a polling approach to retrieve the current state of the data stored in Fatture in Cloud.
If you want to download the complete SDKs examples you can find them here.
In this example, we'll suppose you have to manage just one Company, so we simply inserted its ID directly in the code. If instead, you need to be able to manage multiple companies, you'll need to retrieve the ID of the current company in some way. Check the Company-scoped Methods page for more info.
🏈 Let's start!
To keep the code as simple as possible, we decided to write the data to a JSON lines file, that could be then sent as input for an external system; of course, it is possible to use the retrieved elements as needed: for example, to update a Database status or to perform API calls towards a third-party system.
To keep two systems in sync using polling, it is necessary to reiterate the extraction of the data from our APIs, scheduling the code execution.
In this example, we deliberately omitted to add the code to repeat the execution of our code. For example, you could decide to add a Cron Library to your application or to execute the script using a Job Scheduler on your operating system. This is up to you.
Even if we created this code to keep two systems synchronized periodically, it can also be used for a one-off extraction of the data from the Fatture in Cloud API. Just execute it as it is...
🏗 Libraries
In our examples, we'll use the Fatture in Cloud SDKs; of course, you can just replace our SDKs with a simple HTTP Client if you prefer: check the dedicated page for further info. Additionally, for some languages, we added some other libraries to perform common tasks such as writing to the file system or performing the exponential backoff.
1️⃣ Initialize our SDK
In the first part of this example, we import our SDK and initialize it, using the Access Token requested to perform the API call. For simplicity, we didn't implement the code to retrieve the access token in these examples, but you can find more information in the Quickstarts or in the Authentication Implementation pages.
Since we're trying to collect the list of products for a certain company, the products:r scope will be required; if you need to use another API method please select the appropriate scopes.
Once the token is provided to our SDK, it is possible to start using it to interrogate our APIs.
2️⃣ Implement the Exponential Backoff
The polling strategy implies the exigency to perform a potentially huge amount of requests in a really short period. As explained here, our APIs are protected by a set of limits that could result in an error if too many requests are performed in a certain interval.
This is why in our examples we wrapped the API call with an Exponential Backoff method: it manages retries and time distance between two consecutive attempts, to avoid your script failing for a temporary quota-related issue.
3️⃣ The API Method
The API method that we're using is the List Products method, which returns the list of all the possible products for a certain company. The List methods provide Sorting and Customizing functionalities, but in this example we'll not use them.
Each response of the List methods will be Paginated: to avoid returning enormous amounts of data with a single call, the list of products will be split into different pages, that can be retrieved consecutively. Each response contains a set of dedicated pagination parameters, that are meant to make the pages navigation task easier for you.
In our code, we'll perform the first List request on the first page provided by our API, with a page size of five elements. Then we'll use the pagination parameter last_page to retrieve the subsequent pages, performing the needed number of API calls to export all the needed elements from the APIs.
Please, notice that the pages on our APIs use one-based numbering: the first page has index 1.
4️⃣ Manage the response
Each response contains a data parameter, that is a JSON array representing one page (e.g. one subset of the list of products). Our SDKs parse the JSON array, so you can just use the elements contained in the array to perform the requested operations.
In this example, we're just trying to populate a JSON Lines file, so for each product retrieved we obtain the related JSON representation and append it to the text file.
💻 Code Examples
Here you can find the code described above.
- C#
- Go
- Java
- JavaScript
- PHP
- Python
- Ruby
- TypeScript
// The following dependencies are required
// dotnet add package It.FattureInCloud.Sdk
// dotnet add package Polly
// dotnet add package Polly.Contrib.WaitAndRetry
using System;
using System.IO;
using System.Linq;
using Newtonsoft.Json;
using System.Collections.Generic;
using Polly;
using It.FattureInCloud.Sdk.Api;
using It.FattureInCloud.Sdk.Model;
using It.FattureInCloud.Sdk.Client;
using Polly.Contrib.WaitAndRetry;
namespace poll
{
class Program
{
public static ProductsApi apiInstance;
static void Main(string[] args)
{
// This code should be executed periodically using a cron library or job scheduler.
// For example: https://www.quartz-scheduler.net/
SyncProducts();
}
private static void SyncProducts()
{
// Here we init the Fatture in Cloud SDK
// The Access Token is retrieved using the "GetToken" method
Configuration config = new Configuration();
config.AccessToken = GetToken();
// In this example we're using the Products API
apiInstance = new ProductsApi(config);
// The ID of the controlled company.
var companyId = 2;
// Here we setup the exponential backoff config
var maxRetryAttempts = 5;
var pauseBetweenFailures =
Backoff.ExponentialBackoff(TimeSpan.FromSeconds(2), retryCount: maxRetryAttempts);
var retryPolicy = Policy
.Handle<ApiException>()
.WaitAndRetry(pauseBetweenFailures);
try
{
// In this example we suppose to export the data to a JSON Lines file.
// First, we cancel the content of the destination file
File.WriteAllText("products.jsonl", String.Empty);
// List Products
var perPage = 5;
// We perform the first request
ListProductsResponse result =
ListProductsWithBackoff(companyId, 1, perPage, retryPolicy, apiInstance);
// We use the first response to extract the last page index
var lastPage = result.LastPage;
// We append the products obtained with the first request top the output file
// Data contains an array of products
AppendProductsToFile(result.Data);
// For the missing pages (we already requested the first one)
for (var i = 2; i <= lastPage; i++)
{
// We require the page to the API
result = ListProductsWithBackoff(companyId, i, perPage, retryPolicy, apiInstance);
// And append all the retrieved products
AppendProductsToFile(result.Data);
}
}
catch (ApiException ex)
{
Console.WriteLine("Exception when calling ProductsAPI.ListProducts: " + ex.Message);
Console.WriteLine("Status Code: " + ex.ErrorCode);
Console.WriteLine(ex.StackTrace);
}
}
// In this function we append the products in the JSON Lines file.
// You can replace this function to perform the operations you need.
// For example, you can build SQL queries or call a third-party API using the retrieved products.
private static void AppendProductsToFile(List<Product> products)
{
StreamWriter sw = File.AppendText("products.jsonl");
// For each product in the list
foreach (Product p in products)
{
// We write the product to the file
sw.WriteLine(JsonConvert.SerializeObject(p, Formatting.None) + "\n");
}
sw.Close();
}
// Here we wrap the SDK method with an exponential backoff
// This is to manage the quota exceeded issue
private static ListProductsResponse ListProductsWithBackoff(int companyId, int currentPage, int perPage, Policy retryPolicy, ProductsApi apiInstance)
{
return retryPolicy.Execute(() =>
{
// The actual SDK method is executed here
return apiInstance.ListProducts(companyId, null, "detailed", null, currentPage, 5);
});
}
// This is just a mock: this function should contain the code to retrieve the Access Token
private static string GetToken() {
return "YOUR_TOKEN";
}
}
}
// The following dependencies is required
// go get github.com/fattureincloud/fattureincloud-go-sdk/
// go get github.com/cenkalti/backoff/v4
package main
import (
"context"
"encoding/json"
"fmt"
"os"
backoff "github.com/cenkalti/backoff/v4"
fattureincloudapi "github.com/fattureincloud/fattureincloud-go-sdk/v2/api"
fattureincloud "github.com/fattureincloud/fattureincloud-go-sdk/v2/model"
)
var (
f, _ = os.OpenFile("products.jsonl", os.O_APPEND|os.O_WRONLY, 0644)
// The Access Token is retrieved using the "getToken" method
auth = context.WithValue(context.Background(), fattureincloudapi.ContextAccessToken, getToken())
configuration = fattureincloudapi.NewConfiguration()
apiClient = fattureincloudapi.NewAPIClient(configuration)
companyId = int32(16) // This is the ID of the company we're working on
// Here we define the parameters for the first request.
nextPage = 1
attempts = 0
)
func main() {
// This code should be executed periodically using a cron library or job scheduler.
syncProducts()
}
func syncProducts() {
// In this example we suppose to export the data to a JSON Lines file.
// First, we cancel the content of the destination file
f.Truncate(0)
// Here we define the operation that retrieves the products
operation := func() error {
attempts++
fmt.Printf("Attempt: %d\n", attempts)
// In this example we're using the Products API
// Here we execute the actual SDK method
resp, _, err := apiClient.ProductsAPI.ListProducts(auth, companyId).Page(int32(nextPage)).PerPage(5).Execute()
if resp != nil {
// We check if there are other pages to retrieve
if resp.NextPageUrl.Get() == nil {
nextPage = 0
} else {
nextPage++
}
// We write the products of this page to the file
// "data" contains an array of products
appendProductsToFile(resp.Data)
}
return err
}
// For all the pages
for nextPage != 0 {
attempts = 0
// We call the operation function using Exponential Backoff
err := backoff.Retry(operation, backoff.NewExponentialBackOff())
if err != nil {
fmt.Fprintf(os.Stderr, "Error %v\n", err)
return
}
}
f.Close()
fmt.Println("products succesfully retrieved and saved in ./products.jsonl")
}
// In this function we append the products in the JSON Lines file.
// You can replace this function to perform the operations you need.
// For example, you can build SQL queries or call a third-party API using the retrieved products.
func appendProductsToFile(products []fattureincloud.Product) {
// For each product in the array
for _, element := range products {
// We obtain the related JSON and append it to the file as single line
jsonStr, _ := json.Marshal(element)
f.WriteString(string(jsonStr) + "\n")
}
}
// This is just a mock: this function should contain the code to retrieve the Access Token
func getToken() string {
return "YOUR_TOKEN"
}
import com.google.gson.Gson;
import io.github.resilience4j.core.IntervalFunction;
import io.github.resilience4j.retry.Retry;
import io.github.resilience4j.retry.RetryConfig;
import io.github.resilience4j.retry.RetryRegistry;
import io.vavr.CheckedFunction0;
import it.fattureincloud.sdk.ApiClient;
import it.fattureincloud.sdk.ApiException;
import it.fattureincloud.sdk.Configuration;
import it.fattureincloud.sdk.api.ProductsApi;
import it.fattureincloud.sdk.auth.OAuth;
import it.fattureincloud.sdk.model.ListProductsResponse;
import it.fattureincloud.sdk.model.Product;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
import java.util.List;
public class Application {
public static void main(String[] args) throws Throwable {
// This code should be executed periodically using a cron library or job scheduler.
// For example: http://www.quartz-scheduler.org/
syncProducts();
}
static void syncProducts() throws Throwable {
// Here we init the Fatture in Cloud SDK
ApiClient defaultClient = Configuration.getDefaultApiClient();
// The Access Token is retrieved using the "getToken" method
OAuth OAuth2AuthenticationCodeFlow =
(OAuth) defaultClient.getAuthentication("OAuth2AuthenticationCodeFlow");
OAuth2AuthenticationCodeFlow.setAccessToken(getToken());
// In this example we're using the Products API
ProductsApi apiInstance = new ProductsApi(defaultClient);
// The ID of the controlled company.
int companyId = 2;
// Here we setup the exponential backoff config
RetryConfig config = RetryConfig.custom()
.maxAttempts(10)
.retryExceptions(ApiException.class)
.intervalFunction(IntervalFunction.ofExponentialBackoff(1000, 2))
.build();
RetryRegistry registry = RetryRegistry.of(config);
Retry retry = registry.retry("listProducts", config);
Retry.EventPublisher publisher = retry.getEventPublisher();
publisher.onRetry(event -> System.out.println(event.toString()));
// In this example we suppose to export the data to a JSON Lines file.
// First, we cancel the content of the destination file
Files.write(Paths.get("products.jsonl"), ("").getBytes(),
StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING);
// List Products
int perPage = 5;
// We perform the first request
ListProductsResponse result = listProductsWithBackoff(companyId, 1, perPage, retry, apiInstance);
// We use the first response to extract the last page index
int lastPage = result.getLastPage();
// We append the products obtained with the first request top the output file
// Data contains an array of products
appendProductsToFile(result.getData());
// For the missing pages (we already requested the first one)
for (int i = 2; i <= lastPage; i++)
{
// We require the page to the API
result = listProductsWithBackoff(companyId, i, perPage, retry, apiInstance);
// And append all the retrieved products
appendProductsToFile(result.getData());
}
}
// Here we wrap the SDK method with an exponential backoff
// This is to manage the quota exceeded issue
static ListProductsResponse listProductsWithBackoff(int companyId, int currentPage, int perPage,
Retry retry, ProductsApi apiInstance) throws Throwable {
CheckedFunction0<ListProductsResponse> retryingListSuppliers =
Retry.decorateCheckedSupplier(retry,
() -> apiInstance.listProducts(companyId, null, "detailed", null, currentPage, 5));
return retryingListSuppliers.apply();
}
static void appendProductsToFile(List<Product> products) throws IOException {
for (Product product : products) {
String p = new Gson().toJson(product);
Files.write(Paths.get("products.jsonl"), (p + System.lineSeparator()).getBytes(),
StandardOpenOption.CREATE, StandardOpenOption.APPEND);
}
}
// This is just a mock: this function should contain the code to retrieve the Access Token
static String getToken() {
return "YOUR_TOKEN";
}
}
// The following dependency is required
// yarn add @fattureincloud/fattureincloud-js-sdk
const fs = require("fs");
const fattureInCloudSdk = require("@fattureincloud/fattureincloud-js-sdk");
// Here we init the Fatture in Cloud SDK
// The Access Token is retrieved using the "getToken" method
var defaultClient = fattureInCloudSdk.ApiClient.instance;
var OAuth2AuthenticationCodeFlow =
defaultClient.authentications["OAuth2AuthenticationCodeFlow"];
OAuth2AuthenticationCodeFlow.accessToken = getToken();
// In this example we're using the Products API
var productsApiInstance = new fattureInCloudSdk.ProductsApi();
// This code should be executed periodically using a cron library or job scheduler.
// For example: https://www.npmjs.com/package/node-cron
main()
.then()
.catch((err) => console.error(err));
async function main() {
// In this example we suppose to export the data to a JSON Lines file.
// First, we cancel the content of the destination file
fs.truncate("./products.jsonl", (err) => {
if (err) {
console.error(err);
return;
}
});
// Here we define the parameters for the first request.
let opts = {
fields: null,
fieldset: "detailed",
sort: null,
page: 1, // We're trying to obtain the first page
perPage: 5, // Every page will contain at most 5 products
};
let companyId = 2; // This is the ID of the company we're working on
try {
// We perform the first request
let result = await listProductsWithBackoff(companyId, opts);
// We recover the last page index
let lastPage = result["last_page"];
// We write the products of this page to the file
// "data" contains an array of products
await appendProductsToFile(result["data"]);
// For all the remaining pages (we already have the first one)
for (var i = 2; i <= lastPage; i++) {
// We update the page index
opts["page"] = i;
// We require the page at the selected index
result = await listProductsWithBackoff(companyId, opts);
// And we write the products to the file
await appendProductsToFile(result["data"]);
}
console.log("products succesfully retrieved and saved in ./products.jsonl");
} catch (e) {
console.log(e);
}
}
// In this function we append the products in the JSON Lines file.
// You can replace this function to perform the operations you need.
// For example, you can build SQL queries or call a third-party API using the retrieved products.
async function appendProductsToFile(products) {
// For each product in the array
for (i in products) {
let product = products[i];
// We obtain the related JSON and append it to the file as single line
fs.appendFileSync(
"./products.jsonl",
JSON.stringify(product) + "\n",
(err) => {
if (err) {
console.error(err);
return;
}
}
);
}
}
// Here we wrap the SDK method with an exponential backoff
// This is to manage the quota exceeded issue
async function listProductsWithBackoff(companyId, opts) {
var count = 0;
const delay = (retryCount) =>
new Promise((resolve) => setTimeout(resolve, 2 ** retryCount * 1000));
const getProd = async (retryCount = 0, lastError = null) => {
if (retryCount > 20) throw new Error(lastError);
try {
console.log("attempt:", count++, "wait:", 2 ** retryCount * 1000);
// The actual SDK method is executed here
return await productsApiInstance.listProducts(companyId, opts);
} catch (e) {
await delay(retryCount);
return getProd(retryCount + 1, e);
}
};
try {
var res = await getProd();
return res;
} catch (e) {
console.log(e);
}
}
// This is just a mock: this function should contain the code to retrieve the Access Token
function getToken() {
return "YOUR_TOKEN";
}
<?php
require("vendor/autoload.php");
// The following dependencies are required
// composer require stechstudio/backoff
// composer require fattureincloud/fattureincloud-php-sdk
use FattureInCloud\Api\ProductsApi;
use FattureInCloud\Configuration;
use GuzzleHttp\Client;
use STS\Backoff\Backoff;
// This code should be executed periodically using a cron library or job scheduler.
// For example: https://github.com/Cron/Cron
// Here we init the Fatture in Cloud SDK
// The Access Token is retrieved using the "getToken" method
$config = Configuration::getDefaultConfiguration()->setAccessToken(getToken());
// In this example we're using the Products API
$productsApiInstance = new ProductsApi(
new Client(),
$config
);
// In this example we suppose to export the data to a JSON Lines file.
// First, we cancel the content of the destination file
file_put_contents("./products.jsonl", "");
// This is the ID of the company we're currently managing
$companyId = 2;
// We require the first page using the ListProducts method
$result = listProductsWithBackoff($productsApiInstance, $companyId, 1);
// We extract the index of the last page from the first response
$lastPage = $result["last_page"];
// We append all the products to the destination file
// "data" contains an array of products
appendProductsToFile($result["data"]);
// For all the missing pages (we already have the first one)
for ($i = 2; $i <= $lastPage; $i++) {
// We require the page at the selected index to the API
$result = listProductsWithBackoff($productsApiInstance, $companyId, $i);
// We append this page products to the file
appendProductsToFile($result["data"]);
}
// In this function we append the products in the JSON Lines file.
// You can replace this function to perform the operations you need.
// For example, you can build SQL queries or call a third-party API using the retrieved products.
function appendProductsToFile($products)
{
// For each product in the array
foreach ($products as $product) {
// We encode it to a JSON string and append it to the file as a single line
file_put_contents("products.jsonl", json_encode($product) . "\n", FILE_APPEND);
}
}
// Here we wrap the SDK method with an exponential backoff
// This is to manage the quota exceeded issue
function listProductsWithBackoff($productsApiInstance, $companyId, $currentPage): Object
{
$backoff = new Backoff(100, 'exponential', 300000, true);
return $backoff->run(function () use ($productsApiInstance, $companyId, $currentPage) {
try {
// The actual SDK method is executed here
$result = $productsApiInstance->listProducts($companyId, null, "detailed", null, $currentPage, 5);
} catch (Exception $e) {
var_dump($e);
}
return $result;
});
}
// This is just a mock: this function should contain the code to retrieve the Access Token
function getToken(): String {
return "YOUR_TOKEN"
}
# The following dependencies are required
# pip install backoff
# pip install fattureincloud-python-sdk
import fattureincloud_python_sdk
from fattureincloud_python_sdk.api import products_api
from fattureincloud_python_sdk.exceptions import ApiException
import backoff
# import collections #needed if you are using python > 3.10
# collections.Callable = collections.abc.Callable #needed if you are using python > 3.10
# Here we setup the exponential backoff config
@backoff.on_exception(backoff.expo, ApiException, max_tries=10)
def list_products_with_backoff(products_api_instance, company_id, current_page, per_page):
return products_api_instance.list_products(company_id, page=current_page, per_page=per_page)
# In this function we append the products in the JSON Lines file.
# You can replace this function to perform the operations you need.
# For example, you can build SQL queries or call a third-party API using the retrieved products.
def append_products_to_page(products):
# For each product in the list
for p in products:
f = open("products.jsonl", "a")
# We write the product to the file
f.write(str(p).replace("\n", ""))
f.write("\n")
f.close()
def get_token():
return "YOUR_TOKEN"
def sync_products():
# Here we init the Fatture in Cloud SDK
# The Access Token is retrieved using the "GetToken" method
configuration = fattureincloud_python_sdk.Configuration()
configuration.access_token = get_token()
configuration.retries = 0 # Needed to implement custom backoff
# The ID of the controlled company.
company_id = 2
current_page = 1
per_page = 5
with fattureincloud_python_sdk.ApiClient(configuration) as api_client:
# In this example we're using the Products API
products_api_instance = products_api.ProductsApi(api_client)
# We perform the first request
result = list_products_with_backoff(products_api_instance, company_id, current_page, per_page)
last_page = result.last_page
# We append the products obtained with the first request to the output file
# Data contains an array of products
append_products_to_page(result.data)
# In this example we suppose to export the data to a JSON Lines file.
# First, we cancel the content of the destination file
file = open("products.jsonl","r+")
file.truncate(0)
file.close()
# For the missing pages (we already requested the first one)
for x in range(2, last_page):
# We require the page to the API
result = list_products_with_backoff(products_api_instance, company_id, x, per_page)
# And append all the retrieved products
append_products_to_page(result.data)
# This code should be executed periodically using a cron library or job scheduler.
sync_products()
# The following dependency is required
# gem install fattureincloud_ruby_sdk
require 'fattureincloud_ruby_sdk'
require 'json'
def main()
FattureInCloud_Ruby_Sdk.configure do |config|
# Here we init the Fatture in Cloud SDK
# The Access Token is retrieved using the "get_token" method
config.access_token = get_token()
end
# In this example we're using the Products API
products_api_instance = FattureInCloud_Ruby_Sdk::ProductsAPI.new
retries = 0
max_retries = 20
# This is the ID of the company we're working on
company_id = 2
# Here we define the parameters for the first request.
opts = {
fields: nil,
fieldset: "detailed",
sort: nil,
page: 1, # We're trying to obtain the first page
per_page: 5 # Every page will contain at most 5 products
}
actual_page = 2
result = list_products_with_backoff(company_id, opts, products_api_instance)
last_page = result.last_page
# In this example we suppose to export the data to a JSON Lines file.
# First, we cancel the content of the destination file
File.delete('./products.jsonl') if File.exist?('./products.jsonl')
append_products_to_file(result.data)
while actual_page <= last_page do
opts[:page] = actual_page
res = list_products_with_backoff(company_id, opts, products_api_instance)
append_products_to_file(res.data)
actual_page += 1
end
end
def list_products_with_backoff(company_id, opts, products_api_instance)
retries = 0
begin
puts "attempt: #{retries}\n"
products = products_api_instance.list_products(company_id, opts)
return products
rescue FattureInCloud_Ruby_Sdk::ApiError => e
if retries <= max_retries
retries += 1
sleep 2 ** retries
retry
else
raise "Giving up on the server after #{retries} retries. Got error: #{e.message}"
end
end
end
def append_products_to_file(products)
for product in products
File.write('./products.jsonl', product.to_hash.to_json + "\n", mode: 'a')
end
end
def get_token()
return "YOUR_TOKEN"
end
# This code should be executed periodically using a cron library or job scheduler.
main()
// The following dependency is required
// yarn add @fattureincloud/fattureincloud-ts-sdk
import fs from "fs";
import { Product } from "@fattureincloud/fattureincloud-ts-sdk";
// Here we init the Fatture in Cloud SDK
// The Access Token is retrieved using the "getToken" method
import {
Configuration,
ProductsApi,
} from "@fattureincloud/fattureincloud-ts-sdk";
const apiConfig = new Configuration({
accessToken: getToken(),
});
// In this example we're using the Products API
var productsApiInstance = new ProductsApi(apiConfig);
// This code should be executed periodically using a cron library or job scheduler.
// For example: https://www.npmjs.com/package/node-cron
main()
.then()
.catch((err) => console.error(err));
async function main() {
// In this example we suppose to export the data to a JSON Lines file.
// First, we cancel the content of the destination file
fs.truncate("./products.jsonl", (err) => {
if (err) {
console.error(err);
return;
}
});
// Here we define the parameters for the first request.
let page = 1;
let companyId = 16; // This is the ID of the company we're working on
try {
// We perform the first request
let result = await listProductsWithBackoff(companyId, page);
// We recover the last page index
let lastPage = result["last_page"];
// We write the products of this page to the file
// "data" contains an array of products
await appendProductsToFile(result.data);
// For all the remaining pages (we already have the first one)
for (var i = 2; i <= lastPage; i++) {
// We update the page index
page = i;
// We require the page at the selected index
result = await listProductsWithBackoff(companyId, page);
// And we write the products to the file
await appendProductsToFile(result.data);
}
console.log("products succesfully retrieved and saved in ./products.jsonl");
} catch (e) {
console.log(e);
}
}
// In this function we append the products in the JSON Lines file.
// You can replace this function to perform the operations you need.
// For example, you can build SQL queries or call a third-party API using the retrieved products.
async function appendProductsToFile(products: Array<Product>) {
// For each product in the array
for (var i in products) {
let product = products[i];
// We obtain the related JSON and append it to the file as single line
fs.appendFileSync("./products.jsonl", JSON.stringify(product) + "\n");
}
}
// Here we wrap the SDK method with an exponential backoff
// This is to manage the quota exceeded issue
async function listProductsWithBackoff(companyId: number, page: number) {
var count = 0;
const delay = (retryCount: number) =>
new Promise((resolve) => setTimeout(resolve, 2 ** retryCount * 1000));
const getProd: any = async (retryCount = 0, lastError?: string) => {
if (retryCount > 20) throw new Error(lastError);
try {
console.log("attempt:", count++, "wait:", 2 ** retryCount * 1000);
// The actual SDK method is executed here
return await (
await productsApiInstance.listProducts(
companyId,
undefined,
"detailed",
undefined,
page
)
).data;
} catch (e: any) {
await delay(retryCount);
return getProd(++retryCount, e.message);
}
};
try {
var res = await getProd();
return res;
} catch (e) {
console.log(e);
}
}
// This is just a mock: this function should contain the code to retrieve the Access Token
function getToken() {
return "YOUR_TOKEN";
}