HTML Diff
10 added 10 removed
Original 2026-01-01
Modified 2026-03-10
1 - <p>By <a>Mokhsira Kurbonova</a></p>
1 + <p>By<a>Mokhsira Kurbonova</a></p>
2 <p><em>Solution Recipes are tutorials to achieve specific objectives in Klaviyo. They can also help you master Klaviyo, learn new third-party technologies, and come up with creative ideas. They are written mainly for developers &amp; technically-advanced users.</em></p>
2 <p><em>Solution Recipes are tutorials to achieve specific objectives in Klaviyo. They can also help you master Klaviyo, learn new third-party technologies, and come up with creative ideas. They are written mainly for developers &amp; technically-advanced users.</em></p>
3 <p><em>This is a guest post written by Mokhsira Kurbonova, who recently built this as part of Klaviyo’s internal Solution Architect mentorship program.</em></p>
3 <p><em>This is a guest post written by Mokhsira Kurbonova, who recently built this as part of Klaviyo’s internal Solution Architect mentorship program.</em></p>
4 <p>What you’ll learn</p>
4 <p>What you’ll learn</p>
5 <p>How to send a Slack channel message, starting with a trigger word, to Klaviyo as a custom event using Napkin.io. This process involves utilizing the Slack outgoing Webhook integration, creating a function in Napkin, and as an added bonus, configuring your flow in Klaviyo.</p>
5 <p>How to send a Slack channel message, starting with a trigger word, to Klaviyo as a custom event using Napkin.io. This process involves utilizing the Slack outgoing Webhook integration, creating a function in Napkin, and as an added bonus, configuring your flow in Klaviyo.</p>
6 <p>Why it matters</p>
6 <p>Why it matters</p>
7 <p>According to<a>Axioshq</a>, our weekly internal communication typically consumes around 3-10 hours on average. In addition to regular communication, there are critical pieces of information that require dissemination, such as major sales or new VIP clients. To address this, many organizations rely on Slack as their primary internal communication platform. However, important updates often necessitate follow-up emails.Imagine a scenario where you could simply send a message in a Slack channel and automatically trigger an email through Klaviyo. This streamlined approach to internal communication would significantly enhance workflow efficiency and eliminate unnecessary steps.</p>
7 <p>According to<a>Axioshq</a>, our weekly internal communication typically consumes around 3-10 hours on average. In addition to regular communication, there are critical pieces of information that require dissemination, such as major sales or new VIP clients. To address this, many organizations rely on Slack as their primary internal communication platform. However, important updates often necessitate follow-up emails.Imagine a scenario where you could simply send a message in a Slack channel and automatically trigger an email through Klaviyo. This streamlined approach to internal communication would significantly enhance workflow efficiency and eliminate unnecessary steps.</p>
8 <p>Level of sophistication</p>
8 <p>Level of sophistication</p>
9 <p>Moderate</p>
9 <p>Moderate</p>
10 - <p>Introduction</p>
10 + <h2>Introduction</h2>
11 <p>Klaviyo offers immense customization potential. Through its robust<a>API</a>offering, it’s possible to create custom events for any occasion or use case. These events can serve as triggers for automated flows and facilitate email, SMS, and notification automation. In essence, Klaviyo provides limitless possibilities for automating various communication channels.</p>
11 <p>Klaviyo offers immense customization potential. Through its robust<a>API</a>offering, it’s possible to create custom events for any occasion or use case. These events can serve as triggers for automated flows and facilitate email, SMS, and notification automation. In essence, Klaviyo provides limitless possibilities for automating various communication channels.</p>
12 <h2>Challenge</h2>
12 <h2>Challenge</h2>
13 <p>As Slack serves as the primary communication channel for many organizations, important messages often get buried among less relevant ones. It’s important to simplify the process of disseminating information. In this Solution Recipe, we will outline the process of triggering an email to a Klaviyo List when a pre-configured keyword is sent in a Slack channel.</p>
13 <p>As Slack serves as the primary communication channel for many organizations, important messages often get buried among less relevant ones. It’s important to simplify the process of disseminating information. In this Solution Recipe, we will outline the process of triggering an email to a Klaviyo List when a pre-configured keyword is sent in a Slack channel.</p>
14 <h2>Ingredients</h2>
14 <h2>Ingredients</h2>
15 <ul><li><a>Outgoing Webhook Slack App</a></li>
15 <ul><li><a>Outgoing Webhook Slack App</a></li>
16 <li><a>Napkin io</a></li>
16 <li><a>Napkin io</a></li>
17 <li>2 Klaviyo APIs:1.<a>Get list profiles</a>2.<a>Create event (server-side)</a></li>
17 <li>2 Klaviyo APIs:1.<a>Get list profiles</a>2.<a>Create event (server-side)</a></li>
18 </ul><h2>Instructions</h2>
18 </ul><h2>Instructions</h2>
19 <h3>Step 1:</h3>
19 <h3>Step 1:</h3>
20 <p>Napkin.io offers developers a streamlined and secure platform for writing and deploying code, accessible directly from a web browser. Given this functionality, it proves to be highly advantageous for our specific needs:</p>
20 <p>Napkin.io offers developers a streamlined and secure platform for writing and deploying code, accessible directly from a web browser. Given this functionality, it proves to be highly advantageous for our specific needs:</p>
21 <ul><li>Visit<a>Napkin.io</a>, signup and choose from the range of sign-up options provided:</li>
21 <ul><li>Visit<a>Napkin.io</a>, signup and choose from the range of sign-up options provided:</li>
22 </ul><ul><li>In this example, the solution was written in Python. Navigate to the left-hand side and choose the Python option, as illustrated below:</li>
22 </ul><ul><li>In this example, the solution was written in Python. Navigate to the left-hand side and choose the Python option, as illustrated below:</li>
23 </ul><ul><li>After the dashboard has finished loading, copy the public URL displayed at the top of the screen. This URL will be required for the upcoming steps:</li>
23 </ul><ul><li>After the dashboard has finished loading, copy the public URL displayed at the top of the screen. This URL will be required for the upcoming steps:</li>
24 - </ul><h3>Step 2:<strong><em></em></strong></h3>
24 + </ul><h3>Step 2:</h3>
25 - <p>Integrate Slack’s Outgoing Webhook: </p>
25 + <p>Integrate Slack’s Outgoing Webhook:</p>
26 <p>*If you have Slack admin rights, please follow the instructions provided below. For non-admin users, please share this step with your Workspace admin.</p>
26 <p>*If you have Slack admin rights, please follow the instructions provided below. For non-admin users, please share this step with your Workspace admin.</p>
27 <ul><li>You can directly access the Slack integration by following<a>this link</a>. If you have admin rights, you can add Outgoing Webhooks to your Slack Workspace. For non-admin users, you can request configuration assistance using the same<a>link</a>:</li>
27 <ul><li>You can directly access the Slack integration by following<a>this link</a>. If you have admin rights, you can add Outgoing Webhooks to your Slack Workspace. For non-admin users, you can request configuration assistance using the same<a>link</a>:</li>
28 </ul><ul><li>Once you have successfully added the Webhook, you will be prompted to configure the trigger word, select the desired channel, and paste the Napkin URL from<strong>Step 1</strong>as a “URL(s)” (or share the details of configuration with your workspace admin):</li>
28 </ul><ul><li>Once you have successfully added the Webhook, you will be prompted to configure the trigger word, select the desired channel, and paste the Napkin URL from<strong>Step 1</strong>as a “URL(s)” (or share the details of configuration with your workspace admin):</li>
29 </ul><h3>Step 3:</h3>
29 </ul><h3>Step 3:</h3>
30 <p>Good news! We’ve reached the halfway point! All the essential settings for Slack have been successfully configured. Now, let’s shift our attention to Napkin, where we will work on writing the function that will process incoming payload from Slack, subsequently transmitting this data to Klaviyo.</p>
30 <p>Good news! We’ve reached the halfway point! All the essential settings for Slack have been successfully configured. Now, let’s shift our attention to Napkin, where we will work on writing the function that will process incoming payload from Slack, subsequently transmitting this data to Klaviyo.</p>
31 <ul><li>Return to your function in Napkin, and before we proceed, let’s begin by importing the necessary libraries for our code:</li>
31 <ul><li>Return to your function in Napkin, and before we proceed, let’s begin by importing the necessary libraries for our code:</li>
32 </ul>import requests import urllib.parse import json from datetime import datetime from napkin import request, response<ul><li>As a signed-in user on Napkin, you have the capability to add environment variables to your user functions. This feature will enable us to securely store the Klaviyo private key for future use. Go to Other tab &gt; Environment Variables, add key and value:</li>
32 </ul>import requests import urllib.parse import json from datetime import datetime from napkin import request, response<ul><li>As a signed-in user on Napkin, you have the capability to add environment variables to your user functions. This feature will enable us to securely store the Klaviyo private key for future use. Go to Other tab &gt; Environment Variables, add key and value:</li>
33 - </ul><ul><li>We will now be able to implement this in our code, where “klaviyopk” is my Environment Variable: </li>
33 + </ul><ul><li>We will now be able to implement this in our code, where “klaviyopk” is my Environment Variable:</li>
34 - </ul>import os klkey=os.environ.get('klaviyopk')<ul><li>Slack will send the message details to the Napkin public URL. In order to process this data, we will need to parse it.<a>Napkin io documentation</a>provides the detailed instructions on how to achieve this. However, for your convenience, you can also refer to the code snippet below as an example: </li>
34 + </ul>import os klkey=os.environ.get('klaviyopk')<ul><li>Slack will send the message details to the Napkin public URL. In order to process this data, we will need to parse it.<a>Napkin io documentation</a>provides the detailed instructions on how to achieve this. However, for your convenience, you can also refer to the code snippet below as an example:</li>
35 </ul># Parse inbound payload text= request.form.get('text') channel_name= request.form.get('channel_name') time=datetime.now()<p><strong>Note</strong>: You might have noticed that the timestamp is also included here. This is done to ensure that our Klaviyo event carries the precise timestamp in its payload.</p>
35 </ul># Parse inbound payload text= request.form.get('text') channel_name= request.form.get('channel_name') time=datetime.now()<p><strong>Note</strong>: You might have noticed that the timestamp is also included here. This is done to ensure that our Klaviyo event carries the precise timestamp in its payload.</p>
36 <h3>Step 4:</h3>
36 <h3>Step 4:</h3>
37 - <p>To create a Klaviyo custom event, we require both a profile for whom the event will be registered and the event data itself. A profile represents any individual within your organization who should receive the Slack message as an email. Consequently, you will need to<a>create a new email list in Klaviyo</a>that encompasses the email addresses of your colleagues. This list should have all intended recipients of the email notifications. </p>
37 + <p>To create a Klaviyo custom event, we require both a profile for whom the event will be registered and the event data itself. A profile represents any individual within your organization who should receive the Slack message as an email. Consequently, you will need to<a>create a new email list in Klaviyo</a>that encompasses the email addresses of your colleagues. This list should have all intended recipients of the email notifications.</p>
38 <p>Once the list is ready, we can move forward and pull the list members via<a>Klaviyo API</a>:</p>
38 <p>Once the list is ready, we can move forward and pull the list members via<a>Klaviyo API</a>:</p>
39 # Get Klaviyo list members url = "https://a.klaviyo.com/api/lists/TRuQqu/profiles/?fields[profile]=email" headers = { "accept": "application/json", "revision": "2023-02-22", "Authorization": f"Klaviyo-API-Key {klkey}" } r = requests.get(url, headers=headers)<p>* “TRuQqu” in request represents my list ID, learn how to locate your list ID<a>here</a>. In this example, we are retrieving only the “email” field from the profiles. However, if you intend to send SMS notifications instead of emails, please make sure to adjust the “fields” accordingly. While this step is not mandatory, it can certainly decrease processing time.</p>
39 # Get Klaviyo list members url = "https://a.klaviyo.com/api/lists/TRuQqu/profiles/?fields[profile]=email" headers = { "accept": "application/json", "revision": "2023-02-22", "Authorization": f"Klaviyo-API-Key {klkey}" } r = requests.get(url, headers=headers)<p>* “TRuQqu” in request represents my list ID, learn how to locate your list ID<a>here</a>. In this example, we are retrieving only the “email” field from the profiles. However, if you intend to send SMS notifications instead of emails, please make sure to adjust the “fields” accordingly. While this step is not mandatory, it can certainly decrease processing time.</p>
40 <h3>Step 5:</h3>
40 <h3>Step 5:</h3>
41 <p>At this stage, we need to iterate through all the profiles we have retrieved from the Klaviyo list. Within this loop, we will send a custom event for each profile using<a>events</a>Klaviyo endpoint:</p>
41 <p>At this stage, we need to iterate through all the profiles we have retrieved from the Klaviyo list. Within this loop, we will send a custom event for each profile using<a>events</a>Klaviyo endpoint:</p>
42 - # Loop through each list member and send a custom event with Slack message content as an event property list_members=r.json()['data'] for i in list_members: email=i['attributes']['email'] message=text channel=channel_name timestamp=time.strftime("%Y-%m-%dT%H:%M:%S") url = "https://a.klaviyo.com/api/events/" payload = {"data": { "type": "event", "attributes": { "profile": {"email": email}, "metric": {"name": "Alert"}, "properties": {"text": message, "Slack_channel": channel}, "time": timestamp } }} headers = { "accept": "application/json", "revision": "2023-02-22", "content-type": "application/json", "Authorization": f"Klaviyo-API-Key {klkey}" } r = requests.post(url, json=payload, headers=headers) print(r.text)<p>Solution can be cloned into your Napkin via<a>this link</a>. Please make sure to add your private key, configure the Slack Integration, and change the list ID. </p>
42 + # Loop through each list member and send a custom event with Slack message content as an event property list_members=r.json()['data'] for i in list_members: email=i['attributes']['email'] message=text channel=channel_name timestamp=time.strftime("%Y-%m-%dT%H:%M:%S") url = "https://a.klaviyo.com/api/events/" payload = {"data": { "type": "event", "attributes": { "profile": {"email": email}, "metric": {"name": "Alert"}, "properties": {"text": message, "Slack_channel": channel}, "time": timestamp } }} headers = { "accept": "application/json", "revision": "2023-02-22", "content-type": "application/json", "Authorization": f"Klaviyo-API-Key {klkey}" } r = requests.post(url, json=payload, headers=headers) print(r.text)<p>Solution can be cloned into your Napkin via<a>this link</a>. Please make sure to add your private key, configure the Slack Integration, and change the list ID.</p>
43 <h2>Bonus</h2>
43 <h2>Bonus</h2>
44 - <p>Let’s take a look at what the end result should appear as:From Slack: </p>
44 + <p>Let’s take a look at what the end result should appear as:From Slack:</p>
45 <p>To Klaviyo Automated Flow:</p>
45 <p>To Klaviyo Automated Flow:</p>
46 <p>Information from Slack message can be pulled into the email via<a>event variables:</a></p>
46 <p>Information from Slack message can be pulled into the email via<a>event variables:</a></p>
47 - <h3><strong>Additional Notes about the Code and Its Configuration:</strong><strong><em></em></strong></h3>
47 + <h3><strong>Additional Notes about the Code and Its Configuration:</strong></h3>
48 <p>To effectively parse through the incoming payload, refer to the<a>documentation provided by Napkin.io</a>. Furthermore, when working with Klaviyo API endpoints, it is crucial to utilize a private Klaviyo API key, which should be stored as an<a>environment variable</a>within Napkin.</p>
48 <p>To effectively parse through the incoming payload, refer to the<a>documentation provided by Napkin.io</a>. Furthermore, when working with Klaviyo API endpoints, it is crucial to utilize a private Klaviyo API key, which should be stored as an<a>environment variable</a>within Napkin.</p>
49 <p>The Klaviyo endpoints used in this solution are as follows:</p>
49 <p>The Klaviyo endpoints used in this solution are as follows:</p>
50 <ol><li><a>Get list profiles</a></li>
50 <ol><li><a>Get list profiles</a></li>
51 <li><a>Create event</a></li>
51 <li><a>Create event</a></li>
52 </ol><p>By leveraging these endpoints, you can retrieve the necessary profile information and create custom events within Klaviyo to facilitate seamless communication and automation.</p>
52 </ol><p>By leveraging these endpoints, you can retrieve the necessary profile information and create custom events within Klaviyo to facilitate seamless communication and automation.</p>
53 <h2>Impact</h2>
53 <h2>Impact</h2>
54 <p>This Solutions Recipe provides a comprehensive guide on leveraging Klaviyo APIs to create custom events and automate flows. The example demonstrates a versatile function that can be adapted to extract data from any application and send it to Klaviyo as an event. This enables seamless automation of email, SMS, and notification workflows based on the received data. The versatility of this solution extends far beyond the described use-case. Consider its potential for VIP client notifications, out-of-office status updates, meeting details, SMS notifications for on-call employees and much more. The possibilities are virtually limitless, allowing you to streamline various communication processes and enhance efficiency across a wide range of scenarios.</p>
54 <p>This Solutions Recipe provides a comprehensive guide on leveraging Klaviyo APIs to create custom events and automate flows. The example demonstrates a versatile function that can be adapted to extract data from any application and send it to Klaviyo as an event. This enables seamless automation of email, SMS, and notification workflows based on the received data. The versatility of this solution extends far beyond the described use-case. Consider its potential for VIP client notifications, out-of-office status updates, meeting details, SMS notifications for on-call employees and much more. The possibilities are virtually limitless, allowing you to streamline various communication processes and enhance efficiency across a wide range of scenarios.</p>
55  
55