Using Sheetlabs with Braze
Braze is a popular online customer engagement platform, commonly used to facilitate in-app notifications and automated emails to customers. A number of Sheetlabs customers use Sheetlabs in conjunction with Braze, in order to deliver functionality that is not available in Braze alone.
In order to help future Braze users, we will describe on this page some of the common use cases that customers are using Sheetlabs and Braze together for, and how they are achieving them.
Video tutorial
The video below demonstrates how Sheetlabs can be used to connect Google Sheets with Braze. With this approach, you can use a Google Sheet as a simple content management system for Braze.
Use case - translations
Braze provides a templating system that is used to generate the notifications it sends. Users can create their own templates, and specify placeholders in which customer information will be substituted. This is done using Liquid, originally created by Shopify.
However, this templating system is quite limited. For example, it is not possible to have a single template that is translated into multiple languages. Instead, you have to create one template per language. This is tiresome and error-prone.
Braze's templating system also provides some functionality called Connected Content. This allows you to pull content from an external API, and then use parts of the response whilst generating the notification to send to the customer.
This is where Sheetlabs comes in. Sheetlabs can provide this external API, sourced from either Excel spreadsheets or Google Sheets. This can be used to provide the translations.
Putting this all together:
- A user will create a Google Sheet of translations, with language as the first column, and subsequent columns containing the translation keys and values.
- They will then turn this Google Sheet into a Sheetlabs API. So you might be able to query it with something like
https://sheetlabs.com/ACME/email1_translations?country=IT
- In Braze, they will then create their template that will firstly make a Connected API call to Sheetlabs, store the result in a variable, and then use these results. An example is below.
{% connected_content https://sheetlabs.com/ACME/email1_translations?country={{${country}}} :save translations %}
{{translations[0].greeting}} {{${first_name}}},
{{translations[0].message_body}}
Use case - custom attributes
Braze also lets you store something called Custom attributes against your users. These can then be used in your Liquid templates. However, there is a limit on the number of Custom Attributes you can store. Some enterprising Braze customers have used Sheetlabs to get around such limits.
In this case, you would create a Sheetlabs API that is searchable by user ID (the same ID that Braze uses to identify customers) and returns all of the additional attributes you want. Then, in your Liquid template, you would make a Connected Content API call to the Sheetlabs API to retrieve the customer's additional information. You can then extract this and use it in your Liquid template.
For example:
{% connected_content https://sheetlabs.com/ACME/extended_user_info?userid={{${user_id}}} :save userinfo %}
Dear {{${first_name}}},
Your front door colour is {{userinfo[0].front_door_colour}}
Thanks!
Best practices when using Braze with Sheetlabs
Caching
Braze will cache Connected Content API calls for 5 minutes by default. This is very useful if your template makes use of the same Connected Content API calls repeatedly, with the same parameters. This prevents very large numbers of requests hitting the Sheetlabs backend (Sheetlabs charges based upon usage). The translations use case above would be a good example of where caching is effective.
However, some Connected Content API calls will use the user ID as a parameter (as in the custom attributes use case discussed above). This makes the caching ineffective, as every request is for something different.
There is a potential solution here though. Braze allows you to request and cache up to 1MB of data per request. So, if you can fit all of your customer's data inside 1MB, then you can make a single request to Sheetlabs, and then loop over it inside Liquid to find the appropriate user.
For example:
{% connected_content https://sheetlabs.com/ACME/braze_records :save records :cache_max_age 1200 %}
{%- for record in records -%}
{% if record.externalid == {{${user_id}}} %}
{
"car_make": record.car_make,
"car_model": record.car_model,
"recipients": [ {
"external_user_id": "{{${user_id}}}"
} ]
}
{% endif %}
{%- endfor -%}
If your data does not quite fit inside 1MB, then you can make multiple requests to Sheetlabs for a subset of records, taking care to ensure that the response size for each is under 1MB. You can use the _limit
and _offset
options in the API requests to effectively page through the API results. For example:
{% connected_content https://sheetlabs.com/ACME/braze_records?_limit=10000&_offset=0 :save records1 :cache_max_age 1200 %}
{% connected_content https://sheetlabs.com/ACME/braze_records?_limit=10000&_offset=10000 :save records2 :cache_max_age 1200 %}
{%- for record in records1 -%}
{% if record.externalid == {{${user_id}}} %}
{
"car_make": record.car_make,
"car_model": record.car_model,
"recipients": [ {
"external_user_id": "{{${user_id}}}"
} ]
}
{% endif %}
{%- endfor -%}
{%- for record in records2 -%}
{% if record.externalid == {{${user_id}}} %}
{
"car_make": record.car_make,
"car_model": record.car_model,
"recipients": [ {
"external_user_id": "{{${user_id}}}"
} ]
}
{% endif %}
{%- endfor -%}
Rate limits
Sheetlabs accounts have a default rate limit of 50 requests per second. Beyond this point, you will start to get HTTP 429 (Too Many Requests) responses until you reduce your volume. The rate limit can be raised for Enterprise customers.
You can configure Braze to respect the rate limit of Sheetlabs. See the Braze rate limits documentation for more details.
URL encoding
It is important to ensure that you are URL encoding your request parameters before sending them to Sheetlabs. Braze does not do this by default. See Braze's documentation for more details.
For example:
{% connected_content https://sheetlabs.com/ACME/citydata?city_name={{${city} || url_encode}} :save records1 %}