RCS file: pipe.php,v

retrieving revision 1.1

diff -u -r1.1 pipe.php

--- pipe.php 2010/10/19 21 1.1

+++ pipe.php 2010/11/08 19

@@ -13,7 +13,7 @@

See LICENSE.TXT for details.

vim: expandtab sw=4 ts=4 sts=4:

- $Id: pipe.php,v 1.1 2010/10/19 21 root Exp $

+ $Id: pipe.php,v 1.4 2010/11/08 19 root Exp root $

**********************************************************************/

Hi, can you post here your pipe.txt or send it to my mail please? I can't understand something posted here with rcsdiff.

my pipe.php:

#!/usr/bin/php -q

<?php

/*********************************************************************

pipe.php

Converts piped emails to ticket. Both local and remote!

Peter Rotich <peter@osticket.com>

Copyright (c) 2006-2010 osTicket

http://www.osticket.com

Released under the GNU General Public License WITHOUT ANY WARRANTY.

See LICENSE.TXT for details.

vim: expandtab sw=4 ts=4 sts=4:

$Id: $

**********************************************************************/

<USERMENTION username="chdir">@chdir</USERMENTION>(realpath(dirname(__FILE__)).'/'); //Change dir.

ini_set('memory_limit', '256M'); //The concern here is having enough mem for emails with attachments.

require('api.inc.php');

require_once(INCLUDE_DIR.'class.mailparse.php');

require_once(INCLUDE_DIR.'class.email.php');

//Make sure piping is enabled!

if(!$cfg->enableEmailPiping())

api_exit(EX_UNAVAILABLE,'Email piping not enabled - check MTA settings.');

//Get the input

$data=isset($_SERVER)?file_get_contents('php://input')('php://stdin');

if(empty($data)){

api_exit(EX_NOINPUT,'No data');

}

//Parse the email.

$parser= new Mail_Parse($data);

