微信小程序接入腾讯云IM即时通讯(发送消息开发步骤)

微信小程序接入腾讯云IM即时通讯(聊天窗口)

1.效果图
这里写图片描述

  • 2.功能点
    1.布局要分左右两边布局,如果是自己为发送消息方,都在右边,对方发送的消息在左边。
    2.腾讯云返回的是时间戳,需要转换一下时间,腾讯云是没有返回头像的,需要单独获取并且设置自己跟对方的头像。
    3.发送的消息分为自定义消息普通文本消息,带房源图片 跟价格和小区名称的是自定义的消息,从房源详情进入聊天就自动发送,普通文本消息则在底部栏发送。
    4.获取聊天的历史记录,下拉上翻历史记录,这里没有做本地缓存,是做了每次进入都拉取一次聊天的历史记录的操作。

WXML代码

<scroll-view class='chat' id="chat" style="height:{{height}}px;" scroll-y style='padding-bottom:49px;' >
  <block  wx:for="{{myMessages}}" wx:key="{{index}}">
    <view class='chat-time' wx:if="{{item.time != ''}}">{{item.msgTime}}</view>
    <view class="chat-item flex-wrap {{item.isSelfSend ? 'house' : ''}}" wx:if='{{item.type != ""}}' bindtap='linkDetail'  data-id="{{item.id}}" data-type="{{item.type}}">
        <view class='avatar'>
          <image style="width:40px;height:40px;border-radius:50%;" mode= "scaleToFill" src="{{item.avatar}}"></image>
        </view>
        <view class='content ' style="width:520rpx;">
          <image class='img' style="width:100%;height:120px;" mode= "scaleToFill"  src="{{item.img == '' ? houseDefault : item.img}}"></image>
          <view class='info'>
            <view class='info-name'>{{item.name}}</view>
            <view class='info-title'>{{item.msgContent}}</view>
            <view class='flex-wrap'>
              <view class='flex-item3'>
                <view class='info-price'>{{item.price}}</view>
              </view>
              <view class='flex-item'>
                <view class='info-type'>{{item.type}}</view>
              </view>
            </view>
          </view>
        </view>
    </view>
    <view class="chat-item flex-wrap {{item.isSelfSend ? 's' : ''}}" wx:if='{{item.type == ""}}'>
        <view class='avatar'>
          <image style="width:40px;height:40px;border-radius:50%;" mode= "scaleToFill" src="{{item.avatar}}"></image>
        </view>
        <view class='content '>{{item.msgContent}}</view>
    </view>
  </block>
</scroll-view>

<view class='footer-h'></view>
<view class='chat-footer flex-wrap'>
   <view class='flex-item ' bindtap='send1'> <text class="iconfont icon-yuyin" style='vertical-align: 0;padding-right:0; '></text></view>
   <view class='flex-item5'>
      <input class='input'  bindinput="bindKeyInput" value="{{inputValue}}" placeholder="对ta发送消息"/>
   </view>
   <view class='flex-item2 send' bindtap='bindConfirm'>发送</view>
</view>

WXSS代码

.flex-wrap.s ,.house{
  flex-direction:row-reverse;

}
.h49{
  width: 100%;
  height: 49px;
}
.chat-item.flex-wrap.s{
  margin: 20px 10px 20px 0px;

}
.chat-item.flex-wrap{
  line-height: 20px;
  height: auto;
  margin: 20px 0px 20px 10px;
  
}
.chat-footer{
  position: fixed;
  bottom: 0;
  left: 0;
  width: 100%;
  height: 49px;
  background: #ffffff;
}
.send{
  width: 100%;
  height: 49px;
  line-height: 49px;
  text-align: center;
  background: #69BEFF;
  color: #ffffff;
  font-size: 16px;
}
.icon-yuyin::before{
  font-size: 70rpx;
  color: #7F8389;
  display: block;
  height: 49px;
  line-height: 49px;
  text-align: center;
}
.input{
  height: 49px;
  line-height: 49px;
  font-size: 13px;
}
.avatar{
  width: 40px;
  height: 40px;
  background: #69BEFF;
  border-radius:50%;
  text-align: center;
  line-height: 40px;
  color: #ffffff;
}
.chat-item.flex-wrap .content{
  background: #ffffff;
  margin-left: 10px;
  padding:12px;
  border-radius:10px; 
  width: auto;
  max-width: 480rpx;
  font-size: 15px;
  text-align: justify;
}
.chat-item.flex-wrap.house{
  margin-right: 10px;
}

