# Create images from catalog

## Objetive

The objetive of this tutorial will be to generate nice images that can used as ads in any platform from a list of movies in csv format. In our file we have one line per movie with information like this:&#x20;

| Title | Genre           | Director   | Actors          | Year | Rating | metascore | Description    |
| ----- | --------------- | ---------- | --------------- | ---- | ------ | --------- | -------------- |
| Split | Horror,Thriller | M. Night.. | James McAvoy... | 2016 | 7.3    | 62        | Three girls... |

And we will create images like this one:

![Banner image generated using the API](https://183518148-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MT4xzv1KpJ-qdTnNbSz%2F-MUn0LaxvugVSZbgbm8a%2F-MUr4goGje7ZiTb2ihcY%2Fbase.png?alt=media\&token=9d3fbda1-5176-43b1-b16f-e321eb3aba8f)

## Selecting a template

In order to use the API we need to select a template or create a new one, for this demo we are going to use the template named ***review*** that is available to all users. To select another template enter in the editor and go to the library, there you can see a list of pre made templates.

{% hint style="info" %}
The template id can be found in the sidebar when a template is opened
{% endhint %}

## Nodejs program

For this tutorial we are going to use [nodejs](https://nodejs.org/en/) with the libraries [axios](https://www.npmjs.com/package/axios) to make http requests and [csv-parse](https://www.npmjs.com/package/csv-parse) to parse our source of data.

### Configuration

Our first step will be to set up axios to use our API token, as well as having some parameters that we will use later in our script.

```javascript
// Adrapid API base url
const adrapidBaseUrl = 'https://api.adrapid.com';

// Adrapid template id to be used for banner creation.
const templateId = 'b75e7999-8ac8-4a00-8781-eaef565f1f23';

// User API token, can be found in account page
const token = 'YOUR_USER_TOKEN';

// delay between checks for banner status changes
const pollingDelay = 300;

// amount of banners to create
const bannersCount = 10;

// Modes to create banners, valid modes are html5, png, jpeg, webp and video
const modes = {
  png: true
}

// Add authentication to axios requests
axios.defaults.headers.common = { 'Authorization': `Bearer ${token}` }
```

* **templateId** we are going to use the template named review, it is a public template that can be used by anyone. It can be changed to any public template or you can create a new one from scratch.
* **token:** Your API token that can be found under your account detail&#x73;**.**
* **pollingDelay**: Delay between requests to check for banner changes.
* **bannersCount**: Amount of banners to create.
* **modes:** Modes to create the banners. Valid modes are html5, png, jpeg, webp and video. More information can be found in the API [documentation](https://user-api-docs.adrapid.com/)
* **axios.defaults.headers.common:** We add authentication to all axios request&#x73;**.**

### Create banners

For banner creation were are going to create a function that with a templateId, modes and movie parameter will request a template creation.

```javascript
const createBanners = ({ templateId, modes, movie }) => {
  const overrides = {
    Title_text_1: {
      text: movie.Title
    },
    Subtitle_text_1: {
      text: `${movie["Runtime (Minutes)"]} min | ${movie.Genre}`
    },
    // Custom image url can be used
    Body_img_1: {
      //url: "IMG_URL"
    },
    Body_text_1: {
      text: movie.Description
    },
    Button_text_1: {
      text: movie.Metascore
    },
    Body_text_2: {
      text: `Director: ${movie.Director} | Stars: ${movie.Actors}`
    },
    Button_text_2: {
      text: movie.Rating
    }
  }
  return axios.post(`${adrapidBaseUrl}/banners`, {
    sizeIds: 'all',
    overrides,
    templateId,
    modes,
  }).then(response => response.data);
}
```

The API parameters that we are going to use are:

* **sizeIds: 'all':** The template that we are using includes 3 different sizes (980x300, 320x320 and 160x600) to use all of them we set this parameter to 'all'. If we remove this parameter only the default size will be used.
* **overrides**: With this parameter we override the default template content. We use the name of the item we want to override, valid properties are text, url (for external images) and css.
* **templateId**: Id of the template we want to use, previously set on configuration block.
* **modes:** Modes for the resulting banners, previously set on configuration block.

Complete information of all the parameters can be found [here](https://user-api-docs.adrapid.com/#/banners/post_banners). The response of this request will be a banner object.

### Check banner status

Banner creation is a async operation, for that reason we need to do a polling to check when a banner is ready. With the following function we will make requests until the banner is ready.&#x20;

```javascript
const checkBannerReady = id => {
  return axios.get(`${adrapidBaseUrl}/banners/${id}`).then(response => {
    const banner = response.data;
    if (banner.status == 'ready') return banner;
    if (banner.status == 'failed') { throw new Error('Banner creation failed') };
    return new Promise(resolve => {
      setTimeout(() => {
        resolve(checkBannerReady(id));
      }, pollingDelay);
    });
  });
}
```

Then to wait for a list of banners to be ready we use the follow function:

```javascript
const checkBannersReady = async banners => {
  const readyBanners = [];
  for (const banner of banners) {
    const readyBanner = await checkBannerReady(banner.id);
    readyBanners.push(readyBanner);
  }
  return readyBanners;
};
```

### Start the program

Now that we all the different parts we just need to call our creation function together with our check for banner ready:

```javascript
const creatingBanners = moviesList.get({ limit: bannersCount }).map(movie => createBanners({ movie, templateId, modes }));
Promise.all(creatingBanners).then(banners => {
  console.log('Banner jobs started');
  return checkBannersReady(banners);
}).then(readyBanners => {
    for (const banner of readyBanners) {
    console.log(`banner ${banner.name} ready. Files:`);
    for (const bannerFile of banner.files) {
      console.log({
        name: bannerFile.name,
        type: bannerFile.type,
        size: bannerFile.size,
        url: bannerFile.url,
        width: bannerFile.width,
        height: bannerFile.height
      })
    }
  }
});
```

This will print in the console something like:

```javascript
{
  name: 'base.png',
  type: 'png',
  size: 68314,
  url: 'YOUR_BANNER_URL',
  width: 980,
  height: 300
}
...
{
  name: '160x600.png',
  type: 'png',
  size: 28738,
  url: 'YOUR_BANNER_URL',
  width: 160,
  height: 600
}
```

In url you can find our resulting banner.

### Complete project source code

Full source code example can be found [here](https://github.com/Raviteq/user-api-examples):
