#!/usr/bin/php 'https://hq.palantetech.coop', 'key' => 'ddGq1iMK1aGMluHVxQu2', 'unknown-user' => 'create', 'allow-override' => 'tracker,priority,category,status,project,assigned_to,start_date,due_date,estimated_hours,done_ratio', 'project' => 'catch', 'tracker' => 'support', ); // 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("/tickets\+(\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, 12) == 'tickets-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 = "team@lists.palantetech.coop"; $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; case "larryg601@gmail.com": $project = "nwu"; break; case "director.npap@nlg.org": $project = "npap"; break; case "jgazis@legalmomentum.org": $project = "lm"; break; case "stephenrshalom@gmail.com": $project = "newpolitics-web"; break; case "ari.gardeningmatters@gmail.com": case "mallory.gardeningmatters@gmail.com": case "susan.gardeningmatters@gmail.com": case "heimsteadlenief@gmail.com": $project = "gm-civi"; break; //the following emails will not go into Redmine, and will cause an NDR to go to the sender. case "postmaster@urbanjustice.org": 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; case "nlg.org": $project = "nlg"; break; case "furee.org": $project = "furee"; break; case "opencenter.org": $project = "opencenter-tech"; break; case "vocal-ny.org": $project = "vocal"; break; case "rffny.org": $project = "rff"; break; case "domesticworkersunited.org": $project = "dwu-tech"; break; case "thirdwavefoundation.org": $project = "twf-tech"; break; case "picturethehomeless.org": $project = "pth"; break; case "changethenypd.org": $project = "cpr"; break; case "neweconomynyc.org": $project = "nedap-tech"; break; case "cpehn.org": $project = "cpehn-civi"; break; case "streetwiseandsafe.org": $project = "sas-tech"; break; case "nwu.org": $project = "nwu-civi"; break; case "tandn.org": $project = "tan"; break; case "foodlabdetroit.com": $project = "foodlab"; break; case "urbanjustice.org": $project = "ujc"; break; case "healthcare-now.org": $project = "hcn-civi"; break; case "global-action.org": $project = "gap"; break; case "aclusandiego.org": $project = "aclusdic-civi"; break; case "madre.org": $project = "madre-tech"; break; case "goles.org": $project = "goles-tech"; break; case "srlp.org": $project = "srlp"; break; case "ppnorcal.org": $project = "ppsp"; break; case "caeny.org": $project = "cae-tech"; break; case "ccrjustice.org": $project = "ccr-civi"; break; case "rainforestfund.org": $project = "rfu-tech"; break; case "nlgsf.org": $project = "nlgsf-civi"; break; case "warresisters.org": $project = "wrl"; break; case "gender.town": $project = "msp"; break; case "gsanetwork.org": $project = "gsa"; break; case "culturestrike.org": $project = "cs-dmp"; break; case "lawyerscommittee.org": $project = "lccr-civi"; break; case "ppnyc.org": $project = "ppnyc"; break; case "lavabrooklyn.org": $project = "lava-civi"; break; case "soex.org": $project = "soex"; break; case "woolman.org": $project = "woolman"; break; case "bikesnotbombs.org": $project = "bnb"; break; case "labornotes.org": $project = "labor-notes"; break; case "cbadley.com": $project = "sm"; break; case "lamama.org": $project = "lamama-tech"; break; case "populardemocracy.org": $project = "cpd"; break; case "searac.org": $project = "searac-d6"; break; case "pprm.org": $project = "pprm-adap"; break; case "africans.us": $project = "act"; break; case "campaignlegalcenter.org": $project = "clc"; break; case "advancingjustice-aajc.org": $project = "aajc-drupal-support"; break; case "bikeeastbay.org": $project = "beb-dcvmp"; break; case "movetoamend.org": $project = "mta-drupal"; break; case "raceforward.org": $project = "race-forward-drupal-support"; break; case "gardeningmatters.org": $project = "gm-civi"; break; case "eastbaymeditation.org": $project = "ebmc-cvwmp"; break; case "aorta.coop": $project = "aorta-tech"; break; //put spam domain entries here case "allverbia.xyz": case "tandn.org": echo "dying"; die; } return $project; } ?>