@@ -191,6 +191,80 @@ def format_guardduty_finding(message: Dict[str, Any], region: str) -> Dict[str,
191191 }
192192
193193
194+ class AwsHealthCategory (Enum ):
195+ """Maps AWS Health eventTypeCategory to Slack message format color
196+
197+ eventTypeCategory
198+ The category code of the event. The possible values are issue,
199+ accountNotification, and scheduledChange.
200+ """
201+
202+ accountNotification = "#777777"
203+ scheduledChange = "warning"
204+ issue = "danger"
205+
206+
207+ def format_aws_health (message : Dict [str , Any ], region : str ) -> Dict [str , Any ]:
208+ """
209+ Format AWS Health event into Slack message format
210+
211+ :params message: SNS message body containing AWS Health event
212+ :params region: AWS region where the event originated from
213+ :returns: formatted Slack message payload
214+ """
215+
216+ aws_health_url = (
217+ f"https://phd.aws.amazon.com/phd/home?region={ region } #/dashboard/open-issues"
218+ )
219+ detail = message ["detail" ]
220+ resources = message .get ("resources" , "<unknown>" )
221+ service = detail .get ("service" , "<unknown>" )
222+
223+ return {
224+ "color" : AwsHealthCategory [detail ["eventTypeCategory" ]].value ,
225+ "text" : f"New AWS Health Event for { service } " ,
226+ "fallback" : f"New AWS Health Event for { service } " ,
227+ "fields" : [
228+ {"title" : "Affected Service" , "value" : f"`{ service } `" , "short" : True },
229+ {
230+ "title" : "Affected Region" ,
231+ "value" : f"`{ message .get ('region' )} `" ,
232+ "short" : True ,
233+ },
234+ {
235+ "title" : "Code" ,
236+ "value" : f"`{ detail .get ('eventTypeCode' )} `" ,
237+ "short" : False ,
238+ },
239+ {
240+ "title" : "Event Description" ,
241+ "value" : f"`{ detail ['eventDescription' ][0 ]['latestDescription' ]} `" ,
242+ "short" : False ,
243+ },
244+ {
245+ "title" : "Affected Resources" ,
246+ "value" : f"`{ ', ' .join (resources )} `" ,
247+ "short" : False ,
248+ },
249+ {
250+ "title" : "Start Time" ,
251+ "value" : f"`{ detail .get ('startTime' , '<unknown>' )} `" ,
252+ "short" : True ,
253+ },
254+ {
255+ "title" : "End Time" ,
256+ "value" : f"`{ detail .get ('endTime' , '<unknown>' )} `" ,
257+ "short" : True ,
258+ },
259+ {
260+ "title" : "Link to Event" ,
261+ "value" : f"{ aws_health_url } " ,
262+ "short" : False ,
263+ },
264+ ],
265+ }
266+
267+
194268def format_default (
195269 message : Union [str , Dict ], subject : Optional [str ] = None
196270) -> Dict [str , Any ]:
@@ -265,6 +339,10 @@ def get_slack_message_payload(
265339 )
266340 attachment = notification
267341
342+ elif isinstance (message , Dict ) and message .get ("detail-type" ) == "AWS Health Event" :
343+ notification = format_aws_health (message = message , region = message ["region" ])
344+ attachment = notification
345+
268346 elif "attachments" in message or "text" in message :
269347 payload = {** payload , ** message }
270348
0 commit comments