-
Notifications
You must be signed in to change notification settings - Fork 4.5k
fix(slack): Send only custom template when custom_body is set #7590
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
fix(slack): Send only custom template when custom_body is set #7590
Conversation
|
I think you need to run the DB migration scripts to add the Thank you. |
|
@yoshiokatsuneo This is not a migration issue. |
When a custom template is configured for an alert, the Slack destination was appending the custom_body to the default fields (Query/Alert links) instead of replacing them. This resulted in both default and custom templates being displayed together. This fix restructures the notification logic: - If custom_body is set: send only the custom template - If custom_body is not set: send default template (existing behavior)
bb6f00f to
f370589
Compare
|
@yoshiokatsuneo I'm not sure exactly what triggered it, but until lastweek the However, there's still a valid bug: when using a custom template, both the default template fields (Query/Alert links) AND the custom template are displayed together in Slack notifications. |
|
@yoshiokatsuneo Thank you However, I believe custom-template-only is the expected behavior because:
That said, I acknowledge this is just my perspective, and there may be users who prefer the current append behavior. Proposal: What do you think about adding an option like "Include default fields" (checkbox) when custom template is enabled? This would:
This way, we support both use cases without breaking existing functionality for users who might depend on it. |
|
Thank you. |
|
Thank you for your question. I've updated the PR to support markdown in I added - payload = {"attachments": [{"text": text, "color": color, "mrkdwn_in": ["text"], "fields": [{"value": alert.custom_body}]}]}
+ payload = {"attachments": [{"text": text, "color": color, "mrkdwn_in": ["text", "fields"], "fields": [{"value": alert.custom_body}]}]}Slack API mrkdwn_in Specification |
|
Thank you. I'm wondering what happens if template variable (ex: How do you think ? |
|
That's a really good point I hadn't considered. If a template variable value contains markdown special characters (e.g., I considered several solutions to escape template variable values, but:
Although the alert feature isn't a major part of Redash, I believe we should take a defensive I removed the markdown support and kept it as plain text (same as the original behavior). Thank you for pointing this out! |
Thank you. |
|
@yoshiokatsuneo |
|
Thank you. And, I understand that the it is nice if we can fully customize the alert message. Is this change important for you ? |
|
@yoshiokatsuneo To me, the word "Custom" implies full control over the output. When I set a custom template, Currently, I want to use custom templates, but the inconsistent output structure This is why I believe "custom template only" is the expected behavior. |
|
Thank you.
How do you think ? |
|
I totally agree with your proposal. However, I'd like to share some considerations
Given this scope, I think we should design the abstraction layer first before implementing I'm happy to work on this larger scope PR if you agree. |
I agree that this is a bit challenging. |
|
I tested escape approaches for Slack markdown special characters. Slack doesn't provide an official way to escape markdown formatting characters
Since there's no official escape mechanism for Unofficial Workarounds TestedI found two commonly suggested approaches:
Both methods work by inserting an invisible Unicode character that breaks Slack's markdown pattern matching. Test Commands (curl)I tested both approaches by sending messages to a Slack webhook: # Normal (formatting applied)
curl -X POST -H 'Content-type: application/json' \
--data '{"attachments":[{"text":"*bold* _italic_ ~strike~","mrkdwn_in":["text"]}]}' \
WEBHOOK_URL
# CGJ escaped (no formatting)
curl -X POST -H 'Content-type: application/json' \
--data $'{"attachments":[{"text":"\u034f*bold* \u034f_italic_ \u034f~strike~","mrkdwn_in":["text"]}]}' \
WEBHOOK_URLTest Results
Both methods successfully prevent markdown formatting. However, the Soft hyphen approach has a drawback - when users copy the text from Slack and paste it into a text editor, the invisible Unicode character becomes visible. CGJ (U+034F) is the better approach - it escapes markdown formatting while preserving the original text appearance when copied to other applications. Implementation ApproachBased on these findings, I believe we can implement this using pystache's custom escape function feature. Here's my proposed approach: 1. Add methods to Alert model:These methods allow destinations to pass their own escape function: def get_custom_body(self, escape_func=None):
template = self.options.get("custom_body", self.options.get("template"))
return self.render_template(template, escape_func=escape_func)
def get_custom_subject(self, escape_func=None):
template = self.options.get("custom_subject")
return self.render_template(template, escape_func=escape_func)2. Add escape function in Slack destination:This function handles both official HTML entity escaping and unofficial CGJ-based markdown escaping: def escape_slack_markdown(text):
if text is None:
return ""
text = str(text)
# HTML entities (official Slack requirement)
text = text.replace('&', '&')
text = text.replace('<', '<')
text = text.replace('>', '>')
# Slack markdown characters (CGJ workaround)
for char in ['*', '_', '~', '`']:
text = text.replace(char, '\u034f' + char)
return textThis way:
This gives users full control over their custom templates while protecting against unexpected formatting from template variables. What do you think about this approach? |
|
Thank you for the detailed summary ! The For example, I'm afraid that searching Or, if the copied text with CGJ is embedded in the source code unexpectedly, it may be the cause of the bug... How do you think ? |




Problem
When using a custom template for Slack alert notifications, both the default template fields (Query/Alert links) AND the custom template are displayed together.
Current behavior:
Expected behavior:
When
custom_bodyis set, only the custom template should be displayed.Root Cause
The Slack destination uses
append()to addcustom_bodyto the existing fields instead of replacing them:Solution
Restructure the notification logic:
custom_bodyis set → send only the custom templatecustom_bodyis not set → send default template (existing behavior)