微信企业号在线客服

需求

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

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超级管理员(使用企业微信扫码登录系统)

 

posted @ 2019-09-18 21:21  汪丛兴  阅读(1873)  评论(1编辑  收藏  举报