Last active
July 4, 2017 15:43
-
-
Save shtrih/22797dd16eac4d15702d to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
require_once "fnc/inc/ajax.php"; | |
$params = array( | |
'secret', | |
'from', | |
'message', | |
'message_id', | |
'sent_to', | |
'sent_timestamp', | |
'device_id', | |
'modem_id', # modem_id is fetched in .htaccess: RewriteRule ^sms-sync/?([0-9]+)?$ /sms-sync-handler.php?modem_id=$1 [L,QSA] | |
'queued_messages', | |
'message_results' | |
); | |
$values = array(); | |
foreach ($params as $param) { | |
if (isset($_REQUEST[ $param ])) { | |
$values[ $param ] = $_REQUEST[ $param ]; | |
} | |
} | |
$response = array( | |
'payload' => array( | |
'success' => true, | |
'error' => null | |
), | |
'code' => 200 | |
); | |
ajax_connect_db(); | |
$modem_id = 'SmsSync-' . $values['modem_id']; | |
$has_modem = Sql::queryValue('SELECT 42 FROM `sms_modems` WHERE `modem_id` = ' . Sql::quoteString($modem_id)); | |
# TODO: generate secret for each user | |
$is_secret_valid = isset($values['secret']) && 123456 == $values['secret']; | |
if (!$has_modem) { | |
$response['code'] = 403; | |
$response['payload']['success'] = false; | |
$response['payload']['error'] = 'Wrong device ID.'; | |
} | |
elseif (isset($_GET['task'])) { | |
$response['payload']['task'] = $_GET['task']; | |
$response['payload']['secret'] = 123456; | |
switch ($_GET['task']) { | |
case 'send': { | |
if ($is_secret_valid) { | |
include_once 'fnc/third-party/UUID.php'; | |
$limit = 1; | |
$response['payload']['messages'] = array(); | |
$now_irkutsk = new DateTime("now", new DateTimeZone("Asia/Irkutsk")); | |
$sql_time = Sql::quoteString($now_irkutsk->format("H:i:s")); | |
$queued_messages = Sql::queryAssoc($sql = "SELECT * FROM `sms_gsm_queue` WHERE | |
`processed` = 0 | |
AND `active` = 1 | |
AND `not_before` <= $sql_time | |
AND `not_after` >= $sql_time | |
AND `error` = 0 | |
AND (". SqlWhere::create()->eq('modem_id', $modem_id) ." OR `modem_id` = '') | |
ORDER BY `priority` DESC, `ttl`, `insertdate` LIMIT 0, " . (int)$limit); | |
foreach ($queued_messages as $message) { | |
$uuid = UUID::v4(); | |
$response['payload']['messages'][] = array( | |
'to' => '+' . $message['number'], | |
'message' => $message['text'], | |
'uuid' => $uuid | |
); | |
Sql::update( | |
'sms_gsm_queue', | |
array( | |
'modem_id' => $modem_id, | |
'message_uuid' => $uuid | |
), | |
SqlWhere::create()->eq('id', $message['id']) | |
); | |
} | |
} | |
else { | |
$response['code'] = 403; | |
$response['payload']['success'] = false; | |
$response['payload']['error'] = 'Wrong secret code.'; | |
} | |
} | |
break; | |
case 'sent': { | |
$response['message_uuids'] = array(); | |
if (isset($_POST['queued_messages']) && $_POST['queued_messages']) { | |
foreach ($_POST['queued_messages'] as $uuid) { | |
Sql::update( | |
'sms_gsm_queue', | |
array( | |
'processed' => 1, | |
), | |
SqlWhere::create()->eq('message_uuid', $uuid) | |
); | |
if (Sql::affectedRows()) | |
$response['message_uuids'][] = $uuid; | |
} | |
} | |
} | |
break; | |
/* | |
* To send SMS status delivery report back to the server, SMSsync will make a GET ?task=results to the server | |
* and should receive a list of message UUIDs that are waiting to receive delivery reports. | |
*/ | |
case 'result': | |
case 'results': { | |
/* | |
* Получение отчётов. | |
* { | |
"message_results": [ | |
{ | |
"uuid": "052bf515-ef6b-f424-c4ee", | |
"sent_result_code": 0, | |
"sent_result_message": "SMSSync Message Sent" | |
"delivered_result_code": -1, | |
"delivered_result_message": "" | |
}, | |
] | |
*/ | |
if (isset($_POST['message_results'])) { | |
foreach ($_POST['message_results'] as $message) { | |
/** | |
* Коды ошибок sent_result_code можно посмотреть: | |
* https://gist.github.com/mandric/11287748 | |
* http://developer.android.com/reference/android/telephony/SmsManager.html | |
*/ | |
if (0 == $message['sent_result_code'] && 0 == $message['delivered_result_code']) { | |
Sql::update( | |
'sms_gsm_queue', | |
array( | |
'subpath' => 'sent', | |
), | |
SqlWhere::create()->eq('message_uuid', $message['uuid']) | |
); | |
} | |
} | |
} | |
// отправить список сообщений, для которых нужно получить отчеты о доставке | |
else { | |
$limit = 10; | |
$response['message_uuids'] = Sql::queryAll("SELECT `message_uuid` FROM `sms_gsm_queue` WHERE | |
`processed` = 1 | |
AND `active` = 1 | |
AND `error` = 0 | |
AND `subpath` IS NULL | |
AND ". SqlWhere::create()->eq('modem_id', $modem_id) .' | |
ORDER BY `priority` DESC, `ttl`, `insertdate` LIMIT 0, ' . (int)$limit, array(-1 => 'message_uuid')); | |
} | |
} | |
break; | |
default: { | |
$response['code'] = 500; | |
$response['payload'] = array('success' => false, 'error' => 'Wrong task name.'); | |
} | |
} | |
} | |
// incoming messages | |
else { | |
if ($is_secret_valid) { | |
Sql::insert( | |
'sms_gsm_stat_message', | |
array( | |
'dir' => 'incoming', | |
'body_decoded' => $values['message'], | |
'date' => $values['sent_timestamp'] | |
) | |
); | |
$message_id = Sql::insertId(); | |
Sql::insert( | |
'sms_gsm_stat_message_header', | |
array( | |
'message_id' => $message_id, | |
'header' => 'Modem', | |
'value' => $modem_id | |
) | |
); | |
Sql::insert( | |
'sms_gsm_stat_message_header', | |
array( | |
'message_id' => $message_id, | |
'header' => 'From', | |
'value' => str_replace('+', '', $values['from']) | |
) | |
); | |
Sql::insert( | |
'sms_gsm_stat_message_header', | |
array( | |
'message_id' => $message_id, | |
'header' => 'Received', | |
'value' => gmdate('y-m-d H:i:s', $values['sent_timestamp']) | |
) | |
); | |
} | |
else { | |
$response['code'] = 403; | |
$response['payload']['success'] = false; | |
$response['payload']['error'] = 'Wrong secret code.'; | |
} | |
} | |
echoResponse($response); | |
function echoResponse($response) { | |
if ($response['code']/* > 200*/) { | |
error_log( | |
date_create('now', new DateTimeZone('Asia/Hong_Kong'))->format('[y-m-d H:i:s] ') . json_encode($_REQUEST) . ' | ' . $response['code'] .', '. json_encode($response) | |
. "\n" | |
, 3 | |
, './tmp/' . basename(__FILE__) . '.log' | |
); | |
} | |
Http::sendNoCacheHeaders(); | |
header('Content-Type: application/json; charset=UTF-8'); | |
echo json_encode($response); | |
exit; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
how does it work