Created
June 11, 2021 08:12
-
-
Save vinsonzou/fa6ea86de40dd36bce5eaa4c4e936942 to your computer and use it in GitHub Desktop.
企业微信接口,示例为联系人tag调整,可以自定义任何想实现功能。
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| local require = require | |
| local ngx = ngx | |
| local http = require "resty.http" -- https://github.com/ledgetech/lua-resty-http | |
| local wxcrypt = require "resty.crypt" -- https://github.com/vinsonzou/WXBizMsgCrypt | |
| local xml2lua = require "xml2lua" -- https://github.com/manoelcampos/xml2lua | |
| local handler = require "xmlhandler.tree" | |
| local cjson = require "cjson.safe" | |
| local ngx_re = require "ngx.re" | |
| local json_encode = cjson.encode | |
| local json_decode = cjson.decode | |
| local base64_decode = ngx.decode_base64 | |
| local tconcat = table.concat | |
| local re_find = ngx.re.find | |
| local re_gsub = ngx.re.gsub | |
| local corpId = "企业微信: 企业ID" | |
| local AgentId = "企业微信: 应用-AgentId" | |
| local Secret = "企业微信: 应用-Secret" | |
| local Token = "企业微信: 应用-API接收消息-Token" | |
| local EncodingAESKey = "企业微信: 应用-API接收消息-EncodingAESKey" | |
| local AESKey = base64_decode(EncodingAESKey .. "=") | |
| local wechat = ngx.shared.wechat | |
| local function get_accessToken() | |
| local accessToken, flags = wechat:get("accessToken") | |
| if accessToken then | |
| return accessToken | |
| end | |
| local url = "https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=" .. corpId .. "&corpsecret=" .. Secret | |
| local httpc = http.new() | |
| local res, err = httpc:request_uri(url, { | |
| method = "GET", | |
| keepalive_timeout = 60000, | |
| keepalive_pool = 10 | |
| }) | |
| if res.status == 200 then | |
| local res_body = json_decode(res.body) | |
| if res_body.errcode == 0 then | |
| local ok, err = wechat:set("accessToken", res_body.access_token, res_body.expires_in) | |
| return res_body.access_token | |
| end | |
| end | |
| end | |
| local function get_tag_userlist(accessToken) | |
| local url = "https://qyapi.weixin.qq.com/cgi-bin/tag/get?tagid=34&access_token=" .. accessToken | |
| local httpc = http.new() | |
| local res, err = httpc:request_uri(url, { | |
| method = "POST", | |
| keepalive_timeout = 60000, | |
| keepalive_pool = 10 | |
| }) | |
| if res.status == 200 then | |
| local res_body = json_decode(res.body) | |
| if res_body.errcode == 0 then | |
| local userlist = res_body["userlist"] | |
| local userids = {} | |
| local t = {} | |
| local idx = 0 | |
| for _, v in pairs(userlist) do | |
| idx = idx + 1 | |
| userids[idx] = v.userid | |
| t[idx] = v.name | |
| end | |
| return userids, tconcat(t, ",") | |
| end | |
| end | |
| end | |
| local function del_tag_userlist(accessToken) | |
| local userids, usernames = get_tag_userlist(accessToken) | |
| if #userids == 0 then | |
| return true | |
| end | |
| local url = "https://qyapi.weixin.qq.com/cgi-bin/tag/deltagusers?access_token=" .. accessToken | |
| local httpc = http.new() | |
| local data = { | |
| tagid = 34, | |
| userlist = userids, | |
| } | |
| local res, err = httpc:request_uri(url, { | |
| method = "POST", | |
| body = json_encode(data), | |
| keepalive_timeout = 60000, | |
| keepalive_pool = 10 | |
| }) | |
| if res.status == 200 then | |
| local res_body = json_decode(res.body) | |
| if res_body.errcode == 0 then | |
| return true | |
| end | |
| end | |
| end | |
| local function update_tag_userlist(accessToken, userid) | |
| del_tag_userlist(accessToken) | |
| local url = "https://qyapi.weixin.qq.com/cgi-bin/tag/addtagusers?access_token=" .. accessToken | |
| local httpc = http.new() | |
| local data = { | |
| tagid = 34, | |
| userlist = {userid}, | |
| } | |
| local res, err = httpc:request_uri(url, { | |
| method = "POST", | |
| body = json_encode(data), | |
| keepalive_timeout = 60000, | |
| keepalive_pool = 10 | |
| }) | |
| if res.status == 200 then | |
| local res_body = json_decode(res.body) | |
| if res_body.errcode == 0 then | |
| return true | |
| else | |
| return false | |
| end | |
| end | |
| end | |
| local method = ngx.req.get_method() | |
| local headers = ngx.req.get_headers() | |
| local args = ngx.req.get_uri_args() | |
| local msg_signature = args.msg_signature | |
| local timestamp = args.timestamp | |
| local nonce = args.nonce | |
| local echostr = args.echostr | |
| local msg_encrypt | |
| if method == "GET" and echostr then | |
| local TmpStr = ngx.unescape_uri(echostr) | |
| -- ngx_lua会将GET请求参数的"+" 转换为 " " | |
| -- ngx_lua会将GET请求参数的"=" 转换为 ":" | |
| local encode_str, n, err = re_gsub(TmpStr, [[ ]], "+", "jo") | |
| msg_encrypt = encode_str | |
| elseif method == "POST" then | |
| ngx.req.read_body() | |
| local body_data = ngx.req.get_body_data() | |
| local parser = xml2lua.parser(handler) | |
| parser:parse(body_data) | |
| for i, p in pairs(handler.root) do | |
| msg_encrypt = p.Encrypt | |
| end | |
| end | |
| local signature = wxcrypt:get_sha1({Token, timestamp, nonce, msg_encrypt}) | |
| if signature == msg_signature then | |
| local wxmc = wxcrypt:new(Token, EncodingAESKey, corpId) | |
| local msg = wxmc:decrypt(msg_encrypt) | |
| if method == "POST" then | |
| local EventKey, UserName, CustomAction | |
| local parser = xml2lua.parser(handler) | |
| parser:parse(msg) | |
| for i, p in pairs(handler.root) do | |
| local MsgType = p.MsgType | |
| UserName = p.FromUserName | |
| if MsgType == "event" then | |
| EventKey = p.EventKey | |
| elseif MsgType == "text" then | |
| CustomAction = p.Content | |
| end | |
| end | |
| local ReplyMsg = { | |
| ToUserName = UserName, | |
| FromUserName = corpId, | |
| CreateTime = ngx.time(), | |
| MsgType = "text", | |
| AgentID = AgentId, | |
| } | |
| if EventKey then | |
| if EventKey == "onduty_now" then | |
| local accessToken = get_accessToken() | |
| local userids, usernames = get_tag_userlist(accessToken) | |
| ReplyMsg["Content"] = usernames | |
| local ReplyMsg_xml = xml2lua.toXml(ReplyMsg, "xml") | |
| local encrypted = wxmc:encrypt(ReplyMsg_xml, timestamp, nonce) | |
| ngx.say(encrypted) | |
| elseif re_find(EventKey, [[^onduty_(zhangsan|lisi|wangwu)$]], "jo") then | |
| local result, err = ngx_re.split(EventKey, "_") | |
| local userid = result[2] | |
| local accessToken = get_accessToken() | |
| if update_tag_userlist(accessToken, userid) then | |
| ReplyMsg["Content"] = "当前值班调整为" .. userid | |
| else | |
| ReplyMsg["Content"] = "[异常]当前值班调整为" .. userid | |
| end | |
| local ReplyMsg_xml = xml2lua.toXml(ReplyMsg, "xml") | |
| local encrypted = wxmc:encrypt(ReplyMsg_xml, timestamp, nonce) | |
| ngx.say(encrypted) | |
| end | |
| end | |
| elseif method == "GET" then | |
| ngx.say(msg) | |
| end | |
| end |
Author
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
nginx vhost.conf如下: