@@ -44,9 +44,22 @@ class DingTalkOptionsForm(forms.Form):
4444 help_text = 'Whether to @ all members in the group.' ,
4545 required = False
4646 )
47+ custom_message_enabled = forms .BooleanField (
48+ label = 'Enable Custom Message' ,
49+ help_text = 'If checked, the "Custom Message Template" below will be used.' ,
50+ required = False
51+ )
52+ custom_message_template = forms .CharField (
53+ label = 'Custom Message Template' ,
54+ widget = forms .Textarea (attrs = {'class' : 'span6' , 'placeholder' : '### {title}\n \n **Project**: {project}\n **Error**: {message}\n [View]({url})' }),
55+ help_text = 'Markdown template. Available variables: {project}, {title}, {display_title}, {message}, {url}, {level}, {environment}, {culprit}, {project_slug}, {project_name}, {org_name}.' ,
56+ required = False
57+ )
58+
4759
4860from .__version__ import __version__
49-
61+
62+
5063class DingTalkPlugin (NotificationPlugin ):
5164 author = 'lanxuexing'
5265 author_url = 'https://github.com/lanxuexing/sentry-dingtalk-notify'
@@ -86,6 +99,8 @@ def notify_users(self, group, event, fail_silently=False, triggering_rules=None,
8699 custom_keyword = self .get_option ('custom_keyword' , group .project ) or ''
87100 at_mobiles_str = self .get_option ('at_mobiles' , group .project ) or ''
88101 is_at_all = self .get_option ('is_at_all' , group .project ) or False
102+ custom_message_enabled = self .get_option ('custom_message_enabled' , group .project ) or False
103+ custom_message_template = self .get_option ('custom_message_template' , group .project ) or ''
89104
90105 logger .info (f"DingTalk notify_users called for event { event .event_id } " )
91106
@@ -143,29 +158,51 @@ def notify_users(self, group, event, fail_silently=False, triggering_rules=None,
143158
144159 link = self .get_group_url (group )
145160
146- # Markdown Content
147- # Using a list style for better readability
148- text = f"### { evt_title } \n \n "
149-
150- # Key Metadata
151- text += f"- **📦 Project**: { project_slug } ({ org_name } )\n "
152- text += f"- **🌍 Env**: { environment } \n "
153- text += f"- **🚦 Level**: { level } \n "
154- text += f"- **📍 Location**: `{ culprit } `\n "
161+ # Determine Markdown Content
162+ text = ""
163+ used_custom = False
164+
165+ if custom_message_enabled and custom_message_template :
166+ # Prepare context for custom template
167+ context = {
168+ 'project' : project_name , # Human readable name
169+ 'project_name' : project_name , # Alias
170+ 'project_slug' : project_slug , # Technical slug
171+ 'org_name' : org_name ,
172+ 'title' : evt_title ,
173+ 'display_title' : display_title , # Title with keyword prefix 【Keyword】
174+ 'message' : evt_message ,
175+ 'url' : link ,
176+ 'level' : level ,
177+ 'environment' : environment ,
178+ 'culprit' : culprit ,
179+ }
180+ try :
181+ text = custom_message_template .format (** context )
182+ used_custom = True
183+ logger .info ("DingTalk: Used custom message template." )
184+ except Exception as e :
185+ logger .error (f"DingTalk: Error formatting custom template: { e } . Falling back to default." )
186+ text = "" # Fallback logic below will handle empty text
155187
156- # Error Message (Quote block)
157- if evt_message and evt_message != evt_title :
158- text += f"\n > { evt_message } \n \n "
159- else :
160- text += "\n "
161-
162- # Trigger Context
163- if triggering_rules :
164- text += f"📢 **Trigger**: { ', ' .join (triggering_rules )} \n "
188+ if not text :
189+ # Standard Default Template
190+ text = f"### { evt_title } \n \n "
191+ text += f"- **📦 Project**: { project_slug } ({ org_name } )\n "
192+ text += f"- **🌍 Env**: { environment } \n "
193+ text += f"- **🚦 Level**: { level } \n "
194+ text += f"- **📍 Location**: `{ culprit } `\n "
195+
196+ if evt_message and evt_message != evt_title :
197+ text += f"\n > { evt_message } \n \n "
198+ else :
199+ text += "\n "
200+
201+ if triggering_rules :
202+ text += f"📢 **Trigger**: { ', ' .join (triggering_rules )} \n "
203+
204+ text += f"\n [👉 View Issue on Sentry]({ link } )\n "
165205
166- # Action Link
167- text += f"\n [👉 View Issue on Sentry]({ link } )\n "
168-
169206 # Append @ mentions to text so they are visually highlighted
170207 if at_mobiles :
171208 at_text = ' ' .join ([f"@{ m } " for m in at_mobiles ])
0 commit comments