> ## Knowledge Base Index
> Fetch the complete knowledge base index at: https://support.teeinblue.com/sitemap.xml
> Use this file to discover available pages before exploring further.
> Pure-Markdown content can be obtained by appending a '.md' suffix to the content URLs listed in the sitemap (without the trailing slash).

# Digital Download - Using Make (formerly Integromat)


If you're planning to sell **digital download** (which means sending order designs for customers to download), you can use 3rd-party software to read Shopify orders and send the Teeinblue's design to customers automatically.

Basically, this is how it works:
* When an order is created, Teeinblue adds ++the URL of order design to the&#160;**Line item properties**&#160;of each order item++ in Shopify Orders (make sure you've selected the "Line item property" option in Teeinblue's General settings > Add order design URL to Shopify Orders).
* A 3rd-party software will read the latest Shopify Orders and take the order design in the Line item properties to send to your customers' emails automatically.

![](https://storage.crisp.chat/users/helpdesk/website/6085dc2a7293d800/image_1vs31mn.png)

|| Teeinblue's design URL is available instantly, but the image in that URL might need 1 - 5 minutes to be generated.

Therefore, to make sure the design is ready to be sent to your customers, you should:
* Add a delay for your 3rd-party tool to read the order a few minutes after it's created.
* Or use the action "Mark as fulfilled" to trigger the 3rd-party tool.
---

In this article, we'll help you guys setup ++ [Make](https://www.make.com/en/register?pc=teeinblue) (formerly Integromat) ** ++ to do that.
This software helps you create automation flow between multiple platforms. It offers Free plan for you to get started, you can check out [make.com](https://www.make.com/en/register?pc=teeinblue) website and register.

Before getting started, make sure you've [created a Make account](https://www.make.com/en/register?pc=teeinblue).

# STEP 1. Create a new scenario

* After registering, go to your account and click on **`Scenarios`** page.
* Click on **`Create scenario`** button.

![Create a new scenario](https://storage.crisp.chat/users/helpdesk/website/-/6/0/8/5/6085dc2a7293d800/step1_1y5dm5j.png)
---

# STEP 2. Configure "Shopify" module to get orders from Shopify

## 2.1. Add the "Shopify" module

* Click on + button ➝ search and click to add `Shopify` module.
* Choose **`Watch orders`** option.

![Add Shopify module](https://storage.crisp.chat/users/helpdesk/website/-/6/0/8/5/6085dc2a7293d800/step2_nno9ul.png)

## 2.2. Create a new Shopify connection
**You might skip this step if you've already connected.*

![](https://storage.crisp.chat/users/helpdesk/website/6085dc2a7293d800/image_1pptbhh.png)

* Click **`Add`** and enter your Shopify domain to connect with your Shopify account. You will need to install Make app to your Shopify store (For more instruction of this step, please follow this Make instruction: [link](https://www.make.com/en/help/app/shopify)).
* To ensure Make can retrieve hidden properties (like the **`_tib_design_link`**), your connection must have the correct permissions. 
|| **Important:** When authorizing, ensure you grant all permissions, especially the read orders scopes. If your standard connection throws an ${color}[#ff0000](ACCESS_DENIED) error later, you must create a `Custom App` in your Shopify Admin (Apps > App and sales channel settings  > Develop apps), grant it the read orders scope, and use its `Admin API Access Token` to connect. (For more instruction of this step, please follow this Make instruction: [link](https://www.make.com/en/help/app/shopify))

* **Connection**: select the Shopify connection you've just created in step 2.2. 
* **Limit**: based on your demands (it's the maximum number of orders enter this scenario at a time)
---

# STEP 3. Fetch Item Properties via GraphQL API
Shopify hides certain properties (like **`_tib_design_link`***`*) from standard webhooks. We need to actively request them.

1. Add another Shopify module right after **`Watch Orders`**
2. Choose the **`Make a GraphQL API call`**
![](https://storage.crisp.chat/users/helpdesk/website/-/6/0/8/5/6085dc2a7293d800/step3_1lirol6.png)

3. **Connection**: Select the exact same connection you used in Step 2. 
4. **Query**: Copy and paste the code below into the `Query` field:
```
query getTeeinblueProperties($id: ID!) {
  order(id: $id) {
    name
    displayFinancialStatus
    displayFulfillmentStatus
    lineItems(first: 10) {
      edges {
        node {
          name
          variant {
            title
          }
          customAttributes {
            key
            value
          }
        }
      }
    }
  }
}
```
![](https://storage.crisp.chat/users/helpdesk/website/-/6/0/8/5/6085dc2a7293d800/step3-1_3sqvn6.png)

4. Click **`Advanced settings`**, scroll down to **`Variables`**
5. Variables input format: Choose **`Array (Simple)`**
6. Click **`Add variable`**  
* Key: **`id`** 
* Value: click and map the **`ID`** (the Order ID looking like gid://...) from the previous **`Shopify (1) - Watch orders`** module.
![](https://storage.crisp.chat/users/helpdesk/website/-/6/0/8/5/6085dc2a7293d800/step3-2_14r8qmp.png)

# STEP 4. Run the scenario once & Set up a Filter

|| Crucial Step: Run the scenario once to load the data structure! Before setting up the filters or iterators in the next steps, Make.com needs to "see" a sample order to understand the GraphQL data structure. Here is how to fetch a past order for testing:

## 4.1. Run the scenario once

1. Right-click on the **`Shopify - Watch orders`** module and select **`Choose where to start`**
![](https://storage.crisp.chat/users/helpdesk/website/-/6/0/8/5/6085dc2a7293d800/step4_c6cw33.png)

2. Choose **`Choose manually`** to pick a specific recent order) and click **`Save`**.
![](https://storage.crisp.chat/users/helpdesk/website/-/6/0/8/5/6085dc2a7293d800/step4-3_1jnyb8v.png)

3. Temporarily close any settings panel and click the **`Run once`** button at the bottom left.  (Note: If Make.com shows a warning pop-up saying "You're not using the data generated by this module", simply click **`Run anyway`** ).
4. Wait for the modules to turn green. Now, Make.com has successfully fetched an old order, and all the hidden variables will be visible for you to select in the next steps! 

![](https://storage.crisp.chat/users/helpdesk/website/-/6/0/8/5/6085dc2a7293d800/step4-4_lqs6hg.png)

|| **Important:** After you finish setting up the entire scenario in Step 10, remember to right-click the Watch Orders module again, select **"Choose where to start"**, and change it back to **"From now on"** before turning the scenario ON. This prevents sending emails to old orders! 
|| ![](https://storage.crisp.chat/users/helpdesk/website/-/6/0/8/5/6085dc2a7293d800/step4-5_1mpjjhw.png)

## 4.2. Setup a Filter

###### Add the first "Iterator" module
1. Click on **Flow Control** (under Tools) ➝ choose **Iterator** module to add it to the scenario. It'll show as "Iterator (2)".
![Add "Iterator" module](https://storage.crisp.chat/users/helpdesk/website/-/6/0/8/5/6085dc2a7293d800/step5-1_hu865q.png)
2. Link the `Iterator` to the `Shopify - Make a GraphQL API call` module
Now, click the wrench icon on the dotted line right after the **GraphQL module** ➝ **Set up a filter**. Follow one of these two cases:

![](https://storage.crisp.chat/users/helpdesk/website/-/6/0/8/5/6085dc2a7293d800/step5-2_rwz9v4.png)

###### Follow one of these two cases:

###### ++ Case 1: Trigger when a new order is created: ++  all new orders will automatically enter the flow to send an email.
With this way, all steps are automatic so you don't have to do anything, but you won't have a chance to review the orders.
* **Condition 1:** Expand the **`Body`** folder -> **`data`** -> **`order`** from the GraphQL module, and select **`displayFinancialStatus`**. 
* Text operators: **`Equal to (case insensitive)`** 
* Type: **`PAID`**
![](https://storage.crisp.chat/users/helpdesk/website/-/6/0/8/5/6085dc2a7293d800/step5-3_16phypw.png)

###### ++ Case 2: Trigger when an order is fulfilled: ++  mark orders as fulfilled to make them enter the flow.
With this way, you can review the orders, but you will have to manually mark an order as **`FULFILLED`** in order to send an email.
1. **Condition 1:** 
* Expand the **`Body`** folder -> **`data`** -> **`order`** from the GraphQL module, and select **`displayFinancialStatus`**. 
* Text operators: **`Equal to (case insensitive)`** 
* Value: **`PAID`**. 

Click **`Add AND rule`** 

2. **Condition 2:** 
* Expand the **`Body`** folder -> **`data`** -> **`order`** from the GraphQL module, and select **`displayFulfillmentStatus`**. 
* Text operators: **`Equal to (case insensitive)`** 
* Value: **`FULFILLED`**. 

![](https://storage.crisp.chat/users/helpdesk/website/-/6/0/8/5/6085dc2a7293d800/step5-4_o77k5i.png)
# STEP 5. Extract orders with "Iterator" module

## 5.1. Set up the "Iterator":

* Click on the **`Array`** field ➝ map the following path from the GraphQL module: `Body` -> `data` -> `order` -> `lineItems[]` 
This will help get a list of each line items in Shopify Order.

![](https://storage.crisp.chat/users/helpdesk/website/-/6/0/8/5/6085dc2a7293d800/step6-1_1nacg4z.png)


## 5.2. Add & set up the second "Iterator" module ("Iterator (4)"):

* Add a new **`Iterator`** module, it'll show as **`Iterator (4)`**, and link it to the **`Iterator (3)`**.
* In the **Array** field ➝ click to add the **`customAttributes[]`** from **`Flow control (2) - Iterator`**
|| Purpose: `Iterator (4)` will loop through the specific customization properties of the product that **`Iterator (3)`** is currently processing).


![](https://storage.crisp.chat/users/helpdesk/website/-/6/0/8/5/6085dc2a7293d800/step5-22_1u97a2o.png)

![](https://storage.crisp.chat/users/helpdesk/website/-/6/0/8/5/6085dc2a7293d800/step5-222_1pierbc.png)

---

# (optional) STEP 6. Filter "Digital download" orders
*Skip this step if all of your Teeinblue orders are for digital downloads.*

## 6.1. Add an additional option in Teeinblue

* In your artworks, add an **`Additional Option`** for customers to choose **`Yes`** or **`No`** for **`Digital download`**. You can also use **`Addon Charge`** to charge extra for the digital version.

![Add an option for customers to choose Digital download](https://storage.crisp.chat/users/helpdesk/website/6085dc2a7293d800/image_1hg13z0.png)

* Must enable the **`Show customization data on cart/checkout`** to add the customers' selection to Line item property.

![Add customer's selection for Digital download to Line item property](https://storage.crisp.chat/users/helpdesk/website/6085dc2a7293d800/image_zyk5rn.png)

## 6.2. Add a filter between "Iterator (3)" & "Iterator (4)" to only process order items having "Digital download" = "yes":

* Click on the wrench icon between the 2 modules ➝ Set up a filter
|| IMPORTANT: When copy-pasting the codes below, the variables like `3.customAttributes` might appear as plain black text. Make.com will NOT recognize this! You must delete the black text and click to map the corresponding green variable directly from the Iterator panel.

1. **Condition 1 (Check the Key):**
* In the first empty field, manually type: **`{{join(map(`** then click to select the **`customAttributes[]`** array from **`Iterator (3)`**. Continue typing: **`; "key"); ", ")}}`**
* The final format should look exactly like this: **`{{join(map(3.customAttributes; "key"); ", ")}}`**
* **Text operators:** Select **`Contains (case insensitive)`**
* **Value:** type **`digital`**

Click **`Add AND rule`**

2. **Condition 2 (Check the Value):**
* In the first empty field, manually type: **`{{join(map(`** then click to select the **`customAttributes[]`** array from **`Iterator (3)`**. Continue typing: **`; "value"); ", ")}}`**
* The final format should look exactly like this: **`{{join(map(3.customAttributes; "value"); ", ")}}`**
* **Text operators:** Select **`Contains (case insensitive)`**
* **Value:** type **`yes`**

![Add a filter to only process orders with "Digital" = "Yes"](https://storage.crisp.chat/users/helpdesk/website/-/6/0/8/5/6085dc2a7293d800/step6-2_c4ho31.png)
|| Logic: Make will check if the product currently in `Iterator (3)` is a digital product. If true, it allows the process to move to `Iterator (4)` to extract ALL properties, including the images
---
# STEP 7. Get Teeinblue's design URL & Merge data

## 7.1. Add a "Text aggregator" module

* Click on **`Tools`** (under Tools, next to Flow control) ➝ choose **`Text aggregator`** module to add it.

![Add Tools > Text aggregator](https://storage.crisp.chat/users/helpdesk/website/-/6/0/8/5/6085dc2a7293d800/step7-1_uyj0yz.png)
* Link it with the **`Iterator (4)`**

## 7.2. Add a filter between "Text aggregator" & "Iterator (4)" to get the correct URL

* Click on the wrench icon between the 2 modules ➝ Set up a filter ➝ Add a condition
* Condition: choose the **`Key`** from the **`Flow control (4) - Iterator`** 
* Text operators: **`Contains (Case insensitive)`** 
* Value: **`_tib_design_link`**

![](https://storage.crisp.chat/users/helpdesk/website/-/6/0/8/5/6085dc2a7293d800/step7-2_1erkzar.png)

## 7.3. Enter Text aggregator's configuration

* In the `Source module` field, select the Iterator **`Iterator (4)`**
This will help merge the design URLs of the line items from the same order to one email.

* Click on the **Text** field and enter:
```
{{if(contains(4.key; "tib_design_link"); if(contains(4.value; ".pdf"); "<a href='" + 4.value + "'>Click to download design</a><br>"; "<img src='" + 4.value + "' width='500'><br>"); if(contains(4.key; "customization_image"); "<img src='" + 4.value + "' width='500'><br>"; ))}}
```

|| REMINDER: Please remember to replace the black `4.key` and `4.value` texts with the actual green variables from `Iterator (4)` so the system can read your data correctly.

![](https://storage.crisp.chat/users/helpdesk/website/-/6/0/8/5/6085dc2a7293d800/step7-31_cvjs88.png)
###### Logic: 
Make.com will check the property name (`key`). 
* If the property contains `tib_design_link` (like `_tib_design_link_1`) 
* OR `customization_image` (like `_customization_image`), it will automatically wrap the URL (`value`) inside an HTML `<img>` tag to display the image. 
-> The output of this `Text Aggregator` will be a single block containing all formatted image links

|| Note: The width="500" will be the display size of the design image attached in email sent to customers. You can change the 500 (pixel) to the number you want (recommend 200 - 800px). It doesn't affect the original size when customers download the image.


## 7.4. Add a second "Text Aggregator" module (To Merge Products):
This is where you will retrieve the `Product Name`! Drag and drop another `Text Aggregator` module right after the first one.
* **Source Module:** Select **Iterator [3]**.
* **Text:** Copy and paste the snippet below. Replace `[Product name]` by mapping the `name` variable from Iterator (3), and replace `[Text]` by mapping the `text` output variable from the first Text Aggregator.
```
<b>Product:</b>[Product name]<br>
[Test]<br>
```

![Add product name to the text](https://storage.crisp.chat/users/helpdesk/website/-/6/0/8/5/6085dc2a7293d800/step7-41_rq8irp.png)
---

# (optional) STEP 8. Add a delay (only for Case 1 - Trigger when a new order is created)
*Skip this step if following case 2 - Trigger when an order is fulfilled*

Because it'll take a few minutes for Teeinblue's design to be generated, you should add a delay in sending the design URL to your customers to make sure the image is ready when your customers receive the email.

* Click on **`Tools`** ➝ add **`Sleep`** module & connect it with **`Text aggregator`** module.
* Enter the number of seconds you want to delay (**recommend&#32;`60`**).

![](https://storage.crisp.chat/users/helpdesk/website/-/6/0/8/5/6085dc2a7293d800/sleep_o9aiew.png)

| Should not set a long delay because there's a 5-minute limit execution time for an operation in Make.
---

# STEP 9. Filter if no design URL
*Skip this step if all of your Teeinblue orders are for digital downloads.*

Add a filter between the **Tool** & **Sleep** module (or the final **`Email`** module in **Step 10** if you don't use the **`Sleep`** module):

* Click on the wrench icon between the 2 modules ➝ Set up a filter, Add a condition:
* Condition: choose the **`Text`** from the **`Tool`**  module.
* Basic operators: Exists

 ![Filter if designs exist](https://storage.crisp.chat/users/helpdesk/website/-/6/0/8/5/6085dc2a7293d800/step9_pd5gsf.png)
# STEP 10. Set up email

## 10.1. Add an email service module (Email, Gmail, ...)

To send an email to your customers, you'll need a sender email. Depends on the email service of that sender email, choose a module of that email service. In this example, we'll use "Gmail".

* Click on **`Add another module`** ➝ search and add an email service.

* Choose **`Send an email`** option.

* Link it with the previous module (`Sleep` module or `Text aggregator` if you skip step 8).

## 10.2. Create a new Mail connection
**You might skip this step if you've already connected.*

![](https://storage.crisp.chat/users/helpdesk/website/6085dc2a7293d800/image_ye6drh.png)

* Click `Add` ➝ enter a name for the connection ➝ choose your mail account to authorize and connect.
* For more instruction of this step, please follow this Make instruction:
* Mail module: [link](https://www.make.com/en/help/app/email)
* Gmail module: [link](https://www.integromat.com/en/help/app/google-email)

## 10.3. Enter Mail's configuration
* **Connection**: select the **`Email`** connection you've just created.
* **To**: search and select the **`Customer: Email`** from **`Shopify (1) - Watch orders`**

![Add Customer's email to the "To" address](https://storage.crisp.chat/users/helpdesk/website/-/6/0/8/5/6085dc2a7293d800/mail-email_vsx8md.png)

| Tips: you can add your email address to test the scenario.

* **Subject**: enter a subject for the email. Recommend adding the **Order number** from **`Shopify (1) - Watch orders`** so your customers can recognize their order.

![](https://storage.crisp.chat/users/helpdesk/website/-/6/0/8/5/6085dc2a7293d800/email-name_1ewcoh3.png)


* **Content**: type your email content. And **remember** to add the **`Text`** from **`Text aggregator`** -  it's the text you created in step 5, which contains the design URL ("Value").

![Add "Text" from Text aggregator to the Email content](https://storage.crisp.chat/users/helpdesk/website/-/6/0/8/5/6085dc2a7293d800/mail-content_1vjgikw.png)

All done! Then you can enable and schedule for this scenario (In Free plan, the minimum time is 15mins, you can upgrade to a higher plan to shorten this schedule).

Remember: 
* If you follow case 1: all new orders will enter the flow automatically.
* If you follow case 2: you must mark orders as fulfilled to make them enter the flow.

A complete scenario will look like this:

![Complete scenario](https://storage.crisp.chat/users/helpdesk/website/-/6/0/8/5/6085dc2a7293d800/stepfinal_4kvpm9.png)
|| Need a shortcut or still having trouble?  If you are having difficulties setting up the modules manually, please contact our Support Team! We can assist you directly, or we can try importing a pre-built sample blueprint scenario directly into your Make account to help you get started faster.



