diff --git a/SignalServiceKit/src/Messages/DeviceSyncing/OWSOutgoingSyncMessage.m b/SignalServiceKit/src/Messages/DeviceSyncing/OWSOutgoingSyncMessage.m
index c2a827135..5b177e5fc 100644
--- a/SignalServiceKit/src/Messages/DeviceSyncing/OWSOutgoingSyncMessage.m
+++ b/SignalServiceKit/src/Messages/DeviceSyncing/OWSOutgoingSyncMessage.m
@@ -41,17 +41,11 @@ NS_ASSUME_NONNULL_BEGIN
     return [OWSSignalServiceProtosSyncMessageBuilder new];
 }
 
-- (NSData *)buildPlainTextData
+- (NSData *)buildPlainTextData:(SignalRecipient *)recipient
 {
     OWSSignalServiceProtosContentBuilder *contentBuilder = [OWSSignalServiceProtosContentBuilder new];
     [contentBuilder setSyncMessage:[self buildSyncMessage]];
-    
-#ifndef SKIP_PROFILE_KEYS
-    if (OWSProfilesManager.sharedManager.localProfileKey) {
-        [contentBuilder setProfileKey:OWSProfilesManager.sharedManager.localProfileKey];
-    }
-#endif
-
+    [self addLocalProfileKeyIfNecessary:contentBuilder recipient:recipient];
     return [[contentBuilder build] data];
 }
 