.chat-item.flex-wrap.s .content{
  margin-right: 10px;
  background: #69BEFF;
  color: #ffffff;
}
.chat-item.flex-wrap.house .content{
  margin-right: 10px;
  padding: 0;
  width: 520rpx;
  
}
.content .img{
  border-top-left-radius: 10px;
  border-top-right-radius: 10px;
}
.chat-time{
  width: 80px;
  height: 21px;
  line-height: 21px;
  background: #CECECE;
  color: #ffffff;
  font-size: 12px;
  margin: 20px auto 0px;
  text-align: center;
  border-radius:5px;

}
.content .info{
  padding:0 20rpx 20rpx;
}
.info-price{
  color: #E93D26;
  font-size: 14px;
}
.info-title{
  color: #999999;
  font-size: 12px;
}
.info-type{
  width: 50px;
  height: 18px;
  line-height: 18px;
  color: #ffffff;
  font-size: 12px;
  background: #CECECE;
  text-align: center;
  border-radius: 2px;

}
.footer-h{
  height: 49px;
  width: 100%;
}

js代码


var webim = require('../../utils/webim.js');
var webimhandler = require('../../utils/webim_handler.js');
const app = getApp()
Page({

  /**
   * 页面的初始数据
   */
  data: {
    noData: app.data.imageUrl + '/no-msg.png',
    houseDefault: app.data.imageUrl + '/msg-default.png',
    inputValue:'',//发送的文字消息内容
    myMessages: [],//消息
    selToID:0,
    scrollTop: 0,
    houseId:'',//房源id
    type:'',//房源类型
    height:'',
    complete:0,//默认为有历史记录可以拉取
    is_lock:true//发送消息锁
  },

  /**
   * 生命周期函数--监听页面加载
   */
  onLoad: function (options) {
    
    var that = this;
    
    that.setData({
      height: wx.getSystemInfoSync().windowHeight
    })
    
    if(options){
      if(options.id){//设置会话列表传参过来的为好友id
        that.setData({
          selToID: options.id
        })
        wx.setNavigationBarTitle({
          title: options.name
        })
      }else if (!options.dockingname){//非经纪人角色,私聊账号为推荐经纪人账号
        that.setData({
          selToID: app.data.userInfo.agent_member_id.toString(),
          houseId: options.houseid,
          type:options.type
        })
        wx.setNavigationBarTitle({
          title: '置业顾问' + app.data.userInfo.agent_name
        })
        //拉取所需要自定义的消息数据发送
        that.createhousemsg();
       
      }else{
        that.setData({
          selToID: options.agent_member_id ,
          houseId: options.houseid,
          type: options.type
        })
        wx.setNavigationBarTitle({
          title: '盘方顾问' + options.dockingname
        })
        //拉取所需要自定义的消息数据发送
        that.createhousemsg();
      }
    }
    
  },
  onShow:function () {
    var that = this;    
    wx.setStorageSync('msgKey', '')
    wx.setStorageSync('lastMsgTime', '')
    webimhandler.init({
      accountMode: app.data.Config.accountMode
      , accountType: app.data.Config.accountType
      , sdkAppID: app.data.Config.sdkappid
      , selType: webim.SESSION_TYPE.C2C//私聊
      , agent_member_id: app.data.userInfo.id
      , id: that.data.selToID  
      , name: app.data.userInfo.agent_name
      , icon: app.data.userInfo.agent_pic,
      that: that
    });
    if (webim.checkLogin()) {
      webimhandler.getC2CHistoryMsgs();
    } else {
      webimhandler.sdkLogin(that,app, this.data.selToID,()=> {
        //获取聊天历史记录
        webimhandler.getC2CHistoryMsgs();

      });
    }
    
  },
  //创建自定义房源消息体
  createhousemsg:function(){
    var that = this;
    var param = {
      app_token: app.data.userInfo.app_token,
      id: that.data.houseId,
      type: that.data.type
    }
    app.request('get', 'createhousemsg', that, param,
      (data) => {
	      //这里的data.array.MsgContent为获取到需要发送的消息体字段
        webimhandler.sendCustomMsg(data.array.MsgContent, (data)=>{
          var myMessages = that.setDatas(data)
            that.setData({
              myMessages: myMessages,
            })
          setTimeout(function () {
            that.pageScrollToBottom()
          }, 100)
        })
      }, () => {
        setTimeout(function () {
          login.login(app)
        }, 500)
      }, () => {
        wx.navigateBack({
          delta: 1
        })
        return;
      })
  },

  //获取普通文本消息
  bindKeyInput:function(e){
    var that = this;
     that.setData({
      inputValue:e.detail.value
    })
  },
  // 发送普通文本消息
  bindConfirm: function(e) {
    var that = this;
    
    if(that.data.is_lock){
      that.setData({
        is_lock:false
      })
      if (that.data.inputValue.length == 0) {
        wx.showToast({
          title: '消息不能为空!',
          icon:'none'
        })
        that.setData({
          is_lock: true
        })
        return;
      }
      var content = that.data.inputValue;
      if (!content.replace(/^\s*|\s*$/g, '')) return;
      webimhandler.onSendMsg(content)
    }
  },
  // 清除输入框
  clearInput:function(e){
    this.setData({
      inputValue:''
    })
  },
  /**
   * 下拉上翻历史记录
   */
  onPullDownRefresh: function () {
    if (this.data.complete == 0){

    
      wx.showLoading({
        title: '加载历史记录中...',
      })
      var that = this;
      webimhandler.getPrePageC2CHistoryMsgs()
      wx.stopPullDownRefresh();
    }else{
      wx.showToast({
        title: '没有更多历史记录了',
        icon:'none'
      })
    }
  },

  // 滚动最底部
  pageScrollToBottom: function () {
      wx.createSelectorQuery().select('#chat').boundingClientRect(function (rect) {
        // 使页面滚动到底部
        wx.pageScrollTo({
          scrollTop: rect.bottom
        })
      }).exec()
  },
  // 跳转房源详情
  linkDetail:function(e){
    switch (e.currentTarget.dataset.type){
      case '新房':
        wx.navigateTo({
          url: '../newHouseDetail/newHouseDetail?id=' + e.currentTarget.dataset.id,
        })
        break;
      case '二手房':
        wx.navigateTo({
          url: '../useroomDetail/useroomDetail?id=' + e.currentTarget.dataset.id,
        })
        break;
      case '租房':
        wx.navigateTo({
          url: '../rentroomDetail/rentroomDetail?id=' + e.currentTarget.dataset.id,
        })
        break;
      case '小区':
        wx.navigateTo({
          url: '../unitDetail/unitDetail?id=' + e.currentTarget.dataset.id,
        })
        break;
    }
  },
  setDatas: function (data){
    var that = this;
    var myMessages = data.map((item, index) => {

      switch (item.type) {
        case 1:
          item.type = '二手房'
          break;
        case 2:
          item.type = '租房'
          break;
        case 3:
          item.type = '小区'
          break;
        case 4:
          item.type = '新房'
          break;
      }
      if (item.img == '') {
        item.img = that.data.houseDefault
      }
      return item;
    })

    return myMessages;

  }

  

})

