2018-09-22 01:35:41 +02:00
< ? php
2018-11-17 02:06:44 +01:00
include_once 'api/model.php' ;
2018-09-22 01:35:41 +02:00
2018-11-12 12:41:59 +01:00
try
{
2018-09-22 19:40:50 +02:00
//------------------------------------------------------------------
2018-11-17 02:06:44 +01:00
if ( $_SERVER [ 'REQUEST_METHOD' ] !== 'POST' ) api_return ( 400 , [ 'success' => false , 'error' => ERR :: REQ_METHOD , 'errhighlight' => - 1 , 'message' => 'Invalid request method (must be POST)' ]);
2018-11-13 16:23:04 +01:00
2018-11-12 12:41:59 +01:00
$INPUT = array_merge ( $_GET , $_POST );
2018-09-22 01:35:41 +02:00
2018-11-17 02:06:44 +01:00
if ( ! isset ( $INPUT [ 'user_id' ])) api_return ( 400 , [ 'success' => false , 'error' => ERR :: MISSING_UID , 'errhighlight' => 101 , 'message' => 'Missing parameter [[user_id]]' ]);
if ( ! isset ( $INPUT [ 'user_key' ])) api_return ( 400 , [ 'success' => false , 'error' => ERR :: MISSING_TOK , 'errhighlight' => 102 , 'message' => 'Missing parameter [[user_token]]' ]);
if ( ! isset ( $INPUT [ 'title' ])) api_return ( 400 , [ 'success' => false , 'error' => ERR :: MISSING_TITLE , 'errhighlight' => 103 , 'message' => 'Missing parameter [[title]]' ]);
2018-09-22 19:40:50 +02:00
//------------------------------------------------------------------
2018-09-22 01:35:41 +02:00
2018-11-12 12:41:59 +01:00
$user_id = $INPUT [ 'user_id' ];
$user_key = $INPUT [ 'user_key' ];
$message = $INPUT [ 'title' ];
2018-11-25 18:02:20 +01:00
$content = isset ( $INPUT [ 'content' ]) ? $INPUT [ 'content' ] : '' ;
$priority = isset ( $INPUT [ 'priority' ]) ? $INPUT [ 'priority' ] : '1' ;
$usrmsgid = isset ( $INPUT [ 'msg_id' ]) ? $INPUT [ 'msg_id' ] : null ;
$time = isset ( $INPUT [ 'timestamp' ]) ? $INPUT [ 'timestamp' ] : time ();
2018-09-22 01:35:41 +02:00
2018-09-22 19:40:50 +02:00
//------------------------------------------------------------------
2018-11-25 18:02:20 +01:00
if ( abs ( $time - time ()) > 60 * 60 * 24 * 2 ) api_return ( 400 , [ 'success' => false , 'error' => ERR :: TIMESTAMP_OUT_OF_RANGE , 'errhighlight' => - 1 , 'message' => 'The timestamp mus be within 24 hours of now()' ]);
2018-11-17 02:06:44 +01:00
if ( $priority !== '0' && $priority !== '1' && $priority !== '2' ) api_return ( 400 , [ 'success' => false , 'error' => ERR :: INVALID_PRIO , 'errhighlight' => 105 , 'message' => 'Invalid priority' ]);
2018-10-20 14:57:05 +02:00
2018-11-17 02:06:44 +01:00
if ( strlen ( trim ( $message )) == 0 ) api_return ( 400 , [ 'success' => false , 'error' => ERR :: NO_TITLE , 'errhighlight' => 103 , 'message' => 'No title specified' ]);
if ( $usrmsgid != null && strlen ( $usrmsgid ) > 64 ) api_return ( 400 , [ 'success' => false , 'error' => ERR :: USR_MSG_ID_TOO_LONG , 'errhighlight' => - 1 , 'message' => 'MessageID too long (64 characters)' ]);
2018-09-22 19:40:50 +02:00
//------------------------------------------------------------------
2018-09-22 01:35:41 +02:00
2018-11-12 12:41:59 +01:00
$pdo = getDatabase ();
2018-09-22 01:35:41 +02:00
2018-11-12 12:41:59 +01:00
$stmt = $pdo -> prepare ( 'SELECT user_id, user_key, fcm_token, messages_sent, quota_today, is_pro, quota_day FROM users WHERE user_id = :uid LIMIT 1' );
$stmt -> execute ([ 'uid' => $user_id ]);
2018-09-22 01:35:41 +02:00
2018-11-12 12:41:59 +01:00
$datas = $stmt -> fetchAll ( PDO :: FETCH_ASSOC );
2018-11-17 23:59:57 +01:00
if ( count ( $datas ) <= 0 ) api_return ( 401 , [ 'success' => false , 'error' => ERR :: USER_NOT_FOUND , 'errhighlight' => 101 , 'message' => 'User not found' ]);
2018-11-12 12:41:59 +01:00
$data = $datas [ 0 ];
2018-09-22 01:35:41 +02:00
2018-11-17 02:06:44 +01:00
if ( $data === null ) api_return ( 401 , [ 'success' => false , 'error' => ERR :: USER_NOT_FOUND , 'errhighlight' => 101 , 'message' => 'User not found' ]);
if ( $data [ 'user_id' ] !== ( int ) $user_id ) api_return ( 401 , [ 'success' => false , 'error' => ERR :: USER_NOT_FOUND , 'errhighlight' => 101 , 'message' => 'UserID not found' ]);
if ( $data [ 'user_key' ] !== $user_key ) api_return ( 401 , [ 'success' => false , 'error' => ERR :: USER_AUTH_FAILED , 'errhighlight' => 102 , 'message' => 'Authentification failed' ]);
2018-09-22 01:35:41 +02:00
2018-11-17 17:59:34 +01:00
//------------------------------------------------------------------
if ( strlen ( $message ) > 120 ) api_return ( 400 , [ 'success' => false , 'error' => ERR :: TITLE_TOO_LONG , 'errhighlight' => 103 , 'message' => 'Title too long (120 characters)' ]);
2020-08-03 13:25:49 +02:00
if ( strlen ( $content ) > Statics :: contentlen_max ( $data [ 'is_pro' ])) api_return ( 400 , [ 'success' => false , 'error' => ERR :: CONTENT_TOO_LONG , 'errhighlight' => 104 , 'message' => 'Content too long (' . strlen ( $content ) . ' characters; max := ' . Statics :: contentlen_max ( $data [ 'is_pro' ]) . ' characters)' ]);
2018-11-17 17:59:34 +01:00
//------------------------------------------------------------------
2018-11-12 12:41:59 +01:00
$fcm = $data [ 'fcm_token' ];
2018-09-22 01:35:41 +02:00
2018-11-12 12:41:59 +01:00
$new_quota = $data [ 'quota_today' ] + 1 ;
if ( $data [ 'quota_day' ] === null || $data [ 'quota_day' ] !== date ( " Y-m-d " )) $new_quota = 1 ;
2018-11-17 02:06:44 +01:00
if ( $new_quota > Statics :: quota_max ( $data [ 'is_pro' ])) api_return ( 403 , [ 'success' => false , 'error' => ERR :: QUOTA_REACHED , 'errhighlight' => - 1 , 'message' => 'Daily quota reached (' . Statics :: quota_max ( $data [ 'is_pro' ]) . ')' ]);
2018-09-22 19:57:00 +02:00
2018-11-12 15:19:10 +01:00
if ( $fcm == null || $fcm == '' || $fcm == false )
{
2018-11-17 02:06:44 +01:00
api_return ( 412 , [ 'success' => false , 'error' => ERR :: NO_DEVICE_LINKED , 'errhighlight' => - 1 , 'message' => 'No device linked with this account' ]);
2018-11-12 15:19:10 +01:00
}
2018-11-12 13:03:01 +01:00
//------------------------------------------------------------------
if ( $usrmsgid != null )
{
$stmt = $pdo -> prepare ( 'SELECT scn_message_id FROM messages WHERE sender_user_id=:uid AND usr_message_id IS NOT NULL AND usr_message_id=:umid LIMIT 1' );
$stmt -> execute ([ 'uid' => $user_id , 'umid' => $usrmsgid ]);
if ( count ( $stmt -> fetchAll ( PDO :: FETCH_ASSOC )) > 0 )
{
2018-11-17 02:06:44 +01:00
api_return ( 200 ,
2018-11-12 13:03:01 +01:00
[
'success' => true ,
'message' => 'Message already sent' ,
'suppress_send' => true ,
'response' => '' ,
'messagecount' => $data [ 'messages_sent' ] + 1 ,
'quota' => $data [ 'quota_today' ],
'is_pro' => $data [ 'is_pro' ],
'quota_max' => Statics :: quota_max ( $data [ 'is_pro' ]),
2018-11-17 02:06:44 +01:00
]);
2018-11-12 13:03:01 +01:00
}
}
2018-09-22 19:40:50 +02:00
//------------------------------------------------------------------
2018-09-22 01:35:41 +02:00
2018-11-12 15:51:06 +01:00
$pdo -> beginTransaction ();
2018-11-25 18:02:20 +01:00
$stmt = $pdo -> prepare ( 'INSERT INTO messages (sender_user_id, title, content, priority, sendtime, fcm_message_id, usr_message_id) VALUES (:suid, :t, :c, :p, :ts, :fmid, :umid)' );
2018-11-12 15:51:06 +01:00
$stmt -> execute (
[
'suid' => $user_id ,
't' => $message ,
'c' => $content ,
'p' => $priority ,
2018-11-25 18:02:20 +01:00
'ts' => $time ,
2018-11-12 15:51:06 +01:00
'fmid' => null ,
'umid' => $usrmsgid ,
]);
$scn_msg_id = $pdo -> lastInsertId ();
2018-11-12 12:41:59 +01:00
$url = " https://fcm.googleapis.com/fcm/send " ;
$payload = json_encode (
2018-09-22 01:35:41 +02:00
[
2018-11-12 12:41:59 +01:00
'to' => $fcm ,
//'dry_run' => true,
'android' => [ 'priority' => 'high' ],
//'notification' =>
//[
// 'title' => $message,
// 'body' => $content,
//],
'data' =>
2018-11-17 17:59:34 +01:00
[
'title' => $message ,
'body' => str_limit ( $content , 1900 ),
'trimmed' => ( strlen ( $content ) > 1900 ),
'priority' => $priority ,
2018-11-25 18:02:20 +01:00
'timestamp' => $time ,
2018-11-17 17:59:34 +01:00
'usr_msg_id' => $usrmsgid ,
'scn_msg_id' => $scn_msg_id ,
]
2018-11-12 12:41:59 +01:00
]);
$header =
[
'Authorization' => 'key=' . getConfig ()[ 'firebase' ][ 'server_key' ],
'Content-Type' => 'application/json' ,
];
try
{
$httpresult = sendPOST ( $url , $payload , $header );
2018-11-12 13:03:01 +01:00
if ( try_json ( $httpresult , [ 'success' ]) != 1 )
{
reportError ( " FCM communication failed (success_1 <> true) \n \n " . $httpresult );
2018-11-12 15:51:06 +01:00
$pdo -> rollBack ();
2018-11-17 02:06:44 +01:00
api_return ( 500 , [ 'success' => false , 'error' => ERR :: FIREBASE_COM_ERRORED , 'errhighlight' => - 1 , 'message' => 'Communication with firebase service failed.' ]);
2018-11-12 13:03:01 +01:00
}
2018-11-12 12:41:59 +01:00
}
catch ( Exception $e )
{
reportError ( " FCM communication failed " , $e );
2018-11-12 15:51:06 +01:00
$pdo -> rollBack ();
2018-11-17 02:06:44 +01:00
api_return ( 500 , [ 'success' => false , 'error' => ERR :: FIREBASE_COM_FAILED , 'errhighlight' => - 1 , 'message' => 'Communication with firebase service failed.' . " \n \n " . 'Exception: ' . $e -> getMessage ()]);
2018-11-12 12:41:59 +01:00
}
2018-11-17 17:59:34 +01:00
//------------------------------------------------------------------
2018-11-12 12:41:59 +01:00
$stmt = $pdo -> prepare ( 'UPDATE users SET timestamp_accessed=NOW(), messages_sent=messages_sent+1, quota_today=:q, quota_day=NOW() WHERE user_id = :uid' );
$stmt -> execute ([ 'uid' => $user_id , 'q' => $new_quota ]);
2018-11-12 15:51:06 +01:00
$stmt = $pdo -> prepare ( 'UPDATE messages SET fcm_message_id=:fmid WHERE scn_message_id=:smid' );
$stmt -> execute ([ 'fmid' => try_json ( $httpresult , [ 'results' , 0 , 'message_id' ]), 'smid' => $scn_msg_id ]);
$pdo -> commit ();
2018-11-12 13:03:01 +01:00
2018-11-17 17:59:34 +01:00
//------------------------------------------------------------------
2018-11-17 02:06:44 +01:00
api_return ( 200 ,
2018-11-12 12:41:59 +01:00
[
2018-11-12 13:03:01 +01:00
'success' => true ,
2018-11-13 16:23:04 +01:00
'error' => ERR :: NO_ERROR ,
'errhighlight' => - 1 ,
2018-11-12 13:03:01 +01:00
'message' => 'Message sent' ,
'suppress_send' => false ,
'response' => $httpresult ,
'messagecount' => $data [ 'messages_sent' ] + 1 ,
'quota' => $new_quota ,
'is_pro' => $data [ 'is_pro' ],
'quota_max' => Statics :: quota_max ( $data [ 'is_pro' ]),
2018-11-12 15:51:06 +01:00
'scn_msg_id' => $scn_msg_id ,
2018-11-17 02:06:44 +01:00
]);
2018-09-22 01:35:41 +02:00
}
2018-11-12 12:41:59 +01:00
catch ( Exception $mex )
2018-09-22 01:35:41 +02:00
{
2018-11-12 12:41:59 +01:00
reportError ( " Root try-catch triggered " , $mex );
2022-10-17 21:35:06 +02:00
if ( $pdo !== null && $pdo -> inTransaction ()) $pdo -> rollBack ();
2018-11-17 02:06:44 +01:00
api_return ( 500 , [ 'success' => false , 'error' => ERR :: INTERNAL_EXCEPTION , 'errhighlight' => - 1 , 'message' => 'PHP script threw exception.' . " \n \n " . 'Exception: ' . $e -> getMessage ()]);
2018-09-22 01:35:41 +02:00
}