diff --git a/bin/dbus/callmanager-introspec.xml b/bin/dbus/callmanager-introspec.xml
index 66cb318e86b61245f4600a399b3adc3a60cf7e6a..32a6fe25abf76ba88776891a01852a002588aab2 100644
--- a/bin/dbus/callmanager-introspec.xml
+++ b/bin/dbus/callmanager-introspec.xml
@@ -445,7 +445,8 @@
                 Send a text message to the specified call
             </tp:docstring>
             <arg type="s" name="callID" direction="in"/>
-            <arg type="s" name="message" direction="in"/>
+            <annotation name="org.qtproject.QtDBus.QtTypeName.In1" value="MapStringString"/>
+            <arg type="a{ss}" name="message" direction="in"/>
         </method>
 
         <signal name="newCallCreated" tp:name-for-bindings="newCallCreated">
@@ -498,11 +499,13 @@
 
         <signal name="incomingMessage" tp:name-for-bindings="incomingMessage">
             <tp:docstring>
-                Notify clients that a new text message has been received.
+                Notify clients that new messages have been received. The key is
+                the mime type and the value the mime payload.
             </tp:docstring>
             <arg type="s" name="callID" />
             <arg type="s" name="from" />
-            <arg type="s" name="message" />
+            <annotation name="org.qtproject.QtDBus.QtTypeName.In2" value="MapStringString"/>
+            <arg type="a{ss}" name="messages" />
         </signal>
 
         <signal name="callStateChanged" tp:name-for-bindings="callStateChanged">
diff --git a/bin/dbus/configurationmanager-introspec.xml b/bin/dbus/configurationmanager-introspec.xml
index bb0003f2c1d532d85ceabaa1dc2d71ae96695d62..c3b09f665be1c0a5c64906daa2501c25d86dcd85 100644
--- a/bin/dbus/configurationmanager-introspec.xml
+++ b/bin/dbus/configurationmanager-introspec.xml
@@ -237,7 +237,6 @@
        </method>
 
       <method name="sendTextMessage" tp:name-for-bindings="sendTextMessage">
-          <annotation name="org.qtproject.QtDBus.QtTypeName.Out0" value="MapStringString"/>
           <arg type="s" name="accountID" direction="in">
           </arg>
           <arg type="s" name="to" direction="in">
@@ -247,7 +246,7 @@
        </method>
 
        <signal name="incomingAccountMessage" tp:name-for-bindings="incomingAccountMessage">
-		   <tp:added version="2.2.0"/>
+           <tp:added version="2.2.0"/>
            <tp:docstring>
                Notify clients that a new text message has been received at the account level.
            </tp:docstring>
diff --git a/bin/dbus/dbuscallmanager.cpp b/bin/dbus/dbuscallmanager.cpp
index 4eb4cf30c70cbbf048698ac4535811baea7ff31c..afe237609d9ea9ad87746fd2015f8d5cb9fe1c02 100644
--- a/bin/dbus/dbuscallmanager.cpp
+++ b/bin/dbus/dbuscallmanager.cpp
@@ -289,7 +289,7 @@ DBusCallManager::acceptEnrollment(const std::string& callID, const bool& accepte
 }
 
 void
-DBusCallManager::sendTextMessage(const std::string& callID, const std::string& message)
+DBusCallManager::sendTextMessage(const std::string& callID, const std::map<std::string, std::string>& messages)
 {
-    DRing::sendTextMessage(callID, message);
+    DRing::sendTextMessage(callID, messages, "Me");
 }
diff --git a/bin/dbus/dbuscallmanager.h b/bin/dbus/dbuscallmanager.h
index 6d338f33c979c0318b1abfedc4ddf3f441e7d457..43c8f87aaaf18e2c1ade9449b5112bd6b38b96ee 100644
--- a/bin/dbus/dbuscallmanager.h
+++ b/bin/dbus/dbuscallmanager.h
@@ -106,7 +106,7 @@ class DBusCallManager :
         void setConfirmGoClear(const std::string& callID);
         void requestGoClear(const std::string& callID);
         void acceptEnrollment(const std::string& callID, const bool& accepted);
