mirror of
https://github.com/bbernhard/signal-cli-rest-api.git
synced 2026-05-29 15:14:28 +00:00
Signal Desktop v8.0.0 switched from string ACI fields to binary ACI encoding in protobuf messages. This breaks reactions, mentions, quotes, and other message features when the library cannot parse the new format. Two-part fix applied via patch to signal-cli v0.13.24 source build: 1. Bump signal-service-java from unofficial_137 to unofficial_138, which adds dual-format ACI parsing (string + binary fallback via ServiceId.parseOrNull). 2. Add defensive null guards in MessageEnvelope.java for cases where ServiceId resolution still fails (e.g. ACI.UNKNOWN). Preserves message content with UNKNOWN_UUID fallback rather than dropping entire message components (quotes, reactions, mentions, etc.). The patch is applied during the x86_64 source build. The source-built installDist output replaces the release tarball, so both the JVM and native (GraalVM) paths get the fix. Non-x86_64 architectures continue using the unpatched release tarball until signal-cli cuts a new release with unofficial_138. See: https://github.com/AsamK/signal-cli/pull/1944 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
90 lines
5.5 KiB
Diff
90 lines
5.5 KiB
Diff
Fix Signal Desktop v8.0.0 binary ACI encoding compatibility.
|
|
|
|
Signal Desktop v8.0.0 switched from string ACI fields to binary ACI encoding
|
|
in protobuf messages. This causes null ServiceId values when the library
|
|
cannot parse the new format, breaking reactions, mentions, quotes, and other
|
|
message features.
|
|
|
|
Two-part fix:
|
|
1. Bump signal-service-java from unofficial_137 to unofficial_138 which adds
|
|
dual-format ACI parsing (string + binary fallback).
|
|
2. Add defensive null guards in MessageEnvelope.java for cases where ServiceId
|
|
resolution still fails (e.g. ACI.UNKNOWN), preserving message content with
|
|
UNKNOWN_UUID fallback rather than dropping entire message components.
|
|
|
|
See: https://github.com/AsamK/signal-cli/pull/1944
|
|
|
|
diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml
|
|
index 9b1bd5f4..0000001 100644
|
|
--- a/gradle/libs.versions.toml
|
|
+++ b/gradle/libs.versions.toml
|
|
@@ -11,7 +11,7 @@ slf4j-api = { module = "org.slf4j:slf4j-api", version.ref = "slf4j" }
|
|
slf4j-jul = { module = "org.slf4j:jul-to-slf4j", version.ref = "slf4j" }
|
|
logback = "ch.qos.logback:logback-classic:1.5.25"
|
|
|
|
-signalservice = "com.github.turasa:signal-service-java:2.15.3_unofficial_137"
|
|
+signalservice = "com.github.turasa:signal-service-java:2.15.3_unofficial_138"
|
|
sqlite = "org.xerial:sqlite-jdbc:3.51.1.0"
|
|
hikari = "com.zaxxer:HikariCP:7.0.2"
|
|
junit-jupiter-bom = { module = "org.junit:junit-bom", version.ref = "junit" }
|
|
diff --git a/lib/src/main/java/org/asamk/signal/manager/api/MessageEnvelope.java b/lib/src/main/java/org/asamk/signal/manager/api/MessageEnvelope.java
|
|
index 37946057..57a5a0f4 100644
|
|
--- a/lib/src/main/java/org/asamk/signal/manager/api/MessageEnvelope.java
|
|
+++ b/lib/src/main/java/org/asamk/signal/manager/api/MessageEnvelope.java
|
|
@@ -132,6 +132,7 @@ public record MessageEnvelope(
|
|
return new Data(dataMessage.getTimestamp(),
|
|
dataMessage.getGroupContext().map(GroupContext::from),
|
|
dataMessage.getStoryContext()
|
|
+ .filter(s -> s.getAuthorServiceId() != null)
|
|
.map((SignalServiceDataMessage.StoryContext storyContext) -> StoryContext.from(storyContext,
|
|
recipientResolver,
|
|
addressResolver)),
|
|
@@ -143,9 +144,10 @@ public record MessageEnvelope(
|
|
dataMessage.isEndSession(),
|
|
dataMessage.isProfileKeyUpdate(),
|
|
dataMessage.getProfileKey().isPresent(),
|
|
- dataMessage.getReaction().map(r -> Reaction.from(r, recipientResolver, addressResolver)),
|
|
+ dataMessage.getReaction()
|
|
+ .filter(r -> r.getTargetAuthor() != null)
|
|
+ .map(r -> Reaction.from(r, recipientResolver, addressResolver)),
|
|
dataMessage.getQuote()
|
|
- .filter(q -> q.getAuthor() != null && q.getAuthor().isValid())
|
|
.map(q -> Quote.from(q, recipientResolver, addressResolver, fileProvider)),
|
|
dataMessage.getPayment().map(p -> p.getPaymentNotification().isPresent() ? Payment.from(p) : null),
|
|
dataMessage.getAttachments()
|
|
@@ -159,10 +161,15 @@ public record MessageEnvelope(
|
|
.toList())
|
|
.orElse(List.of()),
|
|
dataMessage.getPollCreate().map(PollCreate::from),
|
|
- dataMessage.getPollVote().map(p -> PollVote.from(p, recipientResolver, addressResolver)),
|
|
+ dataMessage.getPollVote()
|
|
+ .filter(p -> p.getTargetAuthor() != null)
|
|
+ .map(p -> PollVote.from(p, recipientResolver, addressResolver)),
|
|
dataMessage.getPollTerminate().map(PollTerminate::from),
|
|
dataMessage.getMentions()
|
|
- .map(a -> a.stream().map(m -> Mention.from(m, recipientResolver, addressResolver)).toList())
|
|
+ .map(a -> a.stream()
|
|
+ .filter(m -> m.getServiceId() != null)
|
|
+ .map(m -> Mention.from(m, recipientResolver, addressResolver))
|
|
+ .toList())
|
|
.orElse(List.of()),
|
|
dataMessage.getPreviews()
|
|
.map(a -> a.stream().map(preview -> Preview.from(preview, fileProvider)).toList())
|
|
@@ -241,10 +248,13 @@ public record MessageEnvelope(
|
|
RecipientAddressResolver addressResolver,
|
|
final AttachmentFileProvider fileProvider
|
|
) {
|
|
+ final var author = quote.getAuthor() != null && quote.getAuthor().isValid()
|
|
+ ? addressResolver.resolveRecipientAddress(recipientResolver.resolveRecipient(quote.getAuthor()))
|
|
+ .toApiRecipientAddress()
|
|
+ : new RecipientAddress(RecipientAddress.UNKNOWN_UUID);
|
|
return new Quote(quote.getId(),
|
|
- addressResolver.resolveRecipientAddress(recipientResolver.resolveRecipient(quote.getAuthor()))
|
|
- .toApiRecipientAddress(),
|
|
- Optional.of(quote.getText()),
|
|
+ author,
|
|
+ Optional.ofNullable(quote.getText()),
|
|
quote.getMentions() == null
|
|
? List.of()
|
|
: quote.getMentions()
|