#!/usr/bin/php load(); // Debug Mode will show more information. $debugMode = getenv('DEBUG_MODE'); // Dry Run Mode will suppress sending an e-mail to Redmine. Only really useful with debug mode on. $dryRun = getenv('DRY_RUN'); if($debugMode) { error_reporting(E_ALL); } // initialize. $deliveredTo = $from = $project = $email = $subject = NULL; $params = array( 'url' => getenv('REDMINE_URL'), 'key' => getenv('KEY'), 'unknown-user' => 'create', 'allow-override' => 'all', 'project' => getenv('CATCHALL_PROJECT_NAME'), 'tracker' => 'general', ); // read from stdin $fd = fopen("php://stdin", "r"); // Loop through the incoming message, one line at a time. while (!feof($fd)) { $line = fgets($fd); //if this line is the "delivered-to", extract the subaddress, if there is one. if(preg_match("/^delivered-to: (.*)/i", $line, $matches)) { $deliveredTo = $matches[1]; if(preg_match("/support_mt.*\+(\S*)@/i", $deliveredTo, $matches)) { $project = $matches[1]; } } //also extract the "From" address. if(preg_match("/^from: (.*)/i", $line, $matches)) { $from = $matches[1]; } //Alter the Subject if this is a test. $subjectAlterTo = substr($deliveredTo, 1, 12); if(substr($deliveredTo, 1, 15) == 'support_mt_test' && preg_match("/^Subject:(.*)/i", $line)) { $line = $subject = str_replace('Subject: ', 'Subject: [TEST] ', $line); } //build the email variable, which is output to Redmine. $email .= $line; } fclose($fd); //Handle special cases //Strip out "auto-generated" from GCal notifications if($from == 'Google Calendar ') { $params['unknown-user'] = 'accept'; $email = str_replace("Auto-Submitted: auto-generated\n", '', $email); } //Linode alerts from ramen if($from == 'Linode Alerts ') { if(strpos($email, 'Subject: Linode Alert - disk io rate - ramen_ALP')) { die; } } //Linode alerts from gravy if($from == 'Linode Alerts ') { if(strpos($email, 'Subject: Linode Alert - disk io rate - gravy_HQ')) { die; } } //Any e-mails to tickets+fromwebsite@palantetech.com automatically get sent to tickets+prospecting, but no account is created if(strpos($deliveredTo, 'tickets+fromwebsite') !== FALSE) { $project = 'prospecting'; $params['unknown-user'] = 'accept'; } //Any e-mails to tickets+hiring don't get an account created if(strpos($from, 'tickets+hiring' !== FALSE)) { $params['unknown-user'] = 'accept'; } // If we don't know the project yet, attempt to determine it from the complete email address. if(!$project) { $project = ParseSenderEmail($from); } // Still no project? Check the domain of the sender. if(!$project) { $project = ParseSenderDomain($from); } //Add the project code (if applicable). if($project) { $params['project'] = $project; } if($debugMode) { // debug code $email .= "\n\nDelivered To - $deliveredTo\n"; $email .= "Project - $project\n"; $email .= "From - $from\n"; $email .= "Subject - $subject\n"; $email .= "Params:\n"; $email .= print_r($params, TRUE); $debugFileName = '/tmp/EmailProcessing' . time(); echo "$debugFileName"; $debugFile = fopen($debugFileName, 'w'); fwrite($debugFile, $email); fclose($debugFile); // also print to stdout, in case we're running manually echo $email; } if(!$dryRun) { SendToMailHandler($email, $params); } // Send to Ruby mailhandler. function SendToMailHandler($input, $params) { $descriptorspec = array( 0 => array("pipe", "r"), // stdin is a pipe that the child will read from 1 => array("pipe", "w"), // stdout is a pipe that the child will write to 2 => array("pipe", "w"), // stderr is a pipe that the child will write to ); $process = proc_open("/usr/local/bin/rdm-mailhandler.rb --url={$params['url']} --key={$params['key']} --unknown-user={$params['unknown-user']} --no-permission-check --allow-override={$params['allow-override']} --project {$params['project']} --tracker {$params['tracker']}", $descriptorspec, $pipes); if (is_resource($process)) { // $pipes now looks like this: // 0 => writeable handle connected to child stdin // 1 => readable handle connected to child stdout // Any error output will be appended to /tmp/error-output.txt fwrite($pipes[0], $input); fclose($pipes[0]); echo stream_get_contents($pipes[1]); $errorMessage = stream_get_contents($pipes[2]); fclose($pipes[1]); fclose($pipes[2]); // It is important that you close any pipes before calling // proc_close in order to avoid a deadlock $return_value = proc_close($process); // Log errors, also display on screen and send an email if($return_value) { echo $errorMessage; $log = "Redmine redirect error: $errorMessage"; syslog(LOG_ERR, $log); $to = "info@megaphonetech.com"; $subject = "Redmine email routing failure"; $message = $log . "\n\n"; $message .= $input; mail($to, $subject, $message); } echo "command returned $return_value\n"; } } //See if this email address is associated with a particular project function ParseSenderEmail($from) { $project = $email = NULL; if(preg_match("/\b([A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4})\b/i", $from, $matches)) { $email = $matches[1]; } switch($email) { case "ezra.berkley.nepon@gmail.com ": $project = "astraea"; break; //the following emails will not go into Redmine, and will cause an NDR to go to the sender. case "billing@linode.com": echo "dying"; die; } return $project; } function ParseSenderDomain($email) { $domain = $project = NULL; if(preg_match("/@(.*)\b/", $email, $matches)) { $domain = $matches[1]; } switch($domain) { case "legalmomentum.org": $project = "lm-tech"; break; //put spam domain entries here case "allverbia.xyz": echo "dying"; die; } return $project; } ?>