发送自定义消息

//发送消息(自定义消息)
function sendCustomMsg(msgs,callback) {
  var data = msgs.Data;//数据
  var desc = msgs.Desc;//描述
  var ext = msgs.Ext;//拓展字段
  var msgLen = webim.Tool.getStrBytes(data);
  if (msgs.length < 1) {
    alert("发送的消息不能为空!");
    return;
  }
  var maxLen, errInfo;
  if (selType == webim.SESSION_TYPE.C2C) {
    maxLen = webim.MSG_MAX_LENGTH.C2C;
    errInfo = "消息长度超出限制(最多" + Math.round(maxLen / 3) + "汉字)";
  } else {
    maxLen = webim.MSG_MAX_LENGTH.GROUP;
    errInfo = "消息长度超出限制(最多" + Math.round(maxLen / 3) + "汉字)";
  }
  if (msgLen > maxLen) {
    alert(errInfo);
    return;
  }
  if (!selSess) {
    selSess = new webim.Session(selType, id, name, icon, Math.round(new Date().getTime() / 1000));
  }
  var msg = new webim.Msg(selSess, true, -1, -1, -1, id, 0, name);
  var custom_obj = new webim.Msg.Elem.Custom(data, desc, ext);

  msg.addCustom(custom_obj);
  msg.sending = 1;
  // //调用发送消息接口
  webim.sendMsg(msg, function (resp) {
    if (selType == webim.SESSION_TYPE.C2C) {
      // 处理消息
      handlderMsg(msg,false);
      // 获取头像
      getMyAvatar(id, agent_member_id,function(){
        callback(currentMsgsArray)
      });
    }
    that.msginformagent(id, msgs)
    webim.Log.info("发消息成功");
  }, function (err) {
    webim.Log.info("发消息失败");
   
  });
}

