diff --git a/Ring/Ring.xcodeproj/project.pbxproj b/Ring/Ring.xcodeproj/project.pbxproj
index c9543211fb34d35b32f6a92311e7d10a7a82ac99..b6db618c71f2a5c171f031185b68cd6a8a1089e4 100644
--- a/Ring/Ring.xcodeproj/project.pbxproj
+++ b/Ring/Ring.xcodeproj/project.pbxproj
@@ -80,6 +80,8 @@
 		04399B141D1C341A00E99CD9 /* libx264.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 04399AE21D1C341A00E99CD9 /* libx264.a */; };
 		04399B151D1C341A00E99CD9 /* libyaml-cpp.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 04399AE31D1C341A00E99CD9 /* libyaml-cpp.a */; };
 		0586C94B1F684DF600613517 /* UIImage+Helpers.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0586C94A1F684DF600613517 /* UIImage+Helpers.swift */; };
+		0E403F811F7D797300C80BC2 /* MessageCellGenerated.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E403F801F7D797300C80BC2 /* MessageCellGenerated.swift */; };
+		0E403F831F7D79B000C80BC2 /* MessageCellGenerated.xib in Resources */ = {isa = PBXBuildFile; fileRef = 0E403F821F7D79B000C80BC2 /* MessageCellGenerated.xib */; };
 		0EE1B54E1F75ACDE00BA98EE /* CNContactVCardSerialization+Helpers.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EE1B54D1F75ACDE00BA98EE /* CNContactVCardSerialization+Helpers.swift */; };
 		0EE1B5501F75AD4700BA98EE /* VCardUtils.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EE1B54F1F75AD4700BA98EE /* VCardUtils.swift */; };
 		0EEFBA3C1F83DA21000EDBAD /* libsecp256k1.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 0EEFBA3B1F83DA21000EDBAD /* libsecp256k1.a */; };
@@ -296,6 +298,8 @@
 		04399AE21D1C341A00E99CD9 /* libx264.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libx264.a; path = ../fat/lib/libx264.a; sourceTree = "<group>"; };
 		04399AE31D1C341A00E99CD9 /* libyaml-cpp.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = "libyaml-cpp.a"; path = "../fat/lib/libyaml-cpp.a"; sourceTree = "<group>"; };
 		0586C94A1F684DF600613517 /* UIImage+Helpers.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIImage+Helpers.swift"; sourceTree = "<group>"; };
+		0E403F801F7D797300C80BC2 /* MessageCellGenerated.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MessageCellGenerated.swift; sourceTree = "<group>"; };
+		0E403F821F7D79B000C80BC2 /* MessageCellGenerated.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = MessageCellGenerated.xib; sourceTree = "<group>"; };
 		0EE1B54D1F75ACDE00BA98EE /* CNContactVCardSerialization+Helpers.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "CNContactVCardSerialization+Helpers.swift"; sourceTree = "<group>"; };
 		0EE1B54F1F75AD4700BA98EE /* VCardUtils.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = VCardUtils.swift; sourceTree = "<group>"; };
 		0EEFBA3B1F83DA21000EDBAD /* libsecp256k1.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libsecp256k1.a; path = ../DEPS/arm64/lib/libsecp256k1.a; sourceTree = "<group>"; };
@@ -940,6 +944,8 @@
 				1A2D18F21F292D7200B2C785 /* MessageCellReceived.xib */,
 				1A2D18F31F292D7200B2C785 /* MessageCellSent.swift */,
 				1A2D18F41F292D7200B2C785 /* MessageCellSent.xib */,
+				0E403F801F7D797300C80BC2 /* MessageCellGenerated.swift */,
+				0E403F821F7D79B000C80BC2 /* MessageCellGenerated.xib */,
 			);
 			path = Cells;
 			sourceTree = "<group>";
@@ -1152,6 +1158,7 @@
 				1A2D18F61F292D7200B2C785 /* MessageCellReceived.xib in Resources */,
 				1A2D18EF1F291A0100B2C785 /* MeDetailViewController.storyboard in Resources */,
 				1A2D18B11F2915B600B2C785 /* SmartlistViewController.storyboard in Resources */,
