# Resolve snoozed conversations with workflows

> While your users may   change conversation statuses   and use the   snooze status   correctly when awaiting a customers reply you may find a number of your

Source: https://help.kustomer.com/en_us/resolve-snoozed-conversations-with-workflow-r13UnJayj

Last updated: 2026-06-30T16:37:50.965Z

While your users may [**change conversation statuses**](https://help.kustomer.com/en_us/change-conversation-status-HkvUsVS8W) and use the [**snooze status**](https://help.kustomer.com/change-conversation-status-HkvUsVS8W#Snoozing) correctly when awaiting a customer's reply, you may find a number of your snoozed conversations still not receiving a customer response after an extended period of time.

Depending on your team's needs, you may want to send a final outgoing message to these customers, and/or automatically mark these conversations done after a certain time. You can set up Kustomer workflows to automate either or both these processes.

**Who can access this feature?**

**User types**

Admins can access the Workflows page.

  

### In this article:

*   [Prerequisites](#prerequisites)
*   [Create the callable workflow](#create)
*   [Enter the callable workflow JSON code](#json)
    *   [Workflow variation for Gmail integration](#gmail)
    *   [Workflow variation to send a chat message](#chat)
    *   [Workflow variation to send an SMS](#sms)
*   [Create the scheduler workflow](#scheduler)

### Prerequisites

Before following this guide, we recommend that you already be comfortable with the basics of using workflows: [Workflows overview](https://help.kustomer.com/workflows-overview-HJFVTZhzz)

You should also be familiar with creating [callable scheduled workflows](https://help.kustomer.com/scheduled-workflows-H1ydD61hZ), [API keys](https://help.kustomer.com/api-keys-SJs5YTIWX), and adding [workflow variables](https://help.kustomer.com/workflow-variables-rJ2g6DeIV).

### Create the callable workflow

1.  Go to Settings![](https://cdn.kustomerhostedcontent.com/media/570fad9d9001bc1000163b28/efd7549927a36dcf4819ce86f0553c9c.png)and select **Platform > Workflows**.
2.  Select **Add Workflow > Custom Workflow.**
3.  The _New Workflow_ modal will appear. Fill out the **title**. You can leave the **description** field blank because the code snippet below will provide this for you. Toggle **Callable Workflow** on.
4.  Select **Create** to save the workflow.
5.  When the following window appears, select **Cancel** and close it. You'll add the workflow JSON code directly in the next step.

![](https://cdn.kustomerhostedcontent.com/media/570fad9d9001bc1000163b28/73b8955416bd2284e4e5d9be2d9fd553.png)

### Enter the callable workflow JSON code

Use the Workflow Editor to paste in the workflow code supplied below. This JSON code will take care of most of the workflow creation.

**Note:** This workflow uses Kustomer system email (Postmark) to send the final email message. If you are using the [Gmail integration](https://help.kustomer.com/gmail-setup-BJj0xnL4), follow the steps in the next section [Workflow variation for Gmail integration](#gmail).

1.  In the Workflow Editor, use the Workflow Options![](https://cdn.kustomerhostedcontent.com/media/570fad9d9001bc1000163b28/49a025a0049f2c8d0676e1aec6744864.png)to select **Edit Workflow JSON**.![](https://cdn.kustomerhostedcontent.com/media/570fad9d9001bc1000163b28/02c89d262de88bcbdb26c3fd6fbfc2f9.png)
2.  A modal appears where you can edit the code for this workflow directly. **Select** and **delete** all the current JSON code.
3.  Copy the following code block, and paste it into the JSON text field in your Workflow Editor. Then, select **Update** to dismiss the JSON editor and save the changes to the workflow.  
    
    {
      "description": "",
      "name": "send-final-message-and-mark-snoozed-conversation-done",
      "steps": \[
        {
          "transitions": \[
            {
              "target": "cA3N4BBWS",
              "condition": {
                "op": "true",
                "values": \[
                  true
                \]
              }
            }
          \],
          "errorCases": \[\],
          "id": "QoZgm-XHR"
        },
        {
          "transitions": \[
            {
              "target": "N9f5GJx9D",
              "condition": {
                "op": "eq",
                "values": \[
                  "/#steps.mr6a\_zgjB.status",
                  "snoozed"
                \]
              },
              "meta": {
                "name": "Still Snoozed"
              }
            }
          \],
          "errorCases": \[\],
          "id": "cA3N4BBWS"
        },
        {
          "transitions": \[
            {
              "target": "ZApw9lh\_E",
              "condition": {
                "op": "eq",
                "values": \[
                  "/#steps.1.LastMessageIn",
                  "/#steps.mr6a\_zgjB.lastMessageIn.id"
                \]
              },
              "meta": {
                "name": "Customer Last Message is the Same"
              }
            }
          \],
          "errorCases": \[\],
          "id": "N9f5GJx9D"
        },
        {
          "transitions": \[
            {
              "target": "TNb5wj4v2",
              "condition": {
                "op": "and",
                "values": \[
                  {
                    "op": "gt",
                    "values": \[
                      "/#fn:parseInt,steps.ZApw9lh\_E.match",
                      "6"
                    \]
                  },
                  {
                    "op": "neq",
                    "values": \[
                      "/#steps.mr6a\_zgjB.snooze.status",
                      "canceled"
                    \]
                  }
                \]
              },
              "meta": {
                "name": "Conversation Still Snoozed Until Customer Replies"
              }
            }
          \],
          "errorCases": \[\],
          "id": "ZApw9lh\_E",
          "action": "kustomer.regex-match.generic",
          "params": {
            "testString": "{{dateDiff \\"months\\" from=steps.mr6a\_zgjB.snooze.statusAt to=steps.mr6a\_zgjB.snooze.time}}",
            "regex": ".\*"
          },
          "meta": {
            "displayName": "Check Snooze Expiry"
          },
          "appVersion": "kustomer-^1.9.2"
        },
        {
          "transitions": \[
            {
              "target": "01-92dCVs",
              "condition": {
                "op": "true",
                "values": \[
                  true
                \]
              }
            }
          \],
          "errorCases": \[\],
          "id": "TNb5wj4v2"
        },
        {
          "transitions": \[
            {
              "target": "ENfQ9RGA4",
              "condition": {
                "op": "true",
                "values": \[
                  true
                \]
              },
              "meta": {
                "name": "Last Outbound Message is the Same"
              }
            }
          \],
          "errorCases": \[\],
          "id": "01-92dCVs"
        },
        {
          "transitions": \[
            {
              "target": "oYPlEahZh",
              "condition": {
                "op": "exists",
                "values": \[
                  "/#steps.ENfQ9RGA4.id",
                  ""
                \]
              },
              "meta": {
                "name": "Customer Found"
              }
            }
          \],
          "errorCases": \[\],
          "id": "ENfQ9RGA4",
          "action": "kustomer.customer.find",
          "params": {
            "identifier": "/#steps.mr6a\_zgjB.customer"
          },
          "meta": {
            "displayName": "Find Customer ID"
          },
          "appVersion": "kustomer-^1.9.2"
        },
        {
          "transitions": \[
            {
              "target": "\_-MbiSxrg",
              "condition": {
                "op": "exists",
                "values": \[
                  "/#steps.ENfQ9RGA4.emails.0.email",
                  ""
                \]
              },
              "meta": {
                "name": "Customer Has Email Address"
              }
            }
          \],
          "errorCases": \[\],
          "id": "oYPlEahZh"
        },
        {
          "transitions": \[
            {
              "target": "xRzzrUzk\_",
              "condition": {
                "op": "true",
                "values": \[
                  true
                \]
              }
            }
          \],
          "errorCases": \[\],
          "id": "\_-MbiSxrg"
        },
        {
          "transitions": \[
            {
              "target": "pQrO1j0-E",
              "condition": {
                "op": "true",
                "values": \[
                  true
                \]
              }
            }
          \],
          "errorCases": \[\],
          "id": "xRzzrUzk\_",
          "action": "kustomer.app.postmark.message.send",
          "params": {
            "customer": "/#steps.ENfQ9RGA4.id",
            "conversation": "/#steps.mr6a\_zgjB.id",
            "from": "your@emailaddress.here",
            "to": \[
              "/#steps.ENfQ9RGA4.emails.0.email"
            \]
          },
          "appVersion": "postmark-^1.1.11",
          "meta": {
            "displayName": "Send Message"
          }
        },
        {
          "transitions": \[\],
          "errorCases": \[\],
          "id": "pQrO1j0-E",
          "action": "kustomer.conversation.update",
          "params": {
            "id": "/#steps.mr6a\_zgjB.id",
            "status": "done"
          },
          "appVersion": "kustomer-^1.9.2",
          "meta": {
            "displayName": "Mark Conversation Done"
          }
        },
        {
          "transitions": \[
            {
              "target": "QoZgm-XHR",
              "condition": {
                "op": "exists",
                "values": \[
                  "/#steps.mr6a\_zgjB.id",
                  ""
                \]
              },
              "meta": {
                "name": "Conversation Found"
              }
            }
          \],
          "errorCases": \[\],
          "id": "mr6a\_zgjB",
          "action": "kustomer.conversation.find-by-id",
          "params": {
            "id": "/#steps.1.ConversationId"
          },
          "meta": {
            "displayName": "Find Conversation ID"
          },
          "appVersion": "kustomer-^1.9.2"
        }
      \],
      "trigger": {
        "transitions": \[
          {
            "target": "mr6a\_zgjB",
            "condition": {
              "op": "true",
              "values": \[
                true
              \]
            }
          }
        \],
        "id": "1",
        "callable": true,
        "schema": {
          "properties": {
            "ConversationId": {
              "type": "string"
            },
            "LastMessageIn": {
              "type": "string"
            }
          },
          "required": \[
            "ConversationId",
            "LastMessageIn"
          \]
        },
        "eventName": "kustomer.workflow.63105cabcee4d3e0d70fb2f0.call"
      }
    }
    
4.  The workflow will look like this:![](https://cdn.kustomerhostedcontent.com/media/570fad9d9001bc1000163b28/52adb534f2b987c21b037ff38f8d1d4b.png)
5.  Update the **Send Message** step in the workflow to add your email address that the final message should send from, as well as the subject, body, and other fields you would like to modify.

![](https://cdn.kustomerhostedcontent.com/media/570fad9d9001bc1000163b28/6cd2397e063caeb16b2f206f07f8ecc3.png)

### Workflow variation for Gmail integration

If using our [Gmail integration](https://help.kustomer.com/gmail-setup-BJj0xnL4), change the **Send Message** step in the workflow to a **Gmail > Send Message** action instead, and update the required and any optional fields. 

Change the workflow step's _Action App_ from _Postmark_ to **_Gmail_.** Update the fields in the modified action step and save the workflow.![](https://cdn.kustomerhostedcontent.com/media/570fad9d9001bc1000163b28/7a8d16753c734411342fe0fb63e98afe.png)

### Workflow variation to send a chat message

Change the workflow step's _Action App_ from _Postmark_ to **_Chat_**. Update the fields in the modified action step and save the workflow.

![](https://cdn.kustomerhostedcontent.com/media/570fad9d9001bc1000163b28/469d78dd80818c24229bb227b5481791.png)

### Workflow variation to send an SMS

To use this variation, the [text message (SMS) channel](https://help.kustomer.com/integrate-sms-rk5kFV2GG) must be set up. Make sure your customers have a number in the **Phone Numbers** field in their profile to send the SMS to.

1.  Change the workflow step's Action App from _Postmark_ to **Kustomer**. Then, select the _Action Event_: **Rest API JSON**.![](https://cdn.kustomerhostedcontent.com/media/570fad9d9001bc1000163b28/d4d5ea84069e2801a100068e4c87460a.png)
2.  In the URI string field, add `https://<your_company>.api.kustomerapp.com/v1/customers/{{steps.ENfQ9RGA4.id}}/drafts`.
3.  Under _Method_, use `POST`.![](https://cdn.kustomerhostedcontent.com/media/570fad9d9001bc1000163b28/033221e458b19c2815adb359baa62ae5.png)
4.   Add the following code in the **Optional Fields > Data** field. Replace the **body** value with your preferred text, and the **from** value with your company's SMS number.
    
    {
      "body": "your text message",
      "to": "/#steps.ENfQ9RGA4.phones.0.phone",
      "from": "your SMS number",
      "sendAt": "{{{date 'day' count=0}}}",
      "conversation": "/#steps.mr6a\_zgjB.id",
      "channel": "sms"
    }
    
5.  [Create an API key](https://help.kustomer.com/api-keys-SJs5YTIWX) in **Settings![](https://cdn.kustomerhostedcontent.com/media/570fad9d9001bc1000163b28/7350a8e0142a052f8162b88f3b4c4e47.png)** under **Security > API Keys** with the roles **org.permission.draft.create** and **org.user.draft.write**. Copy and save the token for use in the next step.  
    ![](https://cdn.kustomerhostedcontent.com/media/570fad9d9001bc1000163b28/3769615070d80b38273939a3b9727930.png)![](https://cdn.kustomerhostedcontent.com/media/570fad9d9001bc1000163b28/b085ffb9aa8332407dc806dd1ae8e703.png)  
    
6.  Go back to the Workflow Editor, and open the Workflow Options![](https://cdn.kustomerhostedcontent.com/media/570fad9d9001bc1000163b28/b9bc059e3602c1aeddc196bd81e2af2d.png)menu to select **Workflow Variables**. Add the saved token from the API key you created earlier as a workflow variable. Name the workflow variable and add the token in the **Value** field. **Save** and **exit** the workflow editor.  
    ![](https://cdn.kustomerhostedcontent.com/media/570fad9d9001bc1000163b28/85384a84d7fb1548c3ead1334a7dcf13.png)
7.  Select **Step 12: Rest API JSON** of the workflow, and select the key icon![](https://cdn.kustomerhostedcontent.com/media/570fad9d9001bc1000163b28/9ca65bd6bde559df69c50eb7e8ef3518.png)in the **Headers** field to access and copy the workflow variable saved. Add just one space after **Bearer** in the **Headers** field and paste the copied API token.
8.  Finally, set the JSON (boolean) field to `true`. The SMS action step is now complete and should look like below.![](https://cdn.kustomerhostedcontent.com/media/570fad9d9001bc1000163b28/a4b59e80f3755f95a785c878ff749600.png)
9.  **Save** all the changes and **activate** the workflow to send the SMS to customers and mark the conversation done.

7\. **Save** all the changes and **activate** the workflow to send the SMS to customers and mark the conversation done.

### Create the scheduler workflow

It's now time to create the scheduler workflow to trigger your completed callable workflow based on specific conditions.

1.  Go to **Settings** ![](https://cdn.kustomerhostedcontent.com/media/570fad9d9001bc1000163b28/28c549056a52991e28e6d3559208e61c.png)and select **Platform > Workflows**.
2.  Select **Add Workflow > Custom Workflow.**
3.  Fill out the **Workflow Title**. You can leave the **Description** field blank because the code snippet below will provide this for you.
4.  Select **Create** to save the workflow.
5.  In the Workflow Editor, use the **Workflow Options ![](https://cdn.kustomerhostedcontent.com/media/570fad9d9001bc1000163b28/47b3b22beff23e4ae4c01d966e67cd15.png)** menu to select **Edit Workflow JSON**.![](https://cdn.kustomerhostedcontent.com/media/570fad9d9001bc1000163b28/2438864fdf2da16f9f53b08a047d7049.png)
6.  A modal appears where you can edit the code for this workflow directly. **Select** and **delete** all the current JSON code.
7.  Copy the following code block, and paste it into the JSON text field in your Workflow Editor. Then, select **Update** to dismiss the JSON editor and save the changes to the workflow.
    
    {
      "description": "Schedules snoozed conversations to be updated and marked done if not updated after a specific time.",
      "name": "scheduler-for-snoozed-conversations",
      "steps": \[
        {
          "transitions": \[
            {
              "target": "O21wMsmRa",
              "condition": {
                "op": "and",
                "values": \[
                  {
                    "op": "gt",
                    "values": \[
                      "/#fn:parseInt,steps.rKSS-fxFU.match",
                      "6"
                    \]
                  },
                  {
                    "op": "neq",
                    "values": \[
                      "/#steps.1.snooze.status",
                      "canceled"
                    \]
                  }
                \]
              },
              "meta": {
                "name": "Conversation is Snoozed Until Customer Replies"
              }
            }
          \],
          "errorCases": \[\],
          "id": "rKSS-fxFU",
          "action": "kustomer.regex-match.generic",
          "params": {
            "testString": "{{dateDiff \\"months\\" from=steps.1.changes.attributes.snooze.after.statusAt to=steps.1.changes.attributes.snooze.after.time}}",
            "regex": ".\*"
          },
          "meta": {
            "displayName": "Check Snooze Expiry"
          },
          "appVersion": "kustomer-^1.9.2"
        },
        {
          "transitions": \[
            {
              "target": "w3fWxkb6c",
              "condition": {
                "op": "exists",
                "values": \[
                  "/#steps.O21wMsmRa.id",
                  ""
                \]
              },
              "meta": {
                "name": "Found Conversation"
              }
            }
          \],
          "errorCases": \[\],
          "id": "O21wMsmRa",
          "action": "kustomer.conversation.find-by-id",
          "params": {
            "id": "/#steps.1.id"
          },
          "meta": {
            "displayName": "Find Conversation ID"
          },
          "appVersion": "kustomer-^1.9.2"
        },
        {
          "transitions": \[
            {
              "target": "fCxXAcItt",
              "condition": {
                "op": "exists",
                "values": \[
                  "/#steps.w3fWxkb6c.id",
                  ""
                \]
              },
              "meta": {
                "name": "Last Inbound Customer Message Found"
              }
            }
          \],
          "errorCases": \[\],
          "id": "w3fWxkb6c",
          "action": "kustomer.message.find-by-id",
          "params": {
            "id": "/#steps.O21wMsmRa.lastMessageIn.id"
          },
          "meta": {
            "displayName": "Find Last Customer Message"
          },
          "appVersion": "kustomer-^1.9.2"
        },
        {
          "transitions": \[\],
          "errorCases": \[\],
          "id": "fCxXAcItt",
          "action": "kustomer.app.scheduler.schedule-workflow",
          "params": {
            "runAt": {
              "value": 86400,
              "type": "relative"
            }
          },
          "appVersion": "scheduler-^1.0.1"
        }
      \],
      "trigger": {
        "transitions": \[
          {
            "target": "rKSS-fxFU",
            "condition": {
              "op": "and",
              "values": \[
                {
                  "op": "eq",
                  "values": \[
                    "/#steps.1.changes.attributes.status.after",
                    "snoozed"
                  \]
                },
                {
                  "op": "eq",
                  "values": \[
                    "/#steps.1.changes.attributes.snooze.after.status",
                    "scheduled"
                  \]
                },
                {
                  "op": "neq",
                  "values": \[
                    "/#steps.1.changes.attributes.snooze.before.status",
                    "scheduled"
                  \]
                },
                {
                  "op": "neq",
                  "values": \[
                    "/#steps.1.changes.attributes.status.before",
                    "snoozed"
                  \]
                }
              \]
            },
            "meta": {
              "name": "Conversation is Snoozed"
            }
          }
        \],
        "eventName": "kustomer.conversation.update",
        "id": "1",
        "appVersion": "kustomer-^1.9.2",
        "meta": {
          "displayName": "Conversation is Updated"
        }
      }
    }
    
8.  The workflow will look like this:  
    ![](https://cdn.kustomerhostedcontent.com/media/570fad9d9001bc1000163b28/427de295abd21c26dc0bf9887ef051a2.png)  
    
9.  Update **Step 5: Schedule a Workflow** by selecting the callable workflow you created earlier in the **Workflow Title** field.
10.  Under _Type_, select **Set a Relative Time** and select the time period within which you would like the callable workflow to run.
11.  Add the **Required Fields**, which are the parameters that your callable workflow needs before it can perform its action steps.![](https://cdn.kustomerhostedcontent.com/media/570fad9d9001bc1000163b28/0e42b5790d3b1d83d2212eb2785ab1a4.png)
12.  Add any other desired customizations to the workflow before saving all changes.

You are now ready to activate both **Scheduler** and **Callable** workflows to process your snoozed conversations awaiting customer reply.

### **Send timed reminders before auto-closing**

To send follow-up reminder messages at intervals (for example, Day 7, 14, and 21) before auto-closing a snoozed conversation on Day 30, use multiple callable workflows:

1.  ****Trigger workflow:**** Create a workflow triggered by a tag application (for example, "Awaiting Response"). This workflow calls the first reminder workflow.
2.  ****Reminder workflows:**** Create separate callable workflows for each reminder interval. Each workflow waits for the specified number of days, checks whether the conversation is still snoozed, sends a follow-up message if it is, and then calls the next reminder workflow.
3.  ****Auto-close workflow:**** The final callable workflow waits for the last interval, checks whether the conversation is still snoozed, and marks it as ****Done**** if no response was received.

This architecture requires one trigger workflow plus one callable workflow for each reminder interval and the final auto-close step.

### **Auto-close conversations snoozed for a specific duration**

To set up an action that triggers when a conversation has been snoozed for a specific duration (for example, 30 days), use a custom date/time attribute with a workflow:

1.  Create a custom date/time attribute on the Conversation Klass to store the snooze start date.
2.  Build a workflow that populates this attribute when a conversation is snoozed.
3.  Create a second workflow or business rule that checks for conversations where the snooze start date is older than your threshold (for example, 30 days) and marks them as done.

Business rules do not have a built-in "snoozed for X days" trigger. The custom attribute approach provides a workaround for time-based snooze conditions.
