diff --git a/bigbluebutton-html5/imports/api/1.1/audio/client/bridge/sip.js b/bigbluebutton-html5/imports/api/1.1/audio/client/bridge/sip.js
index ad3e42d9f47abb6fe9a93dddbc86909e61803389..c01d378aff7c1e2907e778b3e00d475382feca7c 100644
--- a/bigbluebutton-html5/imports/api/1.1/audio/client/bridge/sip.js
+++ b/bigbluebutton-html5/imports/api/1.1/audio/client/bridge/sip.js
@@ -13,18 +13,18 @@ export default class SIPBridge extends BaseAudioBridge {
     this.userData = userData;
   }
 
-  joinListenOnly() {
+  joinListenOnly(stunServers, turnServers) {
     makeCall('listenOnlyToggle', true);
-    this._joinVoiceCallSIP({ isListenOnly: true });
+    this._joinVoiceCallSIP({ isListenOnly: true, stunServers, turnServers });
   }
 
-  joinMicrophone() {
-    this._joinVoiceCallSIP({ isListenOnly: false });
+  joinMicrophone(stunServers, turnServers) {
+    this._joinVoiceCallSIP({ isListenOnly: false, stunServers, turnServers });
   }
 
   // Periodically check the status of the WebRTC call, when a call has been established attempt to
   // hangup, retry if a call is in progress, send the leave voice conference message to BBB
-  exitAudio(isListenOnly, afterExitCall = () => {}) {
+  exitAudio(isListenOnly, afterExitCall = () => { }) {
     // To be called when the hangup is confirmed
     const hangupCallback = function () {
       console.log(`Exited Voice Conference, listenOnly=${isListenOnly}`);
@@ -40,7 +40,7 @@ export default class SIPBridge extends BaseAudioBridge {
     triedHangup = false;
 
     // function to initiate call
-    const checkToHangupCall = ((context, afterExitCall = () => {}) => {
+    const checkToHangupCall = ((context, afterExitCall = () => { }) => {
       // if an attempt to hang up the call is made when the current session is not yet finished,
       // the request has no effect keep track in the session if we haven't tried a hangup
       if (window.getCallStatus() != null && !triedHangup) {
@@ -96,8 +96,8 @@ export default class SIPBridge extends BaseAudioBridge {
     };
 
     const stunsAndTurns = {
-      stun: this.userData.stuns,
-      turn: this.userData.turns,
+      stun: options.stunServers,
+      turn: options.turnServers,
     };
 
     callIntoConference(extension, (audio) => {
diff --git a/bigbluebutton-html5/imports/api/1.1/audio/client/manager/index.js b/bigbluebutton-html5/imports/api/1.1/audio/client/manager/index.js
index 8092a0931503676d1d658f988c937200984c602e..62033062abb93c795f872fbcb691a5d3521edd12 100644
--- a/bigbluebutton-html5/imports/api/1.1/audio/client/manager/index.js
+++ b/bigbluebutton-html5/imports/api/1.1/audio/client/manager/index.js
@@ -1,3 +1,4 @@
+import Auth from '/imports/ui/services/auth';
 import BaseAudioBridge from '../bridge/base';
 import VertoBridge from '../bridge/verto';
 import SIPBridge from '../bridge/sip';
@@ -24,12 +25,42 @@ export default class AudioManager {
   }
 
   joinAudio(listenOnly) {
-    if (listenOnly || this.microphoneLockEnforced) {
-      this.isListenOnly = true;
-      this.bridge.joinListenOnly();
-    } else {
-      this.bridge.joinMicrophone();
-    }
+    AudioManager.fetchServers().then(({ error, stunServers, turnServers }) => {
+      if (error) {
+        //We need to alert the user about this problem by some gui message.
+        console.error("Couldn't fetch the stuns/turns servers!");
+        return;
+      }
+
+      if (listenOnly || this.microphoneLockEnforced) {
+        this.isListenOnly = true;
+        this.bridge.joinListenOnly(stunServers, turnServers);
+      } else {
+        this.bridge.joinMicrophone(stunServers, turnServers);
+      }
+    });
+  }
+
+  // We use on the SIP an String Array, while in the server, it comes as
+  // an Array of objects, we need to map from Array<Object> to Array<String>
+  static mapToArray({ response, stunServers, turnServers }) {
+    const promise = new Promise((resolve) => {
+      if (response) {
+        resolve({ error: 404, stunServers: [], turnServers: [] });
+      }
+      resolve({
+        stunServers: stunServers.map(server => server.url),
+        turnServers: turnServers.map(server => server.url),
+      });
+    });
+    return promise;
   }
 
+  static fetchServers() {
+    const url = `/bigbluebutton/api/stuns?sessionToken=${Auth.sessionToken}`;
+
+    return fetch(url)
+      .then(response => response.json())
+      .then(json => AudioManager.mapToArray(json));
+  }
 }
diff --git a/bigbluebutton-html5/imports/api/2.0/users/server/methods.js b/bigbluebutton-html5/imports/api/2.0/users/server/methods.js
index 53eab01a42d79a810bc566edd303ba6e0e557e60..3eb0c72e7b52a16f0f6187877908c0da947536f9 100644
--- a/bigbluebutton-html5/imports/api/2.0/users/server/methods.js
+++ b/bigbluebutton-html5/imports/api/2.0/users/server/methods.js
@@ -3,11 +3,13 @@ import mapToAcl from '/imports/startup/mapToAcl';
 import userLogout from './methods/userLogout';
 import validateAuthToken from './methods/validateAuthToken';
 import setEmojiStatus from './methods/setEmojiStatus';
+import listenOnlyToggle from './methods/listenOnlyToggle';
 
-Meteor.methods(mapToAcl(['methods.userLogout', 'methods.setEmojiStatus',
+Meteor.methods(mapToAcl(['methods.userLogout', 'methods.setEmojiStatus', 'methods.listenOnlyToggle',
 ], {
   userLogout,
   setEmojiStatus,
+  listenOnlyToggle,
 }));
 
 Meteor.methods({ validateAuthToken2x: validateAuthToken });
diff --git a/bigbluebutton-html5/imports/api/2.0/users/server/methods/listenOnlyToggle.js b/bigbluebutton-html5/imports/api/2.0/users/server/methods/listenOnlyToggle.js
index 6880569b72b5c4ad87abeac0e74099a3d3f8f35a..45e28835052db9765a571e8346cbc1b7877a9327 100755
--- a/bigbluebutton-html5/imports/api/2.0/users/server/methods/listenOnlyToggle.js
+++ b/bigbluebutton-html5/imports/api/2.0/users/server/methods/listenOnlyToggle.js
@@ -7,7 +7,7 @@ import Users from '/imports/api/2.0/users';
 
 export default function listenOnlyToggle(credentials, isJoining = true) {
   const REDIS_CONFIG = Meteor.settings.redis;
-  const CHANNEL = REDIS_CONFIG.channels.toBBBApps.meeting;
+  const CHANNEL = REDIS_CONFIG.channels.toAkkaApps;
 
   const { meetingId, requesterUserId } = credentials;
 
@@ -18,40 +18,36 @@ export default function listenOnlyToggle(credentials, isJoining = true) {
   let EVENT_NAME;
 
   if (isJoining) {
-    EVENT_NAME = 'user_connected_to_global_audio';
+    EVENT_NAME = 'UserConnectedToGlobalAudioMsg';
   } else {
-    EVENT_NAME = 'user_disconnected_from_global_audio';
+    EVENT_NAME = 'UserDisconnectedFromGlobalAudioMsg';
   }
 
-  const Meeting = Meetings.findOne({ meetingId });
-  if (!Meeting) {
-    throw new Meteor.Error(
-      'meeting-not-found', 'You need a valid meeting to be able to toggle audio');
-  }
-
-  check(Meeting.voiceConf, String);
-
   const User = Users.findOne({
-    meetingId,
     userId: requesterUserId,
   });
 
+  const Meeting = Meetings.findOne({ meetingId });
+
   if (!User) {
     throw new Meteor.Error(
       'user-not-found', 'You need a valid user to be able to toggle audio');
   }
 
-  check(User.user.name, String);
+  // check(User.user.name, String);
+
+  const header = {
+    name: EVENT_NAME,
+    voiceConf: Meeting.voiceProp.voiceConf,
+  };
 
   const payload = {
-    userid: requesterUserId,
-    meeting_id: meetingId,
-    voice_conf: Meeting.voiceConf,
+    userId: requesterUserId,
     name: User.user.name,
   };
 
   Logger.verbose(`User '${requesterUserId}' ${isJoining
     ? 'joined' : 'left'} global audio from meeting '${meetingId}'`);
 
-  return RedisPubSub.publish(CHANNEL, EVENT_NAME, payload);
+  return RedisPubSub.publish(CHANNEL, EVENT_NAME, meetingId, payload, header);
 }
diff --git a/bigbluebutton-html5/imports/startup/client/auth.js b/bigbluebutton-html5/imports/startup/client/auth.js
index 68d10187d55cb6eaa0dffdddbb0689509a66e430..5d6617aa9677e7b9ccf1493d7fa5729d1ceedc43 100755
--- a/bigbluebutton-html5/imports/startup/client/auth.js
+++ b/bigbluebutton-html5/imports/startup/client/auth.js
@@ -21,7 +21,7 @@ export function joinRouteHandler(nextState, replace, callback) {
     .then((data) => {
       const { meetingID, internalUserID, authToken, logoutUrl } = data.response;
 
-      Auth.set(meetingID, internalUserID, authToken, logoutUrl);
+      Auth.set(meetingID, internalUserID, authToken, logoutUrl, sessionToken);
       replace({ pathname: '/' });
       callback();
     });
diff --git a/bigbluebutton-html5/imports/startup/client/base.jsx b/bigbluebutton-html5/imports/startup/client/base.jsx
index 096d407c46a158ecbd232cc497813e7f9f00df96..d4f6dec0b17e756c731fc19f36d04b901ba6771a 100644
--- a/bigbluebutton-html5/imports/startup/client/base.jsx
+++ b/bigbluebutton-html5/imports/startup/client/base.jsx
@@ -85,7 +85,7 @@ Base.defaultProps = defaultProps;
 
 const SUBSCRIPTIONS_NAME = [
   'users2x', 'users', 'chat', 'chat2x', 'cursor', 'cursor2x', 'deskshare', 'meetings', 'meetings2x',
-  'polls', 'polls2x',  'presentations', 'presentations2x', 'shapes', 'shapes2x', 'slides', 'slides2x', 'captions', 'captions2x', 'breakouts', 'breakouts2x',
+  'polls', 'polls2x', 'presentations', 'presentations2x', 'shapes', 'shapes2x', 'slides', 'slides2x', 'captions', 'captions2x', 'breakouts', 'breakouts2x',
 ];
 
 const BaseContainer = createContainer(({ params }) => {
diff --git a/bigbluebutton-html5/imports/ui/components/audio/service.js b/bigbluebutton-html5/imports/ui/components/audio/service.js
index dc86d205b6135d9439487334072482f1384235f6..98e24b1755a1a109f1b25bd5b802cdcb31bf161a 100755
--- a/bigbluebutton-html5/imports/ui/components/audio/service.js
+++ b/bigbluebutton-html5/imports/ui/components/audio/service.js
@@ -2,25 +2,23 @@ import Users from '/imports/api/2.0/users';
 import Auth from '/imports/ui/services/auth';
 
 import AudioManager from '/imports/api/1.1/audio/client/manager';
+import Meetings from '/imports/api/2.0/meetings';
 
 let audioManager;
+
 const init = () => {
   const userId = Auth.userID;
   const User = Users.findOne({ userId });
   const username = User.user.name;
-
-  const turns = [];
-  const stuns = [];
-  // FIX ME
-  const voiceBridge = 'Meeting.voiceConf';
+  const Meeting = Meetings.findOne({ meetingId: User.meetingId });
+  const voiceBridge = Meeting.voiceProp.voiceConf;
+  
   // FIX ME
-  const microphoneLockEnforced = 'Meeting.roomLockSettings.disableMic';
+  const microphoneLockEnforced = false;
 
   const userData = {
     userId,
     username,
-    turns,
-    stuns,
     voiceBridge,
     microphoneLockEnforced,
   };
diff --git a/bigbluebutton-html5/imports/ui/services/auth/index.js b/bigbluebutton-html5/imports/ui/services/auth/index.js
index 2b63515fde11e05f706586cf0c31ae6a5cf9eaea..4b2c73f2f9c1d73815b792feaea7b66684da40f9 100644
--- a/bigbluebutton-html5/imports/ui/services/auth/index.js
+++ b/bigbluebutton-html5/imports/ui/services/auth/index.js
@@ -13,6 +13,7 @@ class Auth {
     this._meetingID = Storage.getItem('meetingID');
     this._userID = Storage.getItem('userID');
     this._authToken = Storage.getItem('authToken');
+    this._sessionToken = Storage.getItem('sessionToken');
     this._logoutURL = Storage.getItem('logoutURL');
     this._loggedIn = {
       value: false,
@@ -29,6 +30,15 @@ class Auth {
     Storage.setItem('meetingID', this._meetingID);
   }
 
+  set sessionToken(sessionToken) {
+    this._sessionToken = sessionToken;
+    Storage.setItem('sessionToken', this._sessionToken);
+  }
+
+  get sessionToken() {
+    return this._sessionToken;
+  }
+
   get userID() {
     return this._userID;
   }
@@ -72,14 +82,16 @@ class Auth {
       requesterUserId: this.userID,
       requesterToken: this.token,
       logoutURL: this.logoutURL,
+      sessionToken: this.sessionToken,
     };
   }
 
-  set(meetingId, requesterUserId, requesterToken, logoutURL) {
+  set(meetingId, requesterUserId, requesterToken, logoutURL, sessionToken) {
     this.meetingID = meetingId;
     this.userID = requesterUserId;
     this.token = requesterToken;
     this.logoutURL = logoutURL;
+    this.sessionToken = sessionToken;
   }
 
   clearCredentials(...args) {
@@ -88,6 +100,7 @@ class Auth {
     this.token = null;
     this.loggedIn = false;
     this.logoutURL = null;
+    this.sessionToken = null;
 
     return Promise.resolve(...args);
   }