/* * @Author: jack.lu * @Date: 2020-4-21 10:10:20 * @Last Modified by: jack.lu * @Last Modified time: 2020-4-21 15:01:41 */ import GoEasyIM from './goeasy-im-1.0.9'; // import GoEasyIM from './goeasy-im-1.1.1'; import restApi from './restapi'; function Friend(uuid, name, avatar,time = "", text = "",date = "",unReadMessage = 0) { this.uuid = uuid; this.name = name; this.avatar = avatar; this.online = false; this.unReadMessage = parseInt(unReadMessage); this.text = text; this.time = time; this.date = date } function Group(uuid, name, avatar) { this.uuid = uuid; this.name = name; this.avatar = avatar; this.unReadMessage = 0; } function CurrentUser(uuid, name, avatar) { this.uuid = uuid; this.name = name; this.avatar = avatar; } function IMService() { this.im = GoEasyIM.getInstance({ host:'hangzhou.goeasy.io',//qos=1 appkey:'BC-453aa755c4ea48148abefc55a86df283' }); this.status = false this.lianjie = false //当前“我” this.currentUser = null; //我的好友 this.friends = {}; this.friendsarr = []; //我的群 this.groups = {}; //私聊消息记录,map格式,每个好友对应一个数组 this.privateMessages = {}; //群聊消息记录,map格式,每个群对应一个数组 this.groupMessages = {}; /* * 监听器们 * * 可以在页面里,根据需求,重写以下监听器, * 便于当各种事件触发时,页面能够执行对应的响应 * */ //收到一条私聊消息 this.onNewPrivateMessageReceive = function (friendId, message) {}; //完成一次私聊历史加载 this.onPrivateHistoryLoad = function (friendId, messages) {}; //收到一条群聊消息 this.onNewGroupMessageReceive = function (groupId, message) {}; //完成一次群聊历史加载 this.onGroupHistoryLoad = function (groupId, messages) {}; //好友列表发生改变 this.onFriendListChange = function (friends) {}; //群列表发生改变 this.onGroupListChange = function (groups) {}; this.whenNewMessage = function () { }; this.whenOnlineUserChange = function () { }; } //登录 IMService.prototype.login = function (uuid, name, avatar) { //初始化当前用户 this.currentUser = new CurrentUser(uuid, name, avatar); //初始化联系人信息,包括群 this.initialContacts(); return true; }; //初始化联系人信息 IMService.prototype.initialContacts = function (friendList) { //查询并初始化好友信息 // let friendList = restApi.findFriends(this.currentUser); let value = uni.getStorageSync('imlist'); if(value != undefined && !value){ return ; } value = JSON.parse(value) let that = this console.log(value) for(let i of value){ const token = uni.getStorageSync('token'); console.log(token) uni.request({ url:"http://mall.dmygkeji.com/api/Specialci/getAtwillUserInfo", data:{ userId:i[0], markup:1 }, method:"POST", header:{ "Authorization" : 'Bearer' + " " + token }, success(res){ console.log(res) that.friends[i[0]] = new Friend(res.data.data.member_id, res.data.data.store_name, res.data.data.member_avatar,i[1],i[2],i[3]); console.log(that.friends) let sorts = function (friends){ let paixu = function (a,b){ if(a.date > b.date && b.unReadMessage == 0){ return 0; }else{ return 1; } } friends.sort(paixu) } that.friendsarr = [] for(let i in that.friends){ console.log(i) that.friendsarr.push(that.friends[i]) } sorts(that.friendsarr) that.onFriendListChange(that.friends); } }) } //将用户列表初始化为一个map,便于后续根据friendId得到friend // friendList.map(friend => { // this.friends[friend.uuid] = new Friend(friend.uuid, friend.name, friend.avatar); // }); //查询并初始化与自己相关的群信息 // let groupList = restApi.findGroups(this.currentUser); // //将群列表初始化为一个map,方便后续根据groupId索引 // groupList.map(group => { // this.groups[group.uuid] = new Group(group.uuid, group.name, group.avatar); // }); }; //获取群成员 IMService.prototype.getGroupMembers = function (groupId) { let members = restApi.findGroupMembers(groupId); let membersMap = {}; members.map(item => { membersMap[item.uuid] = item }); return membersMap; }; IMService.prototype.getGroupMessages = function (groupId) { if (!this.groupMessages[groupId]) { this.groupMessages[groupId] = { sentMessages:[], pendingMessages:[] }; } return this.groupMessages[groupId] }; IMService.prototype.getPrivateMessages = function (friendId) { if (!this.privateMessages[friendId]) { this.privateMessages[friendId] = { sentMessages:[], pendingMessages:[] }; } return this.privateMessages[friendId] }; //重置群聊未读消息 IMService.prototype.resetGroupUnReadMessage = function (group) { this.groups[group.uuid].unReadMessage = 0; this.onGroupListChange(this.groups); }; //将好友的未读消息数字清零 IMService.prototype.resetFriendUnReadMessage = function (friend) { if(friend && friend.uuid){ this.friends[friend.uuid].unReadMessage = 0; } this.onFriendListChange(this.friends); }; //连接GoEasy IMService.prototype.connectIM = function () { //初始化IM相关的监听器 try { this.initialIMListeners(); } catch (error) { console.log(123) } try { console.log(this.currentUser) this.im.connect({ id: this.currentUser.uuid, data: { avatar: this.currentUser.avatar, name: this.currentUser.name } }).then(() => { console.log('连接成功') //订阅与自己相关的群信息 this.subscribeGroupMessage(); //初始化好友们的在线状态 this.initialFriendOnlineStatus(); //订阅我的好友们的上下线信息 this.subscribeFriendsPresence(); }).catch(error => { console.log('连接失败,请确保网络正常,appkey和host正确,code:' + error.code + " content:" + error.content); }); } catch (error) { console.log(12323) } }; //IM监听 IMService.prototype.initialIMListeners = function () { this.im.on(GoEasyIM.EVENT.CONNECTED, () => { console.log('连接成功.') this.status = true }); this.im.on(GoEasyIM.EVENT.DISCONNECTED, () => { console.log('连接断开.') this.status = false this.lianjie = false }); //监听好友上下线 this.im.on(GoEasyIM.EVENT.USER_PRESENCE, (user) => { console.log(user) //更新好友在线状态 let onlineStatus = user.action == 'online' ? true : false; let friend = this.friends[user.userId]; friend.online = onlineStatus; //如果页面传入了相应的listener,执行listener this.onFriendListChange(this.friends); }); //监听私聊消息 this.im.on(GoEasyIM.EVENT.PRIVATE_MESSAGE_RECEIVED, (message) => { console.log(message) //如果不是自己发的,朋友未读消息数 +1 if (message.senderId != this.currentUser.uuid) { let friend = this.friends[message.senderId]; console.log(friend) // return ; let sorts = function (friends){ let paixu = function (a,b){ if(a.date > b.date && b.unReadMessage == 0){ return 0; }else{ return 1; } } friends.sort(paixu) } let that = this if(!friend && friend == undefined){ const token = uni.getStorageSync('token'); console.log(token) uni.request({ url:"http://mall.dmygkeji.com/api/Specialci/getAtwillUserInfo", data:{ userId:message.senderId, markup:1 }, method:"POST", header:{ "Authorization" : 'Bearer' + " " + token }, success(res){ console.log(res) that.friends[message.senderId] = new Friend(res.data.data.member_id, res.data.data.store_name, res.data.data.member_avatar); friend = that.friends[message.senderId]; console.log(friend) friend.unReadMessage++; friend.text = message.type != "text" ? "其他消息" : message.payload.text let time = new Date(message.timestamp) friend.date = message.timestamp friend.time = (time.getHours() < 10 ? '0' + time.getHours() : time.getHours()) + ":" + (time.getMinutes() < 10 ? '0' + time.getMinutes() : time.getMinutes()) + ":" + (time.getSeconds() < 10 ? '0' + time.getSeconds() : time.getSeconds()) console.log(that.friends) that.friendsarr = [] for(let i in that.friends){ console.log(i) that.friendsarr.push(that.friends[i]) } sorts(that.friendsarr) let arr = [] for(let i in that.friends){ arr.push([that.friends[i].uuid,that.friends[i].time,that.friends[i].text,that.friends[i].date,that.friends[i].unReadMessage]) } console.log(arr) uni.setStorageSync('imlist',JSON.stringify(arr)) that.onFriendListChange(that.friends); } }) }else{ console.log(friend) friend.unReadMessage++; friend.text = message.type != "text" ? "其他消息" : message.payload.text let time = new Date(message.timestamp) friend.date = message.timestamp friend.time = (time.getHours() < 10 ? '0' + time.getHours() : time.getHours()) + ":" + (time.getMinutes() < 10 ? '0' + time.getMinutes() : time.getMinutes()) + ":" + (time.getSeconds() < 10 ? '0' + time.getSeconds() : time.getSeconds()) console.log(this.friends) that.friendsarr = [] for(let i in this.friends){ that.friendsarr.push(this.friends[i]) } sorts(that.friendsarr) let arr = [] for(let i in that.friends){ arr.push([that.friends[i].uuid,that.friends[i].time,that.friends[i].text,that.friends[i].date,that.friends[i].unReadMessage]) } console.log(arr) uni.setStorageSync('imlist',JSON.stringify(arr)) this.onFriendListChange(this.friends); } // let value = uni.getStorageSync('imlist'); // value = JSON.parse(value) // if(value.indexOf(message.senderId) == -1){ // value.unshift(message.senderId) // } // uni.setStorageSync('imlist',JSON.stringify(value)) } //更新私聊消息记录 let friendId; if (this.currentUser.uuid == message.senderId) { friendId = message.receiverId; } else { friendId = message.senderId; } removePrivatePendingMessage(this, friendId, message); let friendMessages = this.getPrivateMessages(friendId); friendMessages.sentMessages.push(message); //如果页面传入了相应的listener,执行listener this.onNewPrivateMessageReceive(friendId, message); }); // //监听群聊消息 // this.im.on(GoEasyIM.EVENT.GROUP_MESSAGE_RECEIVED, (message) => { // let groupId = message.groupId; // //群未读消息+1 // let group = this.groups[groupId]; // group.unReadMessage++; // removeGroupPendingMessage(this, groupId, message); // //如果页面传入了相应的listener,执行listener // this.onGroupListChange(this.groups); // //更新群聊消息记录 // let groupMessages = this.getGroupMessages(groupId); // let sentMessages = groupMessages.sentMessages; // sentMessages.push(message); // //如果页面传入了相应的listener,执行listener // this.onNewGroupMessageReceive(groupId, message); // }) }; //订阅群消息 IMService.prototype.subscribeGroupMessage = function () { let groupIds = Object.keys(this.groups); this.im.subscribeGroup(groupIds) .then(() => { console.log('订阅群消息成功') }) .catch(error => { console.log('订阅群消息失败') console.log(error) }) }; //初始化好友在线状态 IMService.prototype.initialFriendOnlineStatus = function () { let friendIds = Object.keys(this.friends); this.im.hereNow({ userIds: friendIds }).then(result => { let onlineFriends = result.content; onlineFriends.map(user => { let friend = this.friends[user.userId]; friend.online = true; }); this.onFriendListChange(this.friends); }).catch(error => { console.log(error) if (error.code == 401) { console.log("获取在线用户失败,您尚未开通用户在线状态,请登录GoEasy,查看应用详情里自助启用."); } }) }; //监听所有好友上下线 IMService.prototype.subscribeFriendsPresence = function () { let friendIds = Object.keys(this.friends); this.im.subscribeUserPresence(friendIds) .then(() => { console.log('监听好友上下线成功') }) .catch(error => { console.log(error); if (error.code == 401) { console.log("监听好友上下线失败,您尚未开通用户状态提醒,请登录GoEasy,查看应用详情里自助启用."); } }); }; //加载单聊历史消息 IMService.prototype.loadPrivateHistoryMessage = function (friendId, timeStamp) { this.im.history({ friendId: friendId, lastTimestamp: timeStamp }).then(result => { let history = result.content; let privateMessages = this.getPrivateMessages(friendId); let friendMessages = privateMessages.sentMessages; for (let i = history.length - 1; i >=0; i--) { friendMessages.unshift(history[i]) } //如果页面传入了相应的listener,执行listener this.onPrivateHistoryLoad(friendId, history); }).catch(error => { console.log(error); if (error.code == 401) { console.log("您尚未开通历史消息,请登录GoEasy,查看应用详情里自助启用."); } }) }; //发送私聊消息 IMService.prototype.sendPrivateTextMessage = function (friendId, text) { let textMessage = this.im.createTextMessage({ text: text }); this.sendPrivateMessage(friendId, textMessage); this.sendMessagesSetStorage(friendId, text) }; //私聊图片消息 IMService.prototype.sendPrivateImageMessage = function (friendId, imageFile) { let imageMessage = this.im.createImageMessage({ file: imageFile, onProgress :function (progress) { console.log(progress) } }); this.sendPrivateMessage(friendId, imageMessage); this.sendMessagesSetStorage(friendId, '其他消息') }; //私聊视频消息 IMService.prototype.sendPrivateVideoMessage = function (friendId, videoFile) { let videoMessage = this.im.createVideoMessage({ file: videoFile, onProgress :function (progress) { console.log(progress) } }); this.sendPrivateMessage(friendId, videoMessage); this.sendMessagesSetStorage(friendId, '其他消息') }; IMService.prototype.sendPrivateAudioMessage = function (friendId, audiofile) { let audioMessage = this.im.createAudioMessage({ file: audiofile, onProgress :function (progress) { console.log(progress) } }); this.sendPrivateMessage(friendId, audioMessage); this.sendMessagesSetStorage(friendId, '其他消息') }; IMService.prototype.sendMessagesSetStorage = function (friendId,message){ let friend = this.friends[friendId]; console.log(friend) // return ; let sorts = function (friends){ let paixu = function (a,b){ if(a.date > b.date && b.unReadMessage == 0){ return 0; }else{ return 1; } } friends.sort(paixu) } let that = this if(!friend && friend == undefined){ const token = uni.getStorageSync('token'); console.log(token) uni.request({ url:"http://mall.dmygkeji.com/api/Specialci/getAtwillUserInfo", data:{ userId:friendId, markup:1 }, method:"POST", header:{ "Authorization" : 'Bearer' + " " + token }, success(res){ console.log(res) that.friends[friendId] = new Friend(res.data.data.member_id, res.data.data.store_name, res.data.data.member_avatar); friend = that.friends[friendId]; console.log(friend) friend.text = message let time = new Date() friend.date = time.getTime() friend.time = (time.getHours() < 10 ? '0' + time.getHours() : time.getHours()) + ":" + (time.getMinutes() < 10 ? '0' + time.getMinutes() : time.getMinutes()) + ":" + (time.getSeconds() < 10 ? '0' + time.getSeconds() : time.getSeconds()) console.log(that.friends) that.friendsarr = [] for(let i in that.friends){ console.log(i) that.friendsarr.push(that.friends[i]) } sorts(that.friendsarr) let arr = [] for(let i in that.friends){ arr.push([that.friends[i].uuid,that.friends[i].time,that.friends[i].text,that.friends[i].date,0]) } console.log(arr) uni.setStorageSync('imlist',JSON.stringify(arr)) that.onFriendListChange(that.friends); } }) }else{ console.log(friend) friend.text = message let time = new Date() friend.date = time.getTime() friend.time = (time.getHours() < 10 ? '0' + time.getHours() : time.getHours()) + ":" + (time.getMinutes() < 10 ? '0' + time.getMinutes() : time.getMinutes()) + ":" + (time.getSeconds() < 10 ? '0' + time.getSeconds() : time.getSeconds()) console.log(this.friends) that.friendsarr = [] for(let i in this.friends){ that.friendsarr.push(this.friends[i]) } sorts(that.friendsarr) let arr = [] for(let i in that.friends){ arr.push([that.friends[i].uuid,that.friends[i].time,that.friends[i].text,that.friends[i].date,0]) } console.log(arr) uni.setStorageSync('imlist',JSON.stringify(arr)) this.onFriendListChange(this.friends); } } //发送私聊消息 IMService.prototype.sendPrivateMessage = function (friendId, message) { //加入pendingMessage列表,成功后将会被挪除 let privateMessages = this.getPrivateMessages(friendId); privateMessages.pendingMessages.push(message); //发送 this.im.sendPrivateMessage(friendId, message) .then((res) => { console.log(res) }) .catch(e => { console.log(e) }) }; //发送群聊消息 IMService.prototype.sendGroupTextMessage = function (groupId, message) { let textMessage = this.im.createTextMessage({ text:message }); this.sendGroupMessage(groupId, textMessage); }; //私聊图片消息 IMService.prototype.sendGroupImageMessage = function (groupId, imageFile) { let imageMessage = this.im.createImageMessage({ file: imageFile, onProgress :function (progress) { console.log(progress) } }); this.sendGroupMessage(groupId, imageMessage); }; //私聊视频消息 IMService.prototype.sendGroupVideoMessage = function (groupId, videoFile) { let videoMessage = this.im.createVideoMessage({ file: videoFile, onProgress :function (progress) { console.log(progress) } }); this.sendGroupMessage(groupId, videoMessage); }; IMService.prototype.sendGroupAudioMessage = function (groupId, audioFile) { let audioMessage = this.im.createAudioMessage({ file: audioFile, onProgress :function (progress) { console.log(progress) } }); this.sendGroupMessage(groupId, audioMessage); }; IMService.prototype.sendGroupMessage =function(groupId, groupMessage) { //先放入Pending列表,待成功后挪除 let groupMessages = this.getGroupMessages(groupId); let pendingMessages = groupMessages.pendingMessages; pendingMessages.push(groupMessage) this.im.sendGroupMessage(groupId, groupMessage) .then((res) => { console.log(res) }) .catch(e => { console.log(e) }) } //群聊历史消息 IMService.prototype.loadGroupHistoryMessage = function (groupId, timeStamp) { this.im.history({ groupId: groupId, lastTimestamp: timeStamp }).then(result => { let history = result.content; let groupMessages = this.getGroupMessages(groupId); let sentGroupMessages = groupMessages.sentMessages; for (let i = history.length - 1; i >= 0; i--) { sentGroupMessages.unshift(history[i]); } this.onGroupHistoryLoad(groupId, history); }).catch(error => { console.log(error) if (error.code == 401) { console.log("您尚未开通历史消息,请登录GoEasy,查看应用详情里自助启用."); } }) }; IMService.prototype.disconnect = function () { this.im.disconnect() }; function removePrivatePendingMessage(imService,friendId, message){ let privateMessages = imService.getPrivateMessages(friendId); let pendingMessages = privateMessages.pendingMessages; let pendingMessageIndex = pendingMessages.findIndex(item => item.messageId == message.messageId); if(pendingMessageIndex > -1) { pendingMessages.splice(pendingMessageIndex,1); } } function removeGroupPendingMessage(imService,groupId, message){ let groupMessages = imService.getGroupMessages(groupId); let pendingMessages = groupMessages.pendingMessages; let pendingMessageIndex = pendingMessages.findIndex(item => item.messageId == message.messageId); if(pendingMessageIndex > -1) { pendingMessages.splice(pendingMessageIndex,1); } } //下面是合并的 //用户 function User(id, nickname, avatar) { this.id = id; this.nickname = nickname; this.avatar = avatar; } //消息 function Message(senderUserId, senderNickname, content, type) { this.senderNickname = senderNickname; this.senderUserId = senderUserId; this.content = content; this.type = type } //聊天室 function Room(id, name, currentUser) { this.id = id; this.name = name; this.currentUser = currentUser; this.onlineUsers = { count: 0, users: [] }; this.messages = []; this.MessageType = { CHAT: 0,//文字聊天 PROP: 1//道具 }; this.Prop = { HEART: 0,//桃心 ROCKET: 1//火箭 }; } IMService.prototype.initialWhenNewMessage = function (whenNewMessage) { this.whenNewMessage = whenNewMessage; }; IMService.prototype.initialWhenOnlineUserChange = function (whenOnlineUserChange) { this.whenOnlineUserChange = whenOnlineUserChange; }; //监听新消息 IMService.prototype.listenerNewMessage = function () { this.im.on(GoEasyIM.EVENT.GROUP_MESSAGE_RECEIVED, (message) => { var content = JSON.parse(message.payload.text); this.addNewMessage(message); this.whenNewMessage(content); }) } IMService.prototype.addNewMessage = function (message) { var content = JSON.parse(message.payload.text); let messageContent = ""; //聊天消息 if (content.type == this.room.MessageType.CHAT) { messageContent = content.content; } //道具消息 if (content.type == this.room.MessageType.PROP) { if (content.content == this.room.Prop.ROCKET) { messageContent = "送出了一枚大火箭"; } if (content.content == this.room.Prop.HEART) { messageContent = "送出了一个大大的比心"; } } //添加消息 let newMessage = new Message(message.senderId, content.senderNickname, messageContent); this.room.messages.push(newMessage); }; //监听用户上下线 IMService.prototype.listenerGroupPresence = function () { this.im.on(GoEasyIM.EVENT.GROUP_PRESENCE, (event) => { //更新在线用户数 this.room.onlineUsers.count = event.groupOnlineCount; if (event.action == 'join' || event.action == 'online') { let userData = JSON.parse(event.userData); //添加新用户 let user = new User(event.userId, userData.nickname, userData.avatar); //添加在线用户,避免用户重复 if (!this.room.onlineUsers.users.find(item => item.id == event.userId)) { this.room.onlineUsers.users.push(user); } //添加进入房间的消息 let message = new Message(event.userId, userData.nickname, " 进入房间", this.room.MessageType.CHAT); this.room.messages.push(message); } else { let offlineUserIndex = this.room.onlineUsers.users.findIndex(item => item.id == event.userId); if (offlineUserIndex > -1) { //将离开的用户从onlineUsers中删掉 let offlineUser = Object.assign(this.room.onlineUsers.users[offlineUserIndex]); this.room.onlineUsers.users.splice(offlineUserIndex, 1); //添加离开消息 let message = new Message(offlineUser.id, offlineUser.nickname, " 离开房间", this.room.MessageType.CHAT) this.room.messages.push(message); } } this.whenOnlineUserChange(this.room.onlineUsers); }) }; //查询和初始化在线用户列表和在线用户数 IMService.prototype.initialOnlineUsers = function (roomId) { let self = this; console.log(roomId) //查询最新上线的用户列表 this.im.groupHereNow(roomId) .then(result => { if (result.code == 200) { let users = []; result.content && result.content.map(function (onlineUser) { let userData = JSON.parse(onlineUser.userData); let user = new User(onlineUser.userId, userData.nickname, userData.avatar); users.push(user); }); self.room.onlineUsers = { users: users }; } }).catch(e => { if (e.code == 401) { console.log("您还没有开通用户在线状态提醒,登录goeasy->我的应用->查看详情->高级功能,自助开通."); } else { console.log(e,1212); } }); //获取聊天室在线用户数 this.im.groupOnlineCount(roomId) .then(result => { this.room.onlineUsers.count = result.content.onlineCount; }).catch(e => { console.log(e) }) }; //订阅聊天室成员上下线 IMService.prototype.subscribePresence = function (roomId) { this.im.subscribeGroupPresence([roomId]) .then(() => { console.log('成员上下线订阅成功') }).catch(e => { console.log(e) }) } //订阅聊天室消息 IMService.prototype.subscribeRoomMessage = function (room) { let user = { id:this.currentUser.uuid, nickname:this.currentUser.name, avatar:this.currentUser.avatar } this.room = new Room(room.id, room.name, user); //监听上下线提醒 this.listenerGroupPresence(); //监听新消息 this.listenerNewMessage(); //订阅用户上下线事件 this.subscribePresence(this.room.id); //订阅聊天室消息 // this.subscribeRoomMessage(this.room.id); this.initialOnlineUsers(this.room.id) this.im.subscribeGroup([this.room.id]) .then(result => { console.log('消息订阅成功') }).catch(e => { console.log(e,'失败') }) } //历史消息 IMService.prototype.initialChatHistory = function (roomId) { var self = this; this.im.history({ groupId: roomId }).then(res => { res.content.forEach(function (message) { self.addNewMessage(message); }) }).catch(function (error) { if (error.code == 401) { console.log("您还没有开通历史消息的权限,登录goeasy->我的应用->查看详情->高级功能,自助开通."); } else { console.log(error); } }) }; //发送消息 IMService.prototype.sendMessages = function (roomId, content) { var contentMessage = { text: JSON.stringify(content) }; let message = this.im.createTextMessage(contentMessage); this.im.sendGroupMessage(roomId, message) .then(() => { console.log('消息发送成功') }).catch(e => { console.log(e); }) }; //退出聊天室 IMService.prototype.quitRoom = function (roomId) { // this.im.subscribeGroup([0]) // .then(result => { // console.log('消息订阅成功') // }).catch(e => { // console.log(e,'失败') // }) // this.subscribePresence(0); this.disconnect() this.connectIM() }; export default IMService;