weworkbot
Version:
203 lines • 8.39 kB
JavaScript
;
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.WeWorkBot = void 0;
const request_promise_native_1 = __importDefault(require("request-promise-native"));
const BOT_URL_WEBHOOK = 'https://qyapi.weixin.qq.com/cgi-bin/webhook/send';
const BOT_URL_UPLOAD = 'https://qyapi.weixin.qq.com/cgi-bin/webhook/upload_media';
const fs_1 = __importDefault(require("fs"));
const md5_1 = require("./md5");
let _internal_bull_queue = null;
function _postMsg(key, msg) {
return __awaiter(this, void 0, void 0, function* () {
const res = (yield (0, request_promise_native_1.default)({
uri: BOT_URL_WEBHOOK,
method: 'POST',
json: true,
qs: {
key: key,
},
body: msg,
}));
if (res.errcode !== 0 || res.errmsg !== 'ok') {
throw new Error(`errcode: ${res.errcode}, errmsg: ${res.errmsg}`);
}
else {
return res;
}
});
}
/**
* 如何使用群机器人
* 在终端某个群组添加机器人之后,创建者可以在机器人详情页看的该机器人特有的webhookurl。开发者可以按以下说明a向这个地址发起HTTP POST 请求,即可实现给该群组发送消息。
* 特别特别要注意:一定要保护好机器人的webhook地址,避免泄漏!不要分享到github、博客等可被公开查阅的地方,否则坏人就可以用你的机器人来发垃圾消息了。
*/
class WeWorkBot {
constructor(params) {
this.key = params.key;
this.noQueue = params.noQueue;
}
/**
* https://developer.work.weixin.qq.com/document/path/91770#%E6%B6%88%E6%81%AF%E5%8F%91%E9%80%81%E9%A2%91%E7%8E%87%E9%99%90%E5%88%B6
* 企业微信规定:每个机器人发送的消息不能超过20条/分钟。
* 这里我们需要传入一个bull的队列,并且队列需要设置 limiter: { max: 1, duration: 3000 }
* 每隔3秒只能发送1次请求,这样能满足20条/分钟的要求
* @param que Bull的队列实例
* @param ENV_NAME 可选参数,如果传入的话,会检查当前的NODE_ENV环境变量和ENV_NAME是否相符,相符合的话,才会定义 process worker,这样可以让worker执行在指定的环境里
*/
static setQueue(que, ENV_NAME) {
_internal_bull_queue = que;
if (!ENV_NAME || process.env.NODE_ENV === ENV_NAME) {
_internal_bull_queue.process((job) => __awaiter(this, void 0, void 0, function* () {
const res = yield _postMsg(job.data.key, job.data.msg);
return res;
}));
}
}
/** 统一发送任意类型的消息 */
send(msg) {
return __awaiter(this, void 0, void 0, function* () {
if (!_internal_bull_queue || process.env.WEWORKBOT_NO_QUEUE || this.noQueue) {
// 如果没有设置队列的话, 或者环境变量指定强制不走队列的话,则直接发送,但是就有可能会被微信限流
// WEWORKBOT_NO_QUEUE 主要用在,有的时候如果队列崩了,需要暂时不走队列,这样可以去处理队列的问题
return yield _postMsg(this.key, msg);
}
else {
const _job = yield _internal_bull_queue.add({
key: this.key,
msg
}); // 任务设置由外部的queue的defaultJobOptions决定,这里不设置了
const res = yield _job.finished();
return res;
}
});
}
/** 发送文本消息 */
sendText(msg) {
return __awaiter(this, void 0, void 0, function* () {
return this.send({
msgtype: 'text',
text: msg,
});
});
}
/** 发送markdown类型消息 */
sendMarkDown(content) {
return __awaiter(this, void 0, void 0, function* () {
return this.send({
msgtype: 'markdown',
markdown: {
content,
},
});
});
}
/** 发送 图片类型消息 */
sendImage(filePath) {
return __awaiter(this, void 0, void 0, function* () {
const buff = yield fs_1.default.promises.readFile(filePath);
const md5hash = (0, md5_1.md5)(buff);
const base64 = buff.toString('base64');
return this.send({
msgtype: 'image',
image: {
base64,
md5: md5hash,
},
});
});
}
/** 发送文件消息,请先用文件上传接口获取media id */
sendFile(mediaId) {
return __awaiter(this, void 0, void 0, function* () {
return this.send({
msgtype: 'file',
file: {
media_id: mediaId,
},
});
});
}
/** 发送图文类型消息 */
sendNews(articles) {
return __awaiter(this, void 0, void 0, function* () {
return this.send({
msgtype: 'news',
news: {
articles,
},
});
});
}
/** 发送文本通知模版卡片 */
sendCardTextNotice(msg) {
return __awaiter(this, void 0, void 0, function* () {
return this.send({
msgtype: 'template_card',
template_card: Object.assign({ card_type: 'text_notice' }, msg),
});
});
}
/** 发送图文展示模版卡片 */
sendCardNewsNotice(msg) {
return __awaiter(this, void 0, void 0, function* () {
return this.send({
msgtype: 'template_card',
template_card: Object.assign({ card_type: 'news_notice' }, msg),
});
});
}
/**
* 文件上传接口
* 要求文件大小在5B~20M之间, 素材上传得到media_id,该media_id仅三天内有效, media_id只能是对应上传文件的机器人可以使用
* */
upload(params) {
return __awaiter(this, void 0, void 0, function* () {
if (!params.filePath && !params.stream) {
throw new Error('Either stream or file path is required!');
}
if (params.filePath && params.stream) {
throw new Error('Only one of stream or file path is required!');
}
const fileStream = params.stream || fs_1.default.createReadStream(params.filePath);
const res = (yield (0, request_promise_native_1.default)({
uri: BOT_URL_UPLOAD,
method: 'POST',
qs: {
key: this.key,
type: 'file',
},
json: true,
formData: {
file: {
value: fileStream,
options: {
filename: 'test.jpg',
// contentType: 'image/jpg',
},
},
},
}));
if (res.errcode === 0 && res.errmsg === 'ok' && res.media_id) {
return res.media_id;
}
else {
const errmsg = `errcode: ${res.errcode}, errmsg: ${res.errmsg}`;
throw new Error(errmsg);
}
});
}
}
exports.WeWorkBot = WeWorkBot;
//# sourceMappingURL=index.js.map