diff --git a/ts/components/conversation/message/message-item/ExpirableReadableMessage.tsx b/ts/components/conversation/message/message-item/ExpirableReadableMessage.tsx
index d444a2509..510938923 100644
--- a/ts/components/conversation/message/message-item/ExpirableReadableMessage.tsx
+++ b/ts/components/conversation/message/message-item/ExpirableReadableMessage.tsx
@@ -94,6 +94,7 @@ export const ExpirableReadableMessage = (props: ExpirableReadableMessageProps) =
     expirationLength,
     expirationTimestamp,
     isExpired: props.isExpired,
+    direction: props.direction,
   };
   const { isExpired } = useIsExpired(expiringProps);
   const isIncoming = direction === 'incoming';
diff --git a/ts/components/conversation/message/message-item/notification-bubble/CallNotification.tsx b/ts/components/conversation/message/message-item/notification-bubble/CallNotification.tsx
index e1d8f73ec..6c32219e4 100644
--- a/ts/components/conversation/message/message-item/notification-bubble/CallNotification.tsx
+++ b/ts/components/conversation/message/message-item/notification-bubble/CallNotification.tsx
@@ -9,7 +9,7 @@ import {
 import { getSelectedConversation } from '../../../../../state/selectors/conversations';
 import { LocalizerKeys } from '../../../../../types/LocalizerKeys';
 import { SessionIconType } from '../../../../icon';
-import { ReadableMessage } from '../ReadableMessage';
+import { ExpirableReadableMessage } from '../ExpirableReadableMessage';
 import { NotificationBubble } from './NotificationBubble';
 
 type StyleType = Record<
@@ -36,7 +36,16 @@ const style: StyleType = {
 };
 
 export const CallNotification = (props: PropsForCallNotification) => {
-  const { messageId, receivedAt, isUnread, notificationType } = props;
+  const {
+    messageId,
+    receivedAt,
+    isUnread,
+    notificationType,
+    direction,
+    expirationLength,
+    expirationTimestamp,
+    isExpired,
+  } = props;
 
   const selectedConvoProps = useSelector(getSelectedConversation);
 
@@ -54,10 +63,14 @@ export const CallNotification = (props: PropsForCallNotification) => {
   const iconColor = styleItem.iconColor;
 
   return (
-    <ReadableMessage
+    <ExpirableReadableMessage
       messageId={messageId}
       receivedAt={receivedAt}
+      direction={direction}
       isUnread={isUnread}
+      expirationLength={expirationLength}
+      expirationTimestamp={expirationTimestamp}
+      isExpired={isExpired}
       key={`readable-message-${messageId}`}
     >
       <NotificationBubble
@@ -65,6 +78,6 @@ export const CallNotification = (props: PropsForCallNotification) => {
         iconType={iconType}
         iconColor={iconColor}
       />
-    </ReadableMessage>
+    </ExpirableReadableMessage>
   );
 };
diff --git a/ts/models/conversation.ts b/ts/models/conversation.ts
index 4ed57a15e..393bd2867 100644
--- a/ts/models/conversation.ts
+++ b/ts/models/conversation.ts
@@ -1215,6 +1215,7 @@ export class ConversationModel extends Backbone.Model<ConversationAttributes> {
         }
       }
     }
+
     return this.addSingleMessage({
       ...messageAttributes,
       conversationId: this.id,
diff --git a/ts/models/message.ts b/ts/models/message.ts
index 8339b8825..e7219a9bd 100644
--- a/ts/models/message.ts
+++ b/ts/models/message.ts
@@ -171,6 +171,7 @@ export class MessageModel extends Backbone.Model<MessageAttributes> {
         messageId: this.id,
         receivedAt: this.get('received_at') || Date.now(),
         isUnread: this.isUnread(),
+        ...this.getPropsForExpiringMessage(),
       };
     }
     perfEnd(`getPropsMessage-${this.id}`, 'getPropsMessage');
@@ -280,7 +281,7 @@ export class MessageModel extends Backbone.Model<MessageAttributes> {
     await deleteExternalMessageFiles(this.attributes);
   }
 
-  public getPropsForExpiringMessage(): PropsForExpiringMessage | null {
+  public getPropsForExpiringMessage(): PropsForExpiringMessage | { direction: MessageModelType } {
     const expirationType = this.get('expirationType');
     const expirationLength = this.get('expireTimer') || null;
 
@@ -291,9 +292,13 @@ export class MessageModel extends Backbone.Model<MessageAttributes> {
         ? expireTimerStart + expirationLength * DURATION.SECONDS
         : null;
 
+    const direction =
+      this.get('direction') || this.get('type') === 'outgoing' ? 'outgoing' : 'incoming';
+
     return {
       convoId: this.get('conversationId'),
       messageId: this.get('id'),
+      direction,
       expirationLength,
       expirationTimestamp,
       isExpired: this.isExpired(),
@@ -309,12 +314,6 @@ export class MessageModel extends Backbone.Model<MessageAttributes> {
       return null;
     }
 
-    // TODO should direction be parts of expiration props?
-    let direction = this.get('direction');
-    if (!direction) {
-      direction = this.get('type') === 'outgoing' ? 'outgoing' : 'incoming';
-    }
-
     const { expirationType, expireTimer, fromSync, source } = timerUpdate;
     const timespan = ExpirationTimerOptions.getName(expireTimer || 0);
     const disabled = !expireTimer;
@@ -328,7 +327,6 @@ export class MessageModel extends Backbone.Model<MessageAttributes> {
       receivedAt: this.get('received_at'),
       isUnread: this.isUnread(),
       expirationType: expirationType || 'off',
-      direction,
       ...this.getPropsForExpiringMessage(),
     };
 
@@ -357,7 +355,6 @@ export class MessageModel extends Backbone.Model<MessageAttributes> {
     return {
       serverName: invitation.name,
       url: serverAddress,
-      direction,
       acceptUrl: invitation.url,
       messageId: this.id as string,
       receivedAt: this.get('received_at'),
@@ -1211,10 +1208,11 @@ export class MessageModel extends Backbone.Model<MessageAttributes> {
     if (
       this.get('expirationType') === 'deleteAfterRead' &&
       this.get('expireTimer') &&
-      !this.get('expirationStartTimestamp')
+      Boolean(this.get('expirationStartTimestamp')) === false
     ) {
-      const message = setExpirationStartTimestamp(this, 'deleteAfterRead', readAt);
-      this.set({ expirationStartTimestamp: message?.get('expirationStartTimestamp') });
+      this.set({
+        expirationStartTimestamp: setExpirationStartTimestamp('deleteAfterRead', readAt),
+      });
     }
 
     Notifications.clearByMessageId(this.id);
diff --git a/ts/receiver/queuedJob.ts b/ts/receiver/queuedJob.ts
index 051791ff8..c14d4e328 100644
--- a/ts/receiver/queuedJob.ts
+++ b/ts/receiver/queuedJob.ts
@@ -359,13 +359,17 @@ export async function handleMessageJob(
         expireTimer: expireUpdate.expireTimer,
       });
 
-      if (messageModel.isIncoming() && messageModel.get('expirationType') === 'deleteAfterSend') {
-        messageModel =
-          setExpirationStartTimestamp(
-            messageModel,
+      if (
+        messageModel.isIncoming() &&
+        messageModel.get('expirationType') === 'deleteAfterSend' &&
+        Boolean(messageModel.get('expirationStartTimestamp')) === false
+      ) {
+        messageModel.set({
+          expirationStartTimestamp: setExpirationStartTimestamp(
             'deleteAfterSend',
             messageModel.get('sent_at')
-          ) || messageModel;
+          ),
+        });
       }
     }
 
diff --git a/ts/session/sending/MessageSentHandler.ts b/ts/session/sending/MessageSentHandler.ts
index bba995516..4c22ef19f 100644
--- a/ts/session/sending/MessageSentHandler.ts
+++ b/ts/session/sending/MessageSentHandler.ts
@@ -136,13 +136,13 @@ async function handleMessageSentSuccess(
 
   if (!shouldMarkMessageAsSynced) {
     const expirationType = fetchedMessage.get('expirationType');
-    if (expirationType) {
-      fetchedMessage =
-        setExpirationStartTimestamp(
-          fetchedMessage,
+    if (expirationType && Boolean(fetchedMessage.get('expirationStartTimestamp')) === false) {
+      fetchedMessage.set({
+        expirationStartTimestamp: setExpirationStartTimestamp(
           expirationType,
           expirationType === 'deleteAfterSend' ? effectiveTimestamp : undefined
-        ) || fetchedMessage;
+        ),
+      });
     }
   }
 
diff --git a/ts/session/utils/calling/CallManager.ts b/ts/session/utils/calling/CallManager.ts
index ac44d4415..50cc54201 100644
--- a/ts/session/utils/calling/CallManager.ts
+++ b/ts/session/utils/calling/CallManager.ts
@@ -28,6 +28,7 @@ import { getCallMediaPermissionsSettings } from '../../../components/settings/Se
 import { PnServer } from '../../apis/push_notification_api';
 import { getNowWithNetworkOffset } from '../../apis/snode_api/SNodeAPI';
 import { approveConvoAndSendResponse } from '../../../interactions/conversationInteractions';
+import { setExpirationStartTimestamp } from '../../../util/expiringMessages';
 
 // tslint:disable: function-name
 
@@ -503,10 +504,16 @@ export async function USER_callRecipient(recipient: string) {
   calledConvo.set('active_at', Date.now()); // addSingleOutgoingMessage does the commit for us on the convo
   weAreCallerOnCurrentCall = true;
 
+  const expirationType = calledConvo.get('expirationType');
   await calledConvo?.addSingleOutgoingMessage({
-    sent_at: now,
-    expireTimer: 0,
     callNotificationType: 'started-call',
+    sent_at: now,
+    expirationType: expirationType !== 'off' ? expirationType : undefined,
+    expireTimer: calledConvo.get('expireTimer') ? calledConvo.get('expireTimer') : 0,
+    expirationStartTimestamp: setExpirationStartTimestamp(
+      expirationType,
+      expirationType === 'deleteAfterSend' ? now : undefined
+    ),
   });
 
   // initiating a call is analogous to sending a message request
@@ -841,13 +848,20 @@ export async function USER_acceptIncomingCallRequest(fromSender: string) {
   const networkTimestamp = getNowWithNetworkOffset();
   const callerConvo = getConversationController().get(fromSender);
   callerConvo.set('active_at', networkTimestamp);
+
+  const expirationType = callerConvo.get('expirationType');
   await callerConvo?.addSingleIncomingMessage({
+    callNotificationType: 'answered-a-call',
     source: UserUtils.getOurPubKeyStrFromCache(),
     sent_at: networkTimestamp,
     received_at: networkTimestamp,
-    expireTimer: 0,
-    callNotificationType: 'answered-a-call',
     unread: 0,
+    expirationType: expirationType !== 'off' ? expirationType : undefined,
+    expireTimer: callerConvo.get('expireTimer') ? callerConvo.get('expireTimer') : 0,
+    expirationStartTimestamp: setExpirationStartTimestamp(
+      expirationType,
+      expirationType === 'deleteAfterSend' ? networkTimestamp : undefined
+    ),
   });
   await buildAnswerAndSendIt(fromSender);
 
@@ -1167,13 +1181,21 @@ async function addMissedCallMessage(callerPubkey: string, sentAt: number) {
     incomingCallConversation.set('active_at', getNowWithNetworkOffset());
   }
 
+  const expirationType = incomingCallConversation.get('expirationType');
   await incomingCallConversation?.addSingleIncomingMessage({
+    callNotificationType: 'missed-call',
     source: callerPubkey,
     sent_at: sentAt,
     received_at: getNowWithNetworkOffset(),
-    expireTimer: 0,
-    callNotificationType: 'missed-call',
     unread: 1,
+    expirationType: expirationType !== 'off' ? expirationType : undefined,
+    expireTimer: incomingCallConversation.get('expireTimer')
+      ? incomingCallConversation.get('expireTimer')
+      : 0,
+    expirationStartTimestamp: setExpirationStartTimestamp(
+      expirationType,
+      expirationType === 'deleteAfterSend' ? sentAt : undefined
+    ),
   });
 }
 
diff --git a/ts/state/ducks/conversations.ts b/ts/state/ducks/conversations.ts
index 826342494..053b7ef58 100644
--- a/ts/state/ducks/conversations.ts
+++ b/ts/state/ducks/conversations.ts
@@ -22,12 +22,12 @@ import {
 } from '../../util/expiringMessages';
 
 export type CallNotificationType = 'missed-call' | 'started-call' | 'answered-a-call';
-export type PropsForCallNotification = {
+
+export interface PropsForCallNotification extends PropsForExpiringMessage {
   notificationType: CallNotificationType;
-  messageId: string;
   receivedAt: number;
   isUnread: boolean;
-};
+}
 
 export type MessageModelPropsWithoutConvoProps = {
   propsForMessage: PropsForMessageWithoutConvoProps;
@@ -78,6 +78,7 @@ export type FindAndFormatContactType = {
 export type PropsForExpiringMessage = {
   convoId?: string;
   messageId: string;
+  direction: MessageModelType;
   expirationTimestamp?: number | null;
   expirationLength?: number | null;
   isExpired?: boolean;
@@ -96,7 +97,6 @@ export interface PropsForExpirationTimer extends PropsForExpiringMessage {
   messageId: string;
   isUnread: boolean;
   receivedAt: number | undefined;
-  direction: MessageModelType;
 }
 
 export type PropsForGroupUpdateGeneral = {
@@ -140,7 +140,6 @@ export type PropsForGroupUpdate = {
 export interface PropsForGroupInvitation extends PropsForExpiringMessage {
   serverName: string;
   url: string;
-  direction: MessageModelType;
   acceptUrl: string;
   messageId: string;
   receivedAt?: number;
diff --git a/ts/util/expiringMessages.ts b/ts/util/expiringMessages.ts
index a88fd885e..71c93a33e 100644
--- a/ts/util/expiringMessages.ts
+++ b/ts/util/expiringMessages.ts
@@ -7,7 +7,6 @@ import { initWallClockListener } from './wallClockListener';
 
 import { Data } from '../data/data';
 import { getConversationController } from '../session/conversations';
-import { MessageModel } from '../models/message';
 import { getNowWithNetworkOffset } from '../session/apis/snode_api/SNodeAPI';
 
 // TODO Might need to be improved by using an enum
@@ -198,16 +197,10 @@ export const ExpirationTimerOptions = {
 };
 
 export function setExpirationStartTimestamp(
-  message: MessageModel,
   mode: DisappearingMessageType,
   timestamp?: number
-): MessageModel | null {
-  if (message.get('expirationStartTimestamp') > 0) {
-    window.log.info(`WIP: Expiration Timer already set. Ignoring new value.`);
-    return null;
-  }
-
-  let expirationStartTimestamp = getNowWithNetworkOffset();
+): number | undefined {
+  let expirationStartTimestamp: number | undefined = getNowWithNetworkOffset();
 
   if (timestamp) {
     window.log.info(
@@ -221,26 +214,25 @@ export function setExpirationStartTimestamp(
     expirationStartTimestamp = Math.min(expirationStartTimestamp, timestamp);
   }
 
-  message.set('expirationStartTimestamp', expirationStartTimestamp);
-
   if (mode === 'deleteAfterRead') {
     window.log.info(
       `WIP: We set the start timestamp for a delete after read message to ${new Date(
         expirationStartTimestamp
-      ).toLocaleTimeString()}`,
-      message
+      ).toLocaleTimeString()}`
     );
   } else if (mode === 'deleteAfterSend') {
     window.log.info(
       `WIP: We set the start timestamp for a delete after send message to ${new Date(
         expirationStartTimestamp
-      ).toLocaleTimeString()}`,
-      message
+      ).toLocaleTimeString()}`
     );
+  } else if (mode === 'off') {
+    window.log.info(`WIP: Disappearing message mode "${mode}" set. We can safely ignore this.`);
+    expirationStartTimestamp = undefined;
   } else {
-    console.log(`WIP: Invalid disappearing message mode "${mode}" set. Ignoring`);
-    return null;
+    window.log.info(`WIP: Invalid disappearing message mode "${mode}" set. Ignoring`);
+    expirationStartTimestamp = undefined;
   }
 
-  return message;
+  return expirationStartTimestamp;
 }