Skip to content

Commit 59aff7c

Browse files
authored
add slack option; update content (#510)
1 parent 5d68493 commit 59aff7c

File tree

4 files changed

+215
-65
lines changed

4 files changed

+215
-65
lines changed

docs/README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -852,6 +852,7 @@ This directory is built automatically. Each task's documentation is generated fr
852852
* [Email vendors when an order shipping address changes](./email-vendors-when-an-order-shipping-address-changes)
853853
* [Email vendors when their products are ordered](./email-vendors-when-their-products-are-ordered)
854854
* [Email your customers after a quiet period of no orders](./email-your-customers-after-a-quiet-period-of-no-orders)
855+
* [Error reporter](./error-reporter)
855856
* [Forward incoming email to another address](./forward-incoming-email-to-another-address)
856857
* [Get email alerts for out of stock products](./get-email-alerts-for-out-of-stock-products)
857858
* [Notify a team when a tagged product is ordered](./notify-a-team-when-a-tagged-product-is-ordered)
@@ -1639,6 +1640,7 @@ This directory is built automatically. Each task's documentation is generated fr
16391640
### Slack
16401641

16411642
* [Demonstration: Post to a Slack channel](./demonstration-post-to-a-slack-channel)
1643+
* [Error reporter](./error-reporter)
16421644
* [Report Toaster: Deliver report PDF via email or Slack](./report-toaster-deliver-report-pdf-via-email-or-slack)
16431645
* [Send a message to Slack](./send-a-message-to-slack)
16441646

docs/error-reporter/README.md

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
# Error reporter
22

3-
Tags: Alert, Error
3+
Tags: Alert, Email, Error, Slack
44

5-
Use this task to get email reports when errors occur with events, tasks, and actions in Mechanic. Use this task out of the box, customize it, or borrow logic for your more advanced error reporting tasks.
5+
Use this task to get email or Slack notifications when errors occur with any events, tasks, and actions in Mechanic. Use this task out of the box, customize it, or borrow logic for your more advanced error reporting tasks.
66

77
* View in the task library: [tasks.mechanic.dev/error-reporter](https://tasks.mechanic.dev/error-reporter)
88
* Task JSON, for direct import: [task.json](../../tasks/error-reporter.json)
@@ -12,7 +12,10 @@ Use this task to get email reports when errors occur with events, tasks, and act
1212

1313
```json
1414
{
15-
"email_recipients__email_array_required": null
15+
"notification_methods__multiselect_o1_email_o2_slack_required": null,
16+
"email_recipients__array": null,
17+
"slack_account": null,
18+
"slack_channel_id_": null
1619
}
1720
```
1821

@@ -30,10 +33,12 @@ mechanic/errors/action
3033

3134
## Documentation
3235

33-
Use this task to get email reports when errors occur with events, tasks, and actions in Mechanic. Use this task out of the box, customize it, or borrow logic for your more advanced error reporting tasks.
36+
Use this task to get email or Slack notifications when errors occur with any events, tasks, and actions in Mechanic. Use this task out of the box, customize it, or borrow logic for your more advanced error reporting tasks.
3437

3538
[Read more about error events](https://learn.mechanic.dev/platform/error-handling).
3639

40+
**IMPORTANT**: To use Slack notifications, you must install the Mechanic Slack app in your Slack workspace (Settings → Authentication → Slack) and confiure a Slack account and Slack channel ID in this task. If the configured channel is private, then you will need to add the Mechanic bot to the channel before it can post messages (`/invite @mechanic`).
41+
3742
## Installing this task
3843

3944
Find this task [in the library at tasks.mechanic.dev](https://tasks.mechanic.dev/error-reporter), and use the "Try this task" button. Or, import [this task's JSON export](../../tasks/error-reporter.json) – see [Importing and exporting tasks](https://learn.mechanic.dev/core/tasks/import-and-export) to learn how imports work.

docs/error-reporter/script.liquid

Lines changed: 171 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,18 @@
1+
{% assign notification_methods = options.notification_methods__multiselect_o1_email_o2_slack_required %}
2+
{% assign email_recipients = options.email_recipients__array %}
3+
{% assign slack_account = options.slack_account %}
4+
{% assign slack_channel_id = options.slack_channel_id_ %}
5+
6+
{% if notification_methods contains "email" and email_recipients == blank %}
7+
{% error "Configure one or more email recipients when choosing the email notification method" %}
8+
{% endif %}
9+
10+
{% if notification_methods contains "slack" and slack_account == blank or slack_channel_id == blank %}
11+
{% error "Configure a slack account and channel ID when choosing the slack notification method" %}
12+
{% endif %}
13+
114
{% comment %}
2-
Only send error emails for the same errors at these thresholds.
15+
-- define thresholds for repeat error sending
316
{% endcomment %}
417

518
{% assign error_thresholds = array %}
@@ -10,8 +23,8 @@
1023
{% assign error_thresholds[4] = 200 %}
1124

1225
{% comment %}
13-
Fingerprinting the error, so that we can track if this is something we have received recently.
14-
See: https://learn.mechanic.dev/techniques/debouncing-events#fingerprinting
26+
-- fingerprint the error, to know if it has been received recently
27+
-- See: https://learn.mechanic.dev/techniques/debouncing-events#fingerprinting
1528
{% endcomment %}
1629

1730
{% assign fingerprint_parts = hash %}
@@ -22,44 +35,68 @@
2235
{% assign fingerprint = fingerprint_parts | json | sha256 %}
2336
{% assign error_count_cache_key = "errors/" | append: fingerprint %}
2437

25-
{% comment %} How many times have we seen this error recently? {% endcomment %}
26-
27-
{% assign recent_error_count = cache[error_count_cache_key] | default: 0 %}
28-
29-
{% assign event_url = "https://admin.shopify.com/store/" | append: shop.myshopify_domain | replace: ".myshopify.com", "/apps/mechanic/events/" | append: error.event.id %}
30-
31-
{% capture email_subject -%}
32-
{{ event.topic }} on {{ shop.name }}
33-
{%- endcapture %}
34-
35-
{% capture email_body %}
36-
<p><b>This is an automated error notification from your Mechanic error reporting task.</b></p>
37-
38-
{% if error_thresholds contains recent_error_count -%}
39-
<p><b>Note:</b> There have been more than {{ recent_error_count }} errors of this type in the last 10 minutes.</p>
40-
{%- endif %}
41-
42-
{% if event.preview %}
43-
<p>View error details</p>
44-
{% else %}
45-
<p><a href="{{ event_url }}">View error details</a></p>
46-
{% endif %}
47-
48-
<p>Error topic: {{ event.topic }}</p>
49-
50-
<p>Error message: <pre>{{ error.message }}</pre></p>
38+
{% comment %}
39+
-- send notification if the same error message from same task has not been cached recently or if matches one of the thresholds for reoccurrence
40+
{% endcomment %}
5141

52-
<p>Thanks,<br><br>{{ shop.name }} via Mechanic</p>
53-
{% endcapture %}
42+
{% assign recent_error_count = cache[error_count_cache_key] | default: 0 | plus: 1 %}
5443

5544
{% comment %}
56-
We only send emails on the first error and again on specific thresholds
45+
-- increment recent error count for this error
5746
{% endcomment %}
5847

59-
{% if recent_error_count == 0 or error_thresholds contains recent_error_count %}
48+
{% action "cache" %}
49+
{
50+
"incr": {
51+
"key": {{ error_count_cache_key | json }},
52+
"ttl": 600
53+
}
54+
}
55+
{% endaction %}
56+
57+
{% unless recent_error_count == 1 or error_thresholds contains recent_error_count %}
58+
{%- capture log_message -%}
59+
There have been {{ recent_error_count }} errors of this type from this task ({{ error.task.name }}) in the last 10 minutes. Waiting until the next threshold before sending another notification.
60+
{%- endcapture -%}
61+
62+
{% log log_message %}
63+
64+
{% break %}
65+
{% endunless %}
66+
67+
{%- capture event_url -%}
68+
{{ shop.admin_url }}apps/mechanic/events/{{ error.event.id }}
69+
{%- endcapture -%}
70+
71+
{% if notification_methods contains "email" %}
72+
{% capture email_subject -%}
73+
Mechanic error on {{ shop.name }}
74+
{%- endcapture %}
75+
76+
{% capture email_body %}
77+
<p><small>This is an automated error notification from your Mechanic error reporting task.</small></p>
78+
{% if error_thresholds contains recent_error_count %}
79+
<p><em>There have been {{ recent_error_count }} errors of this type in the last 10 minutes.</em></p>
80+
{% endif %}
81+
<p><strong>Error topic:</strong> {{ event.topic }}</p>
82+
{% if error.action -%}
83+
<p><strong>Action type:</strong> {{ error.action.type }}</p>
84+
{% endif %}
85+
<p>
86+
<strong>Error message:</strong>
87+
<pre>{{ error.message }}</pre>
88+
</p>
89+
{% if event.preview %}
90+
<p>View error details</p>
91+
{% else %}
92+
<p><a href="{{ event_url }}">View error details</a></p>
93+
{% endif %}
94+
<p>Thanks,<br><br>{{ shop.name }} via Mechanic</p>
95+
{% endcapture %}
96+
6097
{% action "email" %}
6198
{
62-
"to": {{ options.email_recipients__email_array_required | json }},
99+
"to": {{ email_recipients | json }},
63100
"subject": {{ email_subject | json }},
64101
"body": {{ email_body | json }},
65102
"reply_to": {{ shop.customer_email | json }},
@@ -68,15 +105,105 @@
68105
{% endaction %}
69106
{% endif %}
70107

71-
{% comment %}
72-
Increment recent error count for this error
73-
{% endcomment %}
108+
{% if notification_methods contains "slack" %}
109+
{% if event.topic == "mechanic/errors/event" %}
110+
{% assign message_header = "Error in filter" %}
111+
{% else %}
112+
{% assign message_header = "Error in task: " | append: error.task.name %}
113+
{% endif %}
74114

75-
{% action "cache" %}
76-
{
77-
"incr": {
78-
"key": {{ fingerprint | json }},
79-
"ttl": 600
115+
{% action "slack" %}
116+
{
117+
"account": {{ slack_account | json }},
118+
"method": "POST",
119+
"url_path": "/chat.postMessage",
120+
"headers": {
121+
"Content-Type": "application/json"
122+
},
123+
"body": {
124+
"channel": {{ slack_channel_id | json }},
125+
"text": {{ shop.name | prepend: "Error on " | json }},
126+
"blocks": [
127+
{
128+
"type": "header",
129+
"text": {
130+
"type": "plain_text",
131+
"text": {{ message_header | slice: 0, 150 | json }}
132+
}
133+
},
134+
{
135+
"type": "context",
136+
"elements": [
137+
{
138+
"type": "plain_text",
139+
"text": "This is an automated error notification from your Mechanic error reporting task."
140+
}
141+
]
142+
},
143+
{
144+
"type": "section",
145+
"text": {
146+
"type": "mrkdwn",
147+
"text": {{ shop.name | prepend: "*Shop:* " | json }}
148+
}
149+
},
150+
{
151+
"type": "section",
152+
"text": {
153+
"type": "mrkdwn",
154+
"text": {{ event.topic | prepend: "*Error topic:* " | json }}
155+
}
156+
},
157+
{% if error.action -%}
158+
{
159+
"type": "section",
160+
"text": {
161+
"type": "mrkdwn",
162+
"text": {{ error.action.type | prepend: "*Action type:* " | json }}
163+
}
164+
},
165+
{% endif %}
166+
{% if error_thresholds contains recent_error_count -%}
167+
{
168+
"type": "context",
169+
"elements": [
170+
{
171+
"type": "plain_text",
172+
"text": "There have been {{ recent_error_count }} errors of this type from this task in the last 10 minutes."
173+
}
174+
]
175+
},
176+
{%- endif %}
177+
{
178+
"type": "section",
179+
"text": {
180+
"type": "mrkdwn",
181+
"text": "*Error message:*"
182+
}
183+
},
184+
{
185+
"type": "rich_text",
186+
"elements": [
187+
{
188+
"type": "rich_text_preformatted",
189+
"elements": [
190+
{
191+
"type": "text",
192+
"text": {{ error.message | json }}
193+
}
194+
]
195+
}
196+
]
197+
},
198+
{
199+
"type": "section",
200+
"text": {
201+
"type": "mrkdwn",
202+
"text": "<{{ event_url }}|View error details in Mechanic>"
203+
}
204+
}
205+
]
206+
}
80207
}
81-
}
82-
{% endaction %}
208+
{% endaction %}
209+
{% endif %}

0 commit comments

Comments
 (0)