diff --git a/SignalServiceKit/src/Messages/Interactions/TSOutgoingMessage.h b/SignalServiceKit/src/Messages/Interactions/TSOutgoingMessage.h
index a001b8dc0..fbff68ae5 100644
--- a/SignalServiceKit/src/Messages/Interactions/TSOutgoingMessage.h
+++ b/SignalServiceKit/src/Messages/Interactions/TSOutgoingMessage.h
@@ -32,6 +32,8 @@ typedef NS_ENUM(NSInteger, TSGroupMetaMessage) {
 
 @class OWSSignalServiceProtosAttachmentPointer;
 @class OWSSignalServiceProtosDataMessageBuilder;
+@class OWSSignalServiceProtosContentBuilder;
+@class SignalRecipient;
 
 @interface TSOutgoingMessage : TSMessage
 
@@ -107,7 +109,7 @@ typedef NS_ENUM(NSInteger, TSGroupMetaMessage) {
 /**
  * The data representation of this message, to be encrypted, before being sent.
  */
-- (NSData *)buildPlainTextData;
+- (NSData *)buildPlainTextData:(SignalRecipient *)recipient;
 
 /**
  * Intermediate protobuf representation
@@ -176,6 +178,11 @@ typedef NS_ENUM(NSInteger, TSGroupMetaMessage) {
 - (void)updateWithSentRecipient:(NSString *)contactId transaction:(YapDatabaseReadWriteTransaction *)transaction;
 - (void)updateWithSentRecipient:(NSString *)contactId;
 
+#pragma mark -
+
+- (void)addLocalProfileKeyIfNecessary:(OWSSignalServiceProtosContentBuilder *)contentBuilder
+                            recipient:(SignalRecipient *)recipient;
+
 @end
 
 NS_ASSUME_NONNULL_END
diff --git a/SignalServiceKit/src/Messages/Interactions/TSOutgoingMessage.m b/SignalServiceKit/src/Messages/Interactions/TSOutgoingMessage.m
index c6e78154a..4682fce83 100644
--- a/SignalServiceKit/src/Messages/Interactions/TSOutgoingMessage.m
+++ b/SignalServiceKit/src/Messages/Interactions/TSOutgoingMessage.m
@@ -4,8 +4,10 @@
 
 #import "TSOutgoingMessage.h"
 #import "NSDate+millisecondTimeStamp.h"
+#import "OWSOutgoingSyncMessage.h"
 #import "OWSProfilesManager.h"
 #import "OWSSignalServiceProtos.pb.h"
+#import "SignalRecipient.h"
 #import "TSAttachmentStream.h"
 #import "TSContactThread.h"
 #import "TSGroupThread.h"
@@ -456,24 +458,54 @@ NSString *const kTSOutgoingMessageSentRecipientAll = @"kTSOutgoingMessageSentRec
     return [[self dataMessageBuilder] build];
 }
 
-- (NSData *)buildPlainTextData
+- (void)addLocalProfileKeyIfNecessary:(OWSSignalServiceProtosContentBuilder *)contentBuilder
+                            recipient:(SignalRecipient *)recipient
 {
-    OWSSignalServiceProtosContentBuilder *contentBuilder = [OWSSignalServiceProtosContentBuilder new];
-    contentBuilder.dataMessage = [self buildDataMessage];
-    
+    OWSAssert(contentBuilder);
+    OWSAssert(recipient);
+
 #ifndef SKIP_PROFILE_KEYS
-    OWSAssert([self.thread isKindOfClass:[TSContactThread class]]);
-    if ([self.thread isKindOfClass:[TSContactThread class]]) {
-        TSContactThread *contactThread = (TSContactThread *)self.thread;
-        NSString *recipientId = contactThread.contactIdentifier;
-        
-        if (OWSProfilesManager.sharedManager.localProfileKey &&
-            [OWSProfilesManager.sharedManager isUserInProfileWhitelist:recipientId]) {
-            [contentBuilder setProfileKey:OWSProfilesManager.sharedManager.localProfileKey];
+    OWSAssert(OWSProfilesManager.sharedManager.localProfileKey.length > 0);
+    BOOL shouldIncludeProfileKey = NO;
+
+    if ([self isKindOfClass:[OWSOutgoingSyncMessage class]]) {
+        // Always sync the profile key to linked devices.
+        shouldIncludeProfileKey = YES;
+    } else {
+        OWSAssert(self.thread);
+
+        // For 1:1 threads, we want to include the profile key IFF the
+        // contact is in the whitelist.
+        //
+        // For Group threads, we want to include the profile key IFF the
+        // recipient OR the group is in the whitelist.
+        if ([OWSProfilesManager.sharedManager isUserInProfileWhitelist:recipient.recipientId]) {
+            shouldIncludeProfileKey = YES;
+        } else if (self.thread.isGroupThread) {
+            TSGroupThread *groupThread = (TSGroupThread *)self.thread;
+            NSData *groupId = groupThread.groupModel.groupId;
+
+            if ([OWSProfilesManager.sharedManager isGroupIdInProfileWhitelist:groupId]) {
+                [contentBuilder setProfileKey:OWSProfilesManager.sharedManager.localProfileKey];
+            }
+        } else {
+            TSContactThread *contactThread = (TSContactThread *)self.thread;
+            NSString *recipientId = contactThread.contactIdentifier;
+            OWSAssert([recipientId isEqualToString:recipient.recipientId]);
         }
     }
+
+    if (shouldIncludeProfileKey) {
+        [contentBuilder setProfileKey:OWSProfilesManager.sharedManager.localProfileKey];
+    }
 #endif
+}
 
+- (NSData *)buildPlainTextData:(SignalRecipient *)recipient
+{
+    OWSSignalServiceProtosContentBuilder *contentBuilder = [OWSSignalServiceProtosContentBuilder new];
+    contentBuilder.dataMessage = [self buildDataMessage];
+    [self addLocalProfileKeyIfNecessary:contentBuilder recipient:recipient];
     return [[contentBuilder build] data];
 }
 
diff --git a/SignalServiceKit/src/Messages/OWSMessageSender.m b/SignalServiceKit/src/Messages/OWSMessageSender.m
index 3202e2918..7de303db2 100644
--- a/SignalServiceKit/src/Messages/OWSMessageSender.m
+++ b/SignalServiceKit/src/Messages/OWSMessageSender.m
@@ -1166,8 +1166,8 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException";
                                    inThread:(TSThread *)thread
 {
     NSMutableArray *messagesArray = [NSMutableArray arrayWithCapacity:recipient.devices.count];
-    
-    NSData *plainText = [message buildPlainTextData];
+
+    NSData *plainText = [message buildPlainTextData:recipient];
     DDLogDebug(@"%@ built message: %@ plainTextData.length: %lu", self.tag, [message class], (unsigned long)plainText.length);
 
     for (NSNumber *deviceNumber in recipient.devices) {
diff --git a/SignalServiceKit/src/Messages/OWSOutgoingCallMessage.m b/SignalServiceKit/src/Messages/OWSOutgoingCallMessage.m
index 52dadd83a..4989017e3 100644
--- a/SignalServiceKit/src/Messages/OWSOutgoingCallMessage.m
+++ b/SignalServiceKit/src/Messages/OWSOutgoingCallMessage.m
@@ -122,24 +122,11 @@ NS_ASSUME_NONNULL_BEGIN
 //    return _thread;
 //}
 
-- (NSData *)buildPlainTextData
+- (NSData *)buildPlainTextData:(SignalRecipient *)recipient
 {
     OWSSignalServiceProtosContentBuilder *contentBuilder = [OWSSignalServiceProtosContentBuilder new];
     [contentBuilder setCallMessage:[self asProtobuf]];
-    
-#ifndef SKIP_PROFILE_KEYS
-    OWSAssert([self.thread isKindOfClass:[TSContactThread class]]);
-    if ([self.thread isKindOfClass:[TSContactThread class]]) {
-        TSContactThread *contactThread = (TSContactThread *)self.thread;
-        NSString *recipientId = contactThread.contactIdentifier;
-    
-        if (OWSProfilesManager.sharedManager.localProfileKey &&
-            [OWSProfilesManager.sharedManager isUserInProfileWhitelist:recipientId]) {
-            [contentBuilder setProfileKey:OWSProfilesManager.sharedManager.localProfileKey];
-        }
-    }
-#endif
-
+    [self addLocalProfileKeyIfNecessary:contentBuilder recipient:recipient];
     return [[contentBuilder build] data];
 }
 
diff --git a/SignalServiceKit/src/Messages/OWSOutgoingNullMessage.m b/SignalServiceKit/src/Messages/OWSOutgoingNullMessage.m
index 372af0e61..08416b816 100644
--- a/SignalServiceKit/src/Messages/OWSOutgoingNullMessage.m
+++ b/SignalServiceKit/src/Messages/OWSOutgoingNullMessage.m
@@ -36,7 +36,7 @@ NS_ASSUME_NONNULL_BEGIN
 
 #pragma mark - override TSOutgoingMessage
 
-- (NSData *)buildPlainTextData
+- (NSData *)buildPlainTextData:(SignalRecipient *)recipient
 {
     OWSSignalServiceProtosContentBuilder *contentBuilder = [OWSSignalServiceProtosContentBuilder new];
     OWSSignalServiceProtosNullMessageBuilder *nullMessageBuilder = [OWSSignalServiceProtosNullMessageBuilder new];
@@ -57,19 +57,8 @@ NS_ASSUME_NONNULL_BEGIN
     nullMessageBuilder.padding = [Cryptography generateRandomBytes:contentLength];
     
     contentBuilder.nullMessage = [nullMessageBuilder build];
-    
-#ifndef SKIP_PROFILE_KEYS
-    OWSAssert([self.thread isKindOfClass:[TSContactThread class]]);
-    if ([self.thread isKindOfClass:[TSContactThread class]]) {
-        TSContactThread *contactThread = (TSContactThread *)self.thread;
-        NSString *recipientId = contactThread.contactIdentifier;
-        
-        if (OWSProfilesManager.sharedManager.localProfileKey &&
-            [OWSProfilesManager.sharedManager isUserInProfileWhitelist:recipientId]) {
-            [contentBuilder setProfileKey:OWSProfilesManager.sharedManager.localProfileKey];
-        }
-    }
-#endif
+
+    [self addLocalProfileKeyIfNecessary:contentBuilder recipient:recipient];
 
     return [contentBuilder build].data;
 }