{"version":3,"sources":["jsdelivr-header.js","/npm/node-wxeasy@1.5.1/index.js"],"names":[],"mappings":"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","file":"/npm/node-wxeasy@1.5.1/index.js","sourceRoot":"","sourcesContent":["/**\n * Minified by jsDelivr using Terser v5.39.0.\n * Original file: /npm/node-wxeasy@1.5.1/index.js\n *\n * Do NOT use SRI with dynamically generated files! More information: https://www.jsdelivr.com/using-sri-with-dynamic-files\n */\n","'use strict';\r\n\r\nvar sha1 = require('sha1');\r\nvar request = require('request');\r\nvar xml2js = require('xml2js');\r\n\r\nvar Events = require('./api/events');\r\nvar config = require('./config');\r\nvar template = require('./template');\r\n\r\nvar WXeasy = Events.extend({\r\n\r\n    init: function (config) {\r\n        var self = this;\r\n\r\n        this.config = config || {};\r\n        this.app = this.config.app;\r\n        this.appid = this.config.appid || '';\r\n        this.appsecret = this.config.appsecret || '';\r\n        this.token = this.config.token;\r\n        this.API_URL = this.config.access_token_apiurl || ''; // 中控 token 接口\r\n        this.url = this.config.url || '/verify'; // 自定义公众号对接接口\r\n        this.access_token = {}; // 本地保存的临时map 不同 uriType token\r\n        this.timer = {}; // 计数器\r\n        this._init();\r\n    },\r\n\r\n    _init: function () {\r\n        var self = this;\r\n\r\n        self.app.get(self.url, function (req, res) {\r\n            self.checkSignature(req, res);\r\n        });\r\n\r\n        self.app.post(self.url, function (req, res) {\r\n            /**\r\n             * add uriType by Ray 2018-03-30\r\n             * uriType 作为区分不同的来源\r\n             * @type {[string]}\r\n             */\r\n            var uriType = req.query.uriType || '';\r\n            // 挂载在实例对象上面 2020年5月8日\r\n            self.uriType = uriType;\r\n\r\n            self.res = res;\r\n            var buf = '';\r\n            req.setEncoding('utf8');\r\n            req.on('data', function (chunk) {\r\n                buf += chunk;\r\n            });\r\n\r\n            req.on('end', function () {\r\n                xml2js.parseString(buf, function (err, json) {\r\n                    if (err) {\r\n                        err.status = 400;\r\n                        console.log('++++++++++++status 400+++++++++');\r\n                    } else {\r\n                        json.xml['UriType'] = [uriType];\r\n                        /**\r\n                         * 2019-03-15 传递响应\r\n                         */\r\n                        json.xml['Resp'] = [res];\r\n                        self.parse(json.xml);\r\n                    }\r\n                });\r\n            });\r\n        });\r\n    },\r\n\r\n    /**\r\n     * @method checkSignature\r\n     * 验证消息真实性\r\n     */\r\n    checkSignature: function (req, res) {\r\n        var query = req.query;\r\n        var signature = query.signature;\r\n        var echostr = query.echostr;\r\n        var timestamp = query.timestamp;\r\n        var nonce = query.nonce;\r\n\r\n        // 1. 将token、timestamp、nonce三个参数进行字典序排序\r\n        var arr = [this.token, timestamp, nonce];\r\n        arr.sort();\r\n        // 2. 将三个参数字符串拼接成一个字符串进行sha1加密\r\n        var str = sha1(arr.join(\"\"));\r\n        // 3. 开发者获得加密后的字符串可与signature对比，标识该请求来源于微信\r\n        if (str == signature) {\r\n            res.status(200).send(echostr);\r\n        } else {\r\n            res.status(200).send('fail');\r\n        }\r\n    },\r\n\r\n    r: function (err, resp, body, callback) {\r\n        if (!err && resp.statusCode == 200) {\r\n            try {\r\n                callback(JSON.parse(body));\r\n            } catch (e) {\r\n                var data = body.replace(/\\u(\\d+)/g, '');\r\n                try {\r\n                    callback(JSON.parse(data));\r\n                } catch (e) {\r\n                    callback(data);\r\n                }\r\n            }\r\n        }\r\n    },\r\n\r\n    getUrl: function (url, next, uriType) {\r\n        var self = this;\r\n\r\n        if (uriType) {\r\n            if (self.access_token[uriType]) {\r\n                next && next(url + '?access_token=' + self.access_token[uriType]);\r\n                return;\r\n            }\r\n        } else {\r\n            // let isEmpty = Object.keys(self.access_token).length === 0;\r\n            // 不是对象了且有值\r\n            if (typeof self.access_token != 'object' && self.access_token) {\r\n                next && next(url + '?access_token=' + self.access_token);\r\n                return;\r\n            }\r\n        }\r\n        self.getAccessToken(function (data) {\r\n            if (uriType) {\r\n                self.access_token[uriType] = data.access_token;\r\n                // 接近2小时候（7200s）清空token，重新获取token 2020年5月9号\r\n                if (self.access_token[uriType]) {\r\n                    clearTimeout(self.timer[uriType]);\r\n                    self.timer[uriType] = setTimeout(() => {\r\n                        self.access_token[uriType] = '';\r\n                    }, 1000 * 7000);\r\n                }\r\n                next && next(url + '?access_token=' + data.access_token);\r\n            } else {\r\n                self.access_token = data.access_token;\r\n                // 接近2小时候（7200s）清空token，重新获取token 2020年5月9号\r\n                if (self.access_token) {\r\n                    clearTimeout(self.timer);\r\n                    self.timer = setTimeout(() => {\r\n                        self.access_token = '';\r\n                    }, 1000 * 7000);\r\n                }\r\n                next && next(url + '?access_token=' + data.access_token);\r\n            }\r\n            \r\n        }, uriType);\r\n    },\r\n\r\n    // get request\r\n    getRequest: function (url, callback) {\r\n        var self = this;\r\n        request(url, function (err, resp, body) {\r\n            self.r(err, resp, body, callback);\r\n        });\r\n    },\r\n\r\n    // post request\r\n    postRequest: function (url, body, callback) {\r\n        callback = callback || function () {\r\n            console.log('postRequest default callback invoked');\r\n        };\r\n        var self = this;\r\n        var options = {\r\n            url: url,\r\n            method: 'post',\r\n            body: JSON.stringify(body)\r\n        };\r\n        // console.log('========== postRequest ==========');\r\n \r\n        request(options, function (err, resp, body) {\r\n            self.r(err, resp, body, callback);\r\n        });\r\n    },\r\n\r\n    /**\r\n     * @method getAccessToken\r\n     * 从微信服务器获取一个新的access_token\r\n     */\r\n    getAccessToken: function (callback, uriType) {\r\n        var self = this;\r\n\r\n        if (self.API_URL) {\r\n            // 增加参数 2020年5月8日\r\n            let url = self.API_URL;\r\n\r\n            if (uriType) {\r\n                url = `${self.API_URL}?id=${uriType}`;\r\n            } else if (self.uriType) {\r\n                url = `${self.API_URL}?id=${self.uriType}`;\r\n            }\r\n            request(url, function (err, resp, body) {\r\n                if (err || resp.statusCode != 200) {\r\n                    //接口失败，直接走微信\r\n                    var url = config.GET_ACCESS_TOKEN + \"?grant_type=client_credential&appid=\" + self.appid + \"&secret=\" + self.appsecret;\r\n                    self.getRequest(url, callback);\r\n                } else if (!err && resp.statusCode == 200) {\r\n                    callback(JSON.parse(body));\r\n                }\r\n            });\r\n\r\n        } else {\r\n            //直接走微信\r\n            var url = config.GET_ACCESS_TOKEN + \"?grant_type=client_credential&appid=\" + self.appid + \"&secret=\" + self.appsecret;\r\n            self.getRequest(url, callback);\r\n        }\r\n    },\r\n\r\n    /**\r\n     * @method getWeixinIPList\r\n     * 获取微信服务器IP地址\r\n     */\r\n    getWeixinIPList: function (callback) {\r\n        var self = this;\r\n\r\n        self.getUrl(config.GET_WEIXIN_IP_LIST, function (url) {\r\n            self.getRequest(url, callback);\r\n        });\r\n    },\r\n\r\n    parse: function (data) {\r\n        var msgType = data.MsgType[0] ? data.MsgType[0] : 'text';\r\n        switch (msgType) {\r\n            case 'text':\r\n            case 'image':\r\n            case 'voice':\r\n            case 'video':\r\n            case 'shortvideo':\r\n            case 'location':\r\n            case 'link':\r\n                this.parseNormalMsg(data);\r\n                break;\r\n            case 'event':\r\n                this.parseEventMsg(data);\r\n                break;\r\n            default:\r\n                break;\r\n        }\r\n    },\r\n    /**\r\n     * 格式化接收数据\r\n     * @param {* msg}\r\n     * return msg;\r\n     */\r\n    formatMsgContent: function (msg) {\r\n        var content = msg.content;\r\n\r\n        if (content) {\r\n            content = content + \"\";\r\n            msg.content = content.replace(/\\\"|\\%|~|\\“|\\”|\\’|\\‘|\\!|\\！/gi, \"\")\r\n                .replace(/^\\s+|\\s+$/gi, \"\");\r\n        }\r\n        return msg;\r\n    },\r\n    // 接收普通消息\r\n    // 1 文本消息 2 图片消息 3 语音消息 4 视频消息 5 小视频消息 6 地理位置消息 7 链接消息\r\n    parseNormalMsg: function (data) {\r\n        var msg = {};\r\n        for (var i in data) {\r\n            msg[i.slice(0, 1).toLowerCase() + i.slice(1)] = data[i][0];\r\n        }\r\n        // 格式化数据\r\n        msg = this.formatMsgContent(msg);\r\n        this.trigger('allMsg', msg);\r\n        this.trigger(msg.msgType + 'Msg', msg);\r\n    },\r\n\r\n    // 接收事件推送\r\n    // 1 关注/取消关注事件 2 扫描带参数二维码事件 3 上报地理位置事件 4 自定义菜单事件 5 点击菜单拉取消息时的事件推送 6 点击菜单跳转链接时的事件推送\r\n    // 1 subscribeEventMsg unsubscribeEventMsg 2 3 LOCATIONEventMsg\r\n    parseEventMsg: function (data) {\r\n        if (data.Event[0] == 'TEMPLATESENDJOBFINISH' ||\r\n            data.Event[0] == 'VIEW' ||\r\n            data.Event[0] == 'CLICK' ||\r\n            data.Event[0] == 'LOCATION' ||\r\n            data.Event[0] == 'unsubscribe') {\r\n\r\n            // 默认使用传递响应\r\n            if (data.Resp && data.Resp[0]) {\r\n                data.Resp[0].send('');\r\n            } else {\r\n                this.res.send('');\r\n            }\r\n        }\r\n\r\n        var msg = {};\r\n        for (var i in data) {\r\n            msg[i.slice(0, 1).toLowerCase() + i.slice(1)] = data[i][0];\r\n        }\r\n        // 格式化数据\r\n        msg = this.formatMsgContent(msg);\r\n        this.trigger('allEventMsg', msg);\r\n        this.trigger(msg.event + 'EventMsg', msg);\r\n    },\r\n\r\n    /************************************************************\r\n     * 发送消息\r\n     *     发送被动回复消息\r\n     *     客服接口\r\n     *     高级群发接口\r\n     *     模板消息接口\r\n     *     获取自动回复规则\r\n     ************************************************************/\r\n    // 发送被动回复消息\r\n    sendMsg: function (msg) {\r\n        var self = this;\r\n\r\n        var msgType = msg.msgType;\r\n        var out = template[msgType](msg);\r\n\r\n        try {\r\n            /**\r\n             * 2019-03-15\r\n             * 默认使用传递参数的响应\r\n             */\r\n            if (msg.resp) {\r\n                msg.resp.type('xml');\r\n                return msg.resp.send(out);\r\n            }\r\n            self.res.type('xml');\r\n            return self.res.send(out);\r\n        } catch (e) {\r\n            console.log(`${self.url}/?uriType=${self.uriType}`, '>>> sendMsg: ' + e, msg.content);\r\n            return null;\r\n        }\r\n    },\r\n\r\n    sendTextMsg: function (msg) {\r\n        msg.msgType = 'text';\r\n        return this.sendMsg(msg);\r\n    },\r\n\r\n    sendImageMsg: function (msg) {\r\n        msg.msgType = 'image';\r\n        return this.sendMsg(msg);\r\n    },\r\n\r\n    sendVoiceMsg: function (msg) {\r\n        msg.msgType = 'voice';\r\n        return this.sendMsg(msg);\r\n    },\r\n\r\n    sendVideoMsg: function (msg) {\r\n        msg.msgType = 'video';\r\n        return this.sendMsg(msg);\r\n    },\r\n\r\n    sendMusicMsg: function (msg) {\r\n        msg.msgType = 'music';\r\n        return this.sendMsg(msg);\r\n    },\r\n\r\n    sendNewsMsg: function (msg) {\r\n        msg.msgType = 'news';\r\n        return this.sendMsg(msg);\r\n    },\r\n\r\n    // 客服接口\r\n    // 添加客服帐号\r\n    addKFAccount: function (data, callback) {\r\n        var self = this;\r\n\r\n        self.getUrl(config.ADD_KFACCOUNT, function (url) {\r\n            self.postRequest(url, data, callback);\r\n        });\r\n    },\r\n\r\n    // 获取所有客服账号\r\n    getKFList: function (callback) {\r\n        var self = this;\r\n\r\n        self.getUrl(config.GET_KF_LIST, function (url) {\r\n            self.getRequest(url, callback);\r\n        });\r\n    },\r\n    /**\r\n     * 发送客户消息，主动消息 48小时内互动有效\r\n     * @param msg\r\n     * @param callback\r\n     */\r\n    sendCustomMsg: function (msg, callback, noTry) {\r\n        var self = this;\r\n        let uriType = msg.uriType; // 参数\r\n\r\n        if (uriType) {\r\n            delete msg.uriType;\r\n        }\r\n        callback = callback || function (data) {\r\n            if (data.errcode != 0 && data.errcode != 45015) {\r\n                console.log('>>> sendCustomMsg: ', msg, data);\r\n            }\r\n            // 错误信息处理 2020年5月8日；如果失效那么更新\r\n            if (data.errcode == 40001 && !noTry) {\r\n                // 同一个实例\r\n                if (uriType) {\r\n                    self.access_token[uriType] = '';\r\n                    clearTimeout(self.timer[uriType]);\r\n                } else {\r\n                    self.access_token = '';\r\n                    clearTimeout(self.timer);\r\n                }\r\n\r\n                // =========================bug导致循环\r\n                // if (uriType) {\r\n                //     msg.uriType = uriType;\r\n                // }\r\n                // self.sendCustomMsg(msg, callback, true)\r\n            }\r\n        };\r\n\r\n        self.getUrl(config.POST_CUSTOM_MESSAGE, function (url) {\r\n            var options = {\r\n                url: url,\r\n                method: 'post',\r\n                body: JSON.stringify(msg)\r\n            };\r\n            request(options, function (err, resp, body) {\r\n                self.r(err, resp, body, callback);\r\n            });\r\n        }, uriType);\r\n    },\r\n\r\n    /**\r\n     * 发送模板消息\r\n     * @param msg\r\n     * @param callback\r\n     */\r\n    sendTemplateMsg: function (msg, callback) {\r\n        var self = this;\r\n        callback = callback || function (data) {\r\n            console.log('>>> sendTemplateMsg >>> default callback function invoked.');\r\n            console.log(data);\r\n        };\r\n\r\n        self.getUrl(config.POST_TEMPLATE_MESSAGE, function (url) {\r\n            var options = {\r\n                url: url,\r\n                method: 'post',\r\n                body: JSON.stringify(msg)\r\n            };\r\n\r\n            request(options, function (err, resp, body) {\r\n                self.r(err, resp, body, callback);\r\n            });\r\n        });\r\n    },\r\n\r\n    /**\r\n     * @method getCurrentAutoReplyInfo\r\n     * 获取自动回复规则\r\n     */\r\n    getCurrentAutoReplyInfo: function (callback) {\r\n        var self = this;\r\n\r\n        self.getUrl(config.GET_CURRENT_AUTOREPLY_INFO, function (url) {\r\n            self.getRequest(url, callback);\r\n        });\r\n    },\r\n\r\n\r\n\r\n    /************************************************************\r\n     * 自定义菜单\r\n     * 自定义菜单查询接口\r\n     * 自定义菜单删除接口\r\n     * 自定义菜单创建接口\r\n     * 获取自定义菜单配置接口\r\n     ************************************************************/\r\n    /**\r\n     * @method getMenu\r\n     * 自定义菜单查询接口\r\n     */\r\n    getMenu: function (uriType, callback) {\r\n        var self = this;\r\n\r\n        self.getUrl(config.GET_MENU, function (url) {\r\n            self.getRequest(url, callback);\r\n        }, uriType);\r\n    },\r\n\r\n    /**\r\n     * @method deleteMenu\r\n     * 自定义菜单删除接口\r\n     */\r\n    deleteMenu: function (callback) {\r\n        var self = this;\r\n\r\n        self.getUrl(config.DELETE_MENU, function (url) {\r\n            self.getRequest(url, callback);\r\n        });\r\n    },\r\n\r\n    /**\r\n     * @method createMenu\r\n     * 自定义菜单创建接口\r\n     */\r\n    createMenu: function (menuObj, callback) {\r\n        var self = this;\r\n        let uriType = null;\r\n        // 新增，自定义菜单支持配置不同用户参数\r\n        if (menuObj.uriType) {\r\n            uriType = menuObj.uriType;\r\n            delete menuObj.uriType;\r\n        }\r\n\r\n        this.getUrl(config.CREATE_MENU, function (url) {\r\n            var options = {\r\n                url: url,\r\n                method: 'post',\r\n                body: JSON.stringify(menuObj)\r\n            };\r\n\r\n            request(options, function (err, resp, body) {\r\n                self.r(err, resp, body, callback);\r\n            });\r\n        }, uriType);\r\n    },\r\n\r\n    /**\r\n     * @method getCurrentSelfMenuInfo\r\n     * 获取自定义菜单配置接口\r\n     */\r\n    getCurrentSelfMenuInfo: function (callback) {\r\n        var self = this;\r\n\r\n        self.getUrl(config.GET_CURRENT_SELF_MENU_INFO, function (url) {\r\n            self.getRequest(url, callback);\r\n        });\r\n    },\r\n\r\n\r\n    /************************************************************\r\n     * 素材管理\r\n     ************************************************************/\r\n\r\n    /**\r\n     * @method getMaterialCount\r\n     * 获取素材总数\r\n     */\r\n    getMaterialCount: function (callback) {\r\n        var self = this;\r\n\r\n        self.getUrl(config.GET_MATERIAL_COUNT, function (url) {\r\n            self.getRequest(url, callback);\r\n        });\r\n    },\r\n\r\n    /**\r\n     * @method BATCH_GET_MATERIAL\r\n     */\r\n    batchGetMaterial: function (data, callback) {\r\n        var self = this;\r\n\r\n        self.getUrl(config.BATCH_GET_MATERIAL, function (url) {\r\n            self.postRequest(url, data, callback);\r\n        });\r\n\r\n    },\r\n\r\n\r\n    /************************************************************\r\n     * 账号管理\r\n     ************************************************************/\r\n\r\n    /**\r\n     * @method createQrcode\r\n     * 创建二维码ticket\r\n     */\r\n    createQrcode: function (data, callback) {\r\n        var self = this;\r\n\r\n        self.getUrl(config.CREATE_QRCODE, function (url) {\r\n            self.postRequest(url, data, callback);\r\n        });\r\n    },\r\n\r\n    /**\r\n     * @method getShortUrl\r\n     * 长链接转短链接\r\n     */\r\n    getShortUrl: function (data, callback) {\r\n            var self = this;\r\n\r\n            self.getUrl(config.GET_SHORT_URL, function (url) {\r\n                self.postRequest(url, data, callback);\r\n            });\r\n        }\r\n\r\n\r\n        /***************************************\r\n         * 微信用户信息\r\n         * *************************************\r\n         * */\r\n\r\n        ,\r\n    getFocusOpenid: function (nextid, callback) {\r\n        var self = this;\r\n\r\n        if (!nextid || nextid == undefined) nextid = '';\r\n        self.getUrl(config.GET_FOCUS_OPENID, function (url) {\r\n            url += '&next_openid=' + nextid;\r\n            self.getRequest(url, callback);\r\n        });\r\n    },\r\n\r\n    /****************************************\r\n     * 获得单用户信息\r\n     * @param openid\r\n     * @param callback\r\n     ****************************************/\r\n\r\n    getFocusUserInfo: function (openid, callback) {\r\n        var self = this;\r\n\r\n        self.getUrl(config.GET_FOCUS_USERINFO, function (url) {\r\n            url += '&openid=' + openid + '&lang=zh_CN';\r\n            self.getRequest(url, callback);\r\n        });\r\n    },\r\n\r\n    /***************************************\r\n     * data:\r\n     * {\"user_list\": [\r\n            {\r\n               \"openid\": \"otvxTs4dckWG7imySrJd6jSi0CWE\",\r\n               \"lang\": \"zh-CN\"\r\n           },\r\n           {\r\n               \"openid\": \"otvxTs_JZ6SEiP0imdhpi50fuSZg\",\r\n               \"lang\": \"zh-CN\"\r\n           }\r\n       ]}\r\n     * 获得多个用户信息\r\n     * @param data\r\n     * @param callback\r\n     */\r\n\r\n    getFocusListUserInfo: function (data, callback) {\r\n        var self = this;\r\n\r\n        self.getUrl(config.GET_FOCUS_LIST_USERINFO, function (url) {\r\n            self.postRequest(url, data, callback);\r\n        });\r\n    }\r\n});\r\n\r\nmodule.exports = WXeasy;"]}