ack messages on recieve

This commit is contained in:
Mike Schwörer 2018-11-12 15:51:06 +01:00
parent ae246e9219
commit 93ec261dc0
Signed by: Mikescher
GPG Key ID: D3C7172E0A70F8CF
7 changed files with 143 additions and 46 deletions

View File

@ -9,7 +9,8 @@ import java.util.TimeZone;
public class CMessage public class CMessage
{ {
public final long Timestamp ; public final long SCN_ID;
public final long Timestamp;
public final String Title; public final String Title;
public final String Content; public final String Content;
public final PriorityEnum Priority; public final PriorityEnum Priority;
@ -21,8 +22,9 @@ public class CMessage
_format.setTimeZone(TimeZone.getDefault()); _format.setTimeZone(TimeZone.getDefault());
} }
public CMessage(long t, String mt, String mc, PriorityEnum p) public CMessage(long id, long t, String mt, String mc, PriorityEnum p)
{ {
SCN_ID = id;
Timestamp = t; Timestamp = t;
Title = mt; Title = mt;
Content = mc; Content = mc;

View File

@ -38,14 +38,15 @@ public class CMessageList
String title = sharedPref.getString("message["+i+"].title", ""); String title = sharedPref.getString("message["+i+"].title", "");
String content = sharedPref.getString("message["+i+"].content", ""); String content = sharedPref.getString("message["+i+"].content", "");
PriorityEnum prio = PriorityEnum.parseAPI(sharedPref.getInt("message["+i+"].priority", 1)); PriorityEnum prio = PriorityEnum.parseAPI(sharedPref.getInt("message["+i+"].priority", 1));
long scnid = sharedPref.getLong("message["+i+"].scnid", 0);
Messages.add(new CMessage(time, title, content, prio)); Messages.add(new CMessage(scnid, time, title, content, prio));
} }
} }
public CMessage add(final long time, final String title, final String content, final PriorityEnum pe) public CMessage add(final long scnid, final long time, final String title, final String content, final PriorityEnum pe)
{ {
CMessage msg = new CMessage(time, title, content, pe); CMessage msg = new CMessage(scnid, time, title, content, pe);
boolean run = SCNApp.runOnUiThread(() -> boolean run = SCNApp.runOnUiThread(() ->
{ {
@ -58,11 +59,12 @@ public class CMessageList
while (Messages.size()>SCNSettings.inst().LocalCacheSize) Messages.remove(0); while (Messages.size()>SCNSettings.inst().LocalCacheSize) Messages.remove(0);
e.putInt("message_count", count+1); e.putInt( "message_count", count+1);
e.putLong("message["+count+"].timestamp", time); e.putLong( "message["+count+"].timestamp", time);
e.putString("message["+count+"].title", title); e.putString("message["+count+"].title", title);
e.putString("message["+count+"].content", content); e.putString("message["+count+"].content", content);
e.putInt("message["+count+"].priority", pe.ID); e.putInt( "message["+count+"].priority", pe.ID);
e.putLong( "message["+count+"].scnid", scnid);
e.apply(); e.apply();
@ -77,7 +79,7 @@ public class CMessageList
if (!run) if (!run)
{ {
Messages.add(new CMessage(time, title, content, pe)); Messages.add(new CMessage(scnid, time, title, content, pe));
fullSave(); fullSave();
} }
@ -109,10 +111,11 @@ public class CMessageList
for (int i = 0; i < Messages.size(); i++) for (int i = 0; i < Messages.size(); i++)
{ {
e.putLong("message["+i+"].timestamp", Messages.get(i).Timestamp); e.putLong( "message["+i+"].timestamp", Messages.get(i).Timestamp);
e.putString("message["+i+"].title", Messages.get(i).Title); e.putString("message["+i+"].title", Messages.get(i).Title);
e.putString("message["+i+"].content", Messages.get(i).Content); e.putString("message["+i+"].content", Messages.get(i).Content);
e.putInt("message["+i+"].priority", Messages.get(i).Priority.ID); e.putInt( "message["+i+"].priority", Messages.get(i).Priority.ID);
e.putLong( "message["+i+"].scnid", Messages.get(i).SCN_ID);
} }
e.apply(); e.apply();

View File

@ -41,7 +41,7 @@ public class ServerCommunication
@Override @Override
public void onFailure(Call call, IOException e) public void onFailure(Call call, IOException e)
{ {
e.printStackTrace(); Log.e("SC:register", e.toString());
SCNApp.showToast("Communication with server failed", 4000); SCNApp.showToast("Communication with server failed", 4000);
SCNApp.runOnUiThread(() -> { if (loader!=null)loader.setVisibility(View.GONE); }); SCNApp.runOnUiThread(() -> { if (loader!=null)loader.setVisibility(View.GONE); });
} }
@ -77,7 +77,7 @@ public class ServerCommunication
} }
catch (Exception e) catch (Exception e)
{ {
e.printStackTrace(); Log.e("SC:register", e.toString());
SCNApp.showToast("Communication with server failed", 4000); SCNApp.showToast("Communication with server failed", 4000);
} }
finally finally
@ -89,7 +89,7 @@ public class ServerCommunication
} }
catch (Exception e) catch (Exception e)
{ {
e.printStackTrace(); Log.e("SC:register", e.toString());
SCNApp.showToast("Communication with server failed", 4000); SCNApp.showToast("Communication with server failed", 4000);
} }
} }
@ -107,7 +107,7 @@ public class ServerCommunication
@Override @Override
public void onFailure(Call call, IOException e) public void onFailure(Call call, IOException e)
{ {
e.printStackTrace(); Log.e("SC:update_1", e.toString());
SCNApp.showToast("Communication with server failed", 4000); SCNApp.showToast("Communication with server failed", 4000);
SCNApp.runOnUiThread(() -> { if (loader!=null)loader.setVisibility(View.GONE); }); SCNApp.runOnUiThread(() -> { if (loader!=null)loader.setVisibility(View.GONE); });
} }
@ -143,7 +143,7 @@ public class ServerCommunication
} }
catch (Exception e) catch (Exception e)
{ {
e.printStackTrace(); Log.e("SC:update_1", e.toString());
SCNApp.showToast("Communication with server failed", 4000); SCNApp.showToast("Communication with server failed", 4000);
} }
finally finally
@ -155,7 +155,7 @@ public class ServerCommunication
} }
catch (Exception e) catch (Exception e)
{ {
e.printStackTrace(); Log.e("SC:update_1", e.toString());
SCNApp.showToast("Communication with server failed", 4000); SCNApp.showToast("Communication with server failed", 4000);
} }
} }
@ -171,7 +171,7 @@ public class ServerCommunication
client.newCall(request).enqueue(new Callback() { client.newCall(request).enqueue(new Callback() {
@Override @Override
public void onFailure(Call call, IOException e) { public void onFailure(Call call, IOException e) {
e.printStackTrace(); Log.e("SC:update_2", e.toString());
SCNApp.showToast("Communication with server failed", 4000); SCNApp.showToast("Communication with server failed", 4000);
} }
@ -201,7 +201,7 @@ public class ServerCommunication
SCNApp.refreshAccountTab(); SCNApp.refreshAccountTab();
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); Log.e("SC:update_2", e.toString());
SCNApp.showToast("Communication with server failed", 4000); SCNApp.showToast("Communication with server failed", 4000);
} finally { } finally {
SCNApp.runOnUiThread(() -> { SCNApp.runOnUiThread(() -> {
@ -213,7 +213,7 @@ public class ServerCommunication
} }
catch (Exception e) catch (Exception e)
{ {
e.printStackTrace(); Log.e("SC:update_2", e.toString());
SCNApp.showToast("Communication with server failed", 4000); SCNApp.showToast("Communication with server failed", 4000);
} }
} }
@ -229,7 +229,7 @@ public class ServerCommunication
client.newCall(request).enqueue(new Callback() { client.newCall(request).enqueue(new Callback() {
@Override @Override
public void onFailure(Call call, IOException e) { public void onFailure(Call call, IOException e) {
e.printStackTrace(); Log.e("SC:info", e.toString());
SCNApp.showToast("Communication with server failed", 4000); SCNApp.showToast("Communication with server failed", 4000);
SCNApp.runOnUiThread(() -> { SCNApp.runOnUiThread(() -> {
if (loader != null) loader.setVisibility(View.GONE); if (loader != null) loader.setVisibility(View.GONE);
@ -281,7 +281,7 @@ public class ServerCommunication
SCNApp.refreshAccountTab(); SCNApp.refreshAccountTab();
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); Log.e("SC:info", e.toString());
SCNApp.showToast("Communication with server failed", 4000); SCNApp.showToast("Communication with server failed", 4000);
} finally { } finally {
SCNApp.runOnUiThread(() -> { SCNApp.runOnUiThread(() -> {
@ -293,7 +293,7 @@ public class ServerCommunication
} }
catch (Exception e) catch (Exception e)
{ {
e.printStackTrace(); Log.e("SC:info", e.toString());
SCNApp.showToast("Communication with server failed", 4000); SCNApp.showToast("Communication with server failed", 4000);
} }
} }
@ -311,7 +311,7 @@ public class ServerCommunication
client.newCall(request).enqueue(new Callback() { client.newCall(request).enqueue(new Callback() {
@Override @Override
public void onFailure(Call call, IOException e) { public void onFailure(Call call, IOException e) {
e.printStackTrace(); Log.e("SC:upgrade", e.toString());
SCNApp.showToast("Communication with server failed", 4000); SCNApp.showToast("Communication with server failed", 4000);
} }
@ -341,7 +341,7 @@ public class ServerCommunication
SCNApp.refreshAccountTab(); SCNApp.refreshAccountTab();
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); Log.e("SC:upgrade", e.toString());
SCNApp.showToast("Communication with server failed", 4000); SCNApp.showToast("Communication with server failed", 4000);
} finally { } finally {
SCNApp.runOnUiThread(() -> { if (loader != null) loader.setVisibility(View.GONE); }); SCNApp.runOnUiThread(() -> { if (loader != null) loader.setVisibility(View.GONE); });
@ -356,6 +356,32 @@ public class ServerCommunication
} }
} }
public static void ack(int id, String key, CMessage msg)
{
try
{
Request request = new Request.Builder()
.url(BASE_URL + "ack.php?user_id=" + id + "&user_key=" + key + "&scn_msg_id=" + msg.SCN_ID)
.build();
client.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
Log.e("SC:ack", e.toString());
}
@Override
public void onResponse(Call call, Response response) {
// ????
}
});
}
catch (Exception e)
{
Log.e("SC:ack", e.toString());
}
}
private static boolean json_bool(JSONObject o, String key) throws JSONException private static boolean json_bool(JSONObject o, String key) throws JSONException
{ {
Object v = o.get(key); Object v = o.get(key);
@ -375,5 +401,4 @@ public class ServerCommunication
{ {
return o.getString(key); return o.getString(key);
} }
} }

View File

@ -8,6 +8,7 @@ import com.blackforestbytes.simplecloudnotifier.model.CMessage;
import com.blackforestbytes.simplecloudnotifier.model.CMessageList; import com.blackforestbytes.simplecloudnotifier.model.CMessageList;
import com.blackforestbytes.simplecloudnotifier.model.PriorityEnum; import com.blackforestbytes.simplecloudnotifier.model.PriorityEnum;
import com.blackforestbytes.simplecloudnotifier.model.SCNSettings; import com.blackforestbytes.simplecloudnotifier.model.SCNSettings;
import com.blackforestbytes.simplecloudnotifier.model.ServerCommunication;
import com.google.firebase.messaging.FirebaseMessagingService; import com.google.firebase.messaging.FirebaseMessagingService;
import com.google.firebase.messaging.RemoteMessage; import com.google.firebase.messaging.RemoteMessage;
@ -36,9 +37,9 @@ public class FBMService extends FirebaseMessagingService
String title = remoteMessage.getData().get("title"); String title = remoteMessage.getData().get("title");
String content = remoteMessage.getData().get("body"); String content = remoteMessage.getData().get("body");
PriorityEnum prio = PriorityEnum.parseAPI(remoteMessage.getData().get("priority")); PriorityEnum prio = PriorityEnum.parseAPI(remoteMessage.getData().get("priority"));
long scn_id = Long.parseLong(remoteMessage.getData().get("scn_msg_id"));
CMessage msg = CMessageList.inst().add(time, title, content, prio); CMessage msg = CMessageList.inst().add(scn_id, time, title, content, prio);
if (SCNApp.isBackground()) if (SCNApp.isBackground())
{ {
@ -48,6 +49,8 @@ public class FBMService extends FirebaseMessagingService
{ {
NotificationService.inst().showForeground(msg); NotificationService.inst().showForeground(msg);
} }
ServerCommunication.ack(msg);
} }
catch (Exception e) catch (Exception e)
{ {

47
web/ack.php Normal file
View File

@ -0,0 +1,47 @@
<?php
include_once 'model.php';
$INPUT = array_merge($_GET, $_POST);
if (!isset($INPUT['user_id'])) die(json_encode(['success' => false, 'errid'=>101, 'message' => 'Missing parameter [[user_id]]']));
if (!isset($INPUT['user_key'])) die(json_encode(['success' => false, 'errid'=>102, 'message' => 'Missing parameter [[user_key]]']));
if (!isset($INPUT['scn_msg_id'])) die(json_encode(['success' => false, 'errid'=>103, 'message' => 'Missing parameter [[scn_msg_id]]']));
$user_id = $INPUT['user_id'];
$user_key = $INPUT['user_key'];
$scn_msg_id = $INPUT['scn_msg_id'];
//----------------------
$pdo = getDatabase();
$stmt = $pdo->prepare('SELECT user_id, user_key, quota_today, is_pro, quota_day, fcm_token FROM users WHERE user_id = :uid LIMIT 1');
$stmt->execute(['uid' => $user_id]);
$datas = $stmt->fetchAll(PDO::FETCH_ASSOC);
if (count($datas)<=0) die(json_encode(['success' => false, 'errid'=>201, 'message' => 'User not found']));
$data = $datas[0];
if ($data === null) die(json_encode(['success' => false, 'errid'=>202, 'message' => 'User not found']));
if ($data['user_id'] !== (int)$user_id) die(json_encode(['success' => false, 'errid'=>203, 'message' => 'UserID not found']));
if ($data['user_key'] !== $user_key) die(json_encode(['success' => false, 'errid'=>204, 'message' => 'Authentification failed']));
$stmt = $pdo->prepare('SELECT ack FROM messages WHERE scn_message_id=:smid AND sender_user_id=:uid LIMIT 1');
$stmt->execute(['smid' => $scn_msg_id, 'uid' => $user_id]);
$datas = $stmt->fetchAll(PDO::FETCH_ASSOC);
if (count($datas)<=0) die(json_encode(['success' => false, 'errid'=>301, 'message' => 'Message not found']));
$stmt = $pdo->prepare('UPDATE messages SET ack=1 WHERE scn_message_id=:smid AND sender_user_id=:uid');
$stmt->execute(['smid' => $scn_msg_id, 'uid' => $user_id]);
echo json_encode(
[
'success' => true,
'prev_ack' => $datas[0]['ack'],
'new_ack' => 1,
'message' => 'ok'
]);
return 0;

View File

@ -24,12 +24,13 @@ CREATE TABLE `messages`
`sender_user_id` INT(11) NOT NULL, `sender_user_id` INT(11) NOT NULL,
`timestamp` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, `timestamp` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
`ack` BIT NOT NULL DEFAULT 0,
`title` VARCHAR(256) NOT NULL, `title` VARCHAR(256) NOT NULL,
`content` VARCHAR(12288) NULL, `content` VARCHAR(12288) NULL,
`priority` INT(11) NOT NULL, `priority` INT(11) NOT NULL,
`fcn_message_id` VARCHAR(256) NULL, `fcm_message_id` VARCHAR(256) NULL,
`usr_message_id` VARCHAR(256) NULL, `usr_message_id` VARCHAR(256) NULL,
PRIMARY KEY (`scn_message_id`) PRIMARY KEY (`scn_message_id`)

View File

@ -29,9 +29,10 @@ try
if ($priority !== '0' && $priority !== '1' && $priority !== '2') api_return(400, json_encode(['success' => false, 'error' => 1104, 'errhighlight' => 105, 'message' => 'Invalid priority'])); if ($priority !== '0' && $priority !== '1' && $priority !== '2') api_return(400, json_encode(['success' => false, 'error' => 1104, 'errhighlight' => 105, 'message' => 'Invalid priority']));
if (strlen(trim($message)) == 0) api_return(400, json_encode(['success' => false, 'error' => 1201, 'errhighlight' => 103, 'message' => 'No title specified'])); if (strlen(trim($message)) == 0) api_return(400, json_encode(['success' => false, 'error' => 1201, 'errhighlight' => 103, 'message' => 'No title specified']));
if (strlen($message) > 120) api_return(400, json_encode(['success' => false, 'error' => 1202, 'errhighlight' => 103, 'message' => 'Title too long (120 characters)'])); if (strlen($message) > 120) api_return(400, json_encode(['success' => false, 'error' => 1202, 'errhighlight' => 103, 'message' => 'Title too long (120 characters)']));
if (strlen($content) > 10000) api_return(400, json_encode(['success' => false, 'error' => 1203, 'errhighlight' => 104, 'message' => 'Content too long (10000 characters)'])); if (strlen($content) > 10000) api_return(400, json_encode(['success' => false, 'error' => 1203, 'errhighlight' => 104, 'message' => 'Content too long (10000 characters)']));
if ($usrmsgid != null && strlen($usrmsgid) > 64) api_return(400, json_encode(['success' => false, 'error' => 1204, 'errhighlight' => -1, 'message' => 'MessageID too long (64 characters)']));
//------------------------------------------------------------------ //------------------------------------------------------------------
@ -84,6 +85,22 @@ try
//------------------------------------------------------------------ //------------------------------------------------------------------
$pdo->beginTransaction();
$stmt = $pdo->prepare('INSERT INTO messages (sender_user_id, title, content, priority, fcm_message_id, usr_message_id) VALUES (:suid, :t, :c, :p, :fmid, :umid)');
$stmt->execute(
[
'suid' => $user_id,
't' => $message,
'c' => $content,
'p' => $priority,
'fmid' => null,
'umid' => $usrmsgid,
]);
$scn_msg_id = $pdo->lastInsertId();
$url = "https://fcm.googleapis.com/fcm/send"; $url = "https://fcm.googleapis.com/fcm/send";
$payload = json_encode( $payload = json_encode(
[ [
@ -102,6 +119,7 @@ try
'priority' => $priority, 'priority' => $priority,
'timestamp' => time(), 'timestamp' => time(),
'usr_msg_id' => $usrmsgid, 'usr_msg_id' => $usrmsgid,
'scn_msg_id' => $scn_msg_id,
] ]
]); ]);
$header= $header=
@ -117,28 +135,24 @@ try
if (try_json($httpresult, ['success']) != 1) if (try_json($httpresult, ['success']) != 1)
{ {
reportError("FCM communication failed (success_1 <> true)\n\n".$httpresult); reportError("FCM communication failed (success_1 <> true)\n\n".$httpresult);
$pdo->rollBack();
api_return(500, json_encode(['success' => false, 'error' => 9902, 'errhighlight' => -1, 'message' => 'Communication with firebase service failed.'])); api_return(500, json_encode(['success' => false, 'error' => 9902, 'errhighlight' => -1, 'message' => 'Communication with firebase service failed.']));
} }
} }
catch (Exception $e) catch (Exception $e)
{ {
reportError("FCM communication failed", $e); reportError("FCM communication failed", $e);
$pdo->rollBack();
api_return(500, json_encode(['success' => false, 'error' => 9901, 'errhighlight' => -1, 'message' => 'Communication with firebase service failed.'."\n\n".'Exception: ' . $e->getMessage()])); api_return(500, json_encode(['success' => false, 'error' => 9901, 'errhighlight' => -1, 'message' => 'Communication with firebase service failed.'."\n\n".'Exception: ' . $e->getMessage()]));
} }
$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 = $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]); $stmt->execute(['uid' => $user_id, 'q' => $new_quota]);
$stmt = $pdo->prepare('INSERT INTO messages (sender_user_id, title, content, priority, fcn_message_id, usr_message_id) VALUES (:suid, :t, :c, :p, :fmid, :umid)'); $stmt = $pdo->prepare('UPDATE messages SET fcm_message_id=:fmid WHERE scn_message_id=:smid');
$stmt->execute( $stmt->execute([ 'fmid' => try_json($httpresult, ['results', 0, 'message_id']), 'smid' => $scn_msg_id ]);
[
'suid' => $user_id, $pdo->commit();
't' => $message,
'c' => $content,
'p' => $priority,
'fmid' => try_json($httpresult, ['results', 0, 'message_id']),
'umid' => $usrmsgid,
]);
api_return(200, json_encode( api_return(200, json_encode(
[ [
@ -150,10 +164,12 @@ try
'quota' => $new_quota, 'quota' => $new_quota,
'is_pro' => $data['is_pro'], 'is_pro' => $data['is_pro'],
'quota_max' => Statics::quota_max($data['is_pro']), 'quota_max' => Statics::quota_max($data['is_pro']),
'scn_msg_id' => $scn_msg_id,
])); ]));
} }
catch (Exception $mex) catch (Exception $mex)
{ {
reportError("Root try-catch triggered", $mex); reportError("Root try-catch triggered", $mex);
if ($pdo->inTransaction()) $pdo->rollBack();
api_return(500, json_encode(['success' => false, 'error' => 9903, 'errhighlight' => -1, 'message' => 'PHP script threw exception.'."\n\n".'Exception: ' . $e->getMessage()])); api_return(500, json_encode(['success' => false, 'error' => 9903, 'errhighlight' => -1, 'message' => 'PHP script threw exception.'."\n\n".'Exception: ' . $e->getMessage()]));
} }