// 解析消息(普通文本消息,自定义消息)
function convertMsg(msg, prepend) {
    var that = this;
    var elems, elem, type, content, isSelfSend, ifromAccount;
    elems = msg.getElems();
    isSelfSend = msg.getIsSend(); //消息是否为自己发的 true是自己发送,
    ifromAccount = msg.fromAccount
    for (var i in elems) {
        var currentMsg = {}; 
        elem = elems[i];
        type = elem.getType();
        content = elem.getContent();
        switch (type) {
            case webim.MSG_ELEMENT_TYPE.TEXT://文本消息
                var msgContent = convertTextMsgToHtml(content);
                var msgTime = msg.getTime();//得到当前消息发送的时间
                //解析时间
              convertTime(msgTime, function (data) {
              currentMsg.id = ifromAccount;//房源标题                
              currentMsg.msgContent = msgContent;//当前消息的内容
              currentMsg.img = '';
              currentMsg.msgTime = data;
              currentMsg.name = ''
              currentMsg.price = '';
              currentMsg.isSelfSend = isSelfSend;
              currentMsg.ifromAccount = ifromAccount;
              currentMsg.type = '';
                if (prepend){
                  historyMsgsArray.push(currentMsg)
                  
                }else{
                  currentMsgsArray.push(currentMsg);
                }
              
            })

            break;
            case webim.MSG_ELEMENT_TYPE.CUSTOM://自定义消息
              var msgContent = convertCustomMsgToHtml(content);
              var msgTime = msg.getTime();//得到当前消息发送的时间
                  if (msgContent.data == ''){
                    
                  }else{
                    msgContent = JSON.parse(msgContent.data)
                  }
                
                convertTime(msgTime, function (data) {
                  currentMsg.id = msgContent.id//房源标题
                  currentMsg.img = msgContent.img//房源图片
                  currentMsg.msgTime = data;//消息时间                
                  currentMsg.name = msgContent.name //楼盘名称
                  currentMsg.price = msgContent.price //价格
                  currentMsg.type = msgContent.type //类型(1二手房,2租房,3小区,4新房)
                  currentMsg.isSelfSend = isSelfSend;//默认右边
                  currentMsg.ifromAccount = ifromAccount;
                  if (prepend){
                    historyMsgsArray.push(currentMsg)
                  }else{
                    currentMsgsArray.push(currentMsg);
                  }
                })
              

            break;
        }


    }

}

