Open Juliiii opened 5 years ago
近日发现了一个比较有趣的库,co-wechat 。
该库封装了微信公共平台消息接口,并将其作为中间件的形式,配合express,koa等框架使用。
所以尝试着配合腾讯云Serverless,api网关以及该库,做一个自动回复的机器人。
根据微信公众平台技术文档中的指引进行了 个人订阅号的申请,开发者基本配置。以及根据腾讯云云函数文档完成云函数的创建以及Api网关触发器的配置,这里就不一一赘述。跟着文档做就行了。
一开始,跟着co-wechat以及serverless-http的文档写出来以下代码:
"use strict"; const Koa = require("koa"); const serverless = require("serverless-http"); const wechat = require("co-wechat"); const config = { token: 'token', appid: 'appid', encodingAESKey: 'encodinAESKey', }; const app = new Koa(); app.use( wechat(config).middleware(async (message, ctx) => { console.log(message); // 微信输入信息就是这个 message if (message.FromUserName === "作者") { // 回复屌丝(普通回复) return "hehe"; } else if (message.MsgType === "text") { //你也可以这样回复text类型的信息 return { content: "diaosi", type: "text" }; } else if (message.FromUserName === "hehe") { // 回复一段音乐 return { type: "music", content: { title: "来段音乐吧", description: "一无所有", musicUrl: "http://mp3.com/xx.mp3", hqMusicUrl: "http://mp3.com/xx.mp3" } }; } else if (message.FromUserName === "kf") { // 转发到客服接口 return { type: "customerService", kfAccount: "test1@test" }; } else { // 回复高富帅(图文回复) return [ { title: "你来我家接我吧", description: "这是女神与高富帅之间的对话", picurl: "http://nodeapi.cloudfoundry.com/qrcode.jpg", url: "http://nodeapi.cloudfoundry.com/" } ]; } }) ); const handler = serverless(app); exports.main_handler = async (event, context, callback) => { return await handler(event, context); };
并上传到腾讯云Serverless中,同时在微信公众号发送了一个词语,触发了一次云函数:
但是,我却得到了这个错误。
错误可能情况有如下几种:
1、云函数执行错误,这个可以否掉了,因为看起来并不像
2、代码逻辑错误,这个也可以否掉了,基本都是看文档,CV文档的demo代码,流行库的demo代码基本没啥问题。
3、微信公众号的相关配置错误,这个也可以否掉,跟着文档一步步走的,除非我的阅读理解有问题。
4、依赖的第三方库,co-wechat以及serverless-http的处理有问题。
错误可能情况4比较有可能,但是线上的日志查看已经无法继续定位问题,不过幸好腾讯云Serverless还提供了另一个利器:
Tencent Serverless Toolkit for VS Code
所以,我开始使用该VS Code插件进行本地调试。
为了完全模拟微信公众号发来的请求信息,我现在控制台的日志中,CV了一份请求信息,并使用VS Code插件新增了一个Api网关的测试模板。
并在.vscode文件夹下,新建一个launch.json,使用快捷键生成了debugger的scf的调试配置,并加上了cwd,指定工作空间。
由于怀疑是co-wechat库的问题,所以去node_modules下的co-wehcat的源码中看了看,发现他们源码中的确有返回:
但是是哪里出了问题呢,所以我在这附近打了个 断点。
并F5,选择了我新建的测试模板,开始debug。
跳到断点处,发现,这个库返回这个错误的原因在于这一句if代码判断微信发给云函数的签名,即signature与库自己算出来的不一致。然后我再在watch栏添加了这两个值,发现微信发给云函数的签名,不见了!
为什么会不见呢?
我的测试模板中,是明确带着的,大家可以回到上面的测试模板的图可以看到queryString中的signature是有值的。
我再在watch栏查看了ctx.query的值。
空对象!
那问题就基本可以定位在 serverless-http这个库了。
去到该库的源代码,在create-request文件中发现了如下代码:
一目了然。原因为:serverless-http并没有很好兼容腾讯云Api网关的请求格式。腾讯云Api网关的请求格式中,queryString存放着请求的queryString参数,但是serverless-http只取图中两个参数名的参数作为express,koa等的query参数,没有取queryString参数的值
靠着Tencent Serverless Toolkit for VS Code定位了到了问题,所以我在代码中做下兼容,即解决了这个问题。并运行成功,做了个简单的自动回复机器人~
exports.main_handler = async (event, context, callback) => { event.queryStringParameters = event.queryString; return await handler( { ...event, queryStringParameters: event.queryString }, context ); };
起
近日发现了一个比较有趣的库,co-wechat 。
该库封装了微信公共平台消息接口,并将其作为中间件的形式,配合express,koa等框架使用。
所以尝试着配合腾讯云Serverless,api网关以及该库,做一个自动回复的机器人。
承
根据微信公众平台技术文档中的指引进行了 个人订阅号的申请,开发者基本配置。以及根据腾讯云云函数文档完成云函数的创建以及Api网关触发器的配置,这里就不一一赘述。跟着文档做就行了。
一开始,跟着co-wechat以及serverless-http的文档写出来以下代码:
并上传到腾讯云Serverless中,同时在微信公众号发送了一个词语,触发了一次云函数:
但是,我却得到了这个错误。
错误可能情况有如下几种:
1、云函数执行错误,这个可以否掉了,因为看起来并不像
2、代码逻辑错误,这个也可以否掉了,基本都是看文档,CV文档的demo代码,流行库的demo代码基本没啥问题。
3、微信公众号的相关配置错误,这个也可以否掉,跟着文档一步步走的,除非我的阅读理解有问题。
4、依赖的第三方库,co-wechat以及serverless-http的处理有问题。
错误可能情况4比较有可能,但是线上的日志查看已经无法继续定位问题,不过幸好腾讯云Serverless还提供了另一个利器:
Tencent Serverless Toolkit for VS Code
所以,我开始使用该VS Code插件进行本地调试。
转
为了完全模拟微信公众号发来的请求信息,我现在控制台的日志中,CV了一份请求信息,并使用VS Code插件新增了一个Api网关的测试模板。
并在.vscode文件夹下,新建一个launch.json,使用快捷键生成了debugger的scf的调试配置,并加上了cwd,指定工作空间。
由于怀疑是co-wechat库的问题,所以去node_modules下的co-wehcat的源码中看了看,发现他们源码中的确有返回:![image-20190824145920027](https://user-images.githubusercontent.com/23744602/63634418-ce452280-c688-11e9-9549-309e7124871f.png)
但是是哪里出了问题呢,所以我在这附近打了个 断点。
并F5,选择了我新建的测试模板,开始debug。
跳到断点处,发现,这个库返回这个错误的原因在于这一句if代码判断微信发给云函数的签名,即signature与库自己算出来的不一致。然后我再在watch栏添加了这两个值,发现微信发给云函数的签名,不见了!
为什么会不见呢?
我的测试模板中,是明确带着的,大家可以回到上面的测试模板的图可以看到queryString中的signature是有值的。
我再在watch栏查看了ctx.query的值。
空对象!
那问题就基本可以定位在 serverless-http这个库了。
去到该库的源代码,在create-request文件中发现了如下代码:
一目了然。原因为:serverless-http并没有很好兼容腾讯云Api网关的请求格式。腾讯云Api网关的请求格式中,queryString存放着请求的queryString参数,但是serverless-http只取图中两个参数名的参数作为express,koa等的query参数,没有取queryString参数的值
合
靠着Tencent Serverless Toolkit for VS Code定位了到了问题,所以我在代码中做下兼容,即解决了这个问题。并运行成功,做了个简单的自动回复机器人~