Тема: Kayako регестрируем тикеты от лица робота из коммандной строки
Задача: все сообщения посылаемые пользователям завернуть на систему суппорта в лице Kayako. То есть чтобы все отправлялась от лица этой системы и была история. Так же это даем возможность ответить пользователю на полученное письмо и оно попадет не в общий пулл а туда куда нужно и с первоначальной информацией. То есть админу не надо будит пытать пользователя или раскапывать самому в сем дело.
По сути этот принцип можно использовать где угодно.
Средства: Для отправки выбран curl (он везде есть) для самого сообщения xml (с ним умеет работать perl, php и все что угодно). Возможно так де использовать API если такой есть, но было решено не от него отказаться, так как криворукие индусы его меняют периодически, а этот принцип более дуракоупорный, плюс позволяет расширить возможности до безграничных.
Понеслася:
1. Создаем пользователя в системе, который и будит рассылать сообщения, пусть будит Robot.
2. Анализируем поля, которые отправляются во время создания сообшения
From newticketfrom
Subject newticketsubject
OWNER newticketownerstaffid
TYPE newtickettickettypeid
STATUS newticketticketstatusid
PRIORITY newticketticketpriorityid
Send email optnewticket_sendemail
DEPARTMENT newticketdepartmentid
To taginput_newticketto
Recurrence ends recurrence_endtype
Do not recur recurrencetype
TEXT newticketcontents
3. делаем два xml'a, для короткого (по умолчанию) и для полного, с возможностью менять все.
Короткий
# cat test.xml
<?xml version="1.0"?>
<message>
<date>
<newticketsubject>Command line autosubmit ticket script TEST!</newticketsubject>
<newticketcontents>
Test from command line
</newticketcontents>
<newticketdepartmentid>5</newticketdepartmentid>
<taginput_newticketto>[email protected]</taginput_newticketto>
</date>
</message>
Полный
# cat test_full.xml
<?xml version="1.0"?>
<message>
<date>
<newticketfrom>0</newticketfrom>
<newticketsubject>Command line autosubmit ticket script TEST FULL!!!</newticketsubject>
<newticketownerstaffid>12</newticketownerstaffid>
<newtickettickettypeid>1</newtickettickettypeid>
<newticketticketstatusid>4</newticketticketstatusid>
<newticketticketpriorityid>1</newticketticketpriorityid>
<optnewticket_sendemail>1</optnewticket_sendemail>
<newticketdepartmentid>5</newticketdepartmentid>
<taginput_newticketto>[email protected]</taginput_newticketto>
<recurrence_endtype>1</recurrence_endtype>
<recurrencetype>1</recurrencetype>
<newticketcontents>
Test from command line
</newticketcontents>
</date>
</message>
4. Сам скрипт который принимает xml и передает его дальше, разумеется его надо защитить, basic авторизация или по IP, дело вкуса.
# cat autosubmit.php
<pre>
<form enctype="multipart/form-data" action="autosubmit.php?send" method="POST">
<input name="uploadedfile" type="file" />
<input type="submit" value="go" />
</form>
<?php
/*
Alan Vezhbitskis
www.alan.lt
*/
$var_path = '/var/www/html/autosubmit/';
$var_url = 'https://kayako.domain.tld/';
function echoStandOutText($txt)
{
echo "<br>\n$txt\n<br>";
}
// upload
if (@isset ($_GET['send'])) {
$tme = time();
$rnd = rand(111,999);
$target_path = $var_path."tmp/send_".$tme."-".$rnd.".xml";
if(move_uploaded_file($_FILES['uploadedfile']['tmp_name'], $target_path)) {
echo "File ".basename( $_FILES['uploadedfile']['name'])." has been uploaded<br>\n";
} else {
echo "Error<br>\n";
}
} else {
die ("Error!<br>\n");
}
// xml parser
$data = implode("", file($target_path));
$parser = xml_parser_create();
xml_parse_into_struct($parser, $data, $values, $tags);
xml_parser_free($parser);
// data compact
foreach ($values as $k=>$v) {
if ($v['type'] == 'complete' and $v['level'] == '3') {
$t = strtolower($v['tag']);
$xml_date[$t] = $v['value'];
}
}
// data check
if (array_key_exists('newticketfrom', $xml_date)) {
// OK
} else { $xml_date['newticketfrom'] = "0"; }
if (array_key_exists('newticketsubject', $xml_date)) {
// OK
} else { die ("newticketfrom - no value<br>\n"); }
if (array_key_exists('newticketownerstaffid', $xml_date)) {
// OK
} else { $xml_date['newticketownerstaffid'] = ""; }
if (array_key_exists('newtickettickettypeid', $xml_date)) {
// OK
} else { $xml_date['newtickettickettypeid'] = "1"; }
if (array_key_exists('newticketticketstatusid', $xml_date)) {
// OK
} else { $xml_date['newticketticketstatusid'] = "4"; }
if (array_key_exists('newticketticketpriorityid', $xml_date)) {
// OK
} else { $xml_date['newticketticketpriorityid'] = "1"; }
if (array_key_exists('newticketcontents', $xml_date)) {
// OK
} else { die ("newticketcontents - no value<br>\n"); }
if (array_key_exists('optnewticket_sendemail', $xml_date)) {
// OK
} else { $xml_date['optnewticket_sendemail'] = "1"; }
if (array_key_exists('newticketdepartmentid', $xml_date)) {
// OK
} else { die ("newticketdepartmentid - no value<br>\n"); }
if (array_key_exists('taginput_newticketto', $xml_date)) {
// OK
} else { die ("taginput_newticketto - no value<br>\n"); }
if (array_key_exists('recurrence_endtype', $xml_date)) {
// OK
} else { $xml_date['recurrence_endtype'] = "1"; }
if (array_key_exists('recurrencetype', $xml_date)) {
// OK
} else { $xml_date['recurrencetype'] = "0"; }
// auth
$auth_cookies = $var_path."cookies.txt";
$auth_url = $var_url."staff/index.php?/Core/Default/Login";
$auth_fields_string = "";
$auth_fields = array(
'username'=>urlencode("autosubmit_user"),
'password'=>urlencode("autosubmit_user_password_@#$!@#$!@#$"),
'remember'=>'',
'languagecode'=>'',
'submitbutton'=>urlencode("Login")
);
// message
$sender_cookies = $var_path."cookies.txt";
$sender_url = $var_url."staff/index.php?/Tickets/Ticket/NewTicketSubmit/sendmail";
$sender_fields_string = "";
$sender_fields = array(
'newticketfrom'=>urlencode($xml_date['newticketfrom']),
'newticketsubject'=>urlencode($xml_date['newticketsubject']),
'newticketownerstaffid'=>urlencode($xml_date['newticketownerstaffid']),
'newtickettickettypeid'=>urlencode($xml_date['newtickettickettypeid']),
'newticketticketstatusid'=>urlencode($xml_date['newticketticketstatusid']),
'newticketticketpriorityid'=>urlencode($xml_date['newticketticketpriorityid']),
'newticketcontents'=>urlencode($xml_date['newticketcontents']),
'optnewticket_sendemail'=>urlencode($xml_date['optnewticket_sendemail']),
'newticketdepartmentid'=>urlencode($xml_date['newticketdepartmentid']),
'taginput_newticketto'=>urlencode($xml_date['taginput_newticketto']),
'recurrence_endtype'=>urlencode($xml_date['recurrence_endtype']),
'recurrencetype'=>urlencode($xml_date['recurrencetype']),
''=>urlencode(" OK ")
);
foreach($auth_fields as $key=>$value) { $auth_fields_string .= $key.'='.$value.'&'; }
$auth_fields_string=rtrim($auth_fields_string,"&");
foreach($sender_fields as $key=>$value) { $sender_fields_string .= $key.'='.$value.'&'; }
$sender_fields_string=rtrim($sender_fields_string,"&");
$ch = curl_init();
// send auth
curl_setopt ($ch, CURLOPT_USERAGENT,'ToTo/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.13) Gecko/20080311 Firefox/2.0.0.13');
curl_setopt ($ch, CURLOPT_URL,$auth_url);
curl_setopt ($ch, CURLOPT_POST,count($auth_fields));
curl_setopt ($ch, CURLOPT_POSTFIELDS,$auth_fields_string);
curl_setopt ($ch, CURLOPT_COOKIEJAR, $auth_cookies);
curl_setopt ($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt ($ch, CURLOPT_SSL_VERIFYPEER, false);
//$output = curl_exec ($ch);
if( ! $result = curl_exec($ch)) { trigger_error(curl_error($ch)); }
// send message
curl_setopt ($ch, CURLOPT_USERAGENT,'ToTo/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.13) Gecko/20080311 Firefox/2.0.0.13');
curl_setopt ($ch, CURLOPT_URL,$sender_url);
curl_setopt ($ch, CURLOPT_POST,count($sender_fields));
curl_setopt ($ch, CURLOPT_POSTFIELDS,$sender_fields_string);
curl_setopt ($ch, CURLOPT_COOKIEJAR, $sender_cookies);
curl_setopt ($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt ($ch, CURLOPT_SSL_VERIFYPEER, false);
//$output = curl_exec ($ch);
if( ! $result = curl_exec($ch)) { trigger_error(curl_error($ch)); }
curl_close($ch);
?>
5. Теперь из любой системы можно слать сообщения, главное знать кону отправлять, но обычно эти данные доступны локально или могут быть легко взяты с глобальной системы пользователей
/usr/bin/curl -k -F [email protected] https://kayako.domain.tld/autosubmit/autosubmit.php?send
Я это написал в основном для того чтобы рассылать сообщения о вирусах на хостинг серверах, но в последствии этот механизм стал применяться и при невыполнении критических крон скриптов и при проблемах с серверами (если мониторинг не чинится долгое время и никто не реагирует у админов появляется тикит, а тогда работает SLA и все такое, во общем проигнорировать уже не получится) и еще много где...