diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/PushMediaSendJob.java b/app/src/main/java/org/thoughtcrime/securesms/jobs/PushMediaSendJob.java
index e4af6c43f3c94ed611e12b14d155f89d5c5e161a..ee062da34f9450d28377165fa0a53a23db6224ef 100644
--- a/app/src/main/java/org/thoughtcrime/securesms/jobs/PushMediaSendJob.java
+++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/PushMediaSendJob.java
@@ -227,10 +227,8 @@ public class PushMediaSendJob extends PushSendJob {
                                                                                             .build();
 
       if (Util.equals(SignalStore.account().getAci(), address.getAci())) {
-        Optional<UnidentifiedAccessPair> syncAccess  = UnidentifiedAccessUtil.getAccessForSync(context);
-        SignalServiceSyncMessage         syncMessage = buildSelfSendSyncMessage(context, mediaMessage, syncAccess);
-
-        SendMessageResult result = messageSender.sendSyncMessage(syncMessage, syncAccess);
+        Optional<UnidentifiedAccessPair> syncAccess = UnidentifiedAccessUtil.getAccessForSync(context);
+        SendMessageResult                result     = messageSender.sendSyncMessage(mediaMessage);
         SignalDatabase.messageLog().insertIfPossible(messageRecipient.getId(), message.getSentTimeMillis(), result, ContentHint.RESENDABLE, new MessageId(messageId, true));
         return syncAccess.isPresent();
       } else {
diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/PushSendJob.java b/app/src/main/java/org/thoughtcrime/securesms/jobs/PushSendJob.java
index 790399871c390d2e929fe65c53777747642902b6..6ff43706d522a93cdfc822366fa3143155a29d66 100644
--- a/app/src/main/java/org/thoughtcrime/securesms/jobs/PushSendJob.java
+++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/PushSendJob.java
@@ -446,17 +446,6 @@ public abstract class PushSendJob extends SendJob {
     }
   }
 
-  protected SignalServiceSyncMessage buildSelfSendSyncMessage(@NonNull Context context, @NonNull SignalServiceDataMessage message, Optional<UnidentifiedAccessPair> syncAccess) {
-    SignalServiceAddress  localAddress = new SignalServiceAddress(Recipient.self().requireAci(), Recipient.self().requireE164());
-    SentTranscriptMessage transcript   = new SentTranscriptMessage(Optional.of(localAddress),
-                                                                   message.getTimestamp(),
-                                                                   message,
-                                                                   message.getExpiresInSeconds(),
-                                                                   Collections.singletonMap(localAddress, syncAccess.isPresent()),
-                                                                   false);
-    return SignalServiceSyncMessage.forSentTranscript(transcript);
-  }
-
   protected void handleProofRequiredException(@NonNull ProofRequiredException proofRequired, @Nullable Recipient recipient, long threadId, long messageId, boolean isMms)
       throws ProofRequiredException, RetryLaterException
   {
diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/PushTextSendJob.java b/app/src/main/java/org/thoughtcrime/securesms/jobs/PushTextSendJob.java
index 4bbbf79c09a6bd8e5ee9008050b775666dc7e7fe..fada00f4d2cc10c9d06b759333473f6baf657234 100644
--- a/app/src/main/java/org/thoughtcrime/securesms/jobs/PushTextSendJob.java
+++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/PushTextSendJob.java
@@ -190,10 +190,9 @@ public class PushTextSendJob extends PushSendJob {
 
       if (Util.equals(SignalStore.account().getAci(), address.getAci())) {
         Optional<UnidentifiedAccessPair> syncAccess  = UnidentifiedAccessUtil.getAccessForSync(context);
-        SignalServiceSyncMessage         syncMessage = buildSelfSendSyncMessage(context, textSecureMessage, syncAccess);
 
         SignalLocalMetrics.IndividualMessageSend.onDeliveryStarted(messageId);
-        SendMessageResult result = messageSender.sendSyncMessage(syncMessage, syncAccess);
+        SendMessageResult result = messageSender.sendSyncMessage(textSecureMessage);
 
         SignalDatabase.messageLog().insertIfPossible(messageRecipient.getId(), message.getDateSent(), result, ContentHint.RESENDABLE, new MessageId(messageId, false));
         return syncAccess.isPresent();
diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/ReactionSendJob.java b/app/src/main/java/org/thoughtcrime/securesms/jobs/ReactionSendJob.java
index 8a63f86c6c56f026c01e321592cf8b6d8ec5059c..2ce73edef04166f7d6ead74f012e67a432772052 100644
--- a/app/src/main/java/org/thoughtcrime/securesms/jobs/ReactionSendJob.java
+++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/ReactionSendJob.java
@@ -12,6 +12,7 @@ import org.thoughtcrime.securesms.database.SignalDatabase;
 import org.thoughtcrime.securesms.database.model.MessageId;
 import org.thoughtcrime.securesms.database.model.MessageRecord;
 import org.thoughtcrime.securesms.database.model.ReactionRecord;
+import org.thoughtcrime.securesms.dependencies.ApplicationDependencies;
 import org.thoughtcrime.securesms.groups.GroupId;
 import org.thoughtcrime.securesms.jobmanager.Data;
 import org.thoughtcrime.securesms.jobmanager.Job;
@@ -227,14 +228,20 @@ public class ReactionSendJob extends BaseJob {
       GroupUtil.setDataMessageGroupContext(context, dataMessageBuilder, conversationRecipient.requireGroupId().requirePush());
     }
 
-    SignalServiceDataMessage dataMessage = dataMessageBuilder.build();
-    List<SendMessageResult>  results     = GroupSendUtil.sendResendableDataMessage(context,
-                                                                                   conversationRecipient.getGroupId().transform(GroupId::requireV2).orNull(),
-                                                                                   destinations,
-                                                                                   false,
-                                                                                   ContentHint.RESENDABLE,
-                                                                                   messageId,
-                                                                                   dataMessage);
+    SignalServiceDataMessage dataMessage         = dataMessageBuilder.build();
+    List<Recipient>          nonSelfDestinations = destinations.stream().filter(r -> !r.isSelf()).collect(Collectors.toList());
+    boolean                  includesSelf        = nonSelfDestinations.size() != destinations.size();
+    List<SendMessageResult>  results             = GroupSendUtil.sendResendableDataMessage(context,
+                                                                                           conversationRecipient.getGroupId().transform(GroupId::requireV2).orNull(),
+                                                                                           nonSelfDestinations,
+                                                                                           false,
+                                                                                           ContentHint.RESENDABLE,
+                                                                                           messageId,
+                                                                                           dataMessage);
+
+    if (includesSelf) {
+      results.add(ApplicationDependencies.getSignalServiceMessageSender().sendSyncMessage(dataMessage));
+    }
 
     return GroupSendJobHelper.getCompletedSends(destinations, results);
   }
diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/SendDeliveryReceiptJob.java b/app/src/main/java/org/thoughtcrime/securesms/jobs/SendDeliveryReceiptJob.java
index 12bae1ed0c5d8ad2b8467a338e469c210bd6ae7b..dfd4dff3165d2822ceeea8cb97d7e334490ca512 100644
--- a/app/src/main/java/org/thoughtcrime/securesms/jobs/SendDeliveryReceiptJob.java
+++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/SendDeliveryReceiptJob.java
@@ -102,6 +102,11 @@ public class SendDeliveryReceiptJob extends BaseJob {
     SignalServiceMessageSender  messageSender  = ApplicationDependencies.getSignalServiceMessageSender();
     Recipient                   recipient      = Recipient.resolved(recipientId);
 
+    if (recipient.isSelf()) {
+      Log.i(TAG, "Not sending to self, abort");
+      return;
+    }
+
     if (recipient.isUnregistered()) {
       Log.w(TAG, recipient.getId() + " is unregistered!");
       return;
diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/SendReadReceiptJob.java b/app/src/main/java/org/thoughtcrime/securesms/jobs/SendReadReceiptJob.java
index a89255eec620a2ed8f949b07da81543fa24f01c3..9e1ed3fae993d0b05b6e7ea2088e8363072a0001 100644
--- a/app/src/main/java/org/thoughtcrime/securesms/jobs/SendReadReceiptJob.java
+++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/SendReadReceiptJob.java
@@ -4,6 +4,7 @@ package org.thoughtcrime.securesms.jobs;
 import android.app.Application;
 
 import androidx.annotation.NonNull;
+import androidx.annotation.VisibleForTesting;
 
 import org.signal.core.util.logging.Log;
 import org.thoughtcrime.securesms.crypto.UnidentifiedAccessUtil;
@@ -59,6 +60,7 @@ public class SendReadReceiptJob extends BaseJob {
   private final long            timestamp;
   private final List<MessageId> messageIds;
 
+  @VisibleForTesting
   public SendReadReceiptJob(long threadId, @NonNull RecipientId recipientId, List<Long> messageSentTimestamps, List<MessageId> messageIds) {
     this(new Job.Parameters.Builder()
                            .addConstraint(NetworkConstraint.KEY)
@@ -94,6 +96,10 @@ public class SendReadReceiptJob extends BaseJob {
    * maximum size.
    */
   public static void enqueue(long threadId, @NonNull RecipientId recipientId, List<MarkedMessageInfo> markedMessageInfos) {
+    if (recipientId.equals(Recipient.self().getId())) {
+      return;
+    }
+
     JobManager                    jobManager      = ApplicationDependencies.getJobManager();
     List<List<MarkedMessageInfo>> messageIdChunks = Util.chunk(markedMessageInfos, MAX_TIMESTAMPS);
 
@@ -146,6 +152,10 @@ public class SendReadReceiptJob extends BaseJob {
 
     Recipient recipient = Recipient.resolved(recipientId);
 
+    if (recipient.isSelf()) {
+      Log.i(TAG, "Not sending to self, aborting.");
+    }
+
     if (recipient.isBlocked()) {
       Log.w(TAG, "Refusing to send receipts to blocked recipient");
       return;
diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/SendViewedReceiptJob.java b/app/src/main/java/org/thoughtcrime/securesms/jobs/SendViewedReceiptJob.java
index f71eb41e44c752acff70f356d33ad03e9556f8f8..b456edd33c93919499e3afafa98d7915bbb8d68b 100644
--- a/app/src/main/java/org/thoughtcrime/securesms/jobs/SendViewedReceiptJob.java
+++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/SendViewedReceiptJob.java
@@ -150,6 +150,11 @@ public class SendViewedReceiptJob extends BaseJob {
 
     Recipient recipient = Recipient.resolved(recipientId);
 
+    if (recipient.isSelf()) {
+      Log.i(TAG, "Not sending view receipt to self.");
+      return;
+    }
+
     if (recipient.isBlocked()) {
       Log.w(TAG, "Refusing to send receipts to blocked recipient");
       return;
diff --git a/app/src/test/java/org/thoughtcrime/securesms/notifications/MarkReadReceiverTest.java b/app/src/test/java/org/thoughtcrime/securesms/notifications/MarkReadReceiverTest.java
index aef3eb6290fd45cb695bf08abdf4a866b356680a..9f27785ea645174e4c549bef9382d6d121a89f07 100644
--- a/app/src/test/java/org/thoughtcrime/securesms/notifications/MarkReadReceiverTest.java
+++ b/app/src/test/java/org/thoughtcrime/securesms/notifications/MarkReadReceiverTest.java
@@ -19,6 +19,7 @@ import org.thoughtcrime.securesms.jobmanager.Data;
 import org.thoughtcrime.securesms.jobmanager.Job;
 import org.thoughtcrime.securesms.jobmanager.JobManager;
 import org.thoughtcrime.securesms.jobs.MultiDeviceReadUpdateJob;
+import org.thoughtcrime.securesms.recipients.Recipient;
 import org.thoughtcrime.securesms.recipients.RecipientId;
 import org.thoughtcrime.securesms.util.Util;
 import org.whispersystems.libsignal.util.Pair;
@@ -37,21 +38,25 @@ import static org.powermock.api.mockito.PowerMockito.mockStatic;
 import static org.powermock.api.mockito.PowerMockito.when;
 
 @RunWith(PowerMockRunner.class)
-@PrepareForTest(ApplicationDependencies.class)
+@PrepareForTest({ApplicationDependencies.class, Recipient.class})
 public class MarkReadReceiverTest {
 
   private final Context    mockContext    = mock(Context.class);
   private final JobManager mockJobManager = mock(JobManager.class);
+  private final Recipient  mockSelf       = mock(Recipient.class);
   private final List<Job>  jobs           = new LinkedList<>();
 
   @Before
   public void setUp() {
     mockStatic(ApplicationDependencies.class);
+    mockStatic(Recipient.class);
     when(ApplicationDependencies.getJobManager()).thenReturn(mockJobManager);
     doAnswer((Answer<Void>) invocation -> {
       jobs.add((Job) invocation.getArguments()[0]);
       return null;
     }).when(mockJobManager).add(any());
+    when(Recipient.self()).thenReturn(mockSelf);
+    when(mockSelf.getId()).thenReturn(RecipientId.from(-1));
   }
 
   @Test
diff --git a/libsignal/service/src/main/java/org/whispersystems/signalservice/api/SignalServiceMessageSender.java b/libsignal/service/src/main/java/org/whispersystems/signalservice/api/SignalServiceMessageSender.java
index 09eda89e4790ea84daa42a6d6c6f7f5d1b759810..ecee829154d58fee49fcde1cc992bc67b0defbe3 100644
--- a/libsignal/service/src/main/java/org/whispersystems/signalservice/api/SignalServiceMessageSender.java
+++ b/libsignal/service/src/main/java/org/whispersystems/signalservice/api/SignalServiceMessageSender.java
@@ -487,6 +487,12 @@ public class SignalServiceMessageSender {
     return results;
   }
 
+  public SendMessageResult sendSyncMessage(SignalServiceDataMessage dataMessage)
+      throws IOException, UntrustedIdentityException
+  {
+    return sendSyncMessage(createSelfSendSyncMessage(dataMessage), Optional.absent());
+  }
+
   public SendMessageResult sendSyncMessage(SignalServiceSyncMessage message, Optional<UnidentifiedAccessPair> unidentifiedAccess)
       throws IOException, UntrustedIdentityException
   {
@@ -1528,6 +1534,16 @@ public class SignalServiceMessageSender {
     return results;
   }
 
+  private SignalServiceSyncMessage createSelfSendSyncMessage(SignalServiceDataMessage message) {
+    SentTranscriptMessage transcript = new SentTranscriptMessage(Optional.of(localAddress),
+                                                                 message.getTimestamp(),
+                                                                 message,
+                                                                 message.getExpiresInSeconds(),
+                                                                 Collections.singletonMap(localAddress, false),
+                                                                 false);
+    return SignalServiceSyncMessage.forSentTranscript(transcript);
+  }
+
   private List<SendMessageResult> sendMessage(List<SignalServiceAddress>         recipients,
                                               List<Optional<UnidentifiedAccess>> unidentifiedAccess,
                                               long                               timestamp,