// 解析自定义消息
function convertCustomMsgToHtml(content) {
  var data = content.getData();
  var desc = content.getDesc();
  var ext = content.getExt();
  var content = {
    data:data,
    desc: desc,
    ext: ext
  }
  return content;
}

发送普通文本消息

//发送消息(普通消息)
function onSendMsg(msg) {

    //获取消息内容
    var msgtosend = msg;
    var msgLen = webim.Tool.getStrBytes(msg);
    // 创建会话对象
    if (!selSess) {
        selSess = new webim.Session(selType, id, name, icon, Math.round(new Date().getTime() / 1000));
    }
    var isSend = true;//是否为自己发送
    var seq = -1;//消息序列,-1表示sdk自动生成,用于去重
    var random = Math.round(Math.random() * 4294967296);//消息随机数,用于去重
    var msgTime = Math.round(new Date().getTime() / 1000);//消息时间戳
    var subType = webim.C2C_MSG_SUB_TYPE.COMMON;//消息子类型c2c消息时,参考c2c消息子类型对象:webim.C2C_MSG_SUB_TYPE 
    //loginInfo.identifier消息发送者账号,loginInfo.identifierNick消息发送者昵称
    var msg = new webim.Msg(selSess, isSend, seq, random, msgTime, id, subType, name );
    //解析文本和表情
    var expr = /\[[^[\]]{1,3}\]/mg;
    var emotions = msgtosend.match(expr);
    if (!emotions || emotions.length < 1) {
        var text_obj = new webim.Msg.Elem.Text(msgtosend);
        msg.addText(text_obj);
    } else {//有表情
    
    }
    
    webim.sendMsg(msg, function (resp) {
        if (selType == webim.SESSION_TYPE.C2C) {//私聊时,在聊天窗口手动添加一条发的消息

          handlderMsg(msg,false);
          // 设置双方头像
          getMyAvatar(id, agent_member_id, function () {
            that.clearInput();
            var myMessages = that.setDatas(currentMsgsArray);
            that.setData({
              myMessages: myMessages,
              is_lock: true
            })
           
            // setTimeout(function () {
              that.pageScrollToBottom()
            // }, 100)
          });

          that.msginformagent(id, msgtosend)          
          webim.Log.info("发消息成功");
        }
        
     
    }, function (err) {
        webim.Log.error("发消息失败:" + err.ErrorInfo);
    });
}


//解析文本消息元素
function convertTextMsgToHtml(content) {
    return content.getText();
}

统一处理文本消息,自定义消息