-        void sendTextMessage(const std::string& callID, const std::string& message);
+        void sendTextMessage(const std::string& callID, const std::map<std::string, std::string>& messages);
 };
 
 #endif // __RING_CALLMANAGER_H__
diff --git a/src/call.h b/src/call.h
index 78a1f98f4dbd6623d206aa9ae9c829ac7ef41b8a..ee432543ae94c02e9d5d96ccecb5fe2dbe509acd 100644
--- a/src/call.h
+++ b/src/call.h
@@ -301,10 +301,10 @@ class Call : public Recordable, public std::enable_shared_from_this<Call> {
         /**
          * Send a message to a call identified by its callid
          *
-         * @param The actual message to be transmitted
+         * @param A list of mimetype/payload pairs
          * @param The sender of this message (could be another participant of a conference)
          */
-        virtual void sendTextMessage(const std::string &message,
+        virtual void sendTextMessage(const std::map<std::string, std::string>& messages,
                                      const std::string &from) = 0;
 #endif
 
diff --git a/src/client/callmanager.cpp b/src/client/callmanager.cpp
index 625748df23962717048e5b53e0ffb8cb5a29af90..b90e689a6b007a62d82ed0019388b2e74f28c788 100644
--- a/src/client/callmanager.cpp
+++ b/src/client/callmanager.cpp
@@ -332,20 +332,10 @@ acceptEnrollment(const std::string& /*callID*/, bool /*accepted*/)
 }
 
 void
-sendTextMessage(const std::string& callID, const std::string& message, const std::string& from)
+sendTextMessage(const std::string& callID, const std::map<std::string, std::string>& messages, const std::string& from)
 {
 #if HAVE_INSTANT_MESSAGING
-   ring::Manager::instance().sendCallTextMessage(callID, message, from);
-#endif
-}
-
-void
-sendTextMessage(const std::string& callID, const std::string& message)
-{
-#if HAVE_INSTANT_MESSAGING
-    ring::Manager::instance().sendCallTextMessage(callID, message, "Me");
-#else
-    RING_ERR("Could not send \"%s\" text message to %s since Ring daemon does not support it, please recompile with instant messaging support", message.c_str(), callID.c_str());
+   ring::Manager::instance().sendCallTextMessage(callID, messages, from);
 #endif
 }
 
diff --git a/src/dring/callmanager_interface.h b/src/dring/callmanager_interface.h
index b3cfcb6d4fd352d1e8393864a165b2d181c727d8..397eb5e3a73c3b4a2fc36428ebe55783006acf29 100644
--- a/src/dring/callmanager_interface.h
+++ b/src/dring/callmanager_interface.h
@@ -102,8 +102,7 @@ void requestGoClear(const std::string& callID);
 void acceptEnrollment(const std::string& callID, bool accepted);
 
 /* Instant messaging */
-void sendTextMessage(const std::string& callID, const std::string& message);
-void sendTextMessage(const std::string& callID, const std::string& message, const std::string& from);
+void sendTextMessage(const std::string& callID, const std::map<std::string, std::string>& messages, const std::string& from);
 
 // Call signal type definitions
 struct CallSignal {
@@ -129,7 +128,7 @@ struct CallSignal {
         };
         struct IncomingMessage {
                 constexpr static const char* name = "IncomingMessage";
-                using cb_type = void(const std::string&, const std::string&, const std::string&);
+                using cb_type = void(const std::string&, const std::string&, const std::map<std::string, std::string>&);
         };
         struct IncomingCall {
                 constexpr static const char* name = "IncomingCall";
diff --git a/src/iax/iaxcall.cpp b/src/iax/iaxcall.cpp
index 38fb846ba40a6b8e712add3c1e4e4416cf4863b2..c7243eb3160fc1867029594246d1002b5074ed8b 100644
--- a/src/iax/iaxcall.cpp
+++ b/src/iax/iaxcall.cpp
@@ -241,11 +241,13 @@ IAXCall::carryingDTMFdigits(char code)
 }
 
 #if HAVE_INSTANT_MESSAGING
-void
-IAXCall::sendTextMessage(const std::string& message, const std::string& /*from*/)
+
+void IAXCall::sendTextMessage(const std::map<std::string, std::string>& messages,
+                                     const std::string &from)
 {
     std::lock_guard<std::mutex> lock(IAXVoIPLink::mutexIAX);
-    InstantMessaging::send_iax_message(session, getCallId(), message.c_str());
+    for (const auto &message : messages)
+        InstantMessaging::send_iax_message(session, getCallId(), message.second.c_str());
 }
 #endif
 
diff --git a/src/iax/iaxcall.h b/src/iax/iaxcall.h
index d4eb50ca32a82b2a74d3a2dfb59dd775c7bb621e..f02f4b2255b56ebd84e1434cdc9b6df9eba1b302 100644
--- a/src/iax/iaxcall.h
+++ b/src/iax/iaxcall.h
@@ -142,8 +142,9 @@ class IAXCall : public Call
         void carryingDTMFdigits(char code);
 
 #if HAVE_INSTANT_MESSAGING
-        void sendTextMessage(const std::string& message,
-                             const std::string& from);
+
+        virtual void sendTextMessage(const std::map<std::string, std::string>& messages,
+                                     const std::string &from);
 #endif
 
         void putAudioData(AudioBuffer& buf);
diff --git a/src/iax/iaxvoiplink.cpp b/src/iax/iaxvoiplink.cpp
index be32070173b95cda64acbc002070aa4a127dd7a7..d72ec527415a56e8927e0c9be845d5a20eea662e 100644
--- a/src/iax/iaxvoiplink.cpp
+++ b/src/iax/iaxvoiplink.cpp
@@ -261,8 +261,8 @@ IAXVoIPLink::handleBusy(IAXCall& call)
 void
 IAXVoIPLink::handleMessage(iax_event* event, IAXCall& call)
 {
-    Manager::instance().incomingMessage(call.getCallId(), call.getPeerNumber(),
-                                        std::string((const char*) event->data));
+    Manager::instance().incomingMessage(call.getCallId(), call.getPeerNumber() ,std::map<std::string, std::string>
+                                        {{"text/plain", std::string((const char*) event->data)}});
 }
 #endif
 
diff --git a/src/im/instant_messaging.cpp b/src/im/instant_messaging.cpp
index 718a7ddb6a5990b92bf373e01d0bc27901d4b50a..6436a3965db43df4272fb8c44dbe90e6ae4f9011 100644
--- a/src/im/instant_messaging.cpp
+++ b/src/im/instant_messaging.cpp
@@ -1,6 +1,7 @@
 /*
  *  Copyright (C) 2004-2015 Savoir-Faire Linux Inc.
  *  Author: Emmanuel Milou <emmanuel.milou@savoirfairelinux.com>
+ *  Author: Emmanuel Lepage <elv1313@gmail.com>
  *  Author: Alexandre Savard <alexandre.savard@savoirfairelinux.com>
  *
  *  This program is free software; you can redistribute it and/or modify
@@ -160,19 +161,37 @@ InstantMessaging::parseXmlUriList(const std::string &urilist)
     return list;
 }
 
-std::string InstantMessaging::appendUriList(const std::string &text, UriList& list)
+///See rfc2046#section-5.1.4
+static std::string buildMimeMultipartPart(const std::string &type, const std::string &dispo, const std::string &content)
 {
-    return "--boundary Content-Type: text/plain" + text +
-           "--boundary Content-Type: application/resource-lists+xml" +
-           "Content-Disposition: recipient-list" + generateXmlUriList(list) +
-           "--boundary--";
+    return
+    "--boundary\n"
+    "Content-Type: " + type + "\n" +
+    (!dispo.empty() ? "Content-Disposition: "+ dispo + "\n" : "") +
+    "\n" +
+    content + "\n";
+}
+
+std::string InstantMessaging::appendMimePayloads(const std::map<std::string,std::string> payloads, UriList& list)
+{
+    std::string ret;
+
+    for (const auto pair : payloads) {
+        ret += buildMimeMultipartPart(pair.first, {}, pair.second);
+    }
+
+    if (!list.empty())
+        ret += buildMimeMultipartPart("application/resource-lists+xml", "recipient-list", generateXmlUriList(list));
+
+    ret += "--boundary--";
+    return ret;
 }
 
 std::string InstantMessaging::findTextUriList(const std::string &text)
 {
-    const std::string ctype("Content-Type: application/resource-lists+xml");
-    const std::string cdispo("Content-Disposition: recipient-list");
-    const std::string boundary("--boundary--");
+    static const std::string ctype("Content-Type: application/resource-lists+xml");
+    static const std::string cdispo("Content-Disposition: recipient-list");
+    static const std::string boundary("--boundary--");
 
     // init position pointer
     size_t pos = 0;
@@ -185,8 +204,12 @@ std::string InstantMessaging::findTextUriList(const std::string &text)
     if ((pos = text.find(cdispo, pos)) == std::string::npos)
         throw InstantMessageException("Could not find Content-Disposition tag while parsing sip message for recipient-list");
 
-    // xml content start after content disposition tag (plus \n\n)
-    const size_t begin = pos + cdispo.size();
+    // xml content start after content disposition tag
+    size_t begin = pos + cdispo.size();
+
+    //Remove arbitrary number of empty lines, otherwise XML_Parse will return XML_STATUS_ERROR
+    while (text[begin] == '\n' || text[begin] == '\r')
+        begin++;
 
     // find final boundary
     size_t end;
@@ -196,20 +219,98 @@ std::string InstantMessaging::findTextUriList(const std::string &text)
     return text.substr(begin, end - begin);
 }
 
-std::string InstantMessaging::findTextMessage(const std::string &text)
+/*
+ * From RFC2046:
+ *
+ * MIME-Version: 1.0
+ * Content-Type: multipart/alternative; boundary=boundary42
+ *
+ * --boundary42
+ * Content-Type: text/plain; charset=us-ascii
+ *
+ *    ... plain text version of message goes here ...
+ *
+ * --boundary42
+ * Content-Type: text/html
+ *
+ *    ... RFC 1896 text/enriched version of same message
+ *       goes here ...
+ *
+ * --boundary42
+ * Content-Type: application/x-whatever
+ *
+ *    ... fanciest version of same message goes here ...
+ *
+ * --boundary42--
+ */
+
+std::string InstantMessaging::findMimePayload(const std::string &encodedPayloads, const std::string &mime)
 {
-    std::string ctype = "Content-Type: text/plain";
-    const size_t pos = text.find(ctype);
+    const std::string ctype = "Content-Type: " + mime;
+    const size_t pos = encodedPayloads.find(ctype);
     if (pos == std::string::npos)
-        throw InstantMessageException("Could not find Content-Type tag while parsing sip message for text");
-
+        return {};
     const size_t begin = pos + ctype.size();
 
-    const size_t end = text.find("--boundary", begin);
-    if (end == std::string::npos)
-        throw InstantMessageException("Could not find end of text \"boundary\" while parsing sip message for text");
+    const size_t end = encodedPayloads.find("--boundary", begin);
+    if (end == std::string::npos) {
+        RING_DBG("Could not find end of text \"boundary\" while parsing sip message for text");
+        return {};
+    }
 
-    return text.substr(begin, end - begin);
+    return encodedPayloads.substr(begin, end - begin);
+}
+
+std::map< std::string, std::string > InstantMessaging::parsePayloads(const std::string &encodedPayloads)
+{
+    //Constants
+    static const std::string boud  = "--boundary"           ;
+    static const std::string type  = "Content-Type: "       ;
+    static const std::string dispo = "Content-Disposition: ";
+    const size_t end = encodedPayloads.find("--boundary--");
+
+    size_t next_start = encodedPayloads.find(boud);
+
+    std::map< std::string, std::string > ret;
+
+    do {
+        size_t currentStart = next_start;
+
+        next_start = encodedPayloads.find(boud, currentStart+1);
+
+        //Get the mime type
+        size_t context_pos = encodedPayloads.find(type, currentStart+1);
+        if (context_pos == std::string::npos)
+            break;
+        else if (context_pos >= next_start)
+            continue;
+
+        context_pos += type.size();
+
+        size_t mimeTypeEnd = encodedPayloads.find('\n', context_pos+1);
+        if (encodedPayloads[context_pos-1] == '\r')
+            mimeTypeEnd--;
+
+        std::string mimeType = encodedPayloads.substr(context_pos, mimeTypeEnd - context_pos);
+        currentStart = mimeTypeEnd+1;
+
+        //Remove the disposition
+        const size_t dispoPos = encodedPayloads.find(dispo, currentStart);
+        if (dispoPos != std::string::npos && dispoPos < next_start) {
+            currentStart = encodedPayloads.find('\n', dispoPos);
+            while (encodedPayloads[currentStart] == '\n' || encodedPayloads[currentStart] == '\r')
+                currentStart++;
+        }
+
+        //Get the payload
+        std::string payload = encodedPayloads.substr(currentStart, next_start - currentStart);
+
+        //WARNING assume only one message per payload exist
+        ret[mimeType] = payload;
+
+    } while(next_start < end);
+
+    return ret;
 }
 
 } // namespace ring
diff --git a/src/im/instant_messaging.h b/src/im/instant_messaging.h
index 415857c52891582b20c0d9fc15e73dd3da3b7832..8170d2b344af98c9cb4e99a6f0137d3688997e1b 100644
--- a/src/im/instant_messaging.h
+++ b/src/im/instant_messaging.h
@@ -123,7 +123,7 @@ UriList parseXmlUriList(const std::string &urilist);
  *
  * @return formated text stored into a string to be included in sip MESSAGE
  */
-std::string appendUriList(const std::string &text, UriList &list);
+std::string appendMimePayloads(const std::map<std::string,std::string> payloads, UriList& list);
 
 /**
  * Retreive the xml formated uri list in formated text data according to RFC 5365
@@ -135,13 +135,22 @@ std::string appendUriList(const std::string &text, UriList &list);
 std::string findTextUriList(const std::string &text);
 
 /**
- * Retrive the plain text message in formated text data according to RFC 5365
+ * Retrieve a MIME payload from the SIP container RFC5365
  *
- * @param text The formated text message as retreived in the SIP message
+ * @param mime the mime type 
+ *
+ * @param encodedPayloads a MIME encoded set of payloads
  *
  * @return A string containing the actual message
  */
-std::string findTextMessage(const std::string &text);
+std::string findMimePayload(const std::string &encodedPayloads, const std::string &mime = "text/plain");
+
+/**
+ * Retrieve all MIME payloads from encodedPayloads
+ *
+ * @param encodedPayloads a MIME encoded set of payloads
+ */
+std::map< std::string, std::string > parsePayloads(const std::string &encodedPayloads);
 
 }} // namespace ring::InstantMessaging
 
