python对接钉钉加解密实践

寵の児 提交于 2020-03-17 04:58:24

声明:小白,代码比较菜敬请见谅。

需求

通过钉钉的自定义审批流,触发我们自己写的接口(系统or平台)触发后续动作。(特别注意,钉钉接口不支持修改审批状态,故无法实现审批自动化,很好理解,毕竟产品的设计是有它存在的道理,啥都自动了还要审批干啥
1.我是win10系统,用的python3.7, web框架flask,用的三方sdk,解决加解密问题
2.官方提供了个python sdk,用的python2 但是没有提供注册接口回调的加解密功能。
3.结论,使用三方sdk,不用官方sdk,其余操作通过调用钉钉接口处理,很简单。

参考文档

钉钉官方服务端文档:https://open-doc.dingtalk.com/microapp/serverapi2
三方sdk:https://dingtalk-sdk.readthedocs.io/zh_CN/latest/
回调管理:https://ding-doc.dingtalk.com/doc#/serverapi2/pwz3r5
回调列表:https://ding-doc.dingtalk.com/doc#/serverapi2/skn8ld

开始

到钉钉开放平台 — 企业内部开发 —创建应用(值得注意的是接口权限这里单独需要开通,根据情况来就行)
在这里插入图片描述
在这里插入图片描述

代码结构

在这里插入图片描述

app.py


# 首页
from devops import app

@app.route('/')
def hello_world():
    return 'Hello World!'


if __name__ == '__main__':
    app.run(host='0.0.0.0', port=5000, debug=True, threaded=True)

devops/init.py



# coding=utf-8
from flask import Flask, render_template, request

# static_url_path 后的配置相当于增加虚拟目录
app = Flask(__name__, static_url_path='/static')
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
app.config['SQLALCHEMY_COMMIT_ON_TEARDOWN'] = True
app.config['SECRET_KEY'] = 'xxxxxxxxxxxxxxxxxxxxxx'


# 使用flask-restful管理api
from flask_restful import Api

restfulapi = Api(app)

from devops.api.event_callback import EventCallBack

restfulapi.add_resource(EventCallBack, '/api/v1.0/resource_back')

查看:https://open-dev.dingtalk.com/#/index
在这里插入图片描述

devops/api/event_callback.py

from dingtalk.crypto import DingTalkCrypto
import time
from flask import make_response
from flask_restful import Resource, request
import demjson

class Crypto(object):
  def __init__(self):
    # 随便填的字符串
    self.token = '123456'
    # 自己生成的43位随机字符串
    self.aes_key = '123456xxlvdhntotr3x9qhlbytb18zyz5zxxxxxxxxx'
    # 钉钉企业ID(注意这个要在首页获取,不是appkey,这块卡了好久,请看上图)
    self.corpid = '你自己的CorpID'
    self.crypto = DingTalkCrypto(
      token=self.token,
      encoding_aes_key=self.aes_key,
      corpid_or_suitekey=self.corpid
    )


class EventCallBack(Resource):
    def __init__(self):
        self.crypto = Crypto().crypto
    def get(self):
        return "event callback!"

    def post(self):
        for k, v in request.values.items():
            print(k, v)
        po = request.json["encrypt"]
        data = request.values

        # 返回加密success
        result = self.crypto.encrypt_message(
            msg="success"
        )
        print(result)

        return make_response(result)



在这里插入图片描述

devops/api/test.py

import json
import requests

# 根据 appkey 和 appsecret 获取 access_token
def GetToken():
	# 如何获取看上图
    appkey = "xxx"
    appsecret = "xxxxxxx"
    try:
        request = requests.get(
            "https://oapi.dingtalk.com/gettoken?appkey={appkey}&appsecret={appsecret}".format(appkey=appkey,
                                                                                              appsecret=appsecret))
        return request.json()["access_token"]
    except Exception as e:
        print(e)


# 注册回调
def RegisterCallback(access_token):
    # access_token = GetToken()
	# 这里参数具体含义参考 回调管理:https://ding-doc.dingtalk.com/doc#/serverapi2/pwz3r5
	# 下面的url参数是你本地能访问到的公网地址(或内网穿透地址)
    data = {'call_back_tag': ['bpms_task_change', 'bpms_instance_change'], 'token': '123456',
            'aes_key': '123456xxlvdhntotr3x9qhlbytb18zyz5zxxxxxxxxx',
            'url': "http://zhangzd.vaiwan.com/api/v1.0/resource_back"}
    headers = {"Content-Type": "application/json"}
    data = json.dumps(data)
    url = "https://oapi.dingtalk.com/call_back/register_call_back?access_token={access_token}".format(
        access_token=access_token)
    print(url)
    print(data)
    try:
        req = requests.post(url=url, data=data, headers=headers)
        print(req.text)
    except Exception as e:
        print(e)

# 查看事件回调接口
def GetCallback(access_token):
    try:
        url = "https://oapi.dingtalk.com/call_back/get_call_back?access_token={access_token}".format(access_token=access_token)
        request = requests.get(url)
        print(request.text)
    except Exception as e:
        print(e)


access_token = GetToken()
print(access_token)
RegisterCallback(access_token)
GetCallback(access_token)

注意

  1. flask项目先启动,准备接受钉钉回调
  2. 执行test.py注册回调,这时候钉钉会回调flask项目自定义接口
  3. 执行结果
    在这里插入图片描述

附内网穿透工具

clone  git仓库执行命令:git clone https://github.com/open-dingtalk/pierced.git 
cd windows_64
# 下面命令的参数 subdomain随便修改下,最终访问地址为:zhangzd.vaiwan.com。  5000是映射到flask项目的端口
# 浏览器如果不能访问,就重启试试
./ding -config=ding.cfg -subdomain=zhangzd 5000
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!