tkuester / taky

A simple python TAK server
MIT License
184 stars 43 forks source link

Feature Request: Store and forward for chat messages #53

Closed dB-SPL closed 2 years ago

dB-SPL commented 2 years ago

I think it would be a useful feature if the CoT server could store chat messages directed to specific UIDs until they are delivered, regardless of the stale time. Currently, users with intermittent connections to the server, especially when mobile, may still appear available to other users, but chat messages are not delivered.

For messages directed to "All Chat Rooms", I suspect it's more appropriate to only buffer messages for a certain length of time, if at all.

tkuester commented 2 years ago

This one may be a touch more tricky to implement.

The persistence store (in comparison) is fairly dumb... Here's a block of XML documents that should be sent to everyone when they connect! But this is more like a mailbox, and requires tracking of who's received what. I know that COT has a "message received" element for data packages, but I don't know if acknowledgements are sent for GeoChat.

Recognizing that a user is offline and storing the message for later delivery is easy. But I'm not sure how to guarantee that the message was received. Imagine a user with a spotty internet connection: the server tries to send the message to them, but it gets dropped.

Something that may be more feasible... Perhaps a docker image of sorts, with a bundled XMPP server, that has all the guarantees of the message delivery protocol built in. Perhaps even client data packages could be built with XMPP credentials? (I'm not sure on this one...)

I'd love to open this issue to the community for ideas, perhaps they know something that I'm missing!

dB-SPL commented 2 years ago

Yes, this would require more than just simple routing, so it's worth discussing whether it's a job for Taky at all.

I'd actually started working on an XMPP client that would run on an EUD and convert between XMPP and GeoChat, but that was creating conflicting endpoints for contacts. I'm open to other ideas, though.

There are two types of receipts for GeoChat. I believe that "b-t-f-d" is a "delivery receipt", and "b-t-f-r" is a "read receipt". Here is an example of a chat message as well as the receipts that were returned.


<event version="2.0" uid="GeoChat.S-1-5-21-1866384416-781808689-8705090412-1002.ROCK.ad279441-9d21-4d10-9512-23a9557a9bea" type="b-t-f" time="2022-01-02T04:55:11.11Z" start="2022-01-02T04:55:11.11Z" stale="2022-01-03T04:55:11.11Z" how="h-g-i-g-o"><point lat="33.9271440635634" lon="-84.5934567624001" hae="9999999" ce="6.0" le="9999999"/><detail><__chat id="ANDROID-4edf02a64d524b0b" chatroom="ROCK" senderCallsign="ROLL" groupOwner="false"><chatgrp id="ANDROID-4edf02a64d524b0b" uid0="S-1-5-21-1866384416-781808689-8705090412-1002" uid1="ANDROID-4edf02a64d524b0b"/></__chat><link uid="S-1-5-21-1866384416-781808689-8705090412-1002" type="a-f-A" relation="p-p"/><remarks source="BAO.F.WinTAK.S-1-5-21-1866384416-781808689-8705090412-1002" sourceID="S-1-5-21-1866384416-781808689-8705090412-1002" to="ANDROID-4edf02a64d524b0b" time="2022-01-02T04:55:11.11Z">ETA 1600 hrs</remarks><marti><dest callsign="ROCK"/></marti></detail></event>

<event version="2.0" uid="ad279441-9d21-4d10-9512-23a9557a9bea" type="b-t-f-d" how="m-g" time="2022-01-02T04:55:11.092Z" start="2022-01-02T04:55:11.092Z" stale="2022-01-03T04:55:11.092Z"><point lat="32.09958" lon="-81.26142" hae="121.3" ce="3.8" le="9999999.0"/><detail><__chatreceipt parent="RootContactGroup" groupOwner="false" messageId="ad279441-9d21-4d10-9512-23a9557a9bea" chatroom="ROLL" id="S-1-5-21-1866384416-781808689-8705090412-1002" senderCallsign="ROCK"><chatgrp uid0="ANDROID-4edf02a64d524b0b" uid1="S-1-5-21-1866384416-781808689-8705090412-1002" id="S-1-5-21-1866384416-781808689-8705090412-1002"/></__chatreceipt><link uid="ANDROID-4edf02a64d524b0b" type="a-f-G-U-C" relation="p-p"/><__serverdestination destinations="10.4.137.204:4242:tcp:ANDROID-4edf02a64d524b0b"/><marti><dest callsign="ROLL"/></marti></detail></event>

<event version="2.0" uid="ad279441-9d21-4d10-9512-23a9557a9bea" type="b-t-f-r" how="m-g" time="2022-01-02T04:55:11.198Z" start="2022-01-02T04:55:11.198Z" stale="2022-01-03T04:55:11.198Z"><point lat="32.09958" lon="-81.26142" hae="121.3" ce="3.8" le="9999999.0"/><detail><__chatreceipt parent="RootContactGroup" groupOwner="false" messageId="ad279441-9d21-4d10-9512-23a9557a9bea" chatroom="ROLL" id="S-1-5-21-1866384416-781808689-8705090412-1002" senderCallsign="ROCK"><chatgrp uid0="ANDROID-4edf02a64d524b0b" uid1="S-1-5-21-1866384416-781808689-8705090412-1002" id="S-1-5-21-1866384416-781808689-8705090412-1002"/></__chatreceipt><link uid="ANDROID-4edf02a64d524b0b" type="a-f-G-U-C" relation="p-p"/><__serverdestination destinations="10.4.137.204:4242:tcp:ANDROID-4edf02a64d524b0b"/><marti><dest callsign="ROLL"/></marti></detail></event>```
tkuester commented 2 years ago

Oh, wow! ATAK sends read / receive receipts? I didn't know that! Definitely makes it feasible...

I'm leaning towards it outside the realm of taky... ...but this might still be something you can write a plugin for. I still haven't completed the plugin framework. So perhaps I'll see if I can wire up the framework to handle something like this?

dB-SPL commented 2 years ago

Assuming user-created plugins have that kind of access, I'd be happy to write a plugin.

I'll keep an eye out for updates on the plugin framework, but I understand there's a lot of things that need to happen before 1.0.