|
@@ -0,0 +1,190 @@
|
|
|
|
+ <?php
|
|
|
|
+// Copyright (C) 2010 Combodo SARL
|
|
|
|
+//
|
|
|
|
+// This program is free software; you can redistribute it and/or modify
|
|
|
|
+// it under the terms of the GNU General Public License as published by
|
|
|
|
+// the Free Software Foundation; version 3 of the License.
|
|
|
|
+//
|
|
|
|
+// This program is distributed in the hope that it will be useful,
|
|
|
|
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
+// GNU General Public License for more details.
|
|
|
|
+//
|
|
|
|
+// You should have received a copy of the GNU General Public License
|
|
|
|
+// along with this program; if not, write to the Free Software
|
|
|
|
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
|
|
+
|
|
|
|
+/**
|
|
|
|
+ * Specific page to read a mailbox using the POP3 protocol, get the incoming
|
|
|
|
+ * mails, turn them into UserRequest tickets, then remove the mails
|
|
|
|
+ * from the mailbox. In order to create tickets from emails received into
|
|
|
|
+ * such an inbox, this page must be called at frequent intervals, since it
|
|
|
|
+ * will process all the messages sitting in the inbox, then exit.
|
|
|
|
+ * You can use a simple scheduled 'wget' command line script to call this page
|
|
|
|
+ * from either a 'cron'' (Unix) or 'at' (Windows) command.
|
|
|
|
+ *
|
|
|
|
+ * Use this page as an example and feel free to tailor it to your needs,
|
|
|
|
+ * especially the default settings for the ticket (see below)
|
|
|
|
+ *
|
|
|
|
+ * @author Erwan Taloc <erwan.taloc@combodo.com>
|
|
|
|
+ * @author Romain Quetiez <romain.quetiez@combodo.com>
|
|
|
|
+ * @author Denis Flaven <denis.flaven@combodo.com>
|
|
|
|
+ * @license http://www.opensource.org/licenses/gpl-3.0.html LGPL
|
|
|
|
+ */
|
|
|
|
+
|
|
|
|
+// Some PEAR includes that are required for reading emails
|
|
|
|
+include 'Net/POP3.php';
|
|
|
|
+include 'Mail/mimeDecode.php';
|
|
|
|
+
|
|
|
|
+// Parameters to access your mailbox
|
|
|
|
+define('MAILBOX_SERVER', 'pop3.combodo.com'); // Replace with the IP or FQDN name of your POP3 server
|
|
|
|
+define('MAILBOX_SERVER_PORT', 110); // 110 is the default for POP3
|
|
|
|
+define('MAILBOX_ACCOUNT', 'test@combodo.com'); // You mailbox account
|
|
|
|
+define('MAILBOX_PASSWORD', 'combodo'); // Password for this mailbox
|
|
|
|
+
|
|
|
|
+// Default settings for the ticket creation
|
|
|
|
+define('DEFAULT_IMPACT', '2');
|
|
|
|
+define('DEFAULT_URGENCY', '2');
|
|
|
|
+define('DEFAULT_SERVICE_ID', 2);
|
|
|
|
+define('DEFAULT_SUBSERVICE_ID', 12);
|
|
|
|
+define('DEFAULT_PRODUCT', 'Request via eMail');
|
|
|
|
+
|
|
|
|
+require_once('../application/application.inc.php');
|
|
|
|
+require_once('../application/startup.inc.php');
|
|
|
|
+
|
|
|
|
+function GetSender($aHeaders)
|
|
|
|
+{
|
|
|
|
+ $aResult = array('name' => '', 'email' => '');
|
|
|
|
+ $aResult['name'] = $aHeaders['From'];
|
|
|
|
+ $aMatches = array();
|
|
|
|
+ if (preg_match('/\(([0-9a-zA-Z\._]+)@(.+)@(.+)\)/U', array_pop($aHeaders['Received']), $aMatches))
|
|
|
|
+ {
|
|
|
|
+ $aResult['email'] = $aMatches[1].'@'.$aMatches[2];
|
|
|
|
+ }
|
|
|
|
+ return $aResult;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/**
|
|
|
|
+ * Create a User Request ticket from the basic information retrieved from an email
|
|
|
|
+ * @param string $sSenderEmail eMail address of the sender (From), used to lookup a contact in iTop
|
|
|
|
+ * @param string $sSubject eMail's subject, will be turned into the title of the ticket
|
|
|
|
+ * @param string $sBody Body of the email, will be fitted into the ticket's description
|
|
|
|
+ * @return UserRequest The created ticket, or null if the creation failed for some reason...
|
|
|
|
+ */
|
|
|
|
+function CreateTicket($sSenderEmail, $sSubject, $sBody)
|
|
|
|
+{
|
|
|
|
+ $oTicket = null;
|
|
|
|
+ try
|
|
|
|
+ {
|
|
|
|
+ $oContactSearch = new DBObjectSearch('Contact'); // Can be either a Person or a Team, but must be a valid Contact
|
|
|
|
+ $oContactSearch->AddCondition('email', $sSenderEmail, '=');
|
|
|
|
+ $oSet = new DBObjectSet($oContactSearch);
|
|
|
|
+ if ($oSet->Count() == 1)
|
|
|
|
+ {
|
|
|
|
+ $oContact = $oSet->Fetch();
|
|
|
|
+ $oOrganization = MetaModel::GetObject('Organization', $oContact->Get('org_id'));
|
|
|
|
+ $oTicket = new UserRequest;
|
|
|
|
+ $oTicket->Set('title', $sSubject);
|
|
|
|
+ $oTicket->Set('description', $sBody);
|
|
|
|
+ $oTicket->Set('org_id', $oOrganization->GetKey());
|
|
|
|
+ $oTicket->Set('caller_id', $oContact->GetKey());
|
|
|
|
+ $oTicket->Set('impact', DEFAULT_IMPACT);
|
|
|
|
+ $oTicket->Set('urgency', DEFAULT_URGENCY);
|
|
|
|
+ $oTicket->Set('product', DEFAULT_PRODUCT);
|
|
|
|
+ $oTicket->Set('service_id', DEFAULT_SERVICE_ID); // Can be replaced by a search for a valid service for this 'org_id'
|
|
|
|
+ $oTicket->Set('servicesubcategory_id', DEFAULT_SUBSERVICE_ID); // Same as above...
|
|
|
|
+
|
|
|
|
+ // Record the change information about the object
|
|
|
|
+ $oMyChange = MetaModel::NewObject("CMDBChange");
|
|
|
|
+ $oMyChange->Set("date", time());
|
|
|
|
+ $sUserString = $oContact->GetName().', submitted by email';
|
|
|
|
+ $oMyChange->Set("userinfo", $sUserString);
|
|
|
|
+ $iChangeId = $oMyChange->DBInsert();
|
|
|
|
+ $oTicket->DBInsertTracked($oMyChange);
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ echo "No contact found in iTop having the email: $sSenderEmail, email message ignored.\n";
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ catch(Exception $e)
|
|
|
|
+ {
|
|
|
|
+ echo "Error: exception ".$e->getMessage();
|
|
|
|
+ $oTicket = null;
|
|
|
|
+ }
|
|
|
|
+ return $oTicket;
|
|
|
|
+}
|
|
|
|
+/**
|
|
|
|
+ * Main program
|
|
|
|
+ */
|
|
|
|
+// Connect to the POP3 server & open the mailbox
|
|
|
|
+$oPop3 = new Net_POP3();
|
|
|
|
+$oPop3->connect(MAILBOX_SERVER, MAILBOX_SERVER_PORT);
|
|
|
|
+$oPop3->login(MAILBOX_ACCOUNT, MAILBOX_PASSWORD);
|
|
|
|
+
|
|
|
|
+// Read all the messages from the mailbox and tries to create a new ticket for each one
|
|
|
|
+// Note: it is expected that the sender of the email exists a valid contact as a 'Contact'
|
|
|
|
+// in iTop (identified by her/his email address), otherwise the ticket creation will fail
|
|
|
|
+$iNbMessages = $oPop3->numMsg();
|
|
|
|
+for($index = 1; $index <= $iNbMessages; $index++)
|
|
|
|
+{
|
|
|
|
+ $params['include_bodies'] = true;
|
|
|
|
+ $params['decode_bodies'] = true;
|
|
|
|
+ $params['decode_headers'] = true;
|
|
|
|
+ $params['crlf'] = "\r\n";
|
|
|
|
+ $aHeaders = $oPop3->getParsedHeaders($index);
|
|
|
|
+ $aSender = GetSender($aHeaders);
|
|
|
|
+ $oDecoder = new Mail_mimeDecode( $oPop3->getRawHeaders($index).$params['crlf'].$oPop3->getBody($index) );
|
|
|
|
+ $oStructure = $oDecoder->decode($params);
|
|
|
|
+ $sSubject = $aHeaders['Subject'];
|
|
|
|
+ // Search for the text/plain body part
|
|
|
|
+ $iPartIndex = 0;
|
|
|
|
+ $bFound = false;
|
|
|
|
+ $sTextBody = '';
|
|
|
|
+ if (count($oStructure->parts) == 0)
|
|
|
|
+ {
|
|
|
|
+ $sTextBody = $oStructure->body;
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ // Find the first "part" of the body which is in text/plain
|
|
|
|
+ while( ($iPartIndex < count($oStructure->parts)) && (!$bFound) )
|
|
|
|
+ {
|
|
|
|
+ //echo "<p>Reading part $iPartIndex</p>\n";
|
|
|
|
+ if ( ($oStructure->parts[$iPartIndex]->ctype_primary == 'text') &&
|
|
|
|
+ ($oStructure->parts[$iPartIndex]->ctype_secondary == 'plain') )
|
|
|
|
+ {
|
|
|
|
+ $sTextBody = $oStructure->parts[$iPartIndex]->body;
|
|
|
|
+ $bFound = true;
|
|
|
|
+ //echo "<p>Plain text found ! ($sTextBody)</p>\n";
|
|
|
|
+ }
|
|
|
|
+ $iPartIndex++;
|
|
|
|
+ }
|
|
|
|
+ // Try again but this time look for an HTML part
|
|
|
|
+ if (!$bFound)
|
|
|
|
+ {
|
|
|
|
+ while( ($iPartIndex < count($oStructure->parts)) && (!$bFound) )
|
|
|
|
+ {
|
|
|
|
+ //echo "<p>Reading part $iPartIndex</p>\n";
|
|
|
|
+ if ( ($oStructure->parts[$iPartIndex]->ctype_primary == 'text') &&
|
|
|
|
+ ($oStructure->parts[$iPartIndex]->ctype_secondary == 'html') )
|
|
|
|
+ {
|
|
|
|
+ $sTextBody = $oStructure->parts[$iPartIndex]->body;
|
|
|
|
+ $bFound = true;
|
|
|
|
+ //echo "<p>HTML text found ! (".htmlentities($sTextBody).")</p>\n";
|
|
|
|
+ }
|
|
|
|
+ $iPartIndex++;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ $oTicket = CreateTicket($aSender['name'], $aSender['email'], $sSubject, $sBody);
|
|
|
|
+ if ($oTicket != null)
|
|
|
|
+ {
|
|
|
|
+ // Ticket created, delete the email
|
|
|
|
+ $oPop3->deleteMsg($index);
|
|
|
|
+ echo "Ticket: ".$oTicket->GetName()." created.\n";
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+$oPop3->disconnect();
|
|
|
|
+?>
|