用企业微信机器人做交互式前端-输出

本系列所有文章请访问:概述

概述

web界面的ui和微信机器人的ui的区别在于:

  • web界面组合多种控件完成所有信息的整体呈现与输入,信息丰富、操作高效,用户获取的信息量大、容易理解,但注意力易分散

  • 微信机器人则输入输出相分离,输出是一块一块离散输出【文本按行汇集为一块,markdown、文件、图片、语音、视频都是一条消息为一块,如果有菜单,菜单也是独立的一块】;输入则是交互式的,机器人提示-用户输入,一问一答。信息的呈现较为离散,输入更是稀碎到一问一答。所以缺乏整体,而且如果输出太多,也很容易看了后面忘了前面,用户不容易理解,无法快速明确意图,但便于用户集中注意力

为降低开发维护两套ui的工作量,微信机器人利用了web界面的定义来输出信息。

微信机器人中共涉及到三类输出:

  • 容器表的输出

  • 数据表的输出

  • 向前端发出的提示

在本系统的第一篇文章中,笔者就谈过:微信机器人ui的开发,必须最小化变动,最大限度的确保低成本快速定制的实现。所以针对容器表和数据表的输出都是基于web中的定义而不增加任何额外的属性,只增加一些规范性约定,对于遵守这些规范的web界面,可直接用于微信机器人的输出而不需要增加任何额外的工作量。

容器表输出

jxTMS中的web界面是基于web文件定义然后动态生成的:web界面定义。基于此,对容器表的约束就是:

1、用于数据输入输出的控件都是成对的:一个文本控件用来提示说明,然后紧跟着一个绑定了数据名的控件用于输入输出数据

2、只接受部分控件

  • 未绑定数据名的控件支持:text类型的控件用于提取其text属性作为数据显示的提示词;a、button类型的控件提取为操作,用于动态添加子菜单选项

  • 绑定数据名的控件支持:text【文本】、input【单行输入】、dtpicker【时间】、combobox【下拉框】类型的控件直接输出,textarea【多行输入】、htmlContainer【html文本】类型的控件需要用base64解码后输出,此外还支持markdown【md格式文本】、file【文件】、img【图片】、voice【语音】、video【视频】等类型

注1:对于markdown类型来说,由于企业微信机API文档提示目前仅支持markdown语法子集,所以在编写此类知识时得考虑到企业微信的支持能力。同时,markdown控件在web界面中是显示用的输出型控件,markdown文本的编辑则需要codeEditor控件,由于用codeEditor控件直接编辑markdown文本需要非常熟悉markdown语法,所以建议用外部的markdown编辑器编辑后直接复制到codeEditor控件中。此外,jxTMS中常用的编辑器lightweightEditor控件,其编辑出来的是用于web界面显示的html格式的文本,无法用于markdown输出。markdown类型输出示例如下:

注2:对于voice、video类型来说,web界面中并没有相对应的控件,所以虽然微信机器人可以发送这些类型的信息给用户,但jxTMS后台却没有相应的管理界面。因此是暂时保留

注3:对于file类型来说,web界面中主要用于excel导入【下载就是一个链接】,所以和voice、video一样,都已经实现了,但还需要在具体应用中逐步成熟

如,本系列开始我们所演示的容器表测试的web定义为:

//容器表带操作按钮
web wxTestCT type div;
web wxTestCTt1 parent wxTestCT type table title='完成',width=600;
with wxTestCTt1 row 0 col c0 web n type text text='说明:',width=100;
with wxTestCTt1 row 0 col c1 web n bind testIn1 type text width=500;with wxTestCTt1 row 1 col c0 web n type a width=80,text='接受',motion=cmd,demand=wxTestCTAccept,params={'active':'accept'};
with wxTestCTt1 row 1 col c1 web n type a width=80,text='拒绝',motion=cmd,demand=wxTestCTReject,params={'active':'reject'};

其对应的初始化事件响应函数为:

@myModule.wxDisp('tms','容器表测试'.decode('utf-8'),'测试'.decode('utf-8'))
@myModule.event('prepareDisp', 'wxTestCT')
def wxTest(self, db, ctx):jx.log('wxTestCT disp')self.setOutput('testIn1','from wxTestCT')

在web界面的显示是:

而在微信机器人推送给我们时的显示是:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kzMsESsG-1636512124349)(http://115.29.52.95:10002/images/wxRobot-1-4.png)]

即,微信机器人对web定义的处理是

//跳过,如果有多个则会自动插入一个回车
web wxTestCT type div;
//跳过,如果有多个则会自动插入一个回车
web wxTestCTt1 parent wxTestCT type table title='完成',width=600;//一个没有bind的text控件和其后的一个带bind的控件被转换为微信输出中的一行
//其中前者的text作为提示词直接输出
with wxTestCTt1 row 0 col c0 web n type text text='说明:',width=100;
//后者将接收事件响应函数中输出到所绑定的数据名testIn1的值拼接到提示词之后
with wxTestCTt1 row 0 col c1 web n bind testIn1 type text width=500;//两个不带绑定的控件,被提取为操作,作为子菜单动态添加到容器表测试的菜单中
//此时,如果用户输入1,则执行wxTestCTAccept命令;输入2,则执行wxTestCTReject,同时将参数合并到两命令的输入流中
with wxTestCTt1 row 1 col c0 web n type a width=80,text='接受',motion=cmd,demand=wxTestCTAccept,params={'active':'accept'};
with wxTestCTt1 row 1 col c1 web n type a width=80,text='拒绝',motion=cmd,demand=wxTestCTReject,params={'active':'reject'};

容器表的输出在大多数情况下是比较简单的:

  • 按一个提示控件和一个数据控件成对提取,然后在输出时,将提示与数据控件的实时值拼接为一行

  • 操作按钮提取为动态生成的菜单中的一项

但是,有一种容器表就会非常麻烦了,那就是流程,如报销审批,各环节都可录入意见、执行同意或拒绝操作,但绝不能让部门经理的同意操作取代掉总经理的同意操作。即一个流程是共享读、分段操作的,即所有信息都能看到,但输入和可点击的操作按钮是按任务流转到执行人才能操作自己所负责的那一部分的。所以流程的容器表的输入输出控制是非常麻烦的,需要微信机器人跟踪流程的流转来确定该如何动态控制输入、输出与操作菜单。本文暂不展开。

数据表输出

web端的数据表一般是下面这样的:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-sSVHRwQE-1636512124351)(http://115.29.52.95:10002/images/wxRobot-1-5.png)]

包括三个部分:

  • 最上面的工具条【多见于容器表,数据表用的比较少】

  • 查询条件设置面板,包括相应的查询条件设置和一个【搜索】按钮,以实现条件查询

  • 分页的数据列表,但其分页需要web端的分页控件配合来实现;此外,每行数据还可以执行多种操作

由于带查询的分页数据表是针对web端定制的,所以其就不如容器表这么简单的就可以转换给微信机器人使用。所以微信机器人所使用的数据表,一般是web端数据表的简化复制品,即从web的数据表定义中复制过来,然后去掉:

  • 查询面板【因为前面已经说过了:微信机器人输入输出相分离】,条件查询当然也可以实现,但需要配合下节的交互式输入,目前暂不考虑

  • 分页控件,微信机器人根本就没有前端界面,所以web界面中的前端分页后端配合的机制是无法实现的,因此微信机器人中的数据表改由后台来控制分页,默认每页8行数据

  • 限制每行只能有一个操作,这个原因很简单,数据表就是一个多行的输出,如果每行再有两个或以上的操作,那菜单显示与选中的操作就太复杂了

同时,由于数据表是一个多行输出,而考虑到手机宽度很小,所以数据表中的每一列数据都会转成和容器表中相同的一行【提示:值】来显示,所以数据表中的每一行就转换为一块,如下图中的第二个输出:

显然,用于微信机器人的数据表的信息密度是和不能和web端一样的,必须得精干再精干一些。

上图的数据表在web文件中的定义是:

//数据表
web wxTestDT type div;
web wxTestDTt1 parent wxTestDT type table title="noUsed";
with wxTestDTt1 col taskID head taskID hide=true;
with wxTestDTt1 col taskName head 工作内容 width=160;
with wxTestDTt1 col taskState head 状态 width=60;
with wxTestDTt1 col op head 操作 web n type awidth=60,motion=cmd,demand=wxTest,text='查看',require=[{"paramName":"taskID"}];

大家注意观察这个数据表的定义,再和上面的实际输出进行对比,就能观察到数据表实际定义了四列,其中:

  • 工作内容和状态这两列正常显示了出来

  • taskID这一列被定义为hide,所以没有显示,其主要用于保存每行任务所对应的任务ID,以提供给【查看】操作,使得用户在选择了相应的行后可以正确的显示出相应的任务

  • 操作这一列,也没有显示,但笔者在列表后又按了一个1,其实就相当于请求执行第一行的【查看】按钮所对应的wxTest命令,并使用了第一行隐藏起来的taskID进行调用,以查看该任务的详情

命令输出

在web界面中,命令几乎不会独立出现,基本都是依附于容器表和数据表的,这是因为命令没有自己的界面,所以需要容器表和数据表来提供输入输出和用户交流,所以不需要任何输入输出就意味着这是一个有着清晰目的的固定指令。这种脱离上下文的固定指令一般都是系统动作,如个人的登出、系统的关闭、热机刷新等等。

注:即便是【热机刷新】,笔者都制作了一个提示界面和一个按钮【还带有操作前确认】,让用户在执行这种对系统有重大意义的操作前冷静再冷静,确认是真要这么干

但在微信机器人的ui中,由于其输入与输出相分离,所以独立的命令就有了意义,如前面说过的【新成员注册】功能就是一个命令,因为其不需要输出。

严格来说,【新成员注册】也不是不需要输出,因为总是需要一个执行结果的提示吧。但考虑到这样的输出既非常简单,使用起来又是非常频繁的,如果每个独立的命令就为了一个执行结果提示还得制作一个界面,显然是太过低效了。所以针对执行结果的提示,jxTMS中特别定义了一个名为execResultDescr的输出变量,只要是向其输出,jxTMS就会自动通过微信机器人发送给当前用户。

注1:如果web界面未定义绑定了execResultDescr的输出控件,则数据会发送到前端作为本地变量保存,即web界面中如果定义了绑定了execResultDescr的输出控件,则该控件显示用户输出内容;如果未定义,则浏览器中jxTMS前端的运行环境中会增加一个名为execResultDescr的本地变量

注2:如果是静态web界面,则execResultDescr会放入请求结果中

对于捆绑给带有界面的容器表的命令,可以正常使用self.setOutput函数输出,由于容器表可能有很多数据项,而其捆绑的命令可能只会涉及到其中一部分,所以命令的输出是增量的,即jxTMS会收集命令中用self.setOutput函数输出的那些数据项,并只将其与对应的提示成对输出。

主动提示

我们到目前所讲述的都是和某个用户在和其会话中向对方发送消息,如果在公告、主动通知【如有新任务到达等】等非会话场景下,向其发送消息则如下调用:

#发送消息
self.sendWXMsg(db,ctx,appName,peopleAbbr,msg,vs)

其中:

  • appName:就是机器人名

  • peopleAbbr:成员在组织中的别名【没有重名就是其姓名】,不给则是发给所有人

  • msg:以花括号对为占位符的消息模板。如:你有新工作:{},发布人是:{}

  • vs:变参的值数组,就是用vs中的值,逐一替换掉msg中的花括号对

如:

self.sendWXMsg(db,ctx,'tms','测试用户123'.decode('utf-8'),'你有新工作:{},发布人是:{}'.decode('utf-8'),'起来干活了'.decode('utf-8'),'你老板'.decode('utf-8'))

则,用户【测试用户123】就会在企业微信中收到tms机器人发布的:

你有新工作:起来干活了,发布人是:你老板

还可以发送图片和文件:

#发送图片
self.sendWXMsg(db,ctx,appName,peopleAbbr,path)
#发送文件
self.sendWXMsg(db,ctx,appName,peopleAbbr,path)

jxTMS目前已打包为docker容器,可以下拉jxTMS的docker镜像并按jxTMS使用示例尝试使用。

用企业微信机器人做交互式前端-输出相关推荐

  1. 用企业微信机器人做交互式前端-交互式输入

    用企业微信机器人做交互式前端-交互式输入 本系列所有文章请访问:概述 概述 jxTMS所实现的微信机器人其工作的逻辑闭环是: 1.微信机器人向用户显示菜单 2.用户输入菜单选项 3.jxTMS提示用户 ...

  2. 用企业微信机器人做交互式前端-权限

    用企业微信机器人做交互式前端-权限 本系列所有文章请访问:概述 权限 微信机器人只是一个前端的ui,所以其权限管控还是依赖于jxTMS既有的权限管控体系:角色. 在jxTMS中,用户点击后打开一个操作 ...

  3. 用企业微信机器人做交互式前端-添加微信功能

    用企业微信机器人做交互式前端-添加微信功能 本系列所有文章请访问:概述 开通机器人 微信机器人先要在企业微信的后台开通: 创建应用 获取该应用的发送秘钥 生成该应用接收令牌 生成该应用接收秘钥 注1: ...

  4. 企业微信机器人还能这么玩?

    英剧<黑镜:圣诞特别篇>中有一集讲到女主日程非常忙碌,同时又对自己要求很高,于是选择在代码世界复制了一个自己,作为自己的"智能管家",这个智能管家堪称完美,完全熟悉女主 ...

  5. PowerShell 实现企业微信机器人推送消息

    前言企业微信机器人 在ARMS告警管理中创建企业微信机器人后,您可以在通知策略中指定对应的企业微信群用于接收告警.当通知策略的匹配规则被触发时,系统会自动向您指定的企业微信群发送告警通知.企业微信群收 ...

  6. tp5框架实现推送消息到企业微信机器人(从需求分析、方案设计、研发阐述)

    需求 目前需要接入消息推送的模块是任务中心,原因是任务中心是多人协作处理某个特定小组内的所有分析任务,在整个分析的过程中,一个任务的生命周期会经历若干个关键的状态节点, 当分析师或审批人触发了相关动作 ...

  7. 企业微信机器人发送消息

    背景:之前用钉钉机器人可以发送消息,可以将线上的告警通知发送到消息群中,后来企业微信也支持在群组中增加机器人了,钉钉和企业微信机器人的使用很相似,都是使用webhook的方式来进行实现的,话不多说,咱 ...

  8. GitLab cicd 流水线添加企业微信机器人消息通知

    GitLab cicd 流水线添加企业微信机器人消息通知 描述 公司部门需要我们在进行项目发布的时候,希望能通过企业微信机器人,来告诉测试,是发布还是项目出来了问题,因为项目没有做无感知处理,所以每次 ...

  9. python发微信提醒天气_通过Python发送天气信息给企业微信机器人

    一.添加机器人 原文链接:https://www.dqzboy.com 二.创文章来源(Source):浅时光博客建py脚本 #!/usr/bin/python3 # -*- coding: utf- ...

最新文章

  1. 《OpenStack实战》——第1章 介绍OpenStack 1.1OpenStack是什么
  2. 数据库生成T4模版在代码生成中的应用心得
  3. Android 实训:日志(基于外部存储音乐播放器V01)
  4. FAQ接口自动化_转载参考
  5. 数据结构与算法(C++)– 堆排(Heap Sort)
  6. php判断三角形类型,C#_C#判断三角形的类型,题目描述: 输入三角形的三 - phpStudy...
  7. java初学编程题及答案_Java 入门编程题答案记录(记录)
  8. CANOpen定时器
  9. Vue报错:3 errors and 0 warnings potentially fixable with the `--fix` option.
  10. Ogre:ManualObject
  11. ASP.NET页面传值方式
  12. CCF NOI1044 最近元素
  13. python目标函数_python遗传算法目标函数怎么编
  14. BigGAN_用于高保真自然图像合成的大规模 GAN 训练
  15. Archlinux电源管理
  16. jwplayer html插件,Angular4使用经验之:jwplayer插件运用到angular4插件普适法
  17. openfoam前处理:并行计算decomposeParDict和setFieldsDict
  18. velodyne16点云特征分类
  19. 浅谈如何使用Google reCAPTCHA进行人机验证
  20. 传统巨头抢占区块链场景高地 医疗、汽车、金融成为热门赛道

热门文章

  1. matlab模拟出现较大误差是什么原因,求助大神,使用BP神经网络预测数据,为什么误差很大?...
  2. 瓶子里的萤火虫动画特效
  3. lwCs 的代码已开源
  4. 多人在线网络游戏的同步算法一 基础篇
  5. net 6.1 linux 网络接口配置 ifconfig
  6. 用JS实现图片切换、定时器、轮播图
  7. Thymeleaf配置及入门
  8. 郑愁予-《美丽的错误》
  9. ERROR: Command /home/ubuntu/anaconda3/bin/python -u -c 'import setuptools, tokenize;__file__='''/
  10. Telnet,命令级别,DHCP (动态主机配置协议),DHCP租期, 地址池,全局配置,接口配置,DHCP中继代理,网络三要素,路由项匹配算法