diff --git a/daemon/src/call.h b/daemon/src/call.h
index cab2800ea38c0e6a732e1f16e39cf2437e1fab6b..c0fd2fa6891b1e4a4a4a53b44f598f3843690046 100644
--- a/daemon/src/call.h
+++ b/daemon/src/call.h
@@ -289,6 +289,17 @@ class Call : public Recordable {
          */
         virtual void carryingDTMFdigits(char code) = 0;
 
+#if HAVE_INSTANT_MESSAGING
+        /**
+         * Send a message to a call identified by its callid
+         *
+         * @param The actual message to be transmitted
+         * @param The sender of this message (could be another participant of a conference)
+         */
+        virtual void sendTextMessage(const std::string &message,
+                                     const std::string &from) = 0;
+#endif
+
     private:
         bool validTransition(CallState newState);
 
diff --git a/daemon/src/iax/iaxcall.cpp b/daemon/src/iax/iaxcall.cpp
index 76ba15605605bfbfa01ef931604cee420bf04392..3aadb7ca92c8350c78a0cdf60e1e4f64ad7e2324 100644
--- a/daemon/src/iax/iaxcall.cpp
+++ b/daemon/src/iax/iaxcall.cpp
@@ -40,6 +40,10 @@
 #include "manager.h"
 #include "iaxvoiplink.h"
 
+#if HAVE_INSTANT_MESSAGING
+#include "im/instant_messaging.h"
+#endif
+
 static int
 codecToASTFormat(int c)
 {
@@ -226,3 +230,12 @@ IAXCall::carryingDTMFdigits(char code)
     std::lock_guard<std::mutex> lock(IAXVoIPLink::mutexIAX);
     iax_send_dtmf(session, code);
 }
+
+#if HAVE_INSTANT_MESSAGING
+void
+IAXCall::sendTextMessage(const std::string& message, const std::string& /*from*/)
+{
+    std::lock_guard<std::mutex> lock(IAXVoIPLink::mutexIAX);
+    sfl::InstantMessaging::send_iax_message(session, getCallId(), message.c_str());
+}
+#endif
diff --git a/daemon/src/iax/iaxcall.h b/daemon/src/iax/iaxcall.h
index 84101fb98a9fdc9d645557a62b64142006f53cf5..ffb85b7652ad800f7b2bb0fc21eff09dd1e0ee8b 100644
--- a/daemon/src/iax/iaxcall.h
+++ b/daemon/src/iax/iaxcall.h
@@ -31,6 +31,10 @@
 #ifndef IAXCALL_H
 #define IAXCALL_H
 
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
 #include "call.h"
 #include "noncopyable.h"
 
@@ -98,6 +102,11 @@ class IAXCall : public Call {
 
         void carryingDTMFdigits(char code);
 
+#if HAVE_INSTANT_MESSAGING
+        void sendTextMessage(const std::string& message,
+                             const std::string& from);
+#endif
+
     private:
         NON_COPYABLE(IAXCall);
 
diff --git a/daemon/src/iax/iaxvoiplink.cpp b/daemon/src/iax/iaxvoiplink.cpp
index 55ad10a23c8c52a8ded182e95f2f476e69af54d8..8d7f9d7696c5a2b2161a746e45767ba88e3068ab 100644
--- a/daemon/src/iax/iaxvoiplink.cpp
+++ b/daemon/src/iax/iaxvoiplink.cpp
@@ -35,7 +35,6 @@
 
 #include "iaxcall.h"
 #include "eventthread.h"
-#include "im/instant_messaging.h"
 #include "iaxaccount.h"
 #include "logger.h"
 #include "manager.h"
@@ -313,24 +312,6 @@ IAXVoIPLink::newOutgoingCall(const std::string& id, const std::string& toUrl, co
     return call;
 }
 
-#if HAVE_INSTANT_MESSAGING
-void
-IAXVoIPLink::sendTextMessage(const std::string& callID,
-                             const std::string& message,
-                             const std::string& /*from*/)
-{
-    std::lock_guard<std::mutex> lock(iaxCallMapMutex_);
-    auto call = getIAXCall(callID);
-    if (!call)
-        return;
-
-    {
-        std::lock_guard<std::mutex> lock(mutexIAX);
-        sfl::InstantMessaging::send_iax_message(call->session, callID, message.c_str());
-    }
-}
-#endif
-
 void
 IAXVoIPLink::clearIaxCallMap()
 {
diff --git a/daemon/src/iax/iaxvoiplink.h b/daemon/src/iax/iaxvoiplink.h
index 6fd8acca27bdf9495ce8febad6aa12a1318abac8..39c3a03af207c93f1a80c11d8152e1c5527e43c7 100644
--- a/daemon/src/iax/iaxvoiplink.h
+++ b/daemon/src/iax/iaxvoiplink.h
@@ -127,9 +127,6 @@ class IAXVoIPLink : public VoIPLink {
          */
         virtual void cancel(const std::string& /*id*/) {}
 
-#if HAVE_INSTANT_MESSAGING
-        virtual void sendTextMessage(const std::string& callID, const std::string& message, const std::string& from);
-#endif
         static void clearIaxCallMap();
         static void addIaxCall(std::shared_ptr<IAXCall>& call);
         // must be called while holding iaxCallMapMutex
diff --git a/daemon/src/managerimpl.cpp b/daemon/src/managerimpl.cpp
index 909e32e242b79a55f66f3848267aa2cfdbfbf2a6..4b410ead0217447418c818d619c262ffc9872174 100644
--- a/daemon/src/managerimpl.cpp
+++ b/daemon/src/managerimpl.cpp
@@ -1467,18 +1467,14 @@ void ManagerImpl::incomingMessage(const std::string& callID,
             if (item_p == callID)
                 continue;
 
-            std::string accountId(getAccountFromCall(item_p));
+            DEBUG("Send message to %s", item_p.c_str());
 
-            DEBUG("Send message to %s, (%s)", item_p.c_str(), accountId.c_str());
-
-            Account *account = getAccount(accountId);
-
-            if (!account) {
-                ERROR("Failed to get account while sending instant message");
+            if (auto call = getCallFromCallID(item_p)) {
+                call->sendTextMessage(message, from);
+            } else {
+                ERROR("Failed to get call while sending instant message");
                 return;
             }
-
-            account->getVoIPLink()->sendTextMessage(callID, message, from);
         }
 
         // in case of a conference we must notify client using conference id
@@ -1505,18 +1501,14 @@ bool ManagerImpl::sendTextMessage(const std::string& callID, const std::string&
 
         ParticipantSet participants(conf->getParticipantList());
 
-        for (const auto &participant : participants) {
-
-            std::string accountId = getAccountFromCall(participant);
+        for (const auto &participant_id : participants) {
 
-            Account *account = getAccount(accountId);
-
-            if (!account) {
-                DEBUG("Failed to get account while sending instant message");
+            if (auto call = getCallFromCallID(participant_id)) {
+                call->sendTextMessage(message, from);
+            } else {
+                ERROR("Failed to get call while sending instant message");
                 return false;
             }
-
-            account->getVoIPLink()->sendTextMessage(participant, message, from);
         }
 
         return true;
@@ -1531,28 +1523,22 @@ bool ManagerImpl::sendTextMessage(const std::string& callID, const std::string&
 
         ParticipantSet participants(conf->getParticipantList());
 
-        for (const auto &item_p : participants) {
+        for (const auto &participant_id : participants) {
 
-            const std::string accountId(getAccountFromCall(item_p));
-
-            Account *account = getAccount(accountId);
-
-            if (!account) {
-                DEBUG("Failed to get account while sending instant message");
+            if (auto call = getCallFromCallID(participant_id)) {
+                call->sendTextMessage(message, from);
+            } else {
+                ERROR("Failed to get call while sending instant message");
                 return false;
             }
-
-            account->getVoIPLink()->sendTextMessage(item_p, message, from);
         }
     } else {
-        Account *account = getAccount(getAccountFromCall(callID));
-
-        if (!account) {
-            DEBUG("Failed to get account while sending instant message");
+        if (auto call = getCallFromCallID(callID)) {
+            call->sendTextMessage(message, from);
+        } else {
+            ERROR("Failed to get call while sending instant message");
             return false;
         }
-
-        account->getVoIPLink()->sendTextMessage(callID, message, from);
     }
     return true;
 }
diff --git a/daemon/src/sip/sipcall.cpp b/daemon/src/sip/sipcall.cpp
index e3a29ba0fb92c2b8496ec98d01b5fc745b785fae..51c40c0aa07c0a201df5a8c6b3ed77d65d61a614 100644
--- a/daemon/src/sip/sipcall.cpp
+++ b/daemon/src/sip/sipcall.cpp
@@ -40,6 +40,10 @@
 
 #include "audio/audiortp/audio_rtp_factory.h" // for AudioRtpFactoryException
 
+#if HAVE_INSTANT_MESSAGING
+#include "im/instant_messaging.h"
+#endif
+
 #ifdef SFL_VIDEO
 #include "client/videomanager.h"
 
@@ -648,3 +652,18 @@ SIPCall::carryingDTMFdigits(char code)
 
     dtmfSend(*this, code, account->getDtmfType());
 }
+
+#if HAVE_INSTANT_MESSAGING
+void
+SIPCall::sendTextMessage(const std::string &message, const std::string &from)
+{
+    using namespace sfl::InstantMessaging;
+
+    /* Send IM message */
+    UriList list;
+    UriEntry entry;
+    entry[sfl::IM_XML_URI] = std::string("\"" + from + "\"");  // add double quotes for xml formating
+    list.push_front(entry);
+    send_sip_message(inv, getCallId(), appendUriList(message, list));
+}
+#endif // HAVE_INSTANT_MESSAGING
diff --git a/daemon/src/sip/sipcall.h b/daemon/src/sip/sipcall.h
index 9becb5cd0aa373832d6c42be6e1f846bb1c2fa04..076f5bb41a9b099379817108190b2fb578e9b1b7 100644
--- a/daemon/src/sip/sipcall.h
+++ b/daemon/src/sip/sipcall.h
@@ -132,6 +132,11 @@ class SIPCall : public Call {
 
         void carryingDTMFdigits(char code);
 
+#if HAVE_INSTANT_MESSAGING
+        void sendTextMessage(const std::string& message,
+                             const std::string& from);
+#endif
+
     private:
 
         // override of Call::createHistoryEntry
diff --git a/daemon/src/sip/sipvoiplink.cpp b/daemon/src/sip/sipvoiplink.cpp
index 5d0b91c45253d974675770411b032f6c12668340..1bdd1126039200cbaa19464c2951c9b497b0a396 100644
--- a/daemon/src/sip/sipvoiplink.cpp
+++ b/daemon/src/sip/sipvoiplink.cpp
@@ -1025,25 +1025,6 @@ stopRtpIfCurrent(const std::string &id, SIPCall &call)
     }
 }
 
-#if HAVE_INSTANT_MESSAGING
-void SIPVoIPLink::sendTextMessage(const std::string &callID,
-                                  const std::string &message,
-                                  const std::string &from)
-{
-    using namespace sfl::InstantMessaging;
-    auto call = getSipCall(callID);
-    if (!call)
-        return;
-
-    /* Send IM message */
-    UriList list;
-    UriEntry entry;
-    entry[sfl::IM_XML_URI] = std::string("\"" + from + "\"");  // add double quotes for xml formating
-    list.push_front(entry);
-    send_sip_message(call->inv, callID, appendUriList(message, list));
-}
-#endif // HAVE_INSTANT_MESSAGING
-
 void
 SIPVoIPLink::clearSipCallMap()
 {
@@ -1051,7 +1032,6 @@ SIPVoIPLink::clearSipCallMap()
     sipCallMap_.clear();
 }
 
-
 std::vector<std::string>
 SIPVoIPLink::getCallIDs()
 {
diff --git a/daemon/src/sip/sipvoiplink.h b/daemon/src/sip/sipvoiplink.h
index 4af99f6e2c0251c8fee6b27d5a7c70df0a830fb8..09d64f457f00efd2aa8de79c16e7cfcddb868b0e 100644
--- a/daemon/src/sip/sipvoiplink.h
+++ b/daemon/src/sip/sipvoiplink.h
@@ -187,18 +187,6 @@ class SIPVoIPLink : public VoIPLink {
          */
         std::string getUseragentName(SIPAccount *) const;
 
-        /**
-         * Send a SIP message to a call identified by its callid
-         *
-         * @param The Id of the call to send the message to
-         * @param The actual message to be transmitted
-         * @param The sender of this message (could be another participant of a conference)
-         */
-#if HAVE_INSTANT_MESSAGING
-        void sendTextMessage(const std::string& callID,
-                             const std::string& message,
-                             const std::string& from);
-#endif
         void clearSipCallMap();
         void addSipCall(std::shared_ptr<SIPCall>& call);
 
diff --git a/daemon/src/voiplink.h b/daemon/src/voiplink.h
index 248e187a752fbc36a81f0b725de48aca93ad7946..627779bc341c7f2c24e966ee2515fc8e390947f3 100644
--- a/daemon/src/voiplink.h
+++ b/daemon/src/voiplink.h
@@ -93,19 +93,6 @@ class VoIPLink {
          */
         virtual std::vector<std::shared_ptr<Call> > getCalls(const std::string &account_id) const = 0;
 
-        /**
-         * Send a message to a call identified by its callid
-         *
-         * @param The Id of the call to send the message to
-         * @param The actual message to be transmitted
-         * @param The sender of this message (could be another participant of a conference)
-         */
-#if HAVE_INSTANT_MESSAGING
-        virtual void sendTextMessage(const std::string &callID,
-                                     const std::string &message,
-                                     const std::string &from) = 0;
-#endif
-
     protected:
         static void unloadAccount(std::pair<const std::string, Account*> &item);
         bool handlingEvents_;