+				0E403F831F7D79B000C80BC2 /* MessageCellGenerated.xib in Resources */,
 				04399A031D1C2D9D00E99CD9 /* Images.xcassets in Resources */,
 				1A2041841F1EA0FC00C08435 /* CreateAccountViewController.storyboard in Resources */,
 				1A2D18ED1F2919D800B2C785 /* MeViewController.storyboard in Resources */,
@@ -1294,6 +1301,7 @@
 				1A5DC0371F35675E0075E8EF /* ContactRequestCell.swift in Sources */,
 				1A20417C1F1E56FF00C08435 /* WelcomeViewModel.swift in Sources */,
 				1A5DC03D1F35678D0075E8EF /* ContactRequestItem.swift in Sources */,
+				0E403F811F7D797300C80BC2 /* MessageCellGenerated.swift in Sources */,
 				1A2041821F1E906B00C08435 /* CreateProfileViewModel.swift in Sources */,
 				1A0C4EE31F1D673600550433 /* InjectionBag.swift in Sources */,
 				564C44641E943E1E000F92B1 /* NameRegistrationAdapterDelegate.swift in Sources */,
diff --git a/Ring/Ring/Extensions/Chameleon+Ring.swift b/Ring/Ring/Extensions/Chameleon+Ring.swift
index 7ebb62a1685c6ac8f6a6b122305625531548c5f8..0146a074cd2ef35b9bc268b935d8a2fff51d41f9 100644
--- a/Ring/Ring/Extensions/Chameleon+Ring.swift
+++ b/Ring/Ring/Extensions/Chameleon+Ring.swift
@@ -54,5 +54,8 @@ extension Chameleon {
         MessageBubble.appearance(whenContainedInInstancesOf: [MessageCellReceived.self]).tintColor = secondaryContentColor
         MessageBubble.appearance(whenContainedInInstancesOf: [MessageCellReceived.self]).backgroundColor = secondaryColor
         UILabel.appearance(whenContainedInInstancesOf: [MessageBubble.self, MessageCellReceived.self]).textColor = secondaryContentColor
+
+        MessageBubble.appearance(whenContainedInInstancesOf: [MessageCellGenerated.self]).tintColor = UIColor.clear
+        MessageBubble.appearance(whenContainedInInstancesOf: [MessageCellGenerated.self]).backgroundColor = UIColor.clear
     }
 }
