#!/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'); // Test addresses work normally, but tag the email subject with "[TEST]". $test = getenv('TEST'); $deliveryAddress = getenv('DELIVERY_ADDRESS'); 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("/$deliveryAddress.*\+(\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. if ($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); } // 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); saveEmail($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); saveEmail($input); } 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]; } if (($handle = fopen(__DIR__ . "/" . "data/usermap.csv", 'r')) !== FALSE) { while (($data = fgetcsv($handle, 1000)) !== FALSE) { $users[$data[0]] = $data[1]; } } if (isset($users[$email])) { $project = $users[$email]; } return $project; } function ParseSenderDomain($email) { $domain = $project = NULL; if(preg_match("/@(.*)\b/", $email, $matches)) { $domain = $matches[1]; } if (($handle = fopen(__DIR__ . "/" . "data/domainmap.csv", 'r')) !== FALSE) { while (($data = fgetcsv($handle, 1000)) !== FALSE) { $domains[$data[0]] = $data[1]; } } if(isset($domains[$domain])) { $project = $domains[$domain]; } return $project; } function saveEmail($email) { $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; } ?>