if(!$parser->decode()){ //Decode...returns false on decoding errors

api_exit(EX_DATAERR,'Email parse failed \n\n".$data);

}

//Check from address. make sure it is not a banned address.

$fromlist = $parser->getFromAddressList();

//Check for parsing errors on FROM address.

if(!$fromlist || PEAR:($fromlist)){

api_exit(EX_DATAERR,'Invalid FROM address \n\n".$data);

}

$from=$fromlist; //Default.

foreach($fromlist as $fromobj){

if(!Validator:($fromobj->mailbox.'@'.$fromobj->host))

continue;

$from=$fromobj;

break;

}

//TO Address to figure out the email associated with the message.

$tolist = $parser->getToAddressList();

foreach ($tolist as $toaddr){

if(($emailId=Email:($toaddr->mailbox.'@'.$toaddr->host))){

//We've found target email.

break;

}

}

if(!$emailId && ($cclist=$parser->getCcAddressList())) {

foreach ($cclist as $ccaddr){

if(($emailId=Email:($ccaddr->mailbox.'@'.$ccaddr->host))){

break;

}

}

}

//TODO: Options to reject emails without a matching To address in db? May be it was Bcc? Current Policy: If you pipe, we accept policy

require_once(INCLUDE_DIR.'class.ticket.php'); //We now need this bad boy!

$var=array();

$deptId=0;

$name=trim($from->personal,'"');

if($from->comment && $from->comment)

$name.=' ('.$from->comment.')';

$subj=utf8_encode($parser->getSubject());

//1

$subj=preg_replace('/^[\+/', '', $subj);

if(!($body=Format:($parser->getBody())) && $subj)

$body=$subj;

$var=$parser->getMessageId();

$var=$from->mailbox.'@'.$from->host;

$var=$name?utf8_encode($name):$var;

$var=$emailId?$emailId:$cfg->getDefaultEmailId();

$var=$subj?$subj:'';

$var=utf8_encode(Format:($body));

$var=$parser->getHeader();

$var=$cfg->useEmailPriority()?$parser->getPriority();

//2

$var=$parser->getStruct();

$var=$var->headers;

$var=$var->headers;

$var=trim($var);

$var=strlen($var);

$var=trim($var,'<>');

if ($var===strlen($var)+2) {

$var=preg_split('/>+</', $var, PREG_SPLIT_NO_EMPTY);

} else {

$var=array();

}

$var=trim($var);

$var=strlen($var);

$var=trim($var,'<>');

if ($var===strlen($var)+2) {

$var=preg_split('/>+</', $var, PREG_SPLIT_NO_EMPTY);

} else {

$var=array();

}

$var=array_unique(

array_merge($var, $var));

unset($var, $var, $var,

$var);

foreach($var as $k_mmestnik => $v_mmestnik){

$var='<'.$v_mmestnik.'>';

}

unset($k_mmestnik,$v_mmestnik);

openlog("OSTicket: Pipe", LOG_PID, LOG_MAIL);

syslog(LOG_DEBUG, 'Starting run for msg-id: '.$var);

$ticket=null;

foreach($var as $k_mmestnik => $v_mmestnik){

syslog(LOG_INFO, 'Search msg-id: '.$v_mmestnik);

$tickrow_mmestnik=db_query(

"SELECT ticket_id FROM ost_ticket_message WHERE messageId='$v_mmestnik'");

while($row_mmestnik = mysql_fetch_array($tickrow_mmestnik)) {

$tickid_mmestnik = $row_mmestnik;

syslog(LOG_NOTICE, 'Open ticket: '.$extid);

$ticket= new Ticket(Ticket:($extid));

if($ticket) break 2;

syslog(LOG_ERR, 'Open ticket '.$extid.' failed.');

}

}

# TODO: Look for more then one and handle what else is found.

unset($var, $k_mmestnik, $v_mmestnik, $tickrow_mmestnik,

$row_mmestnik, $tickid_mmestnik);

# TODO: Clean up mysql objects properly, how?

if(!$ticket && preg_match ('/',$var,$regs)) {

$extid=trim(preg_replace("/", "", $regs));

$ticket= new Ticket(Ticket:($extid));

//Allow mismatched emails?? For now hell NO.

list($message)=split($tag,$var);

//post message....postMessage does the cleanup.

if(!($msgid=$ticket->postMessage($message,'Email',$var,$var))) {

syslog(LOG_CRIT,'Ticket postMessage failed.');

api_exit(EX_DATAERR,"Unable to post message \n\n $message\n");

}

}

closelog();

//Ticket created...save attachments if enabled.

if($cfg->allowEmailAttachments()) {

if($attachments=$parser->getAttachments()){

}

}

api_exit(EX_SUCCESS);

return NULL;

?>

No results.

Maybe it's because I have mail title like "New ticket created ". I tried answering with different titles - new tickets only.

Maybe it's because "@chdir(realpath(dirname(__FILE__)).'/'); //Change dir."? I tried using "/var/www/ost/api/pipe.php" and "/var/www/ost/api/", where it's located.

Is this mod fully functional yet?

You would run any PHP code I supplied without reading it first? It's to your benefit to learn enough English to use our software and that's why we have not learned how to write applications using locals as this information is useless to us in other areas of our lives. Though if you plan on making use of computers learning how to use diff and patch should be of interest to you any time you are working with text files that change.

The "patch" program is what you are looking for. It's also possible that your pipe may differ from the one I'm using, in that case I'm supposed to be able to do something with an orig and rej files that patch produces. I'm eager to learn this process as this aspect of diff and patch are a mystery to me.

As this is a WIP it should only be available to developers currently.

This version uses tested preg options. The previous options were created following the documentation, it lied. There was also a bug where some variable names didn't match up. Causing the patch to not work at all.

I can only hope that this patch is closer to working.

# rcsdiff -ur1.1 pipe.php

===================================================================

RCS file: pipe.php,v

retrieving revision 1.1

diff -u -r1.1 pipe.php

--- pipe.php 2010/10/19 21 1.1

+++ pipe.php 2010/11/09 16

@@ -13,7 +13,7 @@

See LICENSE.TXT for details.

vim: expandtab sw=4 ts=4 sts=4:

- $Id: pipe.php,v 1.1 2010/10/19 21 root Exp $

+ $Id: pipe.php,v 1.5 2010/11/09 16 root Exp root $

**********************************************************************/

<USERMENTION username="chdir">@chdir</USERMENTION>(realpath(dirname(__FILE__)).'/'); //Change dir.

ini_set('memory_limit', '256M'); //The concern here is having enough mem for emails with attachments.

@@ -78,6 +78,7 @@

if($from->comment && $from->comment)

$name.=' ('.$from->comment.')';

$subj=utf8_encode($parser->getSubject());

+$subj=preg_replace('/^[\+/', '', $subj);

if(!($body=Format:($parser->getBody())) && $subj)

$body=$subj;

@@ -90,8 +91,55 @@

$var=$parser->getHeader();

$var=$cfg->useEmailPriority()?$parser->getPriority();

+$var=$parser->getStruct();

+$var=$var->headers;

+$var=$var->headers;

+$var=trim($var);

+$var=strlen($var);

+$var=trim($var,'<>');

+if ($var===strlen($var)+2) {

+ $var=preg_split('/>+</', $var);

+} else {

+ $var=array();

+}

+$var=trim($var);

+$var=strlen($var);

+$var=trim($var,'<>');

+if ($var===strlen($var)+2) {

+ $var=preg_split('/>+</', $var);

+} else {

+ $var=array();

+}

+$var=array_unique(

+ array_merge($var, $var));

+unset($var, $var, $var,

+ $var);

+foreach($var as $k_mmestnik => $v_mmestnik){

+ $var='<'.$v_mmestnik.'>';

+}

+unset($k_mmestnik,$v_mmestnik);

+

+openlog("OSTicket: Pipe", LOG_PID, LOG_MAIL);

+syslog(LOG_DEBUG, 'Starting run for msg-id: '.$var);

$ticket=null;

-if(preg_match ("",$var,$regs)) {

+foreach($var as $k_mmestnik => $v_mmestnik){

+ if (!$v_mmestnik) continue;

+ syslog(LOG_INFO, 'Search msg-id: '.$v_mmestnik);

+ $tickrow_mmestnik=db_query(

+ "SELECT ticket_id FROM ost_ticket_message WHERE messageId='$v_mmestnik'");

+ while($row_mmestnik = mysql_fetch_array($tickrow_mmestnik)) {

+ $tickid_mmestnik = $row_mmestnik;

+ syslog(LOG_NOTICE, 'Open ticket: '.$tickid_mmestnik);

+ $ticket= new Ticket(Ticket:($tickid_mmestnik));

+ if($ticket) break 2;

+ syslog(LOG_ERR, 'Open ticket '.$tickid_mmestnik.' failed.');

+ }

+}

+# TODO: Look for more then one and handle what else is found.

+unset($var, $k_mmestnik, $v_mmestnik, $tickrow_mmestnik,

+ $row_mmestnik, $tickid_mmestnik);

+# TODO: Clean up mysql objects properly, how?

+if(!$ticket && preg_match ('/',$var,$regs)) {

$extid=trim(preg_replace("/", "", $regs));

$ticket= new Ticket(Ticket:($extid));

//Allow mismatched emails?? For now hell NO.

@@ -113,9 +161,11 @@

list($message)=split($tag,$var);

//post message....postMessage does the cleanup.

if(!($msgid=$ticket->postMessage($message,'Email',$var,$var))) {

+ syslog(LOG_CRIT,'Ticket postMessage failed.');

api_exit(EX_DATAERR,"Unable to post message \n\n $message\n");

}

}

+closelog();

//Ticket created...save attachments if enabled.

if($cfg->allowEmailAttachments()) {

if($attachments=$parser->getAttachments()){

@@ -128,4 +178,5 @@

}

}

api_exit(EX_SUCCESS);

+return NULL;

?>

Here is the same file encoded to avoid being altered by the forum software, it's valid shell code.<<'EOF' tr -d '\n' | base64 -d | bzcat

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

kvYNv7h3mhQ2z8D/xdyRThQkP+qtQoA=

EOF

This is the next edit I'm trying. This corrects a vulnerable SQL injection as well as tries harder to pass the correct parameter to the OST API.

# rcsdiff -kk -qur1.5 -r1.6 pipe.php

--- pipe.php 2010/11/09 16 1.5

+++ pipe.php 2010/11/09 20 1.6

@@ -126,9 +126,11 @@

if (!$v_mmestnik) continue;

syslog(LOG_INFO, 'Search msg-id: '.$v_mmestnik);

$tickrow_mmestnik=db_query(

- "SELECT ticket_id FROM ost_ticket_message WHERE messageId='$v_mmestnik'");

+ 'SELECT ticketID FROM ost_ticket_message '.

+ 'STRAIGHT_JOIN ost_ticket ON ost_ticket_message.ticket_id = ost_ticket.ticket_id '.

+ 'WHERE messageId=\''. mysql_real_escape_string($v_mmestnik). '\'');

while($row_mmestnik = mysql_fetch_array($tickrow_mmestnik)) {

- $tickid_mmestnik = $row_mmestnik;

+ $tickid_mmestnik = $row_mmestnik;

syslog(LOG_NOTICE, 'Open ticket: '.$tickid_mmestnik);

$ticket= new Ticket(Ticket:($tickid_mmestnik));

if($ticket) break 2;

mmestnik, just I see rcsdiff first time, so I thought I could to make a mistake, modding my pipe.php.

As I understood, problem is wrong getting subject from mail title (encoding / parsing / preg rules).

That's one way of looking at it, if I understand you correctly.

Getting the ticket ID from the subject of an email would allow anyone who knows the ticket ID to be able to reply to a ticket(As described previously on this thread or other related threads).

IMHO Depending on ticket ID(s) at all is going to have issues, let's say the ID from the subject is accentually changed or altered by the user. This might cause a registered/authenticated user to post to the wrong ticket, bad+bad+bad=3*bad.

Using md5 or sha hashes is a great idea, although E-Mail has a usable concept called MessageID. MessageID(s) are randomly generated, typically by an email server, and should be uniq across the planet earth.

My patch uses MessageID(s) and *will* not use subject contents. I've just loaded a large mailman archive into my OST and the results look great, about %80 success. One issue worth noting is that Outlook and Exchange do not play nice. Microsoft has patches to correct this, look for In-Reply-To header issues.

The next round of patches that I'm going to look at are to get the MessageID to be placed in "outgoing" messages. VERP and ReplyTo headers will contain the MessageID so that replies to messages sent by OST will be threaded also.

That is the address used will look like this:

xisupport+DB5DFE73-A937-4B27-BD06-19CFEC512FDB=bluegecko.net@internalsupport.nagios.comWhere DB5DFE73-A937-4B27-BD06-19CFEC512FDB@bluegecko.net is the original MesageID. I was also thinking about submitting a self generated MessageID with the email, but as using VERP is better I'm not. It's something only useful in cases were VERP is not an option, in those cases changing Email servers is recommended solution.

Need assistance from OSTicket Developer.

I'm still looking for some assistance with this patch. I feel that there is a short-cut way to open a ticket by MessageID. Here is the current code that seams to do that: syslog(LOG_INFO, 'Search msg-id: '.$v_mmestnik);

$tickrow_mmestnik=db_query(

'SELECT ticketID FROM ost_ticket_message '.

'STRAIGHT_JOIN ost_ticket ON ost_ticket_message.ticket_id = ost_ticket.ticket_id '.

'WHERE messageId=\''. mysql_real_escape_string($v_mmestnik). '\'');

while($row_mmestnik = mysql_fetch_array($tickrow_mmestnik)) {

$tickid_mmestnik = $row_mmestnik;

syslog(LOG_NOTICE, 'Open ticket: '.$tickid_mmestnik);

$ticket= new Ticket(Ticket:($tickid_mmestnik));

if($ticket) break 2;

syslog(LOG_ERR, 'Open ticket '.$tickid_mmestnik.' failed.');

}

This code is working as intended, however I feel that the STRAIGHT_JOIN and the getIdByExtId are reciprocals, that is they can be factored out... If I only knew what I was doing.

As indicated the next step is to alter the way EMails are sent by OST to include a "cookie" that can be used later to map any reply or DSN(bounce message) back to the event and ticket that created it.

If user answered by mail, his message became an comment to his ticket (ok).

If staff answered by mail, his message became a new ticket (fail).

4 days later

Dang,

I came across that as well. Make all your templates start with: The real fix for this is to place credentials in *other* email headers that are not editable by the user. However this worked for now.

Alpha release of this patch.

All,

Now that I have something that I've tested and worked for me, this can be considered alpha. It's still missing VERP for messages sent by OST, however for our site this is not a version 1.0 requirement. Although as Dang reports this is a failure on some deployments as messages sent to OST are not typically sent to staff. On our deployment Mailman sends a copy of every message to staff and OST.

rcsdiff -kk -qur1.5 -r1.6 pipe.php

--- pipe.php 2010/11/09 16 1.5

+++ pipe.php 2010/11/09 20 1.6

@@ -126,9 +126,11 @@

if (!$v_mmestnik) continue;

syslog(LOG_INFO, 'Search msg-id: '.$v_mmestnik);

$tickrow_mmestnik=db_query(

- "SELECT ticket_id FROM ost_ticket_message WHERE messageId='$v_mmestnik'");

+ 'SELECT ticketID FROM ost_ticket_message '.

+ 'STRAIGHT_JOIN ost_ticket ON ost_ticket_message.ticket_id = ost_ticket.ticket_id '.

+ 'WHERE messageId=\''. mysql_real_escape_string($v_mmestnik). '\'');

while($row_mmestnik = mysql_fetch_array($tickrow_mmestnik)) {

- $tickid_mmestnik = $row_mmestnik;

+ $tickid_mmestnik = $row_mmestnik;

syslog(LOG_NOTICE, 'Open ticket: '.$tickid_mmestnik);

$ticket= new Ticket(Ticket:($tickid_mmestnik));

if($ticket) break 2;

# rcsdiff -kk -qur1.1 -r1. pipe.php

--- pipe.php 2010/10/19 21 1.1

+++ pipe.php 2010/11/09 20 1.6

@@ -78,6 +78,7 @@

if($from->comment && $from->comment)

$name.=' ('.$from->comment.')';

$subj=utf8_encode($parser->getSubject());

+$subj=preg_replace('/^[\+/', '', $subj);

if(!($body=Format:($parser->getBody())) && $subj)

$body=$subj;

@@ -90,8 +91,57 @@

$var=$parser->getHeader();

$var=$cfg->useEmailPriority()?$parser->getPriority();

+$var=$parser->getStruct();

+$var=$var->headers;

+$var=$var->headers;

+$var=trim($var);

+$var=strlen($var);

+$var=trim($var,'<>');

+if ($var===strlen($var)+2) {

+ $var=preg_split('/>+</', $var);

+} else {

+ $var=array();

+}

+$var=trim($var);

+$var=strlen($var);

+$var=trim($var,'<>');

+if ($var===strlen($var)+2) {

+ $var=preg_split('/>+</', $var);

+} else {

+ $var=array();

+}

+$var=array_unique(

+ array_merge($var, $var));

+unset($var, $var, $var,

+ $var);

+foreach($var as $k_mmestnik => $v_mmestnik){

+ $var='<'.$v_mmestnik.'>';

+}

+unset($k_mmestnik,$v_mmestnik);

+

+openlog("OSTicket: Pipe", LOG_PID, LOG_MAIL);

+syslog(LOG_DEBUG, 'Starting run for msg-id: '.$var);

$ticket=null;

-if(preg_match ("",$var,$regs)) {

+foreach($var as $k_mmestnik => $v_mmestnik){

+ if (!$v_mmestnik) continue;

+ syslog(LOG_INFO, 'Search msg-id: '.$v_mmestnik);

+ $tickrow_mmestnik=db_query(

+ 'SELECT ticketID FROM ost_ticket_message '.

+ 'STRAIGHT_JOIN ost_ticket ON ost_ticket_message.ticket_id = ost_ticket.ticket_id '.

+ 'WHERE messageId=\''. mysql_real_escape_string($v_mmestnik). '\'');

+ while($row_mmestnik = mysql_fetch_array($tickrow_mmestnik)) {

+ $tickid_mmestnik = $row_mmestnik;

+ syslog(LOG_NOTICE, 'Open ticket: '.$tickid_mmestnik);

+ $ticket= new Ticket(Ticket:($tickid_mmestnik));

+ if($ticket) break 2;

+ syslog(LOG_ERR, 'Open ticket '.$tickid_mmestnik.' failed.');

+ }

+}

+# TODO: Look for more then one and handle what else is found.

+unset($var, $k_mmestnik, $v_mmestnik, $tickrow_mmestnik,

+ $row_mmestnik, $tickid_mmestnik);

+# TODO: Clean up mysql objects properly, how?

+if(!$ticket && preg_match ('/',$var,$regs)) {

$extid=trim(preg_replace("/", "", $regs));

$ticket= new Ticket(Ticket:($extid));

//Allow mismatched emails?? For now hell NO.

@@ -113,9 +163,11 @@

list($message)=split($tag,$var);

//post message....postMessage does the cleanup.

if(!($msgid=$ticket->postMessage($message,'Email',$var,$var))) {

+ syslog(LOG_CRIT,'Ticket postMessage failed.');

api_exit(EX_DATAERR,"Unable to post message \n\n $message\n");

}

}

+closelog();

//Ticket created...save attachments if enabled.

if($cfg->allowEmailAttachments()) {

if($attachments=$parser->getAttachments()){

@@ -128,4 +180,5 @@

}

}

api_exit(EX_SUCCESS);

+return NULL;

?>

<<'EOF' tr -d '\n' | base64 -d | bzcat

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

EOF

This is a copy of the whole /var/www/html/osticket/api/pipe.php file:

<<'EOF' tr -d '\n' | base64 -d | bzcat

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

iY5IavgPHIEhRx8F/xdyRThQkG6NtZM=

EOF

Still looking for assistance from OST developers.

There is one bug I've discovered. Email replies are sent to the user and added into the web interface, however they don't change the ticket's status: Overdue -> Answered.

We are an all for one shop, so assigning tickets is not something that's popular. However the other status bits are important.

Some code to do this as well as help with some of the other question(s) I've raised would be appreciated.

Okay dumb question.

Where do I put this code?

Where to put this file.

There are not any dumb questions, however the answers certainly won't prevent you from doing something that starts your server on fire. Don't make me regret posting the full contents of the file by placing it on-top of something important... Patch files are a good way of preventing exactly that. There is another solution to this problem below.

You should already be familiar with the location of this file, though it's true we all forget things. It sounds like you may need to follow the email piping tutorial, if I'm allowed to read into your question. At some point you may have configured your mail server to run this file as an application to pipe mail messages to. The file's name need not be pipe.php, you could call it mypipe.php. It's important that this file be the one called by your mail software. It may also be important for this file to be located inside your osticket/api folder as exemplified below.

On my system this file is located here:

/var/www/html/osticket/api/pipe.php

2 months later

I'm trying to do one of these mods, but it doesn't seem to work.

Strage thing is, I'm applying this to api/pipe.php but all the changed that I make, I simply don't see anything happening.

Seems that it doesn't access that file to append the info to that ticket?

Some idea's?

7 months later

Receiving response from staff by email.

The patch below (against 1.6.0 ST) allows a response to be received from staff via imap / pop and then processed as if it had come from the web ui.

The response is deemed to be from 'staff' if the from email address matches the email address for the staff member in the staff table.

diff --git a/include/class.mailfetch.php b/include/class.mailfetch.php

--- a/include/class.mailfetch.php

+++ b/include/class.mailfetch.php

@@ -237,8 +237,8 @@

$var=$this->getPriority($mid);

$ticket=null;

- $newticket=true;

+ $staffId = 0;

//Check the subject line for possible ID.

if(preg_match ("",$var,$regs)) {

$extid=trim(preg_replace("/", "", $regs));

$ticket= new Ticket(Ticket:($extid));

@@ -241,9 +241,10 @@

//Check the subject line for possible ID.

if(preg_match ("",$var,$regs)) {

$extid=trim(preg_replace("/", "", $regs));

$ticket= new Ticket(Ticket:($extid));

- //Allow mismatched emails?? For now NO.

- if(!$ticket || strcasecmp($ticket->getEmail(),$var))

+ //Allow mismatched emails?? For now NO, unless it is a staff reply.

+ $staffId = $this->getStaffId($var);

+ if(!$ticket || (strcasecmp($ticket->getEmail(),$var) && $staffId == 0))

$ticket=null;

}

@@ -257,7 +258,12 @@

//Strip quoted reply...TODO: figure out how mail clients do it without special tag..

if($cfg->stripQuotedReply() && ($tag=$cfg->getReplySeparator()) && strpos($var,$tag))

list($message)=split($tag,$var);

- $msgid=$ticket->postMessage($message,'Email',$var,$var);

+ if ($staffId) {

+ $lastMsgId = $ticket->getLastMessageId();

+ $ticket->postResponseByStaff($staffId,$lastMsgId,$message);

+ } else {

+ $msgid=$ticket->postMessage($message,'Email',$var,$var);

+ }

}

//Save attachments if any.

if($msgid && $cfg->allowEmailAttachments()){

@@ -271,6 +277,16 @@

return $ticket;

}

+ function getStaffId($email) {

+ $staffId = 0;

+ $sql='SELECT staff_id FROM '.STAFF_TABLE.' WHERE email='.db_input($email);

+ if(($result=db_query($sql)) && db_num_rows($result)) {

+ $row = db_fetch_array($result);

+ $staffId = $row;

+ }

+ return $staffId;

+ }

+

function saveAttachments($ticket,$mid,$part,$index=0) {

global $cfg;

diff --git a/include/class.ticket.php b/include/class.ticket.php

--- a/include/class.ticket.php

+++ b/include/class.ticket.php

@@ -724,4 +724,11 @@

if(!$thisuser || !$thisuser->getId() || !$thisuser->isStaff()) //just incase

return 0;

+

+ return $this->postResponseByStaff($thisuser->getId(), $msgid, $response, $signature, $attachment, $canalert);

+

+ }

+

+ function postResponseByStaff($staffId,$msgid,$response,$signature='none',$attachment=false,$canalert=true){

+ global $thisuser,$cfg;

@@ -727,6 +734,12 @@

-

+ $ipAddress = '';

+ if($thisuser) {

+ $ipAddress = $thisuser->getIP();

+ }

+

+ $staff = new Staff($staffId);

+

$sql= 'INSERT INTO '.TICKET_RESPONSE_TABLE.' SET created=NOW() '.

',ticket_id='.db_input($this->getId()).

',msg_id='.db_input($msgid).

',response='.db_input(Format:($response)).

@@ -729,10 +742,10 @@

$sql= 'INSERT INTO '.TICKET_RESPONSE_TABLE.' SET created=NOW() '.

',ticket_id='.db_input($this->getId()).

',msg_id='.db_input($msgid).

',response='.db_input(Format:($response)).

- ',staff_id='.db_input($thisuser->getId()).

- ',staff_name='.db_input($thisuser->getName()).

- ',ip_address='.db_input($thisuser->getIP());

+ ',staff_id='.db_input($staffId).

+ ',staff_name='.db_input($staff->getName()).

+ ',ip_address='.db_input($ipAddress);

$resp_id=0;

//echo $sql;

if(db_query($sql) && ($resp_id=db_insert_id())):

@@ -1061,7 +1074,16 @@

return $id;

}

-

+ function getLastMessageId() {

+ $lastMessageId = 0;

+ $sql='SELECT ticketID,MAX(msg_id) AS lastMsgId FROM '.TICKET_TABLE. ' AS t '.

+ 'LEFT JOIN '.TICKET_MESSAGE_TABLE.' AS m USING(ticket_id) '.

+ 'WHERE t.ticketID='.db_input($this->extid);

+ if(($res=db_query($sql)) && db_num_rows($res))

+ list($ticketId,$lastMessageId)=db_fetch_row($res);

+ return $lastMessageId;

+ }

+

function getOpenTicketsByEmail($email){

$sql='SELECT count(*) as open FROM '.TICKET_TABLE.' WHERE status='.db_input('open').' AND email='.db_input($email);

a month later

I went through and made all the changes to the two files that were in the diff. It does indeed work now, when I send a reply back to the ticket it adds it to the ticket and notifies the end user.

However, now every two minutes when my cron.php runs, they're getting a notification that a staff member has replied to their message... Any ideas?

I have done the above from what I can tell exactly but this doesn't seem to be working for me. Any ideas?

5 months later

The patch below (against 1.6.0 ST) allows a response to be received from staff via imap / pop and then processed as if it had come from the web ui.

The response is deemed to be from 'staff' if the from email address matches the email address for the staff member in the staff table.

I don't understand how you would apply this patch. Does this only work on a Linux shell?

Hi! I'm trying to configure the email piping, but I don't know why it doesn't work... I've set up the mail configuration, and enable mail piping. Do I have to set up anything else in cPanel?

I read something about "forwarders", but I don't know how it works exactly.

Could someone help me, please?