// 解析消息(普通文本消息,自定义消息)
function convertMsg(msg, prepend) {
    var that = this;
    var elems, elem, type, content, isSelfSend, ifromAccount;
    elems = msg.getElems();
    isSelfSend = msg.getIsSend(); //消息是否为自己发的 true是自己发送,
    ifromAccount = msg.fromAccount
    for (var i in elems) {
        var currentMsg = {}; 
        elem = elems[i];
        type = elem.getType();
        content = elem.getContent();
        switch (type) {
            case webim.MSG_ELEMENT_TYPE.TEXT://文本消息
                var msgContent = convertTextMsgToHtml(content);
                var msgTime = msg.getTime();//得到当前消息发送的时间
                //解析时间
              convertTime(msgTime, function (data) {
              currentMsg.id = ifromAccount;//房源标题                
              currentMsg.msgContent = msgContent;//当前消息的内容
              currentMsg.img = '';
              currentMsg.msgTime = data;
              currentMsg.name = ''
              currentMsg.price = '';
              currentMsg.isSelfSend = isSelfSend;
              currentMsg.ifromAccount = ifromAccount;
              currentMsg.type = '';
                if (prepend){
                  historyMsgsArray.push(currentMsg)
                  
                }else{
                  currentMsgsArray.push(currentMsg);
                }
              
            })

            break;
            case webim.MSG_ELEMENT_TYPE.CUSTOM://自定义消息
              var msgContent = convertCustomMsgToHtml(content);
              var msgTime = msg.getTime();//得到当前消息发送的时间
                  if (msgContent.data == ''){
                    
                  }else{
                    msgContent = JSON.parse(msgContent.data)
                  }
                
                convertTime(msgTime, function (data) {
                  currentMsg.id = msgContent.id//房源标题
                  currentMsg.img = msgContent.img//房源图片
                  currentMsg.msgTime = data;//消息时间                
                  currentMsg.name = msgContent.name //楼盘名称
                  currentMsg.price = msgContent.price //价格
                  currentMsg.type = msgContent.type //类型(1二手房,2租房,3小区,4新房)
                  currentMsg.isSelfSend = isSelfSend;//默认右边
                  currentMsg.ifromAccount = ifromAccount;
                  if (prepend){
                    historyMsgsArray.push(currentMsg)
                  }else{
                    currentMsgsArray.push(currentMsg);
                  }
                })
              

            break;
        }


    }

}

发送消息成功之后,就需要监听新消息,更新消息的未读数了

//监听新消息(私聊(包括普通消息、全员推送消息),普通群(非直播聊天室)消息)事件
//newMsgList 为新消息数组,结构为[Msg]
function onMsgNotify(newMsgList) {
    var newMsg;
    //获取所有聊天会话
 
    for (var j in newMsgList) {//遍历新消息
        newMsg = newMsgList[j];
        
        if (newMsg.getSession().id() == id) {//为当前聊天对象的消息
            selSess = newMsg.getSession();
            handlderMsg(newMsg, false);
            currentMsgsArray = currentMsgsArray.map((item, index) => {
              if (!item.isSelfSend) {
                item.avatar = myAvatar
              } else {
                item.avatar = friendAvatar
              }
              return item;
            })
            var myMessages = that.setDatas(currentMsgsArray);
            that.setData({
              myMessages: myMessages,

            })
            setTimeout(function () {
              if (that.data.is_chat){
                that.pageScrollToBottom()
              }
            }, 100)
          
        }
    }
    getUnread()
    
}


//更新消息未读数
function getUnread(){
  var sess= {};
  var sessMap = webim.MsgStore.sessMap();
  if (that.data.contactList) {
    // 更新消息的未读数
    for (var i in sessMap) {
      sess = sessMap[i];
      var contactList = that.data.contactList.map((item, index) => {
        if (item.To_Account == sess.id()) {
          item.UnreadMsgCount = sess.unread()
        }
        return item;
      })
      that.setData({
        contactList: contactList
      })
        // 获取最新的会话消息
        webim.getRecentContactList({
          'Count': 10 //最近的会话数 ,最大为 100
        }, function (resp) {
          var MsgShow = resp.SessionItem.filter((item, index) => {
            if (item.To_Account == sess.id()) return item;
          })
         
          var contactList = that.data.contactList.map((item, index) => {
            if (item.To_Account == sess.id()) {
              // 获取最新消息
              if (MsgShow[0].MsgShow == '[其他]'){
                MsgShow[0].MsgShow = '[房源信息]'
              }
              item.MsgShow = MsgShow[0].MsgShow
              
            }
            return item;
          })
          
          that.setData({
            contactList: contactList
          })

        })

      }
  }
}

发送消息就到这里了,历史记录下章讲

  • 5
    点赞
  • 67
    收藏
    觉得还不错? 一键收藏
  • 17
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 17
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值