Script URL: http://www.texthelp.org.uk/hs
Version of script: 2.6.6
Hosting company: North Hosts
URL of phpinfo.php:
URL of session_test.php:
What terms did you try when SEARCHING for a solution:
Lots!
Write your message below:
Hi,
Hoping someone may be able to help. I've been working on HESK so that SMS messages and Twitter DMs also come into HESK and can be replied to (I'm going to share the scripts once I've tidied them up a bit).
The downside to this is that obviously the replies don't have the HESK reference number so it creates a new ticket every time which have to be merged. The email address and name are always the same though, e.g. fakeuser@twitter.user. I want to be able to modify the script so it automatically merges tickets with the same email.
I've been reading through the delete_tickets.php and also looked at the hesk_mergeTickets function in admin_functions.inc.php but I can't quite work out the best way of achieving this merge. I'm guessing maybe having a separate script that runs via cron every minute to merge everything? I'm happy writing the code but would love a pointer as to where to start.
Thank you in advance!
Receiving and replying to Twitter DMs in HESK
Moderator: mkoch227
Receiving and replying to Twitter DMs in HESK
Last edited by texttt on Mon Apr 25, 2016 5:31 pm, edited 1 time in total.
Re: Merging tickets
Why bother merging, it would most likely be much easier to do everything in the script that processes SMS/Twitter:
1. get email
2. query the database to see if any existing tickets with that email exist
3. if yes, submit as a reply to that ticket
4. if no, submit as a new ticket
You could do something similar as the email2ticket function, just change the part that looks for a tracking ID in the subject to query the database for email isntead (step #2 above)
1. get email
2. query the database to see if any existing tickets with that email exist
3. if yes, submit as a reply to that ticket
4. if no, submit as a new ticket
You could do something similar as the email2ticket function, just change the part that looks for a tracking ID in the subject to query the database for email isntead (step #2 above)
Klemen, creator of HESK and PHPJunkyardWas this helpful? You can buy me a drink here 
You should follow me on Twitter here
Help desk software | Cloud help desk | Guestbook | Link manager | Click counter | more PHP Scripts ...
Also browse for php hosting companies, read php books, find php resources and use webmaster tools


Help desk software | Cloud help desk | Guestbook | Link manager | Click counter | more PHP Scripts ...
Also browse for php hosting companies, read php books, find php resources and use webmaster tools
Re: Merging tickets
Hi Klemen,
Many thanks for this, you're a genius! Never even thought of doing it this way, works perfectly.
For anyone else searching this in future, the barebones of my code to receive and reply to Twitter DMs from within HESK: -
Obviously the normal mysql connect and db select.
Then in your loop.
Where $msgfrom is the email address I you are searching for.
The full code to get Twitter messages if you want it is below - it sends an email to a mailbox which you will then have to pull through with HESK's POP3 function. This was deliberate on my part because the code deletes the message off Twitter so by having it go to email you have a backup in case of server failure etc. I use Yahoo mail which works well.
You will need to put a cron job running it pretty often or else multiple messages will fall out of sync as it emails the newest first. I run it every minute, the count=4 is because most hosts have a limit of 250 emails per hour although you may want to check yours has this otherwise emails could go missing.
Many thanks for this, you're a genius! Never even thought of doing it this way, works perfectly.
For anyone else searching this in future, the barebones of my code to receive and reply to Twitter DMs from within HESK: -
Obviously the normal mysql connect and db select.
Then in your loop.
Code: Select all
$result = mysql_query("SELECT *
FROM hesk_tickets
WHERE email = '$msgfrom'");
$row = mysql_fetch_array($result);
$subject = "[#" . $row['trackid'] . "]";
The full code to get Twitter messages if you want it is below - it sends an email to a mailbox which you will then have to pull through with HESK's POP3 function. This was deliberate on my part because the code deletes the message off Twitter so by having it go to email you have a backup in case of server failure etc. I use Yahoo mail which works well.
You will need to put a cron job running it pretty often or else multiple messages will fall out of sync as it emails the newest first. I run it every minute, the count=4 is because most hosts have a limit of 250 emails per hour although you may want to check yours has this otherwise emails could go missing.
Code: Select all
<?php
ini_set('display_errors', 1);
require_once('TwitterAPIExchange.php');
/** Set access tokens here - see: https://dev.twitter.com/apps/ **/
$settings = array(
'oauth_access_token' => "",
'oauth_access_token_secret' => "",
'consumer_key' => "",
'consumer_secret' => ""
);
/** Perform a GET request and echo the response **/
/** Note: Set the GET field BEFORE calling buildOauth(); **/
$url = 'https://api.twitter.com/1.1/direct_messages.json';
$getfield = '?full_text=true&count=4"';
$requestMethod = 'GET';
$twitter = new TwitterAPIExchange($settings);
$response = json_decode($twitter->setGetfield($getfield)
->buildOauth($url, $requestMethod)
->performRequest(), $assoc = TRUE);
mysql_connect("localhost", "user", "password") or die(mysql_error());
mysql_select_db("databasename") or die(mysql_error());
foreach($response as $items)
{
$url = 'https://api.twitter.com/1.1/direct_messages/show.json?';
$requestMethod = 'GET';
$getfields = array('id' => $items['id']);
$twitter = new TwitterAPIExchange($settings);
$do = $twitter->setGetfield($getfield)
->buildOauth($url, $requestMethod)
->performRequest();
extract($items);;
$msgfrom = $sender['screen_name']."@user.twitter";
$result = mysql_query("SELECT *
FROM hesk_tickets
WHERE email = '$msgfrom'");
$row = mysql_fetch_array($result);
$subject = "[#" . $row['trackid'] . "]";
/******** Uncomment for debugging *********************
echo "<strong>Tweet:</strong> ".$text."<br />";
echo "<strong>From:</strong> ".$msgfrom."<br />";
echo "<strong>Subject:</strong> ".$subject."<br /><br />";
*****************************************************************/
// PHP MAIL VERSION
$to = "PUT YOUR EMAIL HERE";
$headers = "From: " . $sender['screen_name'] . "<" .$msgfrom . ">";
mail($to,$subject,$text,$headers);
$url = 'https://api.twitter.com/1.1/direct_messages/destroy.json';
$requestMethod = 'POST';
/** POST fields required by the URL above. See relevant docs as above **/
$postfields = array(
'id' => $id
);
/** Perform a POST request and echo the response **/
$twitter = new TwitterAPIExchange($settings);
$do = $twitter->buildOauth($url, $requestMethod)
->setPostfields($postfields)
->performRequest();
}
?>
Last edited by texttt on Mon Apr 25, 2016 4:44 pm, edited 3 times in total.
Re: Merging tickets
Then in email_functions.inc.php you need to change the first function hesk_mail() to this so that you can reply to Twitter DMs directly from within HESK. Make sure you fill in your own access tokens on line 14.
Code: Select all
function hesk_mail($to,$subject,$message)
{
$emaildomain = substr(strrchr($to, "@"), 1);
if($emaildomain == "user.twitter")
{
require_once('TwitterAPIExchange.php');
$split = explode('@',$to);
$name = $split[0];
/** Set access tokens here - see: https://dev.twitter.com/apps/ **/
$settings = array(
'oauth_access_token' => "",
'oauth_access_token_secret' => "",
'consumer_key' => "",
'consumer_secret' => ""
);
/** URL for REST request, see: https://dev.twitter.com/docs/api/1.1/ **/
$url = 'https://api.twitter.com/1.1/direct_messages/new.json';
$requestMethod = 'POST';
/** POST fields required by the URL above. See relevant docs as above **/
$postfields = array(
'screen_name' => $name,
'text' => $message
);
/** Perform a POST request and echo the response **/
$twitter = new TwitterAPIExchange($settings);
$do = $twitter->buildOauth($url, $requestMethod)
->setPostfields($postfields)
->performRequest();
ob_end_clean();
return true;
}
else
{
global $hesk_settings, $hesklang;
// Demo mode
if ( defined('HESK_DEMO') )
{
return true;
}
// Encode subject to UTF-8
$subject = "=?UTF-8?B?" . base64_encode( hesk_html_entity_decode($subject) ) . "?=";
// Setup "name <email>" for headers
if ($hesk_settings['noreply_name'])
{
$hesk_settings['from_header'] = "=?UTF-8?B?" . base64_encode( hesk_html_entity_decode($hesk_settings['noreply_name']) ) . "?= <" . $hesk_settings['noreply_mail'] . ">";
}
else
{
$hesk_settings['from_header'] = $hesk_settings['noreply_mail'];
}
// Uncomment for debugging
# echo "<p>TO: $to<br >SUBJECT: $subject<br >MSG: $message</p>";
# return true;
// Use PHP's mail function
if ( ! $hesk_settings['smtp'])
{
// Set additional headers
$headers = "From: $hesk_settings[from_header]\n";
$headers.= "Reply-To: $hesk_settings[from_header]\n";
$headers.= "Return-Path: $hesk_settings[webmaster_mail]\n";
$headers.= "Date: " . date(DATE_RFC2822) . "\n";
$headers.= "Content-Type: text/plain; charset=" . $hesklang['ENCODING'];
// Send using PHP mail() function
ob_start();
mail($to,$subject,$message,$headers);
$tmp = trim(ob_get_contents());
ob_end_clean();
return (strlen($tmp)) ? $tmp : true;
}
// Use a SMTP server directly instead
$smtp = new smtp_class;
$smtp->host_name = $hesk_settings['smtp_host_name'];
$smtp->host_port = $hesk_settings['smtp_host_port'];
$smtp->timeout = $hesk_settings['smtp_timeout'];
$smtp->ssl = $hesk_settings['smtp_ssl'];
$smtp->start_tls = $hesk_settings['smtp_tls'];
$smtp->user = $hesk_settings['smtp_user'];
$smtp->password = hesk_htmlspecialchars_decode($hesk_settings['smtp_password']);
$smtp->debug = 1;
// Start output buffering so that any errors don't break headers
ob_start();
// Send the e-mail using SMTP
$to_arr = explode(',',$to);
if ( ! $smtp->SendMessage($hesk_settings['noreply_mail'], $to_arr, array(
"From: $hesk_settings[from_header]",
"To: $to",
"Reply-To: $hesk_settings[from_header]",
"Return-Path: $hesk_settings[webmaster_mail]",
"Subject: " . $subject,
"Date: " . date(DATE_RFC2822),
"Content-Type: text/plain; charset=" . $hesklang['ENCODING']
), $message))
{
// Suppress errors unless we are in debug mode
if ($hesk_settings['debug_mode'])
{
$error = $hesklang['cnsm'] . ' ' . $to . '<br /><br />' .
$hesklang['error'] . ': ' . htmlspecialchars($smtp->error). '<br /><br />' .
'<textarea name="smtp_log" rows="10" cols="60">' . ob_get_contents() . '</textarea>';
ob_end_clean();
hesk_error($error);
}
else
{
$_SESSION['HESK_2ND_NOTICE'] = true;
$_SESSION['HESK_2ND_MESSAGE'] = $hesklang['esf'] . ' ' . $hesklang['contact_webmsater'] . ' <a href="mailto:' . $hesk_settings['webmaster_mail'] . '">' . $hesk_settings['webmaster_mail'] . '</a>';
}
}
ob_end_clean();
return true;
}
} // END hesk_mail()
Re: Merging tickets
Finally you need to put TwitterAPIExchange.php in your inc folder.
I can't post this on the forum because it doesn't accept it but the code is here: -
https://github.com/J7mbo/twitter-api-ph ... change.php
I can't post this on the forum because it doesn't accept it but the code is here: -
https://github.com/J7mbo/twitter-api-ph ... change.php
Last edited by texttt on Mon Apr 25, 2016 4:51 pm, edited 2 times in total.
Re: Merging tickets
And that's it! Nowhere as neat as Klemen's code but it works. The first time you run it you will get the last month's worth of Twitter DMs come through so make sure you run it when it can be supervised initially.
Re: Merging tickets
Thanks for sharing your work!
My opinion is that the code should work first before anything else; if it's "neat" and easy to maintain (not that my code is) that's a bonus for developers, but it doesn't give any bonus functionality to the end user
My opinion is that the code should work first before anything else; if it's "neat" and easy to maintain (not that my code is) that's a bonus for developers, but it doesn't give any bonus functionality to the end user

Klemen, creator of HESK and PHPJunkyardWas this helpful? You can buy me a drink here 
You should follow me on Twitter here
Help desk software | Cloud help desk | Guestbook | Link manager | Click counter | more PHP Scripts ...
Also browse for php hosting companies, read php books, find php resources and use webmaster tools


Help desk software | Cloud help desk | Guestbook | Link manager | Click counter | more PHP Scripts ...
Also browse for php hosting companies, read php books, find php resources and use webmaster tools
Re: Receiving and replying to Twitter DMs in HESK
Thanks Klemen
your code is great very easy to work on.
I've tested this with Mods for Hesk 2.5.5 and it works fine, the only change is that the hesk_mail function is different. Version for Mods for Hesk email_functions.inc.php is

I've tested this with Mods for Hesk 2.5.5 and it works fine, the only change is that the hesk_mail function is different. Version for Mods for Hesk email_functions.inc.php is
Code: Select all
function hesk_mail($to, $subject, $message, $htmlMessage, $modsForHesk_settings, $cc = array(), $bcc = array(), $hasMessageTag = false)
{
$emaildomain = substr(strrchr($to, "@"), 1);
if($emaildomain == "user.twitter")
{
require_once('TwitterAPIExchange.php');
$split = explode('@',$to);
$name = $split[0];
/** Set access tokens here - see: https://dev.twitter.com/apps/ **/
$settings = array(
'oauth_access_token' => "",
'oauth_access_token_secret' => "",
'consumer_key' => "",
'consumer_secret' => ""
);
/** URL for REST request, see: https://dev.twitter.com/docs/api/1.1/ **/
$url = 'https://api.twitter.com/1.1/direct_messages/new.json';
$requestMethod = 'POST';
/** POST fields required by the URL above. See relevant docs as above **/
$postfields = array(
'screen_name' => $name,
'text' => $message
);
/** Perform a POST request and echo the response **/
$twitter = new TwitterAPIExchange($settings);
$do = $twitter->buildOauth($url, $requestMethod)
->setPostfields($postfields)
->performRequest();
ob_end_clean();
return true;
}
else
{
global $hesk_settings, $hesklang, $ticket;
// Are we in demo mode or are all email fields blank? If so, don't send an email.
if (defined('HESK_DEMO')
|| (($to == NULL || $to == '')
&& ($cc == NULL || count($cc) == 0)
&& ($bcc == NULL || count($bcc) == 0))
) {
return true;
}
// Encode subject to UTF-8
$subject = "=?UTF-8?B?" . base64_encode(hesk_html_entity_decode($subject)) . "?=";
// Auto-generate URLs for HTML-formatted emails
$htmlMessage = hesk_makeURL($htmlMessage, '', false);
// Setup "name <email>" for headers
if ($hesk_settings['noreply_name']) {
$hesk_settings['from_header'] = "=?UTF-8?B?" . base64_encode(hesk_html_entity_decode($hesk_settings['noreply_name'])) . "?= <" . $hesk_settings['noreply_mail'] . ">";
} else {
$hesk_settings['from_header'] = $hesk_settings['noreply_mail'];
}
// Uncomment for debugging
# echo "<p>TO: $to<br >SUBJECT: $subject<br >MSG: $message</p>";
# return true;
// Use mailgun
if ($modsForHesk_settings['use_mailgun']) {
ob_start();
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "https://api.mailgun.net/v2/" . $modsForHesk_settings['mailgun_domain'] . "/messages");
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
curl_setopt($ch, CURLOPT_USERPWD, 'api:' . $modsForHesk_settings['mailgun_api_key']);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($ch, CURLOPT_POST, true);
$postfields = array(
'from' => $hesk_settings['from_header'],
'to' => $to,
'h:Reply-To' => $hesk_settings['from_header'],
'subject' => $subject,
'text' => $message
);
if (count($cc) > 0) {
$postfields['cc'] = implode(',', $cc);
}
if (count($bcc) > 0) {
$postfields['bcc'] = implode(',', $bcc);
}
if ($modsForHesk_settings['html_emails']) {
$postfields['html'] = $htmlMessage;
}
if ($hasMessageTag && $modsForHesk_settings['attachments'] && $hesk_settings['attachments']['use'] && isset($ticket['attachments']) && strlen($ticket['attachments'])) {
$postfields = processDirectAttachments('mailgun', $postfields);
}
curl_setopt($ch, CURLOPT_POSTFIELDS, $postfields);
$result = curl_exec($ch);
curl_close($ch);
$tmp = trim(ob_get_contents());
ob_end_clean();
return (strlen($tmp)) ? $tmp : true;
}
$outerboundary = sha1(uniqid());
$innerboundary = sha1(uniqid());
if ($outerboundary == $innerboundary) {
$innerboundary .= '1';
}
$plaintextMessage = $message;
$message = "--" . $outerboundary . "\n";
$message .= "Content-Type: multipart/alternative; boundary=\"" . $innerboundary . "\"\n\n";
$message .= "--" . $innerboundary . "\n";
$message .= "Content-Type: text/plain; charset=" . $hesklang['ENCODING'] . "\n\n";
$message .= $plaintextMessage . "\n\n";
//Prepare the message for HTML or non-html
if ($modsForHesk_settings['html_emails']) {
$message .= "--" . $innerboundary . "\n";
$message .= "Content-Type: text/html; charset=" . $hesklang['ENCODING'] . "\n\n";
$message .= $htmlMessage . "\n\n";
}
//-- Close the email
$message .= "--" . $innerboundary . "--";
// Use PHP's mail function
if (!$hesk_settings['smtp']) {
// Set additional headers
$headers = '';
$headers .= "MIME-Version: 1.0\n";
$headers .= "From: $hesk_settings[from_header]\n";
if (count($cc) > 0) {
$headers .= "Cc: " . implode(',', $cc);
}
if (count($bcc) > 0) {
$headers .= "Bcc: " . implode(',', $bcc);
}
$headers .= "Reply-To: $hesk_settings[from_header]\n";
$headers .= "Return-Path: $hesk_settings[webmaster_mail]\n";
$headers .= "Date: " . date(DATE_RFC2822) . "\n";
$headers .= "Content-Type: multipart/mixed;boundary=\"" . $outerboundary . "\"";
// Add attachments if necessary
if ($hasMessageTag && $modsForHesk_settings['attachments'] && $hesk_settings['attachments']['use'] && isset($ticket['attachments']) && strlen($ticket['attachments'])) {
$message .= processDirectAttachments('phpmail', NULL, $outerboundary);
}
$message .= "\n\n" . '--' . $outerboundary . '--';
// Send using PHP mail() function
ob_start();
mail($to, $subject, $message, $headers);
$tmp = trim(ob_get_contents());
ob_end_clean();
return (strlen($tmp)) ? $tmp : true;
}
// Use a SMTP server directly instead
$smtp = new smtp_class;
$smtp->host_name = $hesk_settings['smtp_host_name'];
$smtp->host_port = $hesk_settings['smtp_host_port'];
$smtp->timeout = $hesk_settings['smtp_timeout'];
$smtp->ssl = $hesk_settings['smtp_ssl'];
$smtp->start_tls = $hesk_settings['smtp_tls'];
$smtp->user = $hesk_settings['smtp_user'];
$smtp->password = hesk_htmlspecialchars_decode($hesk_settings['smtp_password']);
$smtp->debug = 1;
// Start output buffering so that any errors don't break headers
ob_start();
// Send the e-mail using SMTP
$to_arr = explode(',', $to);
$headersArray = array(
"From: $hesk_settings[from_header]",
"To: $to",
"Reply-To: $hesk_settings[from_header]",
"Return-Path: $hesk_settings[webmaster_mail]",
"Subject: " . $subject,
"Date: " . date(DATE_RFC2822)
);
array_push($headersArray, "MIME-Version: 1.0");
array_push($headersArray, "Content-Type: multipart/mixed;boundary=\"" . $outerboundary . "\"");
if (count($cc) > 0) {
array_push($headersArray, "Cc: " . implode(',', $cc));
}
if (count($bcc) > 0) {
array_push($headersArray, "Bcc: " . implode(',', $bcc));
}
// Add attachments if necessary
if ($hasMessageTag && $modsForHesk_settings['attachments'] && $hesk_settings['attachments']['use'] && isset($ticket['attachments']) && strlen($ticket['attachments'])) {
$message .= processDirectAttachments('smtp', NULL, $outerboundary);
}
$message .= "\n\n" . '--' . $outerboundary . '--';
if (!$smtp->SendMessage($hesk_settings['noreply_mail'], $to_arr, $headersArray, $message)) {
// Suppress errors unless we are in debug mode
if ($hesk_settings['debug_mode']) {
$error = $hesklang['cnsm'] . ' ' . $to . '<br /><br />' .
$hesklang['error'] . ': ' . htmlspecialchars($smtp->error) . '<br /><br />' .
'<textarea name="smtp_log" rows="10" cols="60">' . ob_get_contents() . '</textarea>';
ob_end_clean();
hesk_error($error);
} else {
$_SESSION['HESK_2ND_NOTICE'] = true;
$_SESSION['HESK_2ND_MESSAGE'] = $hesklang['esf'] . ' ' . $hesklang['contact_webmsater'] . ' <a href="mailto:' . $hesk_settings['webmaster_mail'] . '">' . $hesk_settings['webmaster_mail'] . '</a>';
}
}
ob_end_clean();
return true;
}
} // END hesk_mail()