zoukankan      html  css  js  c++  java
  • 微信企业号在线客服

    需求

      因企微信企业号后台暂时只提供,历史消息模块,无法适用客服模式,很难及时反馈用户提问的消息,基于企业微信二次开发客服系统,可实现消息实时触达,多客服,知识库等功能

    1.新建项目wechatWork

    2.python 安装wechatpy 

    官方文档:https://wechatpy.readthedocs.io/zh_CN/master/

    pip install wechatpy
    # with cryptography (推荐)
    pip install wechatpy[cryptography]
    # with pycryptodome
    pip install wechatpy[pycrypto]

    3.企业号后台设置消息http接口

    4.设计model.py  应用管理表 客服用户管理表

    from django.contrib.auth.models import User
    from django.db import models
    from django.utils.crypto import random
    # Create your models here.
    from django.utils.html import format_html
    
    
    def rename(newname):
        def decorator(fn):
            fn.__name__ = newname
            return fn
    
        return decorator
    
    
    # 客服人员
    
    class KF(models.Model):
        agent = models.ForeignKey('agent', null=True, to_field="id", on_delete=models.CASCADE, verbose_name="应用名称")
        username = models.CharField(max_length=225, verbose_name="姓名", blank=True, default="")
        userid = models.CharField(max_length=225, verbose_name="UM", blank=True, default="")
        status = models.BooleanField(verbose_name="是否在线")
        avatar = models.URLField(max_length=225, verbose_name="头像", blank=True, default="")
        createTime = models.DateTimeField(auto_now_add=True, verbose_name="创建时间")
        lastTime = models.DateTimeField(auto_now=True, verbose_name="修改时间")
        author = models.CharField(max_length=64, verbose_name="创建者", blank=True, default="")
        editor = models.ForeignKey(User, null=True, on_delete=models.CASCADE, verbose_name="修改者")
    
        class Meta:
            verbose_name_plural = "在线客服"
            ordering = ['id']
    
        @rename("头像")
        def showAvatar(self):
            return format_html("<img src='{}' class='showAvatar'", self.avatar)
    
        def __str__(self):
            return self.username
    
    
    # 行内员工
    
    def randomSign():
        switch = {
            0: "只要还有明天,今天就永远是起跑线。",
            1: "只要还有明天,今天就永远是起跑线。",
            2: "只要还有明天,今天就永远是起跑线。"
        }
        return switch[random.randint(0, len(switch) - 1)]
    
    
    class userList(models.Model):
        username = models.CharField(max_length=225, verbose_name="姓名", blank=True, default="")
        userid = models.CharField(max_length=225, verbose_name="UM", blank=True, default="")
        avatar = models.URLField(max_length=225, verbose_name="头像", blank=True, default="")
        sign = models.CharField(max_length=225, verbose_name="个性签名", blank=True, default=randomSign)
        agent = models.ForeignKey('agent', null=True, to_field="id", on_delete=models.CASCADE, verbose_name="应用名称")
        createTime = models.DateTimeField(auto_now_add=True, verbose_name="创建时间")
        lastTime = models.DateTimeField(auto_now=True, verbose_name="修改时间")
        author = models.CharField(max_length=64, verbose_name="创建者", default="weChat")
        editor = models.ForeignKey(User, null=True, on_delete=models.CASCADE, verbose_name="修改者")
    
        @rename("头像")
        def showAvatar(self):
            return format_html("<img src='{}' class='showAvatar'", self.avatar)
    
        class Meta:
            verbose_name_plural = "用户列表"
            ordering = ['id']
    
        def __str__(self):
            return self.username
    
    
    # 接受的消息
    
    class Message(models.Model):
        ToUserName = models.CharField(max_length=225, verbose_name="企业号ID", blank=True, default="")
        FromUserName = models.CharField(max_length=225, verbose_name="发送者", blank=True, default="")
        CreateTime = models.DateTimeField(verbose_name="发送时间", blank=True, default=None)
        MsgId = models.CharField(max_length=225, verbose_name="消息ID", blank=True, default="")
        AgentID = models.CharField(max_length=225, verbose_name="应用ID", blank=True, default="")
        MsgType = models.CharField(max_length=225, verbose_name="消息类型", blank=True, default="")
        content = models.TextField(max_length=2000, verbose_name="消息内容", blank=True, default="")
        userList = models.ForeignKey('userList', null=True, to_field="id", on_delete=models.CASCADE)
    
        class Meta:
            verbose_name_plural = "所有消息"
            ordering = ['id']
    
        def __str__(self):
            return self.FromUserName
    
    # 企业号应用管理,支持多个应用接入客服系统
    class agent(models.Model): name = models.CharField(max_length=225, verbose_name="应用名称", blank=True, default="") agentid = models.CharField(max_length=225, verbose_name="应用ID", blank=True, default="") secret = models.CharField(max_length=225, verbose_name="应用密钥", blank=True, default="") avatar = models.URLField(max_length=225, verbose_name="部门Logo", blank=True, default="") welcomeText = models.TextField(max_length=2000, verbose_name="欢迎语", blank=True, default="") firstText = models.TextField(max_length=2000, verbose_name="会话提示语", blank=True, default="您好,很高兴为您服务!") conversationTime = models.IntegerField(verbose_name="会话时长(分钟)", default=20) notuserText = models.TextField(max_length=2000, verbose_name="客服不在线提示语", blank=True, default="非常抱歉,客服处于离线状态,您的消息我们已发送IT服务台,马上会有IT同事跟进处理!") webhook_url = models.URLField(verbose_name="群机器人地址", default="") createTime = models.DateTimeField(auto_now_add=True, verbose_name="创建时间") lastTime = models.DateTimeField(auto_now=True, verbose_name="修改时间") author = models.CharField(max_length=64, verbose_name="创建者") editor = models.ForeignKey(User, null=True, on_delete=models.CASCADE, verbose_name="修改者") @rename("部门Logo") def showAvatar(self): return format_html("<img src='{}' class='showAvatar'", self.avatar) @rename("详情") def checkMessage(self): return format_html("<a href='/work/index/{}.html' target='blank'>回复</a>", self.id) class Meta: verbose_name_plural = "应用管理" ordering = ['id'] def __str__(self): return self.name # 客服知识库 class knowledgeBase(models.Model): questionType = models.CharField(max_length=225, verbose_name="问题类型", blank=True, default="") key = models.CharField(max_length=225, verbose_name="关键字", blank=True, default="") rule = models.IntegerField(choices=((0, '包含'), (1, '完全匹配')), default=0, verbose_name='规则') answerType = models.IntegerField(choices=((0, '文字'), (1, '图文'), (2, '图片'), (3, '语音'), (4, '视频')), default=0, verbose_name='发送类型') content = models.TextField(max_length=2000, verbose_name="消息内容", blank=True, default="") createTime = models.DateTimeField(auto_now_add=True, verbose_name="创建时间") lastTime = models.DateTimeField(auto_now=True, verbose_name="修改时间") author = models.CharField(max_length=64, verbose_name="创建者") editor = models.ForeignKey(User, null=True, on_delete=models.CASCADE, verbose_name="修改者") class Meta: verbose_name_plural = "知识库" ordering = ['id'] def __str__(self): return self.name

    5.admin.py 代码

    from django.contrib import admin
    
    # Register your models here.
    
    from import_export import resources
    from import_export.admin import ImportExportModelAdmin
    from wechatpy.enterprise import WeChatClient
    from wechatpy.enterprise.crypto import WeChatCrypto
    from wechatpy.exceptions import InvalidSignatureException
    import weChatWork as config
    
    from work.models import *
    
    admin.site.site_title = "企业号后台管理"
    admin.site.site_header = "企业号后台管理"
    
    # 企业号ID
    corpid = config.settings.weChatWork["corpid"]
    
    
    class agentResource(resources.ModelResource):
        def get_export_headers(self):
            # 是你想要的导出头部标题headers
            return ['应用名称', '欢迎语', '会话提示语', '部门Logo', '创建时间', '修改时间', '创建者', '修改者']
    
        class Meta:
            field = ('name', 'welcomeText', 'firstText', 'avatar', 'createTime', 'lastTime', 'author', 'editor')
            model = agent
            fields = field
            export_order = field
    
    
    @admin.register(agent)
    class agentAdmin(ImportExportModelAdmin):
        fields = ('agentid', 'secret', 'welcomeText', 'firstText', 'notuserText', 'webhook_url', 'conversationTime')
        # 需要显示的字段信息
        list_display = ('showAvatar', 'name', 'welcomeText', 'firstText', 'notuserText', 'webhook_url', 'conversationTime',
                        'createTime',
                        'lastTime', 'author',
                        'editor',
                        'checkMessage')
        exclude = ('avatar', 'author', 'editor')
        # 设置哪些字段可以点击进入编辑界面,默认是第一个字段
        list_display_links = ('showAvatar', 'name')
        model_icon = "fa fa-tag"
        list_per_page = 10
        resource_class = agentResource
    
        def save_model(self, request, obj, form, change):
            if form.is_valid():
                if not change:
                    obj.author = request.user.username
                obj.editor = request.user
                client = WeChatClient(corpid, obj.secret)
                agent = client.agent.get(obj.agentid)
                obj.name = agent["name"]
                obj.avatar = agent["square_logo_url"]
                print(agent)
                obj.save()
            super().save_model(request, obj, form, change)
    
    
    class KFResource(resources.ModelResource):
        def get_export_headers(self):
            # 是你想要的导出头部标题headers
            return ['姓名', 'UM', '头像']
    
        class Meta:
            field = ('username', 'userid', 'sign', 'avatar',)
            model = KF
            fields = field
            export_order = field
    
    
    @admin.register(KF)
    class KFAdmin(ImportExportModelAdmin):
        fields = ("agent", 'userid',)
        # 需要显示的字段信息
        list_display = (
            'id', "agent", "showAvatar", 'username', 'userid', 'status', 'createTime', 'lastTime', 'author', 'editor')
        exclude = ('username', 'status', 'avatar', 'author', 'editor')
        # 设置哪些字段可以点击进入编辑界面,默认是第一个字段
        list_display_links = ('id', 'username')
        model_icon = "fa fa-tag"
        list_per_page = 10
        resource_class = KFResource
    
        def save_model(self, request, obj, form, change):
            if form.is_valid():
                if not change:
                    obj.author = request.user.username
                obj.userid = obj.userid.upper()
                obj.editor = request.user
                obj.status = False
                agentInfo = agent.objects.filter(agentid=obj.agent.agentid).first()
                client = WeChatClient(corpid, agentInfo.secret)
                user = client.user.get(obj.userid)
                obj.username = user["name"]
                obj.avatar = user["avatar"]
                obj.save()
            super().save_model(request, obj, form, change)
    
    
    class userListResource(resources.ModelResource):
        def get_export_headers(self):
            # 是你想要的导出头部标题headers
            return ['姓名', 'UM', '头像']
    
        class Meta:
            field = ('username', 'userid', 'avatar', 'createTime', 'lastTime', 'author', 'editor')
            model = userList
            fields = field
            export_order = field
    
    
    @admin.register(userList)
    class userListAdmin(ImportExportModelAdmin):
        fields = ()
        # 需要显示的字段信息
        list_display = ('id', 'agent', 'showAvatar', 'username', 'userid', 'createTime', 'lastTime', 'author', 'editor')
        # 设置哪些字段可以点击进入编辑界面,默认是第一个字段
        list_display_links = ('id', 'username')
        search_fields = ('username', 'userid')
        model_icon = "fa fa-tag"
        list_per_page = 50
        resource_class = userListResource
    
        def save_model(self, request, obj, form, change):
            if form.is_valid():
                obj.editor = request.user
                obj.save()
            super().save_model(request, obj, form, change)
    
    
    class MessageResource(resources.ModelResource):
        def get_export_headers(self):
            # 是你想要的导出头部标题headers
            return ['企业号ID', '发送者', '发送时间', '消息ID', '应用ID', '消息类型', '消息内容']
    
        class Meta:
            field = ('FromUserName', 'CreateTime', 'MsgId', 'AgentID', 'MsgType', 'content')
            model = Message
            fields = field
            export_order = field
    
    
    # Register your models here.
    @admin.register(Message)
    class MessageAdmin(ImportExportModelAdmin):
        fields = ('FromUserName', 'CreateTime', 'MsgId', 'AgentID', 'MsgType', 'content')
        # 需要显示的字段信息
        list_display = ('id', 'FromUserName', 'CreateTime', 'MsgId', 'AgentID', 'MsgType', 'content')
        # 设置哪些字段可以点击进入编辑界面,默认是第一个字段
        list_display_links = ('id', 'FromUserName')
        model_icon = "fa fa-tag"
        list_per_page = 10
        resource_class = MessageResource
    
    
    class knowledgeBaseResource(resources.ModelResource):
        def get_export_headers(self):
            # 是你想要的导出头部标题headers
            return ['问题类型', '关键字', '规则', '发送类型', '消息内容', '创建时间', '修改时间', '创建者', '修改者']
    
        class Meta:
            field = ('questionType', 'key', 'rule', 'answerType', 'content', 'createTime', 'lastTime', 'author', 'editor')
            model = knowledgeBase
            fields = field
            export_order = field
    
    
    # Register your models here.
    @admin.register(knowledgeBase)
    class knowledgeBaseAdmin(ImportExportModelAdmin):
        fields = ('questionType', 'key', 'rule', 'answerType', 'content')
        # 需要显示的字段信息
        list_display = ('id', 'questionType', 'key', 'rule', 'answerType', 'content')
        # 设置哪些字段可以点击进入编辑界面,默认是第一个字段
        list_display_links = ('id', 'questionType')
        model_icon = "fa fa-tag"
        list_per_page = 10
        resource_class = knowledgeBaseResource

    6.Channels的安装和使用(web socket 及时通讯)

     Channels是针对 Django 项目的一个增强框架,它可以是的同步的 Django 项目转变为异步的项目。它可以使得 Django 项目不仅支持 HTTP 请求,还可以支持 Websocket, chat协议,IOT协议 ,甚至是你自定义的协议,同时也整合了 Django 的 auth 以及 session 系統等等

    Channels 提供从 PYPI 直接pip下载安装
    pip install -U channels==2.0.2 Django==2.0.4 channels_redis==2.1.1

    参考文档:https://www.vimiix.com/post/63/?from=timeline&isappinstalled=0

    7.liunx安装redis

         windows 下安装redis: https://www.runoob.com/redis/redis-install.html

      liunx 安装redis: https://blog.csdn.net/qq_39135287/article/details/83474865

    8.接受微信API发送的消息

    import wechatpy
    from django.contrib import auth
    from wechatpy.enterprise.client.api import WeChatOAuth
    from wechatpy.enterprise.exceptions import InvalidCorpIdException
    from wechatpy import enterprise, parse_message
    from django.shortcuts import render, redirect
    from django.http import JsonResponse, HttpResponse, HttpResponseRedirect
    from django.contrib.auth import authenticate, login, logout
    from django.contrib.auth.decorators import login_required
    from django.contrib.auth.forms import UserCreationForm
    from django.contrib.auth.models import User
    import uuid, datetime, json, time
    import weChatWork as config
    from django.utils.safestring import mark_safe
    from wechatpy.enterprise.crypto import WeChatCrypto
    from wechatpy.exceptions import InvalidSignatureException
    import os
    import urllib
    import work
    from work.models import *
    from django.core.cache import cache
    from wechatpy.enterprise import WeChatClient
    from wechatpy.session.redisstorage import RedisStorage
    from redis import Redis
    from urllib.parse import quote
    from comm import libary
    from django.utils.safestring import mark_safe
    import json
    import urllib3
    
    corpid = config.settings.weChatWork["corpid"]
    sourceFile = config.settings.weChatWork["sourceFile"]
    soucketGroupName = config.settings.weChatWork["soucketGroupName"]
    
    
    # 群消息提问内容
    def template_string(**kwargs):
        return """<font color="warning">新消息</font>
    > 姓名:{username}
    > UM:{um}
    > 发送内容:{content}
    > 点击查看:{url}
    """.format(**kwargs)
    
    
    # 查看请求信息
    
    @login_required
    def requestInfo(request):
        result = request.environ.items()
        return render(request, 'requestInfo.html', {'rinfo': result})
    
    
    # 登录功能
    
    def login(request):
        code = request.GET.get('code', None)
        next = request.GET.get('next', '/')
        agentid = request.GET.get('state', "1000030")
        redirect_uri = quote(request.get_raw_uri(), 'utf-8')
        agentInfo = agent.objects.filter(agentid=agentid).first()
        agentid = agentInfo.agentid
        secret = agentInfo.secret
        client = WeChatClient(corpid, secret)
        if libary.checkMobile(request):
            # 微信登录
            url = client.oauth.authorize_url(redirect_uri, state=agentid)
            if code:
                try:
                    user_info = client.oauth.get_user_info(code)
                    if user_info["errcode"] != "0" and user_info["errmsg"] != "ok":
                        return redirect("/static/error/500.html")
                    registered(request, user_info["UserId"])
                    return redirect(next)
                except Exception as e:
                    print(e.args)
            else:
                return redirect(url)
        else:
            # PC网站登录
            url = "https://open.work.weixin.qq.com/wwopen/sso/qrConnect?appid={0}&agentid={1}&redirect_uri={2}&state={3}".format(
                corpid, agentid, redirect_uri, agentid)
            if code:
                try:
                    print(client.access_token)
                    user_info = client.user.get_info(agentid, code)
                    if user_info["errcode"] != "0" and user_info["errmsg"] != "ok":
                        return redirect("/static/error/500.html")
                    UserId = user_info["UserId"].upper()
                    registered(request, UserId)
                    kfUser = KF.objects.filter(userid=UserId)
                    kfUser.update(status=True)
                    return redirect(next)
                except Exception as e:
                    print(e.errmsg, e.errcode)
                    # 这里需要处理请求里包含的 code 无效的情况
                    pass
            else:
                return redirect(url)
    
    
    # 注销
    def logout(request):
        kfUser = KF.objects.filter(userid=request.user.username).first()
        kfUser.status = False
        kfUser.save()
        auth.logout(request)
        return redirect('/admin/login/')
    
    
    # 注册
    def registered(request, userid):
        user = User.objects.filter(username=userid).first()
        if not user:
            user = User.objects.create_user(username=userid, email=str(userid) + "@pingan.com.cn", password=uuid.uuid1(),
                                            is_staff=True, is_active=True)
        auth.login(request, user)
        return user
    
    
    # 403 未授权页面
    def rorbidden(request):
        return redirect("/static/error/403.html")
    
    
    # Create your tests here.
    @login_required
    def index(request):
        method = request.method.upper()
        if method == "GET":
            return render(request, "work/index.html")
        elif method == "POST":
            UserId = request.user.username
            kfUser = KF.objects.filter(userid=UserId).first()
            kfUser.status = True
            kfUser.save()
            print(request.POST)
            Content = request.POST.get('mine[content]')
            userid = request.POST.get('mine[id]')
            FromUserName = request.POST.get('to[userid]')
            agentInfo = kfUser.agent
            agentid = agentInfo.agentid
            secret = agentInfo.secret
            client = WeChatClient(corpid, secret)
            result = client.message.send_text(agentid, FromUserName, Content)
            print(result)
            return JsonResponse(result)
    
    
    @login_required
    def chatMobile(request):
        return render(request, "work/mobile.html")
    
    
    @login_required
    def GetUserList(request):
        loginUser = request.user.username
        user = KF.objects.filter(userid=loginUser).first()
        mine = {"username": user.username, "id": user.userid, "status": "online", "sign": "嘻哈哈", "avatar": user.avatar}
        ulist = list(
            work.models.userList.objects.filter(agent__agentid=user.agent.agentid).values("id", "username", "userid",
                                                                                          "avatar", "sign"))
        friend = [{"groupname": "今天", "id": 1, "online": len(ulist), "list": ulist},
                  {"groupname": "前天", "id": 2, "online": 0, "list": []},
                  {"groupname": "三天前", "id": 4, "online": 0, "list": []},
                  {"groupname": "已回复", "id": 5, "online": 0, "list": []},
                  {"groupname": "未回复", "id": 6, "online": 0, "list": []}]
        return JsonResponse({'code': 0, 'msg': "", "data": {"mine": mine, "friend": friend, "group": []}})
    
    
    # 微信企业号 接收消息服务器配置
    from django.views.decorators.csrf import csrf_exempt
    
    
    @csrf_exempt
    def weChatIndex(request):
        method = request.method.upper()
        TOKEN = "###"
        EncodingAESKey = "####"
        crypto = WeChatCrypto(TOKEN, EncodingAESKey, corpid)
        echostr = request.GET.get("echostr")
        signature = request.GET.get("msg_signature")
        timestamp = request.GET.get("timestamp")
        nonce = request.GET.get("nonce")
        if method == "GET":
            try:
                echo_str = crypto.check_signature(signature, timestamp, nonce, echostr)
                return HttpResponse(echo_str)
            except InvalidSignatureException:
                pass
        elif method == "POST":
            try:
                decrypted_xml = crypto.decrypt_message(request.body, signature, timestamp, nonce)
            except (InvalidSignatureException, InvalidCorpIdException):
                raise  # 处理异常情况
            else:
                msg = parse_message(decrypted_xml)
                MsgType = msg._data["MsgType"]
                ToUserName = msg._data["ToUserName"]
                FromUserName = msg._data["FromUserName"]
                CreateTime = msg._data["CreateTime"]
                tl = time.localtime(int(CreateTime))
                cTime = time.strftime("%Y-%m-%d %H:%M:%S", tl)
                AgentID = msg._data["AgentID"]
                Message.objects.create(ToUserName=ToUserName, FromUserName=FromUserName,
                                       userList=userList.objects.filter(userid=FromUserName.upper()).first(),
                                       CreateTime=cTime, AgentID=AgentID, MsgType=MsgType, content=json.dumps(msg._data))
                swm = switch_wechat_messages()
                swm.case_to_function(MsgType)(msg._data)
                return JsonResponse({"msg": "OK"})
    
    
    def setWeChatRedis(data, Content):
        ToUserName = data["ToUserName"]
        FromUserName = data["FromUserName"]
        CreateTime = data["CreateTime"]
        MsgType = data["MsgType"]
        MsgId = data["MsgId"]
        AgentID = data["AgentID"]
        currentUser = createUser(FromUserName, AgentID)
        chatlog = []
        print("currentUser=", currentUser)
        print("FromUserName=", FromUserName)
        chatInfo = {"AgentID": AgentID, "username": currentUser.username, "userid": FromUserName,
                    "avatar": currentUser.avatar, "id": currentUser.id,
                    "type": "friend", "content": Content, "timestamp": CreateTime, "mine": True, "MsgType": MsgType}
        # 查询当前应用信息
        agentInfo = agent.objects.filter(agentid=AgentID).first()
        # 获得一个在线客服
        currentKF = KF.objects.filter(agent__agentid=AgentID, status=True).order_by("lastTime").first()
    
        # 判断当前用户是否在线
    
        if currentKF:
            # 判断会话是否过期
            userStateKey = AgentID + "&" + FromUserName
            conversationTime = agentInfo.conversationTime * 60
            # 首次会话自动推送欢迎语
            kfuser = cache.get(userStateKey)
            print("kfuser=", kfuser)
            if not kfuser:
                cache.set(userStateKey, currentKF.userid.upper(), timeout=conversationTime)
                if agentInfo.firstText:
                    client = WeChatClient(corpid, agentInfo.secret)
                    client.message.send_text(AgentID, FromUserName, agentInfo.firstText)
            else:
                cache.set(userStateKey, kfuser, timeout=conversationTime)
            # 选择在线客服推送消息 完成
            # 用户发送的消息 制定到客服 完成
            # 客服离线 消息转发到其他在线客服 完成 (历史消息未完成)
            from work.consumers import sendContent
            message = sendContent(chatInfo)
            sendUser = currentKF.userid.upper()
    
            isLogin = KF.objects.filter(agent__agentid=AgentID, status=True, userid=kfuser).first()
            if isLogin:
                sendUser = kfuser
            else:
                currentKF.save()
    
            from channels.layers import get_channel_layer
            channel_layer = get_channel_layer()
            from asgiref.sync import async_to_sync
            async_to_sync(channel_layer.group_send)(soucketGroupName + sendUser,
                                                    {"type": "chat_message", 'message': message})
    
        else:
            redisKey = AgentID + "$" + FromUserName
            chatlog.append(chatInfo)
            if not cache.get(redisKey):
                cache.set(redisKey, chatlog, timeout=None)
            else:
                redisUser = cache.get(redisKey)
                redisUser.append(chatInfo)
                cache.set(redisKey, redisUser, timeout=None)
    
            if agentInfo.notuserText:
                client = WeChatClient(corpid, agentInfo.secret)
                client.message.send_text(AgentID, FromUserName, agentInfo.notuserText)
    
            content = template_string(
                username=currentUser.username,
                um=FromUserName,
                content=Content,
                url="[发起对话](http://w.pinganbanksz.com:8000/work/chatMobile/)"
            )
            if agentInfo.webhook_url:
                encoded_data = json.dumps({"msgtype": "markdown", "markdown": {'content': content}}).encode('utf-8')
                http = urllib3.PoolManager()
                rr = http.request(method='POST', url=agentInfo.webhook_url, body=encoded_data,
                                  headers={'Content-Type': 'application/json'})
                print(f'webhook response:{rr.data}')
                assert json.loads(rr.data).get('errcode') == 0
    
    
    def downloadFile(data, fileType):
        AgentID = data["AgentID"]
        agentInfo = agent.objects.filter(agentid=AgentID).first()
        agentid = agentInfo.agentid
        secret = agentInfo.secret
        client = WeChatClient(corpid, secret)
        result = client.media.get_url(data["MediaId"])
        file = str(uuid.uuid1()) + "." + fileType
        BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
        sourceUrl = os.path.join(BASE_DIR, sourceFile)
        LocalPath = os.path.join(sourceUrl, file)
        # os.path.join将多个路径组合后返回
        urllib.request.urlretrieve(result, LocalPath)
        return "/{0}/{1}".format(sourceFile, file)
    
    
    class switch_wechat_messages(object):
    
        def case_to_function(self, case):
            fun_name = str(case) + "Message"
            method = getattr(self, fun_name, self.unknownMessage)
            return method
    
        def textMessage(self, data):
            Content = data["Content"]
            setWeChatRedis(data, Content)
    
        def imageMessage(self, data):
            PicUrl = data["PicUrl"]
            setWeChatRedis(data, PicUrl)
    
            print(data)
    
        def shortVideoMessage(self, data):
            print(data)
    
        def videoMessage(self, data):
            fileType = "avi"
            print(data)
            setWeChatRedis(data, downloadFile(data, fileType))
    
        def voiceMessage(self, data):
            fileType = data["Format"]
            setWeChatRedis(data, downloadFile(data, fileType))
            print(data)
    
        def locationMessage(self, data):
            print(data)
    
        def linkMessage(self, data):
            print(data)
    
        def eventMessage(self, data):
            AgentID = data["AgentID"]
            FromUserName = data["FromUserName"]
            createUser(FromUserName, AgentID)
    
        def unknownMessage(self, data):
            print(data)
    
    
    def createUser(userid, AgentID):
        userid = userid.upper()
        agentInfo = agent.objects.filter(agentid=AgentID).first()
        client = WeChatClient(corpid, agentInfo.secret)
        user = client.user.get(userid)
        obj = userList.objects.filter(userid=userid, agent__agentid=AgentID).first()
        if not obj:
            obj = userList.objects.create(username=user["name"], userid=userid, avatar=user["avatar"],
                                          agent=agentInfo)
        else:
            obj.username = user["name"]
            obj.avatar = user["avatar"]
    
        # 用户访问的时候一天推送一次提示语
        if obj.lastTime.date() < datetime.datetime.now().date():
            if obj:
                obj.save()
            result = client.message.send_text(AgentID, userid, agentInfo.welcomeText)
    
        return obj

    8.企业微信PC扫码登录

    在浏览器输入一下地址,XXXXX需要修改为企业号参数(appid, agentid, redirect_uri)

    参数说明:appid   企业ID  企业号后台-->我的企业-->最底部  企业ID

                    agentid 应用ID 企业号后台-->应用管理-->点击XX应用-->即可查看 

          redirect_url 登录成功后跳转系统地址  例如在用户扫码登录后,跳转到百度 http://www.baidu.com  跳转地址需要url 编码

    https://open.work.weixin.qq.com/wwopen/sso/qrConnect?appid=XXXXXXX&agentid=XXXXX&redirect_uri=XXXXX&state=XXXXX
    

      

    7.运行效果图

    1.客户端 (微信企业号即可发起聊天)

     2.客服端 (使用企业微信扫码登录系统)

    2.发送和接受内容

    3.PC超级管理员(使用企业微信扫码登录系统)

     

  • 相关阅读:
    日期和时间
    怎样将GB2312编码的字符串转换为ISO-8859-1编码的字符串?
    数据类型之间的转换:
    类的加载顺序,支出下列程序的输出结果
    内部类
    对象的类型转换
    简单继承
    封装
    计算a+b
    U盘删除文件时提示“文件或目录损坏且无法读取”的解决方法
  • 原文地址:https://www.cnblogs.com/wangcongxing/p/11542430.html
Copyright © 2011-2022 走看看