diff --git a/src/manager.cpp b/src/manager.cpp
index 3c986fcd6e3d65342423d3768dd648759402b750..f766f40a7dfb245ae46e23edcdd73dcfcbaaecec 100644
--- a/src/manager.cpp
+++ b/src/manager.cpp
@@ -1629,10 +1629,11 @@ Manager::incomingCall(Call &call, const std::string& accountId)
 
 //THREAD=VoIP
 #if HAVE_INSTANT_MESSAGING
+
 void
 Manager::incomingMessage(const std::string& callID,
                              const std::string& from,
-                             const std::string& message)
+                             const std::map<std::string, std::string>& messages)
 {
     if (isConferenceParticipant(callID)) {
         auto conf = getConferenceFromCallID(callID);
@@ -1647,7 +1648,7 @@ Manager::incomingMessage(const std::string& callID,
             RING_DBG("Send message to %s", item_p.c_str());
 
             if (auto call = getCallFromCallID(item_p)) {
-                call->sendTextMessage(message, from);
+                call->sendTextMessage(messages, from);
             } else {
                 RING_ERR("Failed to get call while sending instant message");
                 return;
@@ -1655,16 +1656,16 @@ Manager::incomingMessage(const std::string& callID,
         }
 
         // in case of a conference we must notify client using conference id
-        emitSignal<DRing::CallSignal::IncomingMessage>(conf->getConfID(), from, message);
+        emitSignal<DRing::CallSignal::IncomingMessage>(conf->getConfID(), from, messages);
     } else
-        emitSignal<DRing::CallSignal::IncomingMessage>(callID, from, message);
+        emitSignal<DRing::CallSignal::IncomingMessage>(callID, from, messages);
 }
 
 //THREAD=VoIP
 bool
 Manager::sendCallTextMessage(const std::string& callID,
-                             const std::string& message,
-                             const std::string& from)
+                              const std::map<std::string, std::string>& messages,
+                              const std::string& from)
 {
     if (isConference(callID)) {
         RING_DBG("Is a conference, send instant message to everyone");
@@ -1683,7 +1684,7 @@ Manager::sendCallTextMessage(const std::string& callID,
         for (const auto &participant_id : participants) {
 
             if (auto call = getCallFromCallID(participant_id)) {
-                call->sendTextMessage(message, from);
+                call->sendTextMessage(messages, from);
             } else {
                 RING_ERR("Failed to get call while sending instant message");
                 return false;
@@ -1705,7 +1706,7 @@ Manager::sendCallTextMessage(const std::string& callID,
         for (const auto &participant_id : participants) {
 
             if (auto call = getCallFromCallID(participant_id)) {
-                call->sendTextMessage(message, from);
+                call->sendTextMessage(messages, from);
             } else {
                 RING_ERR("Failed to get call while sending instant message");
                 return false;
@@ -1713,7 +1714,7 @@ Manager::sendCallTextMessage(const std::string& callID,
         }
     } else {
         if (auto call = getCallFromCallID(callID)) {
-            call->sendTextMessage(message, from);
+            call->sendTextMessage(messages, from);
         } else {
             RING_ERR("Failed to get call while sending instant message");
             return false;
@@ -1721,6 +1722,7 @@ Manager::sendCallTextMessage(const std::string& callID,
     }
     return true;
 }
+
 #endif // HAVE_INSTANT_MESSAGING
 
 //THREAD=VoIP CALL=Outgoing
diff --git a/src/manager.h b/src/manager.h
index 23917ccbd5f48a9543a1e10d9e580ea677937bff..d586f02966f0376715092a7fe5e5a022a8a8158b 100644
--- a/src/manager.h
+++ b/src/manager.h
@@ -388,19 +388,20 @@ class Manager {
 #if HAVE_INSTANT_MESSAGING
         /**
          * Notify the client with an incoming message
-         * @param accountId	The account identifier
-         * @param message The content of the message
+         * @param accountId     The account identifier
+         * @param messages A map if mime type as key and mime payload as value
          */
-        void incomingMessage(const std::string& callID, const std::string& from, const std::string& message);
-
+        void incomingMessage(const std::string& callID,
+                             const std::string& from,
+                             const std::map<std::string, std::string>& messages);
 
         /**
          * Send a new text message to the call, if participate to a conference, send to all participant.
-         * @param callID	The call to send the message
-         * @param message	The content of the message
-        * @param from	        The sender of this message (could be another participant of a conference)
+         * @param callID        The call to send the message
+         * @param message       A list of pair of mime types and payloads
+        * @param from           The sender of this message (could be another participant of a conference)
          */
-        bool sendCallTextMessage(const std::string& callID, const std::string& message, const std::string& from);
+        bool sendCallTextMessage(const std::string& callID, const std::map<std::string, std::string>& messages, const std::string& from);
 #endif // HAVE_INSTANT_MESSAGING
 
         /**
diff --git a/src/sip/sipcall.cpp b/src/sip/sipcall.cpp
index 1950e76446bedd0fab5ae13f22ecbe3f4cfb78f7..9f9ec612c5e39af11f554e8818182ef7e697d100 100644
--- a/src/sip/sipcall.cpp
+++ b/src/sip/sipcall.cpp
@@ -681,8 +681,9 @@ SIPCall::carryingDTMFdigits(char code)
 }
 
 #if HAVE_INSTANT_MESSAGING
-void
-SIPCall::sendTextMessage(const std::string &message, const std::string &from)
+
+void SIPCall::sendTextMessage(const std::map<std::string, std::string>& messages,
+                                     const std::string &from)
 {
     if (not inv)
         throw VoipLinkException("No invite session for this call");
@@ -692,7 +693,7 @@ SIPCall::sendTextMessage(const std::string &message, const std::string &from)
     InstantMessaging::UriEntry entry;
     entry[InstantMessaging::IM_XML_URI] = std::string("\"" + from + "\"");  // add double quotes for xml formating
     list.push_front(entry);
-    auto msg = InstantMessaging::appendUriList(message, list);
+    auto msg = InstantMessaging::appendMimePayloads(messages, list);
     InstantMessaging::send_sip_message(inv.get(), getCallId(), msg);
 }
 #endif // HAVE_INSTANT_MESSAGING
diff --git a/src/sip/sipcall.h b/src/sip/sipcall.h
index 1b2389e42a4ff194f66d4865308be1ca5313c063..f099c2d811b3197a061bf79b2aee42b01c9e5b97 100644
--- a/src/sip/sipcall.h
+++ b/src/sip/sipcall.h
@@ -163,8 +163,8 @@ class SIPCall : public Call
         void carryingDTMFdigits(char code);
 
 #if HAVE_INSTANT_MESSAGING
-        void sendTextMessage(const std::string& message,
-                             const std::string& from);
+        virtual void sendTextMessage(const std::map<std::string, std::string>& messages,
+                                     const std::string &from);
 #endif
 
         SIPAccountBase& getSIPAccount() const;
diff --git a/src/sip/sipvoiplink.cpp b/src/sip/sipvoiplink.cpp
index 57070c5b6a58eef2b2aacf83629812b15b29aa46..5890328e3e54b1ee612ec1f7c7ddeaccab52143b 100644
--- a/src/sip/sipvoiplink.cpp
+++ b/src/sip/sipvoiplink.cpp
@@ -1166,8 +1166,7 @@ transaction_state_changed_cb(pjsip_inv_session * inv, pjsip_transaction *tsx,
         if (from[0] == '<' && from[from.size() - 1] == '>')
             from = from.substr(1, from.size() - 2);
 
-        Manager::instance().incomingMessage(call->getCallId(), from,
-                                            InstantMessaging::findTextMessage(formattedMessage));
+        Manager::instance().incomingMessage(call->getCallId(), from, InstantMessaging::parsePayloads(formattedMessage));
 
         // Respond with a 200/OK
         sendOK(inv->dlg, r_data, tsx);