mirror of
				https://github.com/moudsen/mailGraph
				synced 2025-10-29 00:27:38 +01:00 
			
		
		
		
	Compare commits
	
		
			14 Commits
		
	
	
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|   | 624ce29a39 | ||
|   | 16729e0720 | ||
|   | 97dba8f197 | ||
|   | 288b0adaf7 | ||
|   | 2859d427f7 | ||
|   | 0cd169a9d2 | ||
|   | 8269195795 | ||
|   | 6da6da77fb | ||
|   | 00a67cbb65 | ||
|   | bf970029ea | ||
|   | 9f3bfb5c69 | ||
|   | 504422f452 | ||
|   | 3ef16ae597 | ||
|   | a597ce6ab3 | 
							
								
								
									
										45
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										45
									
								
								README.md
									
									
									
									
									
								
							| @@ -20,6 +20,41 @@ More information can be found in the Wiki. | ||||
| ## Installation ## | ||||
| Please refer to the Wiki how to get mailGraph installed and configured on your system. | ||||
|  | ||||
| ## mailGraph v2.15 release ## | ||||
| _(2023/08/16)_ | ||||
|  | ||||
| _This version has been verified with Zabbix 5.4 and 6.0 LTS and is expected to work with 6.4 and later (based on v2.10 testing)_ | ||||
|  | ||||
| Release notes | ||||
| - Fixed new error condition found in Zabbix 5.4.12 where zeroed or blank parameters for a webhook are no longer added as parameters in the Javascript. | ||||
| - Refactored error handling inside the Javascript to distinguish automatically between 'email ID response' or a debug or warning level message (this prevents the code of throwing an unknown error like 'Invalid JSON'). | ||||
|  | ||||
| ## mailGraph v2.14 release ## | ||||
| _(2023/07/10)_ | ||||
|  | ||||
| _This version has been verified with Zabbix 5.4 and 6.0 LTS and is expected to work with 6.4 and later (based on v2.10 testing)_ | ||||
|  | ||||
| Release notes | ||||
| - Adding the ability to define FROM details for the emails generated by mailGraph | ||||
|   - `smtp_from_address` to set the from mail address (if not set uses mailing system default). Note: obsolete `mail_from` but retained for backwards compatibility. | ||||
|   - `smtp_from_name` to set the name that goes with the mail address (if not set uses "mailGraph"). | ||||
| - Adding the ability to define REPLY_TO details for the emails generated by mailGraph | ||||
|   - `smtp_reply_address` to set the reply-to mail address (if not set, no reply-to will be added to the message). | ||||
|   - `smtp_reply_name` to set the reply-to name of the mailbox (if not set defaults to "mailGraph feedback"). | ||||
| - Adding a new URL for use in the template: | ||||
|   - `ACK_URL` points to the function in Zabbix for editing and submitting an Acknowledge statement. | ||||
|  | ||||
| ## mailGraph v2.13 release ## | ||||
| _(2023/07/03)_ | ||||
|  | ||||
| _This version has been verified with Zabbix 5.4 and 6.0 LTS and is expected to work with 6.4 and later (based on v2.10 testing)_ | ||||
|  | ||||
| Release notes | ||||
| - Fixed references into Zabbix | ||||
|   - Trigger was missing "context" parameter | ||||
|   - Item was missing "context" parameter | ||||
|   - Problems reference to this host was not generated at all | ||||
|  | ||||
| ## mailGraph v2.12 release ## | ||||
| _(2023/07/02)_ | ||||
|  | ||||
| @@ -32,6 +67,12 @@ Release notes | ||||
| - Addressed any PHP message (deprecation or error) - mailGraph debug output is now "clean" in PHP 7.4.x and PHP 8.2.x | ||||
| - Increased maximum number of graphs from 4 to 8 | ||||
|  | ||||
| **Please consider to move to PHPMailer as soon as possible as Swiftmailer is abandoned. Installation instructions are included on the wiki.** | ||||
|  | ||||
| Principal approach: `composer require phpmailer/phpmailer`, install mailGraph v2.12 or higher. | ||||
|  | ||||
| In case Swiftmailer is no longer used elsewhere you can consider to remove this package with `swiftmailer/swiftmailer`. | ||||
|  | ||||
| ## mailGraph v2.11 release ## | ||||
| _(2023/07/01)_ | ||||
|  | ||||
| @@ -78,6 +119,10 @@ _(2023/06/29)_ | ||||
| Zabbix 6.4.x verification is in progress. Required intermediate release to fix one major issue (Zabbix login parameters deprecation) and some minor coding updates. | ||||
| Expect to continue with automatic configuration within the next 2 months. | ||||
|  | ||||
| ## Special thank you ## | ||||
| I would like to express my gratitude to the following people that have actively contributed to bring bugs and improvements to my attention: | ||||
| - [pqvindesland](https://github.com/pqvindesland) | ||||
|  | ||||
| ## IMPORTANT NOTE for users of mailGraph v1 and Zabbix versions under 5.4 ## | ||||
| As a result of a major functional change in Zabbix 5.4 (Screens no longer exist and are all moved into Dashboards) the mailGraph.screen macro no longer functions under Zabbix 5.4+. A code rewrite is in progress to deal with detecting the Zabbix version and to pick dashboard.get instead of screen.get as a source list for the graphs that should be included in the mail message. | ||||
|  | ||||
|   | ||||
| @@ -1,7 +1,5 @@ | ||||
| { | ||||
|     "script_baseurl": "https:\/\/mydomain.com\/", | ||||
|     "cli_itemId": 0, | ||||
|     "cli_triggerId": 0, | ||||
|     "cli_eventId": 0, | ||||
|     "cli_duration": 0, | ||||
|     "cli_recipient": "recipient@mydomain.com", | ||||
| @@ -15,14 +13,19 @@ | ||||
|     "zabbix_user_pwd": "astrongpassword", | ||||
|     "zabbix_api_user": "alogicalusername", | ||||
|     "zabbix_api_pwd": "astrongpassword", | ||||
|     "mail_from": "sender@mydomain.com", | ||||
|     "subject": "{{ HOST_NAME|raw }}:  ({{ EVENT_SEVERITY }}) {{ EVENT_NAME|raw }}", | ||||
|     "smtp_server": "localhost", | ||||
|     "smtp_port": 25, | ||||
|     "smtp_transport": "none", | ||||
|     "smtp_from_address": "mailgraph@mydomain.com", | ||||
|     "smtp_from_name": "mailGraph", | ||||
|     "smtp_reply_address": "feedback@mydomain.com", | ||||
|     "smtp_from_name": "mailGraph response mailbox", | ||||
|     "smtp_strict": "yes", | ||||
|     "graph_match": "any", | ||||
|     "period": "20m", | ||||
|     "period_header": "Last 20 minutes", | ||||
|     "retention_images": 7, | ||||
|     "retention_logs": 14, | ||||
|     "debug": 0 | ||||
| } | ||||
|   | ||||
| @@ -1,7 +1,5 @@ | ||||
| { | ||||
|     "script_baseurl": "https:\/\/mydomain.com\/", | ||||
|     "cli_itemId": 0, | ||||
|     "cli_triggerId": 0, | ||||
|     "cli_eventId": 0, | ||||
|     "cli_duration": 0, | ||||
|     "cli_recipient": "recipient@mydomain.com", | ||||
| @@ -15,12 +13,15 @@ | ||||
|     "zabbix_user_pwd": "astrongpassword", | ||||
|     "zabbix_api_user": "alogicalusername", | ||||
|     "zabbix_api_pwd": "astrongpassword", | ||||
|     "mail_from": "sender@mydomain.com", | ||||
|     "subject": "{{ HOST_NAME|raw }}:  ({{ EVENT_SEVERITY }}) {{ EVENT_NAME|raw }}", | ||||
|     "smtp_server": "localhost", | ||||
|     "smtp_port": 25, | ||||
|     "smtp_transport": "none", | ||||
|     "smtp_strict": "yes", | ||||
|     "smtp_from_address": "mailgraph@mydomain.com", | ||||
|     "smtp_from_name": "mailGraph", | ||||
|     "smtp_reply_address": "feedback@mydomain.com", | ||||
|     "smtp_from_name": "mailGraph response mailbox", | ||||
|     "graph_match": "any", | ||||
|     "periods": "10m,4h,2d,7d", | ||||
|     "periods_headers": "Last 10 minutes,Last 4 hours,Last 2 days,Last 7 days", | ||||
|   | ||||
| @@ -1,4 +1,15 @@ | ||||
| // mailGraph v2.12 | ||||
| // mailGraph v2.15 | ||||
|  | ||||
| // Function to test string | ||||
| function isJSON(str) { | ||||
| 	try { | ||||
| 		JSON.stringify(JSON.parse(str)); | ||||
| 		return true; | ||||
| 	} catch (e) { | ||||
| 		return false; | ||||
| 	} | ||||
| } | ||||
|  | ||||
| try { | ||||
|     // Pickup parameters | ||||
|     params = JSON.parse(value), | ||||
| @@ -16,21 +27,13 @@ try { | ||||
|     // Declare output type | ||||
|     req.addHeader('Content-Type: application/json'); | ||||
|  | ||||
|     // Must have fields | ||||
|     // Pick up fields relevant for mailGraph API level call while parsing/casting fields that should be integer | ||||
|     fields.itemId = params.itemId * 1; | ||||
|     fields.eventId = params.eventId * 1; | ||||
|     fields.recipient = params.recipient; | ||||
|     fields.baseURL = params.baseURL; | ||||
|     fields.duration = params.duration * 1; | ||||
|  | ||||
|     if (isNaN(fields.eventId)) { | ||||
|       throw '[MailGraph Webhook] Invalid event ID? Integer required (use actual event ID from Zabbix!)'; | ||||
|     } | ||||
|  | ||||
|     if (isNaN(fields.duration)) { | ||||
|       throw '[MailGraph Webhook] Invalid duration? Integer required (set to zero if unknown)!'; | ||||
|     } | ||||
|  | ||||
|     if (fields.recipient.charAt(0) == '{') { | ||||
|       throw '[MailGraph Webhook] Please define recipient for the test message!'; | ||||
|     } | ||||
| @@ -56,20 +59,30 @@ try { | ||||
|     var resp = req.post(params.URL,JSON.stringify(fields)); | ||||
|     Zabbix.Log(4, '[Mailgraph Webhook] Received response:' + resp); | ||||
|  | ||||
|     // If blank the email address is likely incorrect | ||||
|     // The response can be | ||||
|     // - did not receive status 200 as result (contains HTTP server response) | ||||
|     // - null (no response received at all) | ||||
|     // - empty string (likely no e-mail sent due to recipient issue) | ||||
|     // - not json (debugging message for troubleshooting or configuration hints) | ||||
|     // - json (contains the mail message ID sent) | ||||
|  | ||||
|     if (req.getStatus() != 200) { | ||||
|        throw '[MailGraph Webhook] Processing of mailGraph.php failed: ' + resp; | ||||
|     } | ||||
|     if (resp==null) { | ||||
|       throw '[MailGraph Webhook] No data received from mailGraph! Likely the email processing failed? Check mailGraph logging'; | ||||
|       throw '[MailGraph Webhook] No response received from mailGraph.php? This should not occur (check URL and your webserver!)'; | ||||
|     } | ||||
|  | ||||
|     // If there was an error, report it and stop | ||||
|     if (req.getStatus() != 200) { throw JSON.parse(resp).errors[0]; } | ||||
|  | ||||
|     // If no datas returned, report it and stop | ||||
|     if (resp.charAt(0) == "!") { | ||||
|       throw '[MailGraph Webhook] No data received from mailGraph! Likely the event ID provided does not exist? Check mailGraph logging'; | ||||
|     if (resp=='') { | ||||
|       throw '[MailGraph Webhook] No data received from mailGraph - please check recipient address or mailGraph log and retry.'; | ||||
|     } | ||||
|  | ||||
|     // We expect the message id back from the processing script | ||||
|     // Check if JSON was returned | ||||
|     if (!isJSON(resp)) { | ||||
|       throw '[MailGraph Webhook] An error has occurred during processing: ' + resp; | ||||
|     } | ||||
|  | ||||
|     // We expect the message id back from the processing script response in JSON format | ||||
|     msg = JSON.parse(resp); | ||||
|  | ||||
|     result.tags.__message_id = msg.messageId; | ||||
| @@ -80,7 +93,7 @@ try { | ||||
| } | ||||
| catch (error) | ||||
| { | ||||
|     // In case something went wrong in the processing, pass the error back to Zabbix | ||||
|     // In case something else went wrong in the processing, pass the error back to Zabbix | ||||
|     Zabbix.Log(127, 'MailGraph notification failed: '+error); | ||||
|     throw 'MailGraph notification failed : '+error; | ||||
| } | ||||
|   | ||||
							
								
								
									
										120
									
								
								mailGraph.php
									
									
									
									
									
								
							
							
						
						
									
										120
									
								
								mailGraph.php
									
									
									
									
									
								
							| @@ -51,7 +51,15 @@ | ||||
|     // 2.10 2023/06/30 - Mark Oudsen - Refactored deprecated code - now compatible with Zabbix 6.0 LTS, 6.4 | ||||
|     // 2.11 2023/07/01 - Mark Oudsen - Refactored Zabbix javascript - now capturing obvious errors | ||||
|     //                                 Added ability to locate latest problems for testing purposes | ||||
|     // 2.12 2023/07/xx - Mark Oudsen - Replaced SwiftMailer with PHPMailer (based on AutoTLS) | ||||
|     // 2.12 2023/07/02 - Mark Oudsen - Replaced SwiftMailer with PHPMailer (based on AutoTLS) | ||||
|     // 2.13 2023/07/03 - Mark Oudsen - Bugfixes speciifally on links into Zabbix (missing context or info) | ||||
|     // 2.14 2023/07/10 - Mark Oudsen - Adding ability to set 'From'  and 'ReplyTo' addresses in configuration | ||||
|     //                                 Adding ACK_URL for utilization in the template to point to Ack page | ||||
|     //                                 Small refactor on itemId variable processing (no longer mandatory) | ||||
|     //                                 Additional logic added to random eventId to explain in case of issues | ||||
|     //                                 Fixed missing flag for fetching web url related items | ||||
|     // 2.15 2023/08/16 - Mark Oudsen - Bugfix for Zabbix 5.4 where empty or zeroed variables are no longer | ||||
|     //                                 passed by Zabbix (hence resulting in weird errors) | ||||
|     // ------------------------------------------------------------------------------------------------------ | ||||
|     // | ||||
|     // (C) M.J.Oudsen, mark.oudsen@puzzl.nl | ||||
| @@ -86,7 +94,7 @@ | ||||
|     ///////////////////////////////////////////////////////////////////////////////////////////////////////// | ||||
|  | ||||
|     // CONSTANTS | ||||
|     $cVersion = 'v2.12'; | ||||
|     $cVersion = 'v2.15'; | ||||
|     $cCRLF = chr(10).chr(13); | ||||
|     $maskDateTime = 'Y-m-d H:i:s'; | ||||
|     $maxGraphs = 8; | ||||
| @@ -487,16 +495,19 @@ | ||||
|             _log('<<< mailGraph '.$cVersion.' >>>'); | ||||
|             _log('# Invoked from CLI'); | ||||
|  | ||||
|             // Assumes that config.json file has the correct information | ||||
|             // Assumes that config.json file has the correct information for MANDATORY information | ||||
|  | ||||
|             // DEFAULTS | ||||
|             $problemData['eventId'] = 0; | ||||
|             $problemData['duration'] = 0; | ||||
|  | ||||
|             // MANDATORY | ||||
|             $problemData['itemId'] = $config['cli_itemId']; | ||||
|             $problemData['eventId'] = $config['cli_eventId']; | ||||
|             $problemData['recipient'] = $config['cli_recipient']; | ||||
|             $problemData['baseURL'] = $config['cli_baseURL']; | ||||
|             $problemData['duration'] = $config['cli_duration']; | ||||
|  | ||||
|             // OPTIONAL | ||||
|             if (isset($config['cli_eventId'])) { $problemData['eventId'] = $config['cli_eventId']; } | ||||
|             if (isset($config['cli_duration'])) { $problemData['duration'] = $config['cli_duration']; } | ||||
|             if (isset($config['cli_subject'])) { $problemData['subject'] = $config['cli_subject']; } | ||||
|             if (isset($config['cli_period'])) { $problemData['period'] = $config['cli_period']; } | ||||
|             if (isset($config['cli_period_header'])) { $problemData['period_header'] = $config['cli_period_header']; } | ||||
| @@ -504,6 +515,10 @@ | ||||
|             if (isset($config['cli_periods_headers'])) { $problemData['periods_headers'] = $config['cli_periods_headers']; } | ||||
|             if (isset($config['cli_debug'])) { $problemData['debug'] = $config['cli_debug']; } | ||||
|             if (isset($config['cli_proxy'])) { $problemData['HTTPProxy'] = $config['cli_proxy']; } | ||||
|  | ||||
|             // BACKWARDS COMPATIBILITY - obsolete from Zabbix 6.2 onwards | ||||
|             $problemData['itemId'] = 0; | ||||
|             if (isset($config['cli_itemId'])) { $problemData['itemId'] = $config['cli_itemId']; } | ||||
|         } | ||||
|  | ||||
|         if (($argc>1) && ($argv[1]=='cleanup')) | ||||
| @@ -536,6 +551,7 @@ | ||||
|          $cCRLF.json_encode($problemData,JSON_PRETTY_PRINT|JSON_NUMERIC_CHECK)); | ||||
|  | ||||
|     // --- CHECK AND SET P_ VARIABLES --- | ||||
|  | ||||
|     // FROM POST OR CLI DATA | ||||
|  | ||||
|     if (!isset($problemData['eventId'])) { echo "Missing EVENT ID?\n"; die; } | ||||
| @@ -544,8 +560,8 @@ | ||||
|     if (!isset($problemData['recipient'])) { echo "Missing RECIPIENT?\n"; die; } | ||||
|     $p_recipient = $problemData['recipient']; | ||||
|  | ||||
|     if (!isset($problemData['duration'])) { echo "Missing DURATION?\n"; die; } | ||||
|     $p_duration = intval($problemData['duration']); | ||||
|     $p_duration = 0; | ||||
|     if (isset($problemData['duration'])) { $p_duration = intval($problemData['duration']); } | ||||
|  | ||||
|     if (!isset($problemData['baseURL'])) { echo "Missing URL?\n"; die; } | ||||
|     $p_URL = $problemData['baseURL']; | ||||
| @@ -591,6 +607,27 @@ | ||||
|     $p_smtp_password = ''; | ||||
|     if (isset($config['smtp_password'])) { $p_smtp_password = $config['smtp_password']; } | ||||
|  | ||||
|     $p_smtp_from_address = ''; | ||||
|     if (isset($config['smtp_from_address'])) { $p_smtp_from_address = $config['smtp_from_address']; } | ||||
|  | ||||
|     $p_smtp_from_name = 'mailGraph'; | ||||
|     if (isset($config['smtp_from_name'])) { $p_smtp_from_name = $config['smtp_from_name']; } | ||||
|  | ||||
|     $p_smtp_reply_address = ''; | ||||
|     if (isset($config['smtp_reply_address'])) { $p_smtp_reply_address = $config['smtp_reply_address']; } | ||||
|  | ||||
|     $p_smtp_reply_name = 'mailGraph feedback'; | ||||
|     if (isset($config['smtp_reply_name'])) { $p_smtp_reply_name = $config['smtp_reply_name']; } | ||||
|  | ||||
|     // >>> Backwards compatibility but smtp_from_address is leading (<v2.14) | ||||
|     $mailFrom = ''; | ||||
|     if (isset($config['mail_from'])) { $mailFrom = $config['mail_from']; } | ||||
|  | ||||
|     if (($p_smtp_from_address=='') && ($mailFrom!='')) | ||||
|     { | ||||
|         $p_smtp_from_address = $mailFrom; | ||||
|     } | ||||
|  | ||||
|     $p_graph_match = 'any'; | ||||
|     if ((isset($config['graph_match'])) && ($config['graph_match']=='exact')) { $p_graph_match = 'exact'; } | ||||
|  | ||||
| @@ -607,6 +644,19 @@ | ||||
|     $z_tmp_cookies = $z_path.'tmp/'; | ||||
|     $z_log_path = $z_path.'log/'; | ||||
|  | ||||
|     // If tmp or log does not exist, create them | ||||
|     if (!is_dir($z_tmp_cookies)) | ||||
|     { | ||||
|         mkdir($z_tmp_cookies); | ||||
|         _log('+ created TMP directory "'.$z_tmp_cookies.'"'); | ||||
|     } | ||||
|  | ||||
|     if (!is_dir($z_log_path)) | ||||
|     { | ||||
|         mkdir($z_log_path); | ||||
|         _log('+ created LOG directory "'.$z_log_path.'"'); | ||||
|     } | ||||
|  | ||||
|     // Zabbix user (requires Super Admin access rights to access image generator script) | ||||
|     $z_user = $config['zabbix_user']; | ||||
|     $z_pass = $config['zabbix_user_pwd']; | ||||
| @@ -627,9 +677,6 @@ | ||||
|         $z_api_pass = $config['zabbix_api_pwd']; | ||||
|     } | ||||
|  | ||||
|     // Mail sender | ||||
|     $mailFrom = $config['mail_from']; | ||||
|  | ||||
|     // Derived variables - do not change! | ||||
|     $z_server = $p_URL;                             // Zabbix server URL from config | ||||
|     $z_url_api = $z_server  ."api_jsonrpc.php";     // Zabbix API URL | ||||
| @@ -715,9 +762,29 @@ | ||||
|                          'id'=>nextRequestID()); | ||||
|  | ||||
|         $thisProblems = postJSON($z_url_api, $request); | ||||
|         _log('> Problem data'.$cCRLF.json_encode($thisProblems,JSON_PRETTY_PRINT|JSON_NUMERIC_CHECK)); | ||||
|         _log('> Problem data (recent)'.$cCRLF.json_encode($thisProblems,JSON_PRETTY_PRINT|JSON_NUMERIC_CHECK)); | ||||
|  | ||||
|         if (!isset($thisProblems['result'][0])) { echo '! No response data received?'.$cCRLF; die; } | ||||
|         if (!isset($thisProblems['result'][0])) | ||||
|         { | ||||
|             _log('- No response data received. Retrying with less recent problems ... '); | ||||
|  | ||||
|             $request = array('jsonrpc'=>'2.0', | ||||
|                              'method'=>'problem.get', | ||||
|                              'params'=>array('output'=>'extend', | ||||
|                                              'recent'=>'false', | ||||
|                                              'limit'=>1), | ||||
|                              'auth'=>$token, | ||||
|                              'id'=>nextRequestID()); | ||||
|  | ||||
|             $thisProblems = postJSON($z_url_api, $request); | ||||
|             _log('> Problem data (not recent)'.$cCRLF.json_encode($thisProblems,JSON_PRETTY_PRINT|JSON_NUMERIC_CHECK)); | ||||
|  | ||||
|             if (!isset($thisProblems['result'][0])) | ||||
|             { | ||||
|                 _log('! Cannot continue: mailGraph is unable to pick a random event via the Zabbix API. It is highly likely that no active problems exist? Please retry or determine and set an event ID manually and retry.'); | ||||
|                 die; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         $p_eventId = $thisProblems['result'][0]['eventid']; | ||||
|         _log('> Picked up random last event #'.$p_eventId); | ||||
| @@ -865,6 +932,7 @@ | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     // If no specific itemId is requested take the first item found on the items list from the host | ||||
|     if (!isset($p_itemId)) | ||||
|     { | ||||
|         foreach($thisTrigger['result'][0]['functions'] as $aFunction) | ||||
| @@ -884,6 +952,7 @@ | ||||
|     $request = array('jsonrpc'=>'2.0', | ||||
|                      'method'=>'item.get', | ||||
|                      'params'=>array('itemids'=>$p_itemId, | ||||
|                          'webitems'=>'true', | ||||
|                          'output'=>'extend'), | ||||
|                      'auth'=>$token, | ||||
|                      'id'=>nextRequestID()); | ||||
| @@ -1358,7 +1427,10 @@ | ||||
|     $mailData['LOG_HTML'] = str_replace($cCRLF,'<br/>',$mailData['LOG_HTML']); | ||||
|     $mailData['LOG_HTML'] = str_replace('<br/>','<br/>'.$cCRLF,$mailData['LOG_HTML']); | ||||
|  | ||||
|     $mailData['LOG_HTML'] = '<html lang="en"><head><meta http-equiv=Content-Type content="text/html; charset=UTF-8">'.$cCRLF. | ||||
|     $mailData['LOG_HTML'] = '<html lang="en"><head><meta http-equiv=Content-Type content="text/html; charset=UTF-8"></head>'.$cCRLF. | ||||
|                             '<style type="text/css">'.$cCRLF. | ||||
|                             'body { font-family: courier, courier new, serif; font-size: 12px; }'.$cCRLF. | ||||
|                             '</style>'.$cCRLF. | ||||
|                             '<body>'.$cCRLF. | ||||
|                             $mailData['LOG_HTML'].$cCRLF. | ||||
|                             '</body>'.$cCRLF. | ||||
| @@ -1370,12 +1442,14 @@ | ||||
|  | ||||
|     // Prepare others | ||||
|  | ||||
|     $mailData['TRIGGER_URL'] = $z_server.'triggers.php?form=update&triggerid='.$mailData['TRIGGER_ID']; | ||||
|     $mailData['ITEM_URL'] = $z_server.'items.php?form=update&hostid='.$mailData['HOST_ID'].'&itemid='.$mailData['ITEM_ID']; | ||||
|     $mailData['TRIGGER_URL'] = $z_server.'triggers.php?form=update&triggerid='.$mailData['TRIGGER_ID'].'&context=host'; | ||||
|     $mailData['ITEM_URL'] = $z_server.'items.php?form=update&hostid='.$mailData['HOST_ID'].'&itemid='.$mailData['ITEM_ID'].'&context=host'; | ||||
|     $mailData['HOST_URL'] = $z_server.'hosts.php?form=update&hostid='.$mailData['HOST_ID']; | ||||
|     $mailData['ACK_URL'] = $z_server.'zabbix.php?action=popup&popup_action=acknowledge.edit&eventids[]='.$mailData['EVENT_ID']; | ||||
|     $mailData['EVENTDETAILS_URL'] = $z_server.'tr_events.php?triggerid='.$mailData['TRIGGER_ID'].'&eventid='.$mailData['EVENT_ID']; | ||||
|  | ||||
|     $mailData['EVENT_DURATION'] = $p_duration; | ||||
|     $mailData['HOST_PROBLEMS_URL'] = $z_server.'zabbix.php?show=1&name=&inventory%5B0%5D%5Bfield%5D=type&inventory%5B0%5D%5Bvalue%5D=&evaltype=0&tags%5B0%5D%5Btag%5D=&tags%5B0%5D%5Boperator%5D=0&tags%5B0%5D%5Bvalue%5D=&show_tags=3&tag_name_format=0&tag_priority=&show_opdata=0&show_timeline=1&filter_name=&filter_show_counter=0&filter_custom_time=0&sort=clock&sortorder=DESC&age_state=0&show_suppressed=0&unacknowledged=0&compact_view=0&details=0&highlight_row=0&action=problem.view&hostids%5B%5D='.$mailData['HOST_ID']; | ||||
|  | ||||
|     ///////////////////////////////////////////////////////////////////////////////////////////////////////// | ||||
|     // Compose & Send Message /////////////////////////////////////////////////////////////////////////////// | ||||
| @@ -1409,8 +1483,18 @@ | ||||
|             ]; | ||||
|         } | ||||
|  | ||||
|         // --- Define from and recipient | ||||
|         $mail->setFrom($mailFrom, 'mailGraph'); | ||||
|         // --- Define from | ||||
|         $mail->Sender = $p_smtp_from_address; | ||||
|         $mail->SetFrom($p_smtp_from_address, $p_smtp_from_name, FALSE); | ||||
|  | ||||
|         // --- Define reply-to | ||||
|         if ($p_smtp_reply_address!='') | ||||
|         { | ||||
|             $mail->clearReplyTos(); | ||||
|             $mail->addReplyTo($p_smtp_reply_address, $p_smtp_reply_name); | ||||
|         } | ||||
|  | ||||
|         // --- Add recipient | ||||
|         $mail->addAddress($p_recipient); | ||||
|  | ||||
|         // --- Prepare embedding of the graphs by attaching and generating "cid" (content-id) information | ||||
|   | ||||
| @@ -1,7 +1,7 @@ | ||||
| <?xml version="1.0" encoding="UTF-8"?> | ||||
| <zabbix_export> | ||||
|     <version>5.4</version> | ||||
|     <date>2023-07-02T12:48:36Z</date> | ||||
|     <date>2023-08-16T12:05:37Z</date> | ||||
|     <media_types> | ||||
|         <media_type> | ||||
|             <name>MailGraph</name> | ||||
| @@ -9,7 +9,7 @@ | ||||
|             <parameters> | ||||
|                 <parameter> | ||||
|                     <name>baseURL</name> | ||||
|                     <value>https://myzabbix.example.com/</value> | ||||
|                     <value>https://myzabbix.com/zabbix/</value> | ||||
|                 </parameter> | ||||
|                 <parameter> | ||||
|                     <name>duration</name> | ||||
| @@ -35,10 +35,6 @@ | ||||
|                     <name>infoTest</name> | ||||
|                     <value>Test</value> | ||||
|                 </parameter> | ||||
|                 <parameter> | ||||
|                     <name>itemId</name> | ||||
|                     <value>{ITEM.ID}</value> | ||||
|                 </parameter> | ||||
|                 <parameter> | ||||
|                     <name>periods</name> | ||||
|                     <value>10m,4h,1d,7d</value> | ||||
| @@ -61,10 +57,21 @@ | ||||
|                 </parameter> | ||||
|                 <parameter> | ||||
|                     <name>URL</name> | ||||
|                     <value>https://myzabbix.example.com/mailGraph.php</value> | ||||
|                     <value>https://myzabbix.com/mailGraph.php</value> | ||||
|                 </parameter> | ||||
|             </parameters> | ||||
|             <script>// mailGraph v2.12 | ||||
|             <script>// mailGraph v2.15 | ||||
|  | ||||
| // Function to test string | ||||
| function isJSON(str) { | ||||
| 	try { | ||||
| 		JSON.stringify(JSON.parse(str)); | ||||
| 		return true; | ||||
| 	} catch (e) { | ||||
| 		return false; | ||||
| 	} | ||||
| } | ||||
|  | ||||
| try { | ||||
|     // Pickup parameters | ||||
|     params = JSON.parse(value), | ||||
| @@ -82,21 +89,13 @@ try { | ||||
|     // Declare output type | ||||
|     req.addHeader('Content-Type: application/json'); | ||||
|  | ||||
|     // Must have fields | ||||
|     // Pick up fields relevant for mailGraph API level call while parsing/casting fields that should be integer | ||||
|     fields.itemId = params.itemId * 1; | ||||
|     fields.eventId = params.eventId * 1; | ||||
|     fields.recipient = params.recipient; | ||||
|     fields.baseURL = params.baseURL; | ||||
|     fields.duration = params.duration * 1; | ||||
|  | ||||
|     if (isNaN(fields.eventId)) { | ||||
|       throw '[MailGraph Webhook] Invalid event ID? Integer required (use actual event ID from Zabbix!)'; | ||||
|     } | ||||
|  | ||||
|     if (isNaN(fields.duration)) { | ||||
|       throw '[MailGraph Webhook] Invalid duration? Integer required (set to zero if unknown)!'; | ||||
|     } | ||||
|  | ||||
|     if (fields.recipient.charAt(0) == '{') { | ||||
|       throw '[MailGraph Webhook] Please define recipient for the test message!'; | ||||
|     } | ||||
| @@ -122,20 +121,30 @@ try { | ||||
|     var resp = req.post(params.URL,JSON.stringify(fields)); | ||||
|     Zabbix.Log(4, '[Mailgraph Webhook] Received response:' + resp); | ||||
|  | ||||
|     // If blank the email address is likely incorrect | ||||
|     // The response can be | ||||
|     // - did not receive status 200 as result (contains HTTP server response) | ||||
|     // - null (no response received at all) | ||||
|     // - empty string (likely no e-mail sent due to recipient issue) | ||||
|     // - not json (debugging message for troubleshooting or configuration hints) | ||||
|     // - json (contains the mail message ID sent) | ||||
|  | ||||
|     if (req.getStatus() != 200) { | ||||
|        throw '[MailGraph Webhook] Processing of mailGraph.php failed: ' + resp; | ||||
|     } | ||||
|     if (resp==null) { | ||||
|       throw '[MailGraph Webhook] No data received from mailGraph! Likely the email processing failed? Check mailGraph logging'; | ||||
|       throw '[MailGraph Webhook] No response received from mailGraph.php? This should not occur (check URL and your webserver!)'; | ||||
|     } | ||||
|  | ||||
|     // If there was an error, report it and stop | ||||
|     if (req.getStatus() != 200) { throw JSON.parse(resp).errors[0]; } | ||||
|  | ||||
|     // If no datas returned, report it and stop | ||||
|     if (resp.charAt(0) == "!") { | ||||
|       throw '[MailGraph Webhook] No data received from mailGraph! Likely the event ID provided does not exist? Check mailGraph logging'; | ||||
|     if (resp=='') { | ||||
|       throw '[MailGraph Webhook] No data received from mailGraph - please check recipient address or mailGraph log and retry.'; | ||||
|     } | ||||
|  | ||||
|     // We expect the message id back from the processing script | ||||
|     // Check if JSON was returned | ||||
|     if (!isJSON(resp)) { | ||||
|       throw '[MailGraph Webhook] An error has occurred during processing: ' + resp; | ||||
|     } | ||||
|  | ||||
|     // We expect the message id back from the processing script response in JSON format | ||||
|     msg = JSON.parse(resp); | ||||
|  | ||||
|     result.tags.__message_id = msg.messageId; | ||||
| @@ -146,7 +155,7 @@ try { | ||||
| } | ||||
| catch (error) | ||||
| { | ||||
|     // In case something went wrong in the processing, pass the error back to Zabbix | ||||
|     // In case something else went wrong in the processing, pass the error back to Zabbix | ||||
|     Zabbix.Log(127, 'MailGraph notification failed: '+error); | ||||
|     throw 'MailGraph notification failed : '+error; | ||||
| }</script> | ||||
| @@ -174,11 +183,7 @@ Host: {HOST.NAME} | ||||
| Severity: {EVENT.SEVERITY} | ||||
| Operational data: {EVENT.OPDATA} | ||||
| Original problem ID: {EVENT.ID} | ||||
| {TRIGGER.URL} | ||||
|  | ||||
| eventId: {EVENT.ID} | ||||
| TriggerId: {TRIGGER.ID} | ||||
| itemId: {ITEM.ID]</message> | ||||
| Trigger ID (/url): {TRIGGER.ID} {TRIGGER.URL}</message> | ||||
|                 </message_template> | ||||
|                 <message_template> | ||||
|                     <event_source>TRIGGERS</event_source> | ||||
| @@ -190,11 +195,7 @@ Problem duration: {EVENT.DURATION} | ||||
| Host: {HOST.NAME} | ||||
| Severity: {EVENT.SEVERITY} | ||||
| Original problem ID: {EVENT.ID} | ||||
| {TRIGGER.URL} | ||||
|  | ||||
| eventId: {EVENT.ID} | ||||
| TriggerId: {TRIGGER.ID} | ||||
| itemId: {ITEM.ID]</message> | ||||
| Trigger ID: {TRIGGER.ID} {TRIGGER.URL}</message> | ||||
|                 </message_template> | ||||
|                 <message_template> | ||||
|                     <event_source>TRIGGERS</event_source> | ||||
| @@ -205,11 +206,11 @@ itemId: {ITEM.ID]</message> | ||||
|  | ||||
| Current problem status is {EVENT.STATUS}, age is {EVENT.AGE}, acknowledged: {EVENT.ACK.STATUS}. | ||||
|  | ||||
| eventId: {EVENT.ID} | ||||
| TriggerId: {TRIGGER.ID} | ||||
| itemId: {ITEM.ID]</message> | ||||
| Event ID: {EVENT.ID} | ||||
| Trigger ID: {TRIGGER.ID}</message> | ||||
|                 </message_template> | ||||
|             </message_templates> | ||||
|         </media_type> | ||||
|     </media_types> | ||||
| </zabbix_export> | ||||
|  | ||||
|   | ||||
| @@ -124,6 +124,7 @@ | ||||
| {% if GRAPH_ZABBIXLINK|length > 0 %} | ||||
|                     // Graph ID: <a href="{{ GRAPH_ZABBIXLINK }}">{{ GRAPH_ID }}</a> | ||||
| {% endif %} | ||||
|                     // <a href="{{ ACK_URL }}">Ack</a> | ||||
|                 </div> | ||||
|             </td> | ||||
|         </tr> | ||||
|   | ||||
		Reference in New Issue
	
	Block a user