初始化服务器
本文介绍的完整代码参见https://github.com/hejinzhi/wechatServer
- 输入npm init 初始化项目,全部采用默认值即可。
npm init
- 在根目录建立tsconfig.json,代码如下
{
"compilerOptions": {
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"lib": [
"es6"
],
"outDir": "build", //编译后文件输出到build这个文件夹内
"module": "commonjs",
"target": "es5"
},
"include": [
"*.ts"
],
"exclude": [
"node_modules"
]
}
- 安装 Express 框架和 typing 文件
npm install express @types/express @types/node
- 在根目录建立app.ts文件,输入以下代码,这样,一个简单的服务器就搭建完毕了。
import * as express from 'express';
const app=express();
app.get('/',(req,res)=>{
res.send('我已经收到您的请求了');
});
app.listen(3000,'localhost',()=>{
console.log('server running on http://localhost:3000');
});
- 但是nodejs只会认js,怎么把ts转换成js呢?使用vs code的编译功能即可。首先先全局安装typescript。
npm install -g typescript
然后在vs code中按下快捷键ctrl+shift+b,调出编译选项。选项一是根据 tsconfig 的配置把指定的ts编译成js,该动作只会执行一次。选项二是监视文件的变化,如发现有变化,立刻执行编译动作。
-
选择选项二,就会看到vs code已经把ts文件编译成js文件,并放到build文件夹内
-
执行node build/app.js 运行,出现以下提示证明服务器已经成功运行起来。
打开浏览器,输入http://localhost:3000/就可以看到服务器返回信息了,这样一个最简单的服务器就搭建完毕了。
服务器已经运行起来,我们稍作调整,让服务器可以提供静态资源的访问。先在根目录下建立文件夹public,放一张图片进去(如1.png),然后修改app.ts如下:
import * as express from 'express';
const app=express();
app.use(express.static('public'));
app.get('/',(req,res)=>{
res.send('我已经收到您的请求了');
});
app.listen(3000,'localhost',()=>{
console.log('server running on http://localhost:3000');
});
在浏览器输入http://localhost:3000/1.png,我们会发现报错。原因是我们是使用node来启动app.js的。app.js的代码已经发生了改变,我们需要ctrl+c中断服务,node build/app.js重新执行才可以。
重新运行后,我们会发现可以访问1.png这张图片了。
- 代码每次变更,都需要重启服务器,显得非常麻烦。我们可以nodemon解决这个问题。先全局安装nodemon。
npm install -g nodemon
使用nodemon启动app.js
nodemon build/app.js
这样,每次ts有变化,编译器会自动把它编译成js,js有变化,服务器就会自动重启。现在我们可以愉快的进行后续的开发了。
开始企业微信开发
- API官方文档
- 要想使用微信的api,必须先向微信服务器申请一个access token.
第三步:获取access_token
请求方式:GET(HTTPS)
请求URL:https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=ID&corpsecret=SECRECT
注:此处标注大写的单词ID和SECRET,为需要替换的变量,根据实际获取值更新。其它接口也采用相同的标注,不再说明。
-
登录企业微信后台,新建一个应用,应用的名字和图标可自行设置。
创建后,点击应用进入详情页,就可以看到AgentId和Secret。这个Secret就是上面提到的corpsecret。
corpid在这里“我的企业”最底部查到
- 安装request-promise模块,用于向微信服务器发起请求
npm install request-promise @types/request-promise request @types/request --save
在跟目录建立lib文件夹,在lib内新建Request.ts,对request-promise进行简单的封装。
import * as rp from 'request-promise';
export class Request{
public static get (url:string){
let options={
method: 'GET',
uri: url,
json: true
};
return rp(options);
}
public static post (url:string,body:any){
let options={
method: 'POST',
uri: url,
body: body,
json: true
};
return rp(options);
}
}
- 在根目录建立wechat文件夹,把跟微信相关的文件都放在一起
- 在wechat文件夹内新建config.ts,把一些常量写在里面
export const baseUrl='https://qyapi.weixin.qq.com/cgi-bin/';
export const ApiUrl={
getToken: baseUrl+'gettoken',
send:baseUrl+'/message/send',
};
export const AlertModule ={
corpid:'wx227****', //修改为对应的id
corpsecret:'3dDxXtr*****', //修改为对应的secret
agentId:'1000005'
}
- 在wechat文件夹内新建util.ts工具类,用于获取,刷新,本地化存储token,关键代码如下(因代码过长,只截取部分关键代码,完整代码请到这里查看)
public static async saveToken() {
let token: Token;
try {
let data: Token = await Request.get(ApiUrl.getToken + `?corpid=${AlertModule.corpid}&corpsecret=${AlertModule.corpsecret}`);
data.expires_time = new Date().getTime() + data.expires_in * 1000;
token = data;
fs.writeFileSync(__dirname + '/token.txt', JSON.stringify(token));
} catch (e) {
console.log('get token error');
throw new Error('get token error');
}
}
- 在wechat文件夹内新建wechat.ts类,把相关的操作都封装在wechat类中
import { NewsMessage, Articles } from './../model/NewsMessage';
import { TextMessage } from './../model/TextMessage';
import { Util } from './utils';
import { ApiUrl } from './config';
import { Request } from './../lib/request';
export class Wechat {
constructor() {
}
public static async sendTextMessage(toUser: string, content: string, agentId: number = 1000005, safe: number = 0) {
let token = await Util.getToken();
let body: TextMessage = {
touser: toUser,
msgtype: 'text',
agentid: agentId,
text: {
content: content
},
safe: safe
};
return Request.post(ApiUrl.send + `?access_token=${token}`, body);
}
public static async sendNewsMessage(toUser: string, news:Articles[], agentId: number = 1000005, safe: number = 0) {
let token = await Util.getToken();
let body: NewsMessage = {
touser: toUser,
msgtype: 'news',
agentid: agentId,
news:{
articles:news
}
};
return Request.post(ApiUrl.send + `?access_token=${token}`, body);
}
}
- 让我们修改一下app.ts,让后台给用户推送一条文本消息吧。
import { Wechat } from './wechat/wechat';
import * as express from 'express';
const app=express();
app.use(express.static('public'));
app.get('/',async (req,res)=>{
await Wechat.sendTextMessage('FE717','我的第一条推送消息');
res.send('已成功发出一条消息');
});
app.listen(3000,'localhost',()=>{
console.log('server running on http://localhost:3000');
});
执行nodemon build/app.js,在浏览器输入http://localhost:3000/即可推送消息。
- 至此,一个简单的企业微信消息推送就完成了。剩下的就是根据业务去写推送逻辑了,本次介绍到此为止,如读者有疑问,可以通过qq:504151911跟我联系,谢谢!