{"id":13564221,"url":"https://github.com/node-webot/co-wechat","last_synced_at":"2025-04-04T09:08:24.501Z","repository":{"id":21826535,"uuid":"25149508","full_name":"node-webot/co-wechat","owner":"node-webot","description":"Wechat for Koa","archived":false,"fork":false,"pushed_at":"2019-08-26T01:40:28.000Z","size":52,"stargazers_count":427,"open_issues_count":9,"forks_count":91,"subscribers_count":16,"default_branch":"master","last_synced_at":"2025-03-28T08:06:24.016Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/node-webot.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2014-10-13T08:10:16.000Z","updated_at":"2024-08-24T05:01:13.000Z","dependencies_parsed_at":"2022-07-16T14:18:14.600Z","dependency_job_id":null,"html_url":"https://github.com/node-webot/co-wechat","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/node-webot%2Fco-wechat","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/node-webot%2Fco-wechat/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/node-webot%2Fco-wechat/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/node-webot%2Fco-wechat/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/node-webot","download_url":"https://codeload.github.com/node-webot/co-wechat/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247149501,"owners_count":20891954,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-08-01T13:01:28.251Z","updated_at":"2025-04-04T09:08:24.479Z","avatar_url":"https://github.com/node-webot.png","language":"JavaScript","funding_links":[],"categories":["JavaScript"],"sub_categories":[],"readme":"co-wechat [![NPM version](https://badge.fury.io/js/co-wechat.png)](http://badge.fury.io/js/co-wechat) [![Build Status](https://travis-ci.org/node-webot/co-wechat.png?branch=master)](https://travis-ci.org/node-webot/co-wechat) [![Dependencies Status](https://david-dm.org/node-webot/co-wechat.png)](https://david-dm.org/node-webot/co-wechat) [![Coverage Status](https://coveralls.io/repos/node-webot/co-wechat/badge.png)](https://coveralls.io/r/node-webot/co-wechat)\n======\n\n微信公众平台消息接口服务中间件\n\n## 升级注意事项\n\n### 支持 Koa2\n\n如果仍然使用 Koa1，请使用co-wechat@1.x。\n\n### middleware 方法变更\n\nmiddleware() 方法接受一个 async function 作为参数。\n\n```js\napp.use(wechat(config).middleware(async (message, ctx) =\u003e {\n  // TODO\n}));\n```\n\n### 上下文与返回值变更\n\n现在的上下文不再是原始的 请求上下文，而仅仅是 message 对象。\n\n业务的返回值现在直接返回即可，无需关注上下文。比如：\n\n```js\nasync (message, ctx) =\u003e {\n  return 'Hello world!';\n}\n```\n\n### 取消 session 的支持\n\n不再支持 session 的功能。如需使用 session 功能，建议使用 redis 自行处理逻辑，取 message.FromUserName 作为 key，取一个合适的 ttl 时间即可。\n\n## 功能列表\n\n- 自动回复（文本、图片、语音、视频、音乐、图文）\n\n## Installation\n\n```sh\n$ npm install co-wechat\n```\n\n## Use with koa2\n\n```js\nconst wechat = require('co-wechat');\n\nconst config = {\n  token: 'THE TOKEN',\n  appid: 'THE APPID',\n  encodingAESKey: 'THE ENCODING AES KEY'\n};\n\napp.use(wechat(config).middleware(async (message, ctx) =\u003e {\n  // 微信输入信息就是这个 message\n  if (message.FromUserName === 'diaosi') {\n    // 回复屌丝(普通回复)\n    return 'hehe';\n  } else if (message.FromUserName === 'text') {\n    //你也可以这样回复text类型的信息\n    return {\n      content: 'text object',\n      type: 'text'\n    };\n  } else if (message.FromUserName === 'hehe') {\n    // 回复一段音乐\n    return {\n      type: \"music\",\n      content: {\n        title: \"来段音乐吧\",\n        description: \"一无所有\",\n        musicUrl: \"http://mp3.com/xx.mp3\",\n        hqMusicUrl: \"http://mp3.com/xx.mp3\"\n      }\n    };\n  } else if (message.FromUserName === 'kf') {\n    // 转发到客服接口\n    return {\n      type: \"customerService\",\n      kfAccount: \"test1@test\"\n    };\n  } else {\n    // 回复高富帅(图文回复)\n    return [\n      {\n        title: '你来我家接我吧',\n        description: '这是女神与高富帅之间的对话',\n        picurl: 'http://nodeapi.cloudfoundry.com/qrcode.jpg',\n        url: 'http://nodeapi.cloudfoundry.com/'\n      }\n    ];\n  }\n}));\n```\n\n\u003e 备注：token 在微信平台的开发者中心申请\n\n## 开启调试模式（用于[微信公众平台接口调试工具](https://mp.weixin.qq.com/debug/cgi-bin/apiinfo)调试)\n```js\n//构造函数的第二个函数isDebug参数，为true或别的正值时表示开启，推荐用配置或是环境变量的方式传参\nwechat(config, true)\n```\n\n配置成debug模式后，用微信公众平台接口调试工具发送POST请求(比如消息接口调试-文本消息)时返回结果不会提示Invalid signature\n\n### 回复消息\n\n当用户发送消息到微信公众账号，自动回复一条消息。这条消息可以是文本、图片、语音、视频、音乐、图文。详见：[官方文档](http://mp.weixin.qq.com/wiki/index.php?title=发送被动响应消息)\n\n#### 回复文本\n```js\nasync (message, ctx) =\u003e {\n  return 'Hello world!';\n}\n// 或者\nasync (message, ctx) =\u003e {\n  return {type: \"text\", content: 'Hello world!'};\n}\n```\n#### 回复图片\n\n```js\nasync (message, ctx) =\u003e {\n  return {\n    type: \"image\",\n    content: {\n      mediaId: 'mediaId'\n    }\n  };\n}\n```\n#### 回复语音\n\n```js\nasync (message, ctx) =\u003e {\n  return {\n    type: \"voice\",\n    content: {\n      mediaId: 'mediaId'\n    }\n  };\n}\n```\n#### 回复视频\n```js\nasync (message, ctx) =\u003e {\n  return {\n    type: \"video\",\n    content: {\n      mediaId: 'mediaId',\n      thumbMediaId: 'thumbMediaId'\n    }\n  };\n}\n```\n#### 回复音乐\n```js\nasync (message, ctx) =\u003e {\n  return {\n    title: \"来段音乐吧\",\n    description: \"一无所有\",\n    musicUrl: \"http://mp3.com/xx.mp3\",\n    hqMusicUrl: \"http://mp3.com/xx.mp3\"\n  };\n}\n```\n#### 回复图文\n```js\nasync (message, ctx) =\u003e {\n  return [\n    {\n      title: '你来我家接我吧',\n      description: '这是女神与高富帅之间的对话',\n      picurl: 'http://nodeapi.cloudfoundry.com/qrcode.jpg',\n      url: 'http://nodeapi.cloudfoundry.com/'\n    }\n  ];\n}\n```\n\n#### 回复空串\n```js\nasync (message, ctx) =\u003e {\n  return '';\n}\n```\n\n#### 转发到客服接口\n```js\nasync (message, ctx) =\u003e {\n  return {\n    type: \"customerService\",\n    kfAccount: \"test1@test\" //可选\n  };\n}\n```\n\n## 集成到 Egg.js\n\n路由设置\n```js\n// app/router.js\n'use strict';\n\nmodule.exports = app =\u003e {\n  // 将 get/post 请求都转给 home.wechat\n  app.all('/', 'home.wechat');\n};\n```\n\n控制器\n\n```js\n'use strict';\n\nconst wechat = require('co-wechat');\n\nmodule.exports = app =\u003e {\n  class HomeController extends app.Controller {}\n\n  // 因为 Egg 需要用类的形式来组织，而 wechat 是通过 middleware 方法来生成中间件\n  HomeController.prototype.wechat = wechat({\n    token: 'token',\n    appid: 'appid',\n    encodingAESKey: ''\n  }).middleware(async (message, ctx) =\u003e {\n    // TODO\n  });\n\n  return HomeController;\n};\n```\n\n### 相同路由支持多账号\n\n```js\n// app/router.js\n'use strict';\n\nmodule.exports = app =\u003e {\n  // 将 get/post 请求都转给 home.wechat\n  app.all('/wechat/:appid', 'home.prehandle', 'home.wechat');\n};\n```\n\n在前置中间件中预先设置 ctx.wx_token 或 ctx.wx_cryptor：\n\n```js\n'use strict';\n\nconst WXBizMsgCrypt = require('wechat-crypto');\nconst wechat = require('co-wechat');\n\nmodule.exports = app =\u003e {\n  class HomeController extends app.Controller {\n    async prehandle(ctx, next) {\n      const appid = ctx.params.appid;\n      const token = getTokenByAppid(appid);\n      ctx.wx_token = token\n      // 或者\n      const encodingAESKey = getEncodingAESKeyByAppid(appid);\n\n      ctx.wx_cryptor = new WXBizMsgCrypt(token, encodingAESKey, appid);\n      await next();\n    }\n  }\n\n  HomeController.prototype.wechat = wechat({\n    // 当有前置中间件设置 ctx.wx_token 和 ctx.wx_cryptor 时，这里配置随意填写\n    // token: 'token',\n    // appid: 'appid',\n    // encodingAESKey: ''\n  }).middleware(async (message, ctx) =\u003e {\n    // TODO\n  });\n\n  return HomeController;\n};\n```\n\n\u003e 注意，上述的 getTokenByAppid 和 getEncodingAESKeyByAppid 方法根据自己情况请自行提供。\n\n## Show cases\n### Node.js API 自动回复\n\n![Node.js API自动回复机器人](http://nodeapi.diveintonode.org/assets/qrcode.jpg)\n\n欢迎关注。\n\n代码：\u003chttps://github.com/JacksonTian/api-doc-service\u003e\n\n你可以在[CloudFoundry](http://www.cloudfoundry.com/)、[appfog](https://www.appfog.com/)、[BAE](http://developer.baidu.com/wiki/index.php?title=docs/cplat/rt/node.js)等搭建自己的机器人。\n\n## 详细API\n原始API文档请参见：[消息接口指南](http://mp.weixin.qq.com/wiki/index.php?title=消息接口指南)。\n\n## 交流群\nQQ群：157964097，使用疑问，开发，贡献代码请加群。\n\n## 捐赠\n如果您觉得Wechat对您有帮助，欢迎请作者一杯咖啡\n\n![捐赠wechat](https://cloud.githubusercontent.com/assets/327019/2941591/2b9e5e58-d9a7-11e3-9e80-c25aba0a48a1.png)\n\n或者[![](http://img.shields.io/gratipay/JacksonTian.svg)](https://www.gittip.com/JacksonTian/)\n\n## License\nThe MIT license.\n\n## Contributors\n\n```\n\n project  : co-wechat\n repo age : 3 years, 1 month\n active   : 21 days\n commits  : 59\n files    : 10\n authors  :\n    46  Jackson Tian  78.0%\n     6  ifeiteng      10.2%\n     3  lixiaojun     5.1%\n     2  Andrew Lyu    3.4%\n     1  Jealee3000    1.7%\n     1  fancyoung     1.7%\n\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnode-webot%2Fco-wechat","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnode-webot%2Fco-wechat","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnode-webot%2Fco-wechat/lists"}