]> nmode's Git Repositories - signal-cli/commitdiff
Implement json output for receive
authorAsamK <asamk@gmx.de>
Thu, 15 Jun 2017 21:45:14 +0000 (23:45 +0200)
committerAsamK <asamk@gmx.de>
Fri, 16 Jun 2017 10:05:22 +0000 (12:05 +0200)
src/main/java/org/asamk/signal/JsonAttachment.java [new file with mode: 0644]
src/main/java/org/asamk/signal/JsonCallMessage.java [new file with mode: 0644]
src/main/java/org/asamk/signal/JsonDataMessage.java [new file with mode: 0644]
src/main/java/org/asamk/signal/JsonError.java [new file with mode: 0644]
src/main/java/org/asamk/signal/JsonGroupInfo.java [new file with mode: 0644]
src/main/java/org/asamk/signal/JsonMessageEnvelope.java [new file with mode: 0644]
src/main/java/org/asamk/signal/JsonSyncMessage.java [new file with mode: 0644]
src/main/java/org/asamk/signal/Main.java
src/main/java/org/asamk/signal/storage/protocol/JsonSignalProtocolStore.java

diff --git a/src/main/java/org/asamk/signal/JsonAttachment.java b/src/main/java/org/asamk/signal/JsonAttachment.java
new file mode 100644 (file)
index 0000000..53946df
--- /dev/null
@@ -0,0 +1,21 @@
+package org.asamk.signal;
+
+import org.whispersystems.signalservice.api.messages.SignalServiceAttachment;
+import org.whispersystems.signalservice.api.messages.SignalServiceAttachmentPointer;
+
+class JsonAttachment {
+    String contentType;
+    long id;
+    int size;
+
+    JsonAttachment(SignalServiceAttachment attachment) {
+        this.contentType = attachment.getContentType();
+        final SignalServiceAttachmentPointer pointer = attachment.asPointer();
+        if (attachment.isPointer()) {
+            this.id = pointer.getId();
+            if (pointer.getSize().isPresent()) {
+                this.size = pointer.getSize().get();
+            }
+        }
+    }
+}
diff --git a/src/main/java/org/asamk/signal/JsonCallMessage.java b/src/main/java/org/asamk/signal/JsonCallMessage.java
new file mode 100644 (file)
index 0000000..98a01b2
--- /dev/null
@@ -0,0 +1,31 @@
+package org.asamk.signal;
+
+import org.whispersystems.signalservice.api.messages.calls.*;
+
+import java.util.List;
+
+class JsonCallMessage {
+    OfferMessage offerMessage;
+    AnswerMessage answerMessage;
+    BusyMessage busyMessage;
+    HangupMessage hangupMessage;
+    List<IceUpdateMessage> iceUpdateMessages;
+
+    JsonCallMessage(SignalServiceCallMessage callMessage) {
+        if (callMessage.getOfferMessage().isPresent()) {
+            this.offerMessage = callMessage.getOfferMessage().get();
+        }
+        if (callMessage.getAnswerMessage().isPresent()) {
+            this.answerMessage = callMessage.getAnswerMessage().get();
+        }
+        if (callMessage.getBusyMessage().isPresent()) {
+            this.busyMessage = callMessage.getBusyMessage().get();
+        }
+        if (callMessage.getHangupMessage().isPresent()) {
+            this.hangupMessage = callMessage.getHangupMessage().get();
+        }
+        if (callMessage.getIceUpdateMessages().isPresent()) {
+            this.iceUpdateMessages = callMessage.getIceUpdateMessages().get();
+        }
+    }
+}
diff --git a/src/main/java/org/asamk/signal/JsonDataMessage.java b/src/main/java/org/asamk/signal/JsonDataMessage.java
new file mode 100644 (file)
index 0000000..eda5402
--- /dev/null
@@ -0,0 +1,34 @@
+package org.asamk.signal;
+
+import org.whispersystems.signalservice.api.messages.SignalServiceAttachment;
+import org.whispersystems.signalservice.api.messages.SignalServiceDataMessage;
+
+import java.util.ArrayList;
+import java.util.List;
+
+class JsonDataMessage {
+    long timestamp;
+    String message;
+    int expiresInSeconds;
+    List<JsonAttachment> attachments;
+    JsonGroupInfo groupInfo;
+
+    JsonDataMessage(SignalServiceDataMessage dataMessage) {
+        this.timestamp = dataMessage.getTimestamp();
+        if (dataMessage.getGroupInfo().isPresent()) {
+            this.groupInfo = new JsonGroupInfo(dataMessage.getGroupInfo().get());
+        }
+        if (dataMessage.getBody().isPresent()) {
+            this.message = dataMessage.getBody().get();
+        }
+        this.expiresInSeconds = dataMessage.getExpiresInSeconds();
+        if (dataMessage.getAttachments().isPresent()) {
+            this.attachments = new ArrayList<>(dataMessage.getAttachments().get().size());
+            for (SignalServiceAttachment attachment : dataMessage.getAttachments().get()) {
+                this.attachments.add(new JsonAttachment(attachment));
+            }
+        } else {
+            this.attachments = new ArrayList<>();
+        }
+    }
+}
diff --git a/src/main/java/org/asamk/signal/JsonError.java b/src/main/java/org/asamk/signal/JsonError.java
new file mode 100644 (file)
index 0000000..05fe3ae
--- /dev/null
@@ -0,0 +1,9 @@
+package org.asamk.signal;
+
+class JsonError {
+    String message;
+
+    JsonError(Throwable exception) {
+        this.message = exception.getMessage();
+    }
+}
diff --git a/src/main/java/org/asamk/signal/JsonGroupInfo.java b/src/main/java/org/asamk/signal/JsonGroupInfo.java
new file mode 100644 (file)
index 0000000..89c5515
--- /dev/null
@@ -0,0 +1,24 @@
+package org.asamk.signal;
+
+import org.whispersystems.signalservice.api.messages.SignalServiceGroup;
+import org.whispersystems.signalservice.internal.util.Base64;
+
+import java.util.List;
+
+class JsonGroupInfo {
+    String groupId;
+    List<String> members;
+    String name;
+    String type;
+
+    JsonGroupInfo(SignalServiceGroup groupInfo) {
+        this.groupId = Base64.encodeBytes(groupInfo.getGroupId());
+        if (groupInfo.getMembers().isPresent()) {
+            this.members = groupInfo.getMembers().get();
+        }
+        if (groupInfo.getName().isPresent()) {
+            this.name = groupInfo.getName().get();
+        }
+        this.type = groupInfo.getType().toString();
+    }
+}
diff --git a/src/main/java/org/asamk/signal/JsonMessageEnvelope.java b/src/main/java/org/asamk/signal/JsonMessageEnvelope.java
new file mode 100644 (file)
index 0000000..2ce39cc
--- /dev/null
@@ -0,0 +1,36 @@
+package org.asamk.signal;
+
+import org.whispersystems.signalservice.api.messages.SignalServiceContent;
+import org.whispersystems.signalservice.api.messages.SignalServiceEnvelope;
+import org.whispersystems.signalservice.api.push.SignalServiceAddress;
+
+class JsonMessageEnvelope {
+    String source;
+    int sourceDevice;
+    String relay;
+    long timestamp;
+    boolean isReceipt;
+    JsonDataMessage dataMessage;
+    JsonSyncMessage syncMessage;
+    JsonCallMessage callMessage;
+
+    public JsonMessageEnvelope(SignalServiceEnvelope envelope, SignalServiceContent content) {
+        SignalServiceAddress source = envelope.getSourceAddress();
+        this.source = source.getNumber();
+        this.sourceDevice = envelope.getSourceDevice();
+        this.relay = source.getRelay().isPresent() ? source.getRelay().get() : null;
+        this.timestamp = envelope.getTimestamp();
+        this.isReceipt = envelope.isReceipt();
+        if (content != null) {
+            if (content.getDataMessage().isPresent()) {
+                this.dataMessage = new JsonDataMessage(content.getDataMessage().get());
+            }
+            if (content.getSyncMessage().isPresent()) {
+                this.syncMessage = new JsonSyncMessage(content.getSyncMessage().get());
+            }
+            if (content.getCallMessage().isPresent()) {
+                this.callMessage = new JsonCallMessage(content.getCallMessage().get());
+            }
+        }
+    }
+}
diff --git a/src/main/java/org/asamk/signal/JsonSyncMessage.java b/src/main/java/org/asamk/signal/JsonSyncMessage.java
new file mode 100644 (file)
index 0000000..92ad1cc
--- /dev/null
@@ -0,0 +1,24 @@
+package org.asamk.signal;
+
+import org.whispersystems.signalservice.api.messages.multidevice.ReadMessage;
+import org.whispersystems.signalservice.api.messages.multidevice.SignalServiceSyncMessage;
+
+import java.util.List;
+
+class JsonSyncMessage {
+    JsonDataMessage sentMessage;
+    List<String> blockedNumbers;
+    List<ReadMessage> readMessages;
+
+    JsonSyncMessage(SignalServiceSyncMessage syncMessage) {
+        if (syncMessage.getSent().isPresent()) {
+            this.sentMessage = new JsonDataMessage(syncMessage.getSent().get().getMessage());
+        }
+        if (syncMessage.getBlockedList().isPresent()) {
+            this.blockedNumbers = syncMessage.getBlockedList().get().getNumbers();
+        }
+        if (syncMessage.getRead().isPresent()) {
+            this.readMessages = syncMessage.getRead().get();
+        }
+    }
+}
index 9acb9fb6225072956357a13ead25d03b92caa80f..afd5a51574d5851a7cff35dfa975cb0b86c1cb45 100644 (file)
  */
 package org.asamk.signal;
 
