前言
? ? ? ? 為了實現系統調用團隊會議功能,組織發起企業微信會議,于是需要和企業微信做API對接。對接過程很難受,文檔不清晰、沒有SDK、沒有技術支持甚至文檔報文和實際接口報文都不匹配,只能說企業微信的API是從業以來見過的最難用的API,僅個人觀點。
? ? ? ? 在配置自建應用后,訪問API接口竟然需要設置可信IP,不論是出于安全還是別的商業目的,該手段都太古老,怎奈人在屋檐下不得不低頭。可是在配置時又需要域名驗證等雜七雜八的問題,特此記錄解決過程分享給大家。
正文
1、自信滿滿配置IP
????????本以為打開這個頁面直接輸入外網IP即可,未曾想是個只讀框,需要處理藍色背景的提示信息,設置可信域名或解析加密URL
? ? ? ? 可信域名自然沒有,申請證書申請域名費時費力,測試階段根本沒必要
? ? ??
? ? ? ? 于是選擇第二個選項,文字描述很抽象,筆者也是查閱各方資料才總結出來。
????????大體意思就是要在能外網訪問的機器上部署一個服務,當企業微信的測試請求訪問過去時,按照一定的加解密規則以及入參,返回對應的響應信息。這樣企業微信才認為你這臺機器是“自己人”,允許你繼續配置可信IP,簡直就是!@#*¥&()@!!。
2、罵罵咧咧獲取信任
? ? ? ? 一回頭看自己還在屋檐下,繼續低頭想辦法唄。首先把后兩項全部選擇隨機獲取,記錄好生成的字符串,一會發布服務需要使用。接下來表演開始:
2.1、準備外網服務器
????????找一臺可以外網訪問的機器,當然還需要一個打通的端口,在這臺機器上安裝Python3
2.2、獲取Python項目
? ? ? ? 按照這個GitHub地址,下載一個python項目,解壓后重命名為?weworkapi_python
????????https://github.com/sbzhu/weworkapi_python/archive/refs/heads/master.zip
? ? ? ? 也可以使用指令處理:
wget https://github.com/sbzhu/weworkapi_python/archive/refs/heads/master.zip
unzip master.zip
mv weworkapi_python-master weworkapi_python
2.3、執行監聽服務腳本
與上述項目同級開啟命令窗,使用下述腳本觸發執行,其中執行前需要替換三個參數,前兩個為剛剛隨機生成的,最后一個在企業信息中可以看到的企業ID。
qy_api = [WXBizMsgCrypt("XXXXXXX", "XXXXXXX", "XXXXXXX"),
] #對應接受消息回調模式中的token,EncodingAESKey 和 企業信息中的企業id
#-*- encoding:utf-8 -*-
from flask import abort, request
from flask import Flask
from xml.dom.minidom import parseString
import _thread
import time
import os
import sys
sys.path.append("weworkapi_python/callback") # 正確的模塊導入路徑
from WXBizMsgCrypt3 import WXBizMsgCrypt # https://github.com/sbzhu/weworkapi_python 項目地址
app = Flask(__name__)# 對應步驟4中接受消息回調模式中的URL,如域名是'www.example.com' 那么在步驟4中填入的url就為"http://www.example.com/hook_path"
@app.route('/hook_path', methods=['GET','POST'])
def douban():if request.method == 'GET':echo_str = signature(request, 0)return(echo_str)elif request.method == 'POST':echo_str = signature2(request, 0)return(echo_str)qy_api = [WXBizMsgCrypt("qCV0ro7W4CJQtn3RHbVwgYU5GAZ29AK", "PQzmYlT4vGP3ItW9OmvreGkkLpDS3A9jH2GsyfDtP3q", "ww7b1bc3d6d"),
] #對應接受消息回調模式中的token,EncodingAESKey 和 企業信息中的企業id# 開啟消息接受模式時驗證接口連通性
def signature(request, i): msg_signature = request.args.get('msg_signature', '')timestamp = request.args.get('timestamp', '')nonce = request.args.get('nonce', '')echo_str = request.args.get('echostr', '')ret,sEchoStr=qy_api[i].VerifyURL(msg_signature, timestamp,nonce,echo_str)if (ret != 0):print("ERR: VerifyURL ret: " + str(ret))return("failed")else:return(sEchoStr)# 實際接受消息
def signature2(request, i):msg_signature = request.args.get('msg_signature', '')timestamp = request.args.get('timestamp', '')nonce = request.args.get('nonce', '')data = request.data.decode('utf-8')ret,sMsg=qy_api[i].DecryptMsg(data,msg_signature, timestamp,nonce)if (ret != 0):print("ERR: DecryptMsg ret: " + str(ret))return("failed")else:with open ("/var/log/qywx.log", 'a+') as f: # 消息接收日志doc = parseString(sMsg)collection = doc.documentElementname_xml = collection.getElementsByTagName("FromUserName")msg_xml = collection.getElementsByTagName("Content")type_xml = collection.getElementsByTagName("MsgType")pic_xml = collection.getElementsByTagName("PicUrl")msg = ""name = ""msg_type = type_xml[0].childNodes[0].dataif msg_type == "text": #文本消息name = name_xml[0].childNodes[0].data #發送者idmsg = msg_xml[0].childNodes[0].data #發送的消息內容f.write(time.strftime('[%Y-%m-%d %H:%M:%S]') + "[ch%d] %s:%s\n" % (i, name, msg))_thread.start_new_thread(os.system, ("python3 command.py '%s' '%s' '%d' '%d'" % (name, msg, i, 0), )) #此處將消息進行外部業務處理elif msg_type == "image": #圖片消息name = name_xml[0].childNodes[0].datapic_url = pic_xml[0].childNodes[0].dataf.write(time.strftime('[%Y-%m-%d %H:%M:%S]') + "[ch%d] %s:圖片消息\n" % (i, name))_thread.start_new_thread(os.system, ("python3 command.py '%s' '%s' '%d' '%d'" % (name, pic_url, i, 1), )) #此處將消息進行外部業務處理f.close()return("ok")if __name__=='__main__':app.run("0.0.0.0", 8066) #本地監聽端口,可自定義
#執行腳本
python wechat.py
若執行報錯提示缺失依賴,按照pip3進行安裝即可。
2.4、最終結果獲取
執行成功后會根據token和secret生成監聽服務,命令窗提示 ip:port ,其中端口可以在上述腳本中配置。
3、配置可驗證的URL
將生成的信息配置到對應目錄
http://公網IP地址:8066/hook_path
點擊保存后即可正常配置可信IP,至此整個荒誕的信任危機解除,只能三個字形容:真無聊。
總結
? ? ? ? 整個配置過程網上資料甚少,企業微信方也沒有在線支持,只依靠社區實現網友之間的相濡以沫,如果能再給我一次機會,我一定選別的app進行對接,慎重慎重。