diff --git a/Ring/Ring/Features/ContactRequests/ContactRequestsViewModel.swift b/Ring/Ring/Features/ContactRequests/ContactRequestsViewModel.swift
index bac3eabc8bf48e94b9006428a185ef48fd9c05df..70aa514c893d1af498af64d2b90f08979121b314 100644
--- a/Ring/Ring/Features/ContactRequests/ContactRequestsViewModel.swift
+++ b/Ring/Ring/Features/ContactRequests/ContactRequestsViewModel.swift
@@ -26,13 +26,16 @@ class ContactRequestsViewModel: ViewModel {
 
     let contactsService: ContactsService
     let accountsService: AccountsService
+    let conversationService: ConversationsService
     let nameService: NameService
 
     fileprivate let disposeBag = DisposeBag()
+    fileprivate let log = SwiftyBeaver.self
 
     required init(with injectionBag: InjectionBag) {
         self.contactsService = injectionBag.contactsService
         self.accountsService = injectionBag.accountService
+        self.conversationService = injectionBag.conversationsService
         self.nameService = injectionBag.nameService
     }
 
@@ -62,6 +65,26 @@ class ContactRequestsViewModel: ViewModel {
     func accept(withItem item: ContactRequestItem) -> Observable<Void> {
         let acceptCompleted = self.contactsService.accept(contactRequest: item.contactRequest, withAccount: self.accountsService.currentAccount!)
 
+        let accountHelper = AccountModelHelper(withAccount: self.accountsService.currentAccount!)
+        self.conversationService.saveMessage(withContent:
+            GeneratedMessageType.receivedContactRequest.rawValue,
+                                             byAuthor: accountHelper.ringId!,
+                                             toConversationWith: item.contactRequest.ringId,
+                                             currentAccountId: (self.accountsService.currentAccount?.id)!, generated: true)
+            .subscribe(onCompleted: { [unowned self] in
+                self.log.debug("Message saved")
+            })
+            .disposed(by: disposeBag)
+        self.conversationService.saveMessage(withContent:
+            GeneratedMessageType.contactRequestAccepted.rawValue,
+                                             byAuthor: accountHelper.ringId!,
+                                             toConversationWith: item.contactRequest.ringId,
+                                             currentAccountId: (self.accountsService.currentAccount?.id)!, generated: true)
+            .subscribe(onCompleted: { [unowned self] in
+                self.log.debug("Message saved")
+            })
+            .disposed(by: disposeBag)
+
         if let vCard = item.contactRequest.vCard {
             let saveVCardCompleted = self.contactsService.saveVCard(vCard: vCard, forContactWithRingId: item.contactRequest.ringId)
             return Observable<Void>.zip(acceptCompleted, saveVCardCompleted) { _, _ in
diff --git a/Ring/Ring/Features/Conversations/Conversation/Cells/MessageCellGenerated.swift b/Ring/Ring/Features/Conversations/Conversation/Cells/MessageCellGenerated.swift
new file mode 100644
index 0000000000000000000000000000000000000000..2fd92806700164efea1d0a37392eac54c3f73c0b
--- /dev/null
+++ b/Ring/Ring/Features/Conversations/Conversation/Cells/MessageCellGenerated.swift
@@ -0,0 +1,28 @@
+/*
+ *  Copyright (C) 2017 Savoir-faire Linux Inc.
+ *
+ *  Author: Kateryna Kostiuk <kateryna.kostiuk@savoirfairelinux.com>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.
+ */
+
+import Foundation
+import Reusable
+
+class MessageCellGenerated: UITableViewCell, NibReusable {
+
+    @IBOutlet weak var bubble: MessageBubble!
+    @IBOutlet weak var messageLabel: UILabel!
+}
diff --git a/Ring/Ring/Features/Conversations/Conversation/Cells/MessageCellGenerated.xib b/Ring/Ring/Features/Conversations/Conversation/Cells/MessageCellGenerated.xib
new file mode 100644
index 0000000000000000000000000000000000000000..84e845047a4bef715839a7d6d62f49acfc89e897
--- /dev/null
+++ b/Ring/Ring/Features/Conversations/Conversation/Cells/MessageCellGenerated.xib
@@ -0,0 +1,60 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="12121" systemVersion="16G29" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
+    <device id="retina4_7" orientation="portrait">
+        <adaptation id="fullscreen"/>
+    </device>
+    <dependencies>
+        <deployment identifier="iOS"/>
+        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="12089"/>
+        <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
+    </dependencies>
+    <objects>
+        <placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
+        <placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
+        <tableViewCell contentMode="scaleToFill" selectionStyle="none" indentationWidth="10" rowHeight="60" id="3QB-g7-MaS" customClass="MessageCellGenerated" customModule="Ring" customModuleProvider="target">
+            <rect key="frame" x="0.0" y="0.0" width="510" height="47"/>
+            <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
+            <tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="3QB-g7-MaS" id="Dkz-SA-3Af">
+                <rect key="frame" x="0.0" y="0.0" width="510" height="46.5"/>
+                <autoresizingMask key="autoresizingMask"/>
+                <subviews>
+                    <view clipsSubviews="YES" contentMode="scaleToFill" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="xVQ-Jk-Sxy" customClass="MessageBubble" customModule="Ring" customModuleProvider="target">
+                        <rect key="frame" x="179" y="8" width="152.5" height="30.5"/>
+                        <subviews>
+                            <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label Label Label Label " lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="ijf-jY-sqW">
+                                <rect key="frame" x="8" y="4" width="136.5" height="22.5"/>
+                                <fontDescription key="fontDescription" type="system" pointSize="12"/>
+                                <nil key="textColor"/>
+                                <nil key="highlightedColor"/>
+                            </label>
+                        </subviews>
+                        <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
+                        <constraints>
+                            <constraint firstAttribute="bottom" secondItem="ijf-jY-sqW" secondAttribute="bottom" constant="4" id="SxF-yH-rea"/>
+                            <constraint firstItem="ijf-jY-sqW" firstAttribute="leading" secondItem="xVQ-Jk-Sxy" secondAttribute="leading" constant="8" id="Wqz-dB-u71"/>
+                            <constraint firstItem="ijf-jY-sqW" firstAttribute="top" secondItem="xVQ-Jk-Sxy" secondAttribute="top" constant="4" id="bc9-iJ-EjK"/>
+                            <constraint firstAttribute="height" relation="greaterThanOrEqual" constant="30" id="hS0-Te-OEU"/>
+                            <constraint firstAttribute="trailing" secondItem="ijf-jY-sqW" secondAttribute="trailing" constant="8" id="jne-iL-4tV"/>
+                        </constraints>
+                        <userDefinedRuntimeAttributes>
+                            <userDefinedRuntimeAttribute type="number" keyPath="cornerRadius">
+                                <real key="value" value="4"/>
+                            </userDefinedRuntimeAttribute>
+                        </userDefinedRuntimeAttributes>
+                    </view>
+                </subviews>
+                <color key="tintColor" name="controlColor" catalog="System" colorSpace="catalog"/>
+                <constraints>
+                    <constraint firstItem="xVQ-Jk-Sxy" firstAttribute="centerX" secondItem="Dkz-SA-3Af" secondAttribute="centerX" id="2E6-jB-N9L"/>
+                    <constraint firstAttribute="bottom" secondItem="xVQ-Jk-Sxy" secondAttribute="bottom" constant="8" id="Qbn-zO-KWj"/>
+                    <constraint firstItem="xVQ-Jk-Sxy" firstAttribute="top" secondItem="Dkz-SA-3Af" secondAttribute="top" constant="8" id="R6Q-PY-A3m"/>
+                </constraints>
+            </tableViewCellContentView>
+            <connections>
+                <outlet property="bubble" destination="xVQ-Jk-Sxy" id="dRd-NH-FPh"/>
+                <outlet property="messageLabel" destination="ijf-jY-sqW" id="Wcu-8D-wWf"/>
+            </connections>
+            <point key="canvasLocation" x="-411" y="-132"/>
+        </tableViewCell>
+    </objects>
+</document>
diff --git a/Ring/Ring/Features/Conversations/Conversation/ConversationViewController.swift b/Ring/Ring/Features/Conversations/Conversation/ConversationViewController.swift
index 3af4ed4e78169a6e32b94b96ee774d58a9a737dc..bf31333fc01b7c8e0736a8ff256da30caac5c43f 100644
--- a/Ring/Ring/Features/Conversations/Conversation/ConversationViewController.swift
+++ b/Ring/Ring/Features/Conversations/Conversation/ConversationViewController.swift
@@ -81,7 +81,8 @@ class ConversationViewController: UIViewController, UITextFieldDelegate, Storybo
         //invite button
         let inviteItem = UIBarButtonItem()
         inviteItem.image = UIImage(named: "add_person")
-        inviteItem.rx.tap.subscribe(onNext: { [unowned self] in
+        inviteItem.rx.tap.throttle(0.5, scheduler: MainScheduler.instance)
+            .subscribe(onNext: { [unowned self] in
             self.inviteItemTapped()
         }).disposed(by: self.disposeBag)
 
@@ -118,6 +119,7 @@ class ConversationViewController: UIViewController, UITextFieldDelegate, Storybo
         //Register cell
         self.tableView.register(cellType: MessageCellSent.self)
         self.tableView.register(cellType: MessageCellReceived.self)
+        self.tableView.register(cellType: MessageCellGenerated.self)
 
         //Bind the TableView to the ViewModel
         self.viewModel.messages.subscribe(onNext: { [weak self] (messageViewModels) in
@@ -203,6 +205,12 @@ extension ConversationViewController: UITableViewDataSource {
                 return cell
             }
 
+            if messageViewModel.bubblePosition() == .generated {
+                let cell = tableView.dequeueReusableCell(for: indexPath, cellType: MessageCellGenerated.self)
+                cell.messageLabel.text = messageViewModel.content
+                return cell
+            }
+
             let cell = tableView.dequeueReusableCell(for: indexPath, cellType: MessageCellSent.self)
             cell.messageLabel.text = messageViewModel.content
             return cell
diff --git a/Ring/Ring/Features/Conversations/Conversation/ConversationViewModel.swift b/Ring/Ring/Features/Conversations/Conversation/ConversationViewModel.swift
index 6fd3b91196b264ca3b8a4f269f94005cd865cb98..16b7bd75655ecdad5e9259a61bf284260fbe71a8 100644
--- a/Ring/Ring/Features/Conversations/Conversation/ConversationViewModel.swift
+++ b/Ring/Ring/Features/Conversations/Conversation/ConversationViewModel.swift
@@ -2,6 +2,7 @@
  *  Copyright (C) 2017 Savoir-faire Linux Inc.
  *
  *  Author: Silbino Gonçalves Matado <silbino.gmatado@savoirfairelinux.com>
+ *  Author: Kateryna Kostiuk <kateryna.kostiuk@savoirfairelinux.com>
  *
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by
@@ -85,9 +86,16 @@ class ConversationViewModel: ViewModel {
             if let contact = contact {
                 self.inviteButtonIsAvailable.onNext(!contact.confirmed)
             }
-            self.contactsService.contactStatus.subscribe(onNext: { contact in
-                self.inviteButtonIsAvailable.onNext(!contact.confirmed)
-            }).disposed(by: self.disposeBag)
+            self.contactsService.contactStatus.filter({ cont in
+                return cont.ringId == contact?.ringId
+            })
+                .subscribe(onNext: { [unowned self] cont in
+
+                    self.inviteButtonIsAvailable.onNext(!cont.confirmed)
+                    if cont.confirmed {
+                        self.generateMessage(ofType: GeneratedMessageType.contactRequestAccepted)
+                    }
+                }).disposed(by: self.disposeBag)
 
             // subscribe to presence updates for the conversation's associated contact
             self.presenceService
@@ -216,13 +224,13 @@ class ConversationViewModel: ViewModel {
                          to: self.conversation.recipientRingId)
             .subscribe(onCompleted: { [unowned self] in
                 let accountHelper = AccountModelHelper(withAccount: self.accountService.currentAccount!)
-                self.saveMessage(withContent: content, byAuthor: accountHelper.ringId!, toConversationWith: self.conversation.recipientRingId)
+                self.saveMessage(withContent: content, byAuthor: accountHelper.ringId!, toConversationWith: self.conversation.recipientRingId, generated: false)
             }).disposed(by: self.disposeBag)
     }
 
-    fileprivate func saveMessage(withContent content: String, byAuthor author: String, toConversationWith account: String) {
+    fileprivate func saveMessage(withContent content: String, byAuthor author: String, toConversationWith account: String, generated: Bool) {
         self.conversationsService
-            .saveMessage(withContent: content, byAuthor: author, toConversationWith: account, currentAccountId: (accountService.currentAccount?.id)!)
+            .saveMessage(withContent: content, byAuthor: author, toConversationWith: account, currentAccountId: (accountService.currentAccount?.id)!, generated: generated)
             .subscribe(onCompleted: { [unowned self] in
                 self.log.debug("Message saved")
             })
@@ -245,12 +253,45 @@ class ConversationViewModel: ViewModel {
     }
 
     func sendContactRequest() {
+
+        let contactExists =  self.contactsService.contact(withRingId: self.conversation.recipientRingId) != nil ? true : false
         self.accountService.loadVCard(forAccounr: self.accountService.currentAccount!)
-            .subscribe(onSuccess: { card in
-                self.contactsService.sendContactRequest(toContactRingId: self.conversation.recipientRingId, vCard: card, withAccount: self.accountService.currentAccount!).subscribe(onCompleted: {
-                    self.log.info("contact request sent")
-                }).disposed(by: self.disposeBag)
+            .subscribe(onSuccess: { [unowned self] (card) in
+                self.contactsService.sendContactRequest(toContactRingId: self.conversation.recipientRingId, vCard: card, withAccount: self.accountService.currentAccount!)
+                    .subscribe(onCompleted: {
+                        if !contactExists {
+                            self.generateMessage(ofType: GeneratedMessageType.sendContactRequest)
+                        }
+                        self.log.info("contact request sent")
+                    }).disposed(by: self.disposeBag)
+            }, onError: { [unowned self]  _ in
+                self.contactsService.sendContactRequest(toContactRingId: self.conversation.recipientRingId, vCard: nil, withAccount: self.accountService.currentAccount!)
+                    .subscribe(onCompleted: {
+                        if !contactExists {
+                            self.generateMessage(ofType: GeneratedMessageType.sendContactRequest)
+                        }
+                        self.log.info("contact request sent")
+                    }).disposed(by: self.disposeBag)
+
             }).disposed(by: self.disposeBag)
+    }
 
+    func generateMessage(ofType messageType: GeneratedMessageType) {
+        if self.generatedMessageExists(ofType: messageType) {
+            return
+        }
+
+        let accountHelper = AccountModelHelper(withAccount: self.accountService.currentAccount!)
+        self.saveMessage(withContent:
+            messageType.rawValue, byAuthor: accountHelper.ringId!, toConversationWith: self.conversation.recipientRingId, generated: true)
+    }
+
+    func generatedMessageExists(ofType messageType: GeneratedMessageType) -> Bool {
+        for message in self.conversation.messages
+            where message.content == messageType.rawValue {
+
+                return true
+        }
+        return false
     }
 }
diff --git a/Ring/Ring/Features/Conversations/Conversation/MessageViewModel.swift b/Ring/Ring/Features/Conversations/Conversation/MessageViewModel.swift
index 5843907308b8bb41005cee8c62472bd7de3aa253..b766246ef1b25a0e8202fb56764e6135969493a3 100644
--- a/Ring/Ring/Features/Conversations/Conversation/MessageViewModel.swift
+++ b/Ring/Ring/Features/Conversations/Conversation/MessageViewModel.swift
@@ -23,6 +23,13 @@ import RxSwift
 enum BubblePosition {
     case received
     case sent
+    case generated
+}
+
+enum GeneratedMessageType: String {
+    case sendContactRequest = "The invitation has been sent"
+    case receivedContactRequest = "Contact request received"
+    case contactRequestAccepted = "ACCEPTED"
 }
 
 class MessageViewModel {
@@ -41,13 +48,15 @@ class MessageViewModel {
     }
 
     func bubblePosition() -> BubblePosition {
-
+        if self.message.isGenerated {
+            return .generated
+        }
         let accountHelper = AccountModelHelper(withAccount: accountService.currentAccount!)
 
         if self.message.author == accountHelper.ringId! {
             return .sent
         } else {
-            return .received
+            return.received
         }
     }
 }
diff --git a/Ring/Ring/Models/MessageModel.swift b/Ring/Ring/Models/MessageModel.swift
index bc1d91d184acfa39e4573775e41148540faef3db..1a2631b1ca87b6297dfd40ed834f9efcb139708e 100644
--- a/Ring/Ring/Models/MessageModel.swift
+++ b/Ring/Ring/Models/MessageModel.swift
@@ -27,6 +27,7 @@ class MessageModel: Object {
     dynamic var content: String = ""
     dynamic var author: String = ""
     dynamic var status: MessageStatus = .unknown
+    dynamic var isGenerated: Bool = false
 
     convenience init(withId id: Int64, receivedDate: Date, content: String, author: String) {
         self.init()
@@ -35,5 +36,6 @@ class MessageModel: Object {
         self.content = content
         self.author = author
         self.status = .unknown
+        self.isGenerated = false
     }
 }
diff --git a/Ring/Ring/Services/ContactsService.swift b/Ring/Ring/Services/ContactsService.swift
index 3b31fb34ac5ea2c6c1423dc050e5e99262f7b844..5d39b5a3c64b1ed23442d79a353abad4353d1e74 100644
--- a/Ring/Ring/Services/ContactsService.swift
+++ b/Ring/Ring/Services/ContactsService.swift
@@ -70,7 +70,9 @@ class ContactsService {
             return ContactModel(withDictionary: contactDict)
         }) {
             for contact in contacts {
-                self.contacts.value.append(contact)
+                if self.contacts.value.index(of: contact) == nil {
+                    self.contacts.value.append(contact)
+                }
             }
         }
     }
@@ -212,16 +214,11 @@ extension ContactsService: ContactsAdapterDelegate {
     func contactAdded(contact uri: String, withAccountId accountId: String, confirmed: Bool) {
         //Update trust request list
         self.removeContactRequest(withRingId: uri)
-
-        //if contact list is empty thats mean app just starts and we receive all contacts was added
-        if self.contacts.value.isEmpty {
-            return
-        }
         // update contact status
         if let contact = self.contact(withRingId: uri) {
             if contact.confirmed != confirmed {
                 contact.confirmed = confirmed
-                contactStatus.onNext(contact)
+                self.contactStatus.onNext(contact)
             }
         }
             //sync contacts with daemon contacts
diff --git a/Ring/Ring/Services/ConversationsService.swift b/Ring/Ring/Services/ConversationsService.swift
index d8d177665f91cc847a9612b8c72ff8e497d11fa3..d4cc1a010f7954c8a0663481c10c28f5b5511d4a 100644
--- a/Ring/Ring/Services/ConversationsService.swift
+++ b/Ring/Ring/Services/ConversationsService.swift
@@ -40,6 +40,7 @@ class ConversationsService: MessagesAdapterDelegate {
     var conversations: Observable<Results<ConversationModel>>
 
     init(withMessageAdapter adapter: MessagesAdapter) {
+
         guard let realm = try? Realm() else {
             fatalError("Enable to instantiate Realm")
         }
@@ -50,6 +51,7 @@ class ConversationsService: MessagesAdapterDelegate {
 
         conversations = Observable.collection(from: results, synchronousStart: true)
         MessagesAdapter.delegate = self
+
     }
 
     func sendMessage(withContent content: String,
@@ -63,7 +65,11 @@ class ConversationsService: MessagesAdapterDelegate {
             let accountHelper = AccountModelHelper(withAccount: senderAccount)
 
             if accountHelper.ringId! != recipientRingId {
-                _ = self.saveMessage(withContent: content, byAuthor: accountHelper.ringId!, toConversationWith: recipientRingId, currentAccountId: senderAccount.id)
+                _ = self.saveMessage(withContent: content,
+                                     byAuthor: accountHelper.ringId!,
+                                     toConversationWith: recipientRingId,
+                                     currentAccountId: senderAccount.id,
+                                     generated: false)
             }
 
             completable(.completed)
@@ -90,10 +96,14 @@ class ConversationsService: MessagesAdapterDelegate {
     func saveMessage(withContent content: String,
                      byAuthor author: String,
                      toConversationWith recipientRingId: String,
-                     currentAccountId: String) -> Completable {
+                     currentAccountId: String,
+                     generated: Bool?) -> Completable {
 
         return Completable.create(subscribe: { [unowned self] completable in
             let message = MessageModel(withId: 0, receivedDate: Date(), content: content, author: author)
+            if let generated = generated {
+                message.isGenerated = generated
+            }
 
             //Get conversations for this sender
             var currentConversation = self.results.filter({ conversation in
@@ -185,7 +195,8 @@ class ConversationsService: MessagesAdapterDelegate {
             self.saveMessage(withContent: content,
                              byAuthor: senderAccount,
                              toConversationWith: senderAccount,
-                             currentAccountId: receiverAccountId)
+                             currentAccountId: receiverAccountId,
+                             generated: false)
                 .subscribe(onCompleted: { [unowned self] in
                     self.log.info("Message saved")
                 })