Page 5 of 5

Re: Email (Imap) Addon

Posted: Wed Mar 09, 2016 5:09 pm
by sp119
This appears to be an older add-on but I was wondering if anyone knows if it works for Hesk 2.5.5?

Our POP3 service is going away and I need to migrate to IMAP. Any idea on whether this add-on still works?

If it's working could someone post the latest full code for me to try out?

Thanks!!

--Sean

Re: Email (Imap) Addon

Posted: Mon Jun 20, 2016 6:26 pm
by sp119
I have been able to make this IMAP code work with the exception of the attachments. I am using Hesk 2.6.7 (latest version as of 6/20/2016).

I'm no PHP guru so I don't know why the attachments don't work. This is the same code as is listed a few posts up by oliworx on 11/30/2011 but the attachments are not working.

ANY help to get the attachments to work would be appreciated!!! My pop3 access is going away in 8 days and I need a solution!!!

Thanks,

--Sean

Code: Select all

    <?php
    ////////////////////////////////////////// Settings //////////////////////////////////////////
    $server              = "pop.domaine.com";    //mail server.
    $user                 = "mail@domaine.com";    // Mail Username
    $password             = "STRONGPASSWORD";          // Mail Password
    $unreadonly           = "N";                  // if unreadonly is Y then process unread mail only 
   $delete               = "Y";                  // if delete is Y then processed mail will be deleted
    $debug                = "0";                  // Display Notices about in/outgoing emails 1 = on | 0 = off
    $category             = "1";                  // Hesk Category ID to trow all emails in
    $priority             = "3";                  // 3=Low 2=Medium 1=High
    /////////////////////////////////////////////////////////////////////////////////////////////

   define('IN_SCRIPT',1);
   define('HESK_PATH','');

   if (!function_exists('imap_open')) die("IMAP functions are not available.");
   if ($debug==1) error_reporting(E_ALL); else error_reporting(0);

   // Get all the required files and functions
   require(HESK_PATH . 'hesk_settings.inc.php');
   require(HESK_PATH . 'inc/common.inc.php');
   require(HESK_PATH . 'inc/email_functions.inc.php');

   // Connect to database
   require(HESK_PATH . 'inc/database.inc.php');

   hesk_dbConnect() or hesk_error("$hesklang[cant_connect_db] $hesklang[contact_webmsater] $hesk_settings[webmaster_mail]!");

   // $host = "{".$server.":143}"."INBOX";
   $host = "{".$server.":993/imap/ssl/novalidate-cert}"."INBOX";

   $conn    = imap_open($host, $user, $password) or die("<br><br><b>Error: Can't connect to mailbox</b>");
   $check = imap_mailboxmsginfo($conn);
   
   if ($unreadonly == "Y") {
      $msgnos = imap_search($conn, 'UNSEEN');
   } else {
      $msgnos = imap_search($conn, 'ALL');
   }
   foreach ($msgnos as $msgno) {
      list($subject, $name, $email, $date, $message, $trackingID) = getMessage($conn, $msgno);
      
      if (!$trackingID) {
         $trackingID = hesk_createID();   // create new trackingID 
         $myattachments = create_attachment($conn, $msgno, $trackingID ); // create attachement 
         $trackingID = createNewTicket($subject, $name, $email, $date, $message, $trackingID ,$myattachments );
      } else {
         $myattachments = create_attachment($conn, $msgno, $trackingID );
         createNewReply($subject, $name, $email, $date, $message, $trackingID, $myattachments);
      }
      
      if ($delete == "Y") imap_delete($conn, $msgno);  // mark the current message for deletion
   }
   if ($delete == "Y") imap_expunge($conn);  // delete all messages marked for deletion
   imap_close($conn);
   
   function extract_attachments($connection, $message_number) {
      $structure = imap_fetchstructure($connection, $message_number);
         
      $attachments = array();
      if(isset($structure->parts) && count($structure->parts)) {

         for($i = 0; $i < count($structure->parts); $i++) {

            $attachments[$i] = array(
               'is_attachment' => false,
               'filename' => '',
               'name' => '',
               'attachment' => ''
            );
            
            if($structure->parts[$i]->ifdparameters) {
               foreach($structure->parts[$i]->dparameters as $object) {
                  if(strtolower($object->attribute) == 'filename') {
                     $attachments[$i]['is_attachment'] = true;
                     $tmpfrom = imap_mime_header_decode($object->value);
                     $attachments[$i]['filename'] = quoted_printable_decode($tmpfrom[0]->text);
                  }
               }
            }
            
            if($structure->parts[$i]->ifparameters) {
               foreach($structure->parts[$i]->parameters as $object) {
                  if(strtolower($object->attribute) == 'name') {
                     $attachments[$i]['is_attachment'] = true;
                     $tmpfrom = imap_mime_header_decode($object->value);
                     $attachments[$i]['name'] = quoted_printable_decode($tmpfrom[0]->text);
                  }
               }
            }
            
            if($attachments[$i]['is_attachment']) {
               $attachments[$i]['attachment'] = imap_fetchbody($connection, $message_number, $i+1);
               if($structure->parts[$i]->encoding == 3) { // 3 = BASE64
                  $attachments[$i]['attachment'] = base64_decode($attachments[$i]['attachment']);
               }
               elseif($structure->parts[$i]->encoding == 4) { // 4 = QUOTED-PRINTABLE
                  $attachments[$i]['attachment'] = quoted_printable_decode($attachments[$i]['attachment']);
               }
            }
         }
      }
      return $attachments;
   }
   // Functions
   function getHeader($msgStream, $msgNumber) {
     // strips the mail header and places everything in an array .. like from name, from email, date and subject
     $mailheader = imap_headerinfo($msgStream, $msgNumber);
     $headerArray = array();
     $headerArray[0] = $mailheader->subject;
     $from = $mailheader->from;
     foreach ($from as $id => $object) {
      $headerArray[1]  = $object->personal;  // from personal
      $headerArray[2]  = $object->mailbox . "@" . $object->host;  // from address
     }
     $headerArray[3] = $mailheader->Date;

     return $headerArray;
   }

   function extractPlain($msgStream, $msgNumber, $st = null, $num = "")
   {
      // pull the plain text for message $n
      if (!$st) $st = imap_fetchstructure($msgStream, $msgNumber);
      if (!empty($st->parts)) {
        for ($i = 0, $j = count($st->parts); $i < $j; $i++) {
          $part = $st->parts[$i];
          if ($part->subtype == 'PLAIN') {
            return imap_fetchbody($msgStream, $msgNumber, $num.($i+1));
          }

          if (!empty($part->parts)) {
            $body = extractPlain($msgStream, $msgNumber, $part, ($i+1).".");
            if ($body) return $body;
          }
        }
      } else {
        return imap_body($msgStream, $msgNumber);
      }
   }

   function getMessage($msgStream, $msgNumber)
   {
      // pull the plain text for message $n
      $message =  mimeDecode(nl2br(extractPlain($msgStream, $msgNumber)));
      $headerArray = getHeader($msgStream, $msgNumber);
      $subject = mimeDecode(htmlentities(addslashes($headerArray[0])));
      $name    = mimeDecode(htmlentities(addslashes($headerArray[1])));
      $email   = htmlentities($headerArray[2]);
      $date    = htmlentities($headerArray[3]);
      $txt = "";
   
      if (preg_match("/- TrackingID: (.*)/", $subject, $matches)) {
         $trackingID = $matches[1];
      }
      
      return array($subject, $name, $email, $date, $message, $trackingID);
   }
   
   function mimeDecode($string)
   {
      $tmpfrom = imap_mime_header_decode($string);
      return quoted_printable_decode($tmpfrom[0]->text);
   }
   function createNewTicket($subject, $name, $email, $date, $message, $trackingID, $attachments)
   {
           
      global $category, $priority, $hesk_settings, $hesklang;
     
     $trackingURL = $hesk_settings['hesk_url'].'/ticket.php?track='.$trackingID;
   if (get_magic_quotes_gpc()) {$message = stripslashes($message);};
         $sql = "INSERT INTO `".hesk_dbEscape($hesk_settings['db_pfix'])."tickets` (`trackid`,`name`,`email`,`category`,`priority`,`subject`,`message`,`dt`,`lastchange`,`ip`,`status`,`attachments`,`custom1`,`custom2`,`custom3`,`custom4`,`custom5`) VALUES ('$trackingID','$name','$email','$category','$priority','$subject','".mysql_real_escape_string($message)."',NOW(),NOW(),'email','0','$attachments','','','','','')";


      $result = hesk_dbQuery($sql);
      
      /* Get e-mail message for customer */

      $ticket = array(
         'name'       => hesk_msgToPlain($name,1),
         'subject'    => hesk_msgToPlain($subject,1),
         'trackid'    => $trackingID,
         'category'    => $category,
         'priority'    => $priority,
         'message'    => hesk_msgToPlain($message,1)
      );
      
      $msg = hesk_getEmailMessage('new_ticket',$ticket);
                
      /* Send e-mail */
      $headers = "From: $hesk_settings[noreply_mail]\n";
      $headers.= "Reply-to: $hesk_settings[noreply_mail]\n";
      $headers.= "Return-Path: $hesk_settings[webmaster_mail]\n";
      $headers.= "Content-type: text/plain; charset=".$hesklang['ENCODING'];
      @mail($email,$hesklang['ticket_received']." - TrackingID: $trackingID",$msg,$headers);
      
      /* Need to notify any admins? */
     
      $admins=array();
      $sql = "SELECT `email`,`isadmin`,`categories` FROM `".hesk_dbEscape($hesk_settings['db_pfix'])."users` WHERE `notify_new_unassigned`='1'";
      $result = hesk_dbQuery($sql);
      while ($myuser=hesk_dbFetchAssoc($result))
      {
        /* Is this an administrator? */
        if ($myuser['isadmin']) {$admins[]=$myuser['email']; continue;}
        /* Not admin, is he allowed this category? */
        $cat=substr($myuser['categories'], 0, -1);
        $myuser['categories']=explode(',',$cat);
        if (in_array($category,$myuser['categories']))
        {
          $admins[]=$myuser['email']; continue;
        }
      }
     
     
      if (count($admins)>0)
      {
        $trackingURL_admin=$hesk_settings['hesk_url'].'/admin/admin_ticket.php?track='.$trackingID;

         $ticket = array(
            'name'       => hesk_msgToPlain($name,1),
            'subject'    => hesk_msgToPlain($subject,1),
            'trackid'    => $trackingID,
            'category'    => $category,
            'priority'    => $priority,
            'message'    => hesk_msgToPlain($message,1)
         );
      
        $msg = hesk_getEmailMessage('new_ticket_staff',$ticket);

        /* Send e-mail to staff */
        $email=implode(',',$admins);
        $headers = "From: $hesk_settings[noreply_mail]\n";
        $headers.= "Reply-to: $hesk_settings[noreply_mail]\n";
        $headers.= "Return-Path: $hesk_settings[webmaster_mail]\n";
        $headers.= "Content-type: text/plain; charset=".$hesklang['ENCODING'];
        @mail($email,$hesklang['new_ticket_submitted'],$msg,$headers);
      }

      echo "<h3>New ticket : $trackingID</h3>";
      return $trackingID;
   }

   function createNewReply($subject, $name, $email, $date, $message, $trackingID, $attachments)
   {
      global $hesk_settings, $hesklang;
      $trackingID = trim($trackingID);
      $trackingURL = $hesk_settings['hesk_url'].'/ticket.php?track='.$trackingID;
      $sql = "SELECT id FROM  `".hesk_dbEscape($hesk_settings['db_pfix'])."tickets` WHERE trackid='$trackingID'";
      $result = hesk_dbQuery($sql) or hesk_error("$hesklang[cant_sql]: $sql</p><p>$hesklang[mysql_said]:<br>".mysql_error()."</p><p>$hesklang[contact_webmsater] $hesk_settings[webmaster_mail]");
      $data = hesk_dbFetchAssoc($result);
      $replyto = $data["id"];

      /* Make sure the ticket is open */
      $sql = "UPDATE `".hesk_dbEscape($hesk_settings['db_pfix'])."tickets` SET `status`='1',`lastreplier`='0',`lastchange`=NOW() WHERE `id`=".hesk_dbEscape($replyto)." LIMIT 1";
      $result = hesk_dbQuery($sql);

      /* Add reply */
      $sql = "
      INSERT INTO `".hesk_dbEscape($hesk_settings['db_pfix'])."replies` (
      `replyto`,`name`,`message`,`dt`,`attachments`
      )
      VALUES (
      '".hesk_dbEscape($replyto)."',
      '".hesk_dbEscape($name)."',
      '".hesk_dbEscape($message)."',
      NOW(),
      '".hesk_dbEscape($attachments)."'
      )
      ";
      $result = hesk_dbQuery($sql);
      /* Need to notify any admins? */
      $admins=array();
      $sql = "SELECT `email`,`isadmin`,`categories` FROM `".hesk_dbEscape($hesk_settings['db_pfix'])."users` WHERE `notify_reply_my`='1'";
      $result = hesk_dbQuery($sql);
      while ($myuser=hesk_dbFetchAssoc($result))
      {
        /* Is this an administrator? */
        if ($myuser['isadmin']) {$admins[]=$myuser['email']; continue;}
        /* Not admin, is he allowed this category? */
        $cat=substr($myuser['categories'], 0, -1);
        $myuser['categories']=explode(",",$cat);
        if (in_array($category,$myuser['categories']))
        {
          $admins[]=$myuser['email']; continue;
        }
      }

      if (count($admins)>0)
      {
        /* Prepare ticket message for the e-mail */
        
        $message = hesk_msgToPlain($message,1);
        $trackingURL_admin = $hesk_settings['hesk_url'].'/admin/admin_ticket.php?track='.$trackingID;

        $ticket = array(
            'name'       => hesk_msgToPlain($name,1),
            'subject'    => hesk_msgToPlain($subject,1),
            'trackid'    => $trackingID,
            'category'    => $category,
            'priority'    => $priority,
            'message'    => hesk_msgToPlain($message,1)
         );
         
        $msg = hesk_getEmailMessage('new_reply_by_customer', $ticket);
   
        /* Send e-mail to staff */
        $email=implode(',',$admins);
        $headers = "From: $hesk_settings[noreply_mail]\n";
        $headers.= "Reply-to: $hesk_settings[noreply_mail]\n";
        $headers.= "Return-Path: $hesk_settings[webmaster_mail]\n";
        $headers.= "Content-type: text/plain; charset=".$hesklang['ENCODING'];
        @mail($email,$hesklang['new_reply_ticket'],$msg,$headers);
      }
      echo "<h3>new answer for ticket : $trackingID</h3>";
   }
   /*
    * Extract Attachment from mail
    * and create in Hesk Database
    */
   function create_attachment($conn, $uid, $trackingID)
   {
      global $hesk_settings, $hesklang;
      $trackingID = trim($trackingID);
      
      $myattachments = '';
      
      $attachments = extract_attachments($conn, $uid);
      for($i = 0; $i < count($attachments); $i++) {
         if ($attachments[$i]['is_attachment'] == true) {
                     
            $attachment = save_file($attachments[$i]);
            if (!empty($attachment))
            {
               $sql = "INSERT INTO `".hesk_dbEscape($hesk_settings['db_pfix'])."attachments` (`ticket_id`,`saved_name`,`real_name`,`size`) VALUES (
               '".hesk_dbEscape($trackingID)."',
               '".hesk_dbEscape($attachment['saved_name'])."',
               '".hesk_dbEscape($attachment['real_name'])."',
               '".hesk_dbEscape($attachment['size'])."'
               )";
               
               $result = hesk_dbQuery($sql);
               $myattachments .= hesk_dbInsertID() . '#' . $attachment['real_name'] .',';
            }
         }
      }
      
      return $myattachments;
   }
   /*
    * Save Attachment to disk
    */
   function save_file($attachement)
   {
      global $hesk_settings, $hesklang, $trackingID, $hesk_error_buffer;

      #$hesk_error_buffer .= '<br>BBBBBBBBBB';
      
      /* Return if name is empty */
      if (empty($attachement['name'])) {return '';}

      /* Check file extension */
      $ext = strtolower(strrchr($attachement['name'], "."));
      if ( ! in_array($ext,$hesk_settings['attachments']['allowed_types']))
      {
         return hesk_fileError(sprintf($hesklang['type_not_allowed'],$attachement['name'][$i]));
      }

      /* Check file size */
      if (strlen($attachement['attachment']) > ($hesk_settings['attachments']['max_size']*1024))
      {
         return hesk_fileError(sprintf($hesklang['file_too_large'],$attachement['name']));
      }
      else
      {
         $file_size = strlen($attachement['attachment']);
      }

      /* Generate a random file name */
      $file_realname = str_replace(array('/','\\','#',',',' '), array('','','','','_'),$attachement['name']);
      $useChars='AEUYBDGHJLMNPQRSTVWXZ123456789';
      $tmp = $useChars{mt_rand(0,29)};
      for($j=1;$j<10;$j++)
      {
         $tmp .= $useChars{mt_rand(0,29)};
      }

      if (defined('KB'))
      {
         $file_name = substr(md5($tmp . $file_realname), 0, 200) . $ext;
      }
      else
      {
         $file_name = substr($trackingID . '_' . md5($tmp . $file_realname), 0, 200) . $ext;
      }

      /* Save file */
      $fh = fopen($hesk_settings['server_path'].'/attachments/'.$file_name, 'w') or die("<br><br><b>can't open file</b>");
      fwrite($fh, $attachement['attachment']);
      fclose($fh);

      $info = array(
         'saved_name'=> $file_name,
         'real_name' => $file_realname,
         'size'      => $file_size
      );

      return $info;
   }
?>

Re: Email (Imap) Addon

Posted: Wed Jun 22, 2016 4:47 pm
by sp119
Actually there are a few issues with the code that make it problematic. First the attachments which I have already mentioned.

Second - if the customer replies to an email it updates the status to "waiting reply" but the reply doesn't actually go into the ticket. So you can tell they replied based on the status, but you don't actually see what they said.

I am not able to write PHP code well enough to try and fix these issues so I will most likely have to find another helpdesk solution.

I'm very surprised that IMAP hasn't taken a priority with this amazing helpdesk system. I REALLY like using Hesk and all the functionality it has, but since I HAVE to have IMAP and IMAP is not supported I must look elsewhere.