light-bridge
Version:
LightBridge ===========
285 lines (247 loc) • 6.76 kB
JavaScript
/**
* @file 微信企业号 主动调用模式封装
* @author r2space@gmail.com
*/
;
var light = require("light-framework")
, fs = require("fs")
, path = require("path")
, util = require("util")
, formstream = require("formstream")
, urllib = require("urllib")
, request = light.util.request
, conf = light.util.config.wechat
, sign = require("./sign")
, constant = require("../constant");
var accessToken = undefined
, jsapiTicket = undefined
, expiredToken = 0
, expiredTicket = 0;
/**
* 获取组一览
* @param callback
*/
exports.departments = function(callback) {
fetchAccessToken(function(err, token) {
if (err) {
return callback(err);
}
var url = constant.WECHAT_URL + "/department/list?access_token=" + token;
request(url, function(err, response, body) {
if (err || response.statusCode != 200) {
return callback(err || response.statusCode);
}
callback(err, JSON.parse(body));
});
});
};
/**
* 发送新闻消息
* @param meta
* {
* "touser": "UserID1|UserID2|UserID3",
* "toparty": " PartyID1 | PartyID2 ",
* "totag": " TagID1 | TagID2 ",
* "msgtype": "news",
* "agentid": "1",
* "news": {
* "articles":[
* {
* "title": "Title",
* "description": "Description",
* "url": "URL",
* "picurl": "PIC_URL"
* },
* {
* "title": "Title",
* "description": "Description",
* "url": "URL",
* "picurl": "PIC_URL"
* }
* ]
* }
* }
* @param callback
*/
exports.sendNews = function(meta, callback) {
fetchAccessToken(function(err, token) {
if (err) {
return callback(err);
}
meta = meta || {};
meta.msgtype = "news";
meta.agentid = meta.agentid || conf.agentId;
meta.text = {content: message};
var url = constant.WECHAT_URL + "/message/send?access_token=" + token;
urllib.request(url, body(meta), function (err, result) {
callback(err, result);
});
});
};
/**
* 发送图片消息
* @param meta
* {
* touser:
* toparty:
* totag:
* agentid:
* safe:
* }
* @param image
* @param callback
*/
exports.sendImage = function(meta, image, callback) {
fetchAccessToken(function(err, token) {
if (err) {
return callback(err);
}
uploadFile(token, image, "file", function(err, info) {
if (err) {
return callback(err);
}
meta = meta || {};
meta.msgtype = "image";
meta.agentid = meta.agentid || conf.agentId;
meta.image = {media_id: info.media_id};
var url = constant.WECHAT_URL + "/message/send?access_token=" + token;
urllib.request(url, body(meta), function(err, result) {
callback(err, result);
});
});
});
};
/**
* 发送文本消息
* @param meta
* {
* touser:
* toparty:
* totag:
* agentid:
* safe:
* }
* @param message
* @param callback
*/
exports.sendMessage = function(meta, message, callback) {
fetchAccessToken(function(err, token) {
if (err) {
return callback(err);
}
meta = meta || {};
meta.msgtype = "text";
meta.agentid = meta.agentid || conf.agentId;
meta.text = {content: message};
var url = constant.WECHAT_URL + "/message/send?access_token=" + token;
urllib.request(url, body(meta), function (err, result) {
callback(err, result);
});
});
};
/**
* 获取post的消息格式
* @param data
* @returns Object
*/
function body(data) {
return {
dataType: "json",
type: "POST",
data: data,
headers: {
"Content-Type": "application/json"
}
};
}
/**
* 上传文件
* @param token
* @param filepath
* @param type
* @param callback
*/
function uploadFile(token, filepath, type, callback) {
var stat = fs.statSync(filepath)
, form = formstream();
form.file("media", filepath, path.basename(filepath), stat.size);
var options = {
dataType: "json",
type: "POST",
timeout: 60000, // 60秒超时
headers: form.headers(),
stream: form
};
var url = constant.WECHAT_URL + "/media/upload?access_token=" + token + "&type=" + type;
urllib.request(url, options, function(err, body) {
callback(err, body);
});
}
/**
* 获取OAuth2验证用URL
* @param redirect 验证通过后,重定向的页面URL
* @param customParameter 重定向是传递的自定义参数 a-zA-Z0-9
* @returns String OAuth用URL
*/
exports.oauthUrl = function(redirect, customParameter) {
var url = "https://open.weixin.qq.com/connect/oauth2/authorize"
, format = url + "?appid=%s&redirect_uri=%s&response_type=code&scope=snsapi_base&state=%s#wechat_redirect";
return util.format(format, conf.CorpID, redirect, scope, customParameter);
};
/**
* 用CorpID和Secret来换取AccessToken
* AccessToken有效期为7200秒
* corpID 企业号的标识,在企业号管理页面获取
* secret 管理组凭证密钥,在企业号管理页面获取
* @param callback 返回access_token
*/
function fetchAccessToken(callback) {
// 未超时,则继续复用
if (new Date().getTime() < expiredToken) {
return callback(undefined, accessToken);
}
// 获取token
var url = constant.WECHAT_URL + "/gettoken?corpid=" + conf.CorpID + "&corpsecret=" + conf.Secret;
request(url, function(err, response, body) {
if (err || response.statusCode != 200) {
return callback(err || response.statusCode);
}
var data = JSON.parse(body);
accessToken = data.access_token;
expiredToken = new Date().getTime() + (data.expires_in - 5) * 1000; // 提前5秒
callback(err, accessToken);
});
}
/**
* jsapi_ticket的有效期为7200秒,通过access_token来获取
* @param callback 返回jsapi_ticket
*/
function fetchJsapiTicket(callback) {
// 未超时,则继续复用
if (new Date().getTime() < expiredTicket) {
return callback(undefined, jsapiTicket);
}
// 获取token
var url = constant.WECHAT_URL + "/get_jsapi_ticket?access_token=" + accessToken;
request(url, function(err, response, body) {
if (err || response.statusCode != 200) {
return callback(err || response.statusCode);
}
var data = JSON.parse(body);
jsapiTicket = data.ticket;
expiredTicket = new Date().getTime() + (data.expires_in - 5) * 1000; // 提前5秒
callback(err, jsapiTicket);
});
}
/**
* 获取JSAPI的config信息
* @param url 网页的URL
* @param callback 回调,返回config信息
*/
exports.getJsConfig = function(url, callback) {
fetchAccessToken(function(err, token) {
fetchJsapiTicket(function(err, ticket) {
callback(err, sign(jsapiTicket, url));
});
});
};