+import com.fasterxml.jackson.annotation.JsonAutoDetect;
+import com.fasterxml.jackson.annotation.PropertyAccessor;
+import com.fasterxml.jackson.core.JsonGenerator;
+import com.fasterxml.jackson.databind.DeserializationFeature;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.SerializationFeature;
+import com.fasterxml.jackson.databind.node.ObjectNode;
 import net.sourceforge.argparse4j.ArgumentParsers;
 import net.sourceforge.argparse4j.impl.Arguments;
 import net.sourceforge.argparse4j.inf.*;
@@ -420,7 +427,8 @@ public class Main {
                     }
                     boolean ignoreAttachments = ns.getBoolean("ignore_attachments");
                     try {
-                        m.receiveMessages((long) (timeout * 1000), TimeUnit.MILLISECONDS, returnOnTimeout, ignoreAttachments, new ReceiveMessageHandler(m));
+                        final Manager.ReceiveMessageHandler handler = ns.getBoolean("json") ? new JsonReceiveMessageHandler(m) : new ReceiveMessageHandler(m);
+                        m.receiveMessages((long) (timeout * 1000), TimeUnit.MILLISECONDS, returnOnTimeout, ignoreAttachments, handler);
                     } catch (IOException e) {
                         System.err.println("Error while receiving messages: " + e.getMessage());
                         return 3;
@@ -822,6 +830,9 @@ public class Main {
         parserReceive.addArgument("--ignore-attachments")
                 .help("Don’t download attachments of received messages.")
                 .action(Arguments.storeTrue());
+        parserReceive.addArgument("--json")
+                .help("Output received messages in json format, one json object per line.")
+                .action(Arguments.storeTrue());
 
         Subparser parserDaemon = subparsers.addParser("daemon");
         parserDaemon.addArgument("--system")
@@ -1116,7 +1127,37 @@ public class Main {
                 }
             }
         }
+    }
+
+    private static class JsonReceiveMessageHandler implements Manager.ReceiveMessageHandler {
+        final Manager m;
+        final ObjectMapper jsonProcessor;
+
+        public JsonReceiveMessageHandler(Manager m) {
+            this.m = m;
+            this.jsonProcessor = new ObjectMapper();
+            jsonProcessor.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY); // disable autodetect
+            jsonProcessor.enable(SerializationFeature.WRITE_NULL_MAP_VALUES);
+            jsonProcessor.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
+            jsonProcessor.disable(JsonGenerator.Feature.AUTO_CLOSE_TARGET);
+        }
 
+        @Override
+        public void handleMessage(SignalServiceEnvelope envelope, SignalServiceContent content, Throwable exception) {
+            ObjectNode result = jsonProcessor.createObjectNode();
+            if (exception != null) {
+                result.putPOJO("error", new JsonError(exception));
+            }
+            if (envelope != null) {
+                result.putPOJO("envelope", new JsonMessageEnvelope(envelope, content));
+            }
+            try {
+                jsonProcessor.writeValue(System.out, result);
+                System.out.println();
+            } catch (IOException e) {
+                e.printStackTrace();
+            }
+        }
     }
 
     private static String formatTimestamp(long timestamp) {
index 885fdfb3d3e4959a07c078019cc19094d797c549..0085f0c7d3db7a915e12357ee6c0032045afab62 100644 (file)
@@ -8,7 +8,10 @@ import org.whispersystems.libsignal.IdentityKey;
 import org.whispersystems.libsignal.IdentityKeyPair;
 import org.whispersystems.libsignal.InvalidKeyIdException;
 import org.whispersystems.libsignal.SignalProtocolAddress;
-import org.whispersystems.libsignal.state.*;
+import org.whispersystems.libsignal.state.PreKeyRecord;
+import org.whispersystems.libsignal.state.SessionRecord;
+import org.whispersystems.libsignal.state.SignalProtocolStore;
+import org.whispersystems.libsignal.state.SignedPreKeyRecord;
 
 import java.util.List;
 import java.util.Map;