中文版 (Chinese Version of this walkthrough)
This tutorial covers a basic sample using WeChat JSSDK and TypeScript together.
-
Install node.js.
-
Get your own domain and node.js server. See Create a Node.js Application on Web App for using Azure.
-
Finish step 1 - binding domain name. If you don't have an official WeChat account, you can apply for a test account. Keep your appId, appsecret and host URL at hand.
Create a new package,
mkdir wxapp
cd wxapp
npm init
In scripts
in package.json
, add,
"scripts": {
"start": "node index.js",
"build-ts": "node ./node_modules/typescript/bin/tsc"
},
Install dependencies (express, ejs, request, and sha1),
npm install --save express ejs request sha1
Install TypeScript and type definition files for installed packages,
npm install --save-dev typescript @types/node @types/express @types/request @types/sha1
Since DefinitelyTyped does not have type definitions for WeChat JSSDK at the mement , copy the types
folder containing wechat.d.ts to the project root folder (wxapp
).
Add TypeScript configuration file tsconfig.json
under the project root folder,
{
"compilerOptions": {
"target": "es6", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', or 'ESNEXT'. */
"module": "commonjs", /* Specify module code generation: 'commonjs', 'amd', 'system', 'umd' or 'es2015'. */
"moduleResolution": "node" /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */
}
}
You can add other compiler flags (e.g. strict
) based on your own need.
According to WeChat documentation, using WeChat JSSDK requires getting jsapi_ticket from WeChat server on our server side and then using wx.config
to get API permission on the cliend side. A rough flow looks like below,
Add index.ts
in the root folder,
import * as express from "express";
import * as request from "request";
import sha1 = require("sha1");
let app = express();
// Insert metadata
let appId = ''; // Insert your appId
let appsecret = ''; // insert your appsecret
let url = ''; // insert host url, e.g. http://wxapp.azurewebsites.net/
let nonceStr = ''; // insert any string
// define an interface containing params for wx.config
interface configObj {
appId: string,
timestamp: string,
nonceStr: string,
signature: string
}
// handshake with WeChat server and get signature for wx.config
function getWXConfig(cb) {
request.get('https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid='+appId+'&secret='+appsecret, (err, res, body) => {
request.get('https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token='+JSON.parse(body).access_token+'&type=jsapi', (err, res, body) => {
let ticket = JSON.parse(body).ticket;
let o: configObj = {
appId: appId,
nonceStr: nonceStr,
timestamp: new Date().getTime() / 1000 + '',
signature: ''
};
o.signature = sha1('jsapi_ticket='+ticket+'&noncestr='+o.nonceStr+'×tamp='+o.timestamp+'&url='+url).toString();
cb(o);
});
});
}
app.engine('.html', require('ejs').__express); // set up ejs as view engine
app.set('views', __dirname + '/views'); // set views dir
app.set('view engine', 'html'); // use .html for ejs files
app.use(express.static('public')) // expose assets in /public
app.get('/', function (req, res) {
getWXConfig(config => {
// handshake with WeChat server and render index.html with the returned signature
res.render('index', {
appId: config.appId,
timestamp: config.timestamp,
nonceStr: config.nonceStr,
signature: config.signature,
});
})
});
app.listen(8080);
Fill in your appId and other metadata in index.ts
,
// Insert metadata
let appId = ''; // Insert your appId
let appsecret = ''; // insert your appsecret
let url = ''; // insert host url, e.g. http://wxapp.azurewebsites.net/
let nonceStr = 'hellotypescript'; // insert any string
Our server will get jsapi_ticket from WeChat server through getWXConfig
, and render the signature for wx.config in client side html through ejs.
Within index.ts
, we've defined our client side files to be stored in /views
(html
to be rendered by ejs) and /public
(other files). The next step will cover client side pages.
app.set('views', __dirname + '/views'); // set views dir
app.use(express.static('public')) // expose assets in /public
Create views
folder under the root folder and add index.html
,
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title> WeChat TypeScript sample </title>
</head>
<body>
<script type="text/javascript" src="http://res.wx.qq.com/open/js/jweixin-1.0.0.js"></script>
<script type="text/javascript">
wx.config({
debug: false,
appId: '<%=appId%>',
timestamp: '<%=timestamp%>',
nonceStr: '<%=nonceStr%>',
signature: '<%=signature%>',
jsApiList: [
'checkJsApi',
'onMenuShareTimeline',
'onMenuShareAppMessage',
'onMenuShareQQ',
'onMenuShareWeibo',
'onMenuShareQZone',
'hideMenuItems',
'showMenuItems',
'hideAllNonBaseMenuItem',
'showAllNonBaseMenuItem',
'translateVoice',
'startRecord',
'stopRecord',
'onVoiceRecordEnd',
'playVoice',
'onVoicePlayEnd',
'pauseVoice',
'stopVoice',
'uploadVoice',
'downloadVoice',
'chooseImage',
'previewImage',
'uploadImage',
'downloadImage',
'getNetworkType',
'openLocation',
'getLocation',
'hideOptionMenu',
'showOptionMenu',
'closeWindow',
'scanQRCode',
'chooseWXPay',
'openProductSpecificView',
'addCard',
'chooseCard',
'openCard'
]
});
</script>
<script type="text/javascript" src="/js/demo.js"></script>
</body>
</html>
index.html
includes the JSSDK (http://res.wx.qq.com/open/js/jweixin-1.0.0.js
) and a simple demo (/js/demo.js
). The embedded JavaScript includes rendered signature from getWXConfig
and uses wx.config
to get API permission from WeChat.
Create public/js
folder under the root folder, and add demo.ts
,
wx.ready(() => {
// open specifc location on map
wx.openLocation({
latitude: 0,
longitude: 0,
name: '',
address: '',
scale: 1,
infoUrl: ''
});
})
wx.error((err) => alert(err));
In this simple demo, we only use wx.openLocation
to open a map, but you can try calling any API from JsApiList
in demo.ts
.
Transpile .ts
files to .js
,
npm run build-ts
Deploy the project to server.
After deployment, translate your URL to QR code and open 微信扫一扫 to see the demo in action.