python 获取钉钉审批流数据

第一章 Python 获取钉钉OA审批流数据


文章目录

  • 第一章 Python 获取钉钉OA审批流数据
  • 前言
  • 一、钉钉是什么?
  • 二、使用步骤
    • 1.准备条件
    • 2.引入库
    • 3.写代码
  • 总结


前言

随着社会的不断发展,使用钉钉的企业也越来越多,本文就介绍了python获取钉钉审批流数据。

一、钉钉是什么?

   钉钉是一款由阿里巴巴集团开发的企业通讯和协作工具,类似于Slack或Microsoft Teams。它提供了即时通讯、视频会议、日程安排、文件共享等功能,旨在帮助企业提高沟通效率和团队协作能力。钉钉在中国以及全球范围内被广泛应用于企业办公和团队协作中。。

二、使用步骤

1.准备条件

需要去钉钉后台获取开发者权限,新建一个应用,将OA权限赋予该应用,并获得appkey ,appscret

2.引入库

代码如下(示例):

import os, sys, time, datetime, traceback
import ast
import requests
from cffi.backend_ctypes import long
from alibabacloud_dingtalk.workflow_1_0.client import Client as dingtalkworkflow_1_0Client
from alibabacloud_tea_openapi import models as open_api_models
from alibabacloud_dingtalk.workflow_1_0 import models as dingtalkworkflow__1__0_models
from alibabacloud_tea_util import models as util_models
from alibabacloud_tea_util.client import Client as UtilClient

3.写代码

代码如下(示例):

# 固定- 将当前py文件所在文件夹加入环境
present_dir = os.path.dirname(os.path.abspath(__file__))
sys.path.append(present_dir)

# 固定- 将当前py文件所在文件夹的上级文件夹路径加入环境
father_dir = os.path.dirname(present_dir)
sys.path.append(father_dir)

# 初始化路径
token_path = os.path.join(present_dir, 'token.txt')
process_path = os.path.join(present_dir, 'process.txt')


def strtime_to_datetime(timestr):
    """将字符串格式的时间 (含毫秒) 转为 datetime 格式
    :param timestr: {str}'2016-02-25 20:21:04.242'
    :return: {datetime}2016-02-25 20:21:04.242000
    """
    res = datetime.datetime.strptime(timestr, "%Y-%m-%d %H:%M:%S")
    res = datetime.datetime.strftime(res, "%Y-%m-%d %H:%M:%S.%f")
    local_datetime = datetime.datetime.strptime(res, "%Y-%m-%d %H:%M:%S.%f")
    return local_datetime


def datetime_to_timestamp(datetime_obj):
    """将本地(local) datetime 格式的时间 (含毫秒) 转为毫秒时间戳
    :param datetime_obj: {datetime}2016-02-25 20:21:04.242000
    :return: 13 位的毫秒时间戳  1456402864242
    """
    local_timestamp = long(time.mktime(datetime_obj.timetuple()) * 1000.0 + datetime_obj.microsecond / 1000.0)
    return local_timestamp


def strtime_to_timestamp(local_timestr):
    """将本地时间 (字符串格式,含毫秒) 转为 13 位整数的毫秒时间戳
    :param local_timestr: {str}'2016-02-25 20:21:04.242'
    :return: 1456402864242
    """
    local_datetime = strtime_to_datetime(local_timestr)
    timestamp = datetime_to_timestamp(local_datetime)
    return timestamp


class DingTalkClass:
    def __init__(self, appkey, appsecret):
        self.appkey = appkey
        self.appsecret = appsecret
        self.access_token = {'access_token': '', 'get_time': ''}

    def get_token(self):
        """
            获取 token  token 有效期两个小时
        :return:
        """
        if os.path.exists(token_path):
            with open(token_path, 'r+') as f:
                res = f.read()
                if res != '':
                    self.access_token = ast.literal_eval(res)

        # 比较时间
        now_time = datetime.datetime.now()
        if self.access_token['get_time'] != '':
            last_get_time = strtime_to_datetime(self.access_token['get_time'])
            # 上一次的token 时间加上120分钟
            minutes_120 = last_get_time + datetime.timedelta(minutes=120)
            # 判断上一次获取token 的时间是否小于当前时间
            if minutes_120 < now_time:
                print('重新获取token')
            else:
                print('历史获取token')
                return
        else:
            print('获取token')
        get_token_url = "https://oapi.dingtalk.com/gettoken?appkey={}&appsecret={}".format(self.appkey, self.appsecret)

        try:
            resp = requests.get(url=get_token_url).json()
            self.access_token['access_token'] = resp['access_token']
            self.access_token['get_time'] = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time()))
            # 更新token.txt 的内容
            with open(token_path, 'w') as f:
                f.write(str(self.access_token))
        except Exception as e:
            print(e)

    @staticmethod
    def create_client() -> dingtalkworkflow_1_0Client:
        """
        使用 Token 初始化账号Client
        @return: Client
        @throws Exception
        """
        config = open_api_models.Config()
        config.protocol = 'https'
        config.region_id = 'central'
        return dingtalkworkflow_1_0Client(config)

    def get_userVisibilities(self):
        """
            获取指定用户可见的审批表单列表
        :return:
        """
        client = DingTalkClass.create_client()
        list_user_visible_bpms_processes_headers = dingtalkworkflow__1__0_models.ListUserVisibleBpmsProcessesHeaders()
        list_user_visible_bpms_processes_headers.x_acs_dingtalk_access_token = self.access_token['access_token']
        list_user_visible_bpms_processes_request = dingtalkworkflow__1__0_models.ListUserVisibleBpmsProcessesRequest(
            max_results=100,
            next_token=0
        )
        try:
            res = client.list_user_visible_bpms_processes_with_options(list_user_visible_bpms_processes_request,
                                                                       list_user_visible_bpms_processes_headers,
                                                                       util_models.RuntimeOptions())

            res_dict = {}
            for i in res.body.result.process_list:
                res_dict[i.name] = i.process_code
            with open(process_path, 'w+') as f:
                f.write(str(res_dict))
        except Exception as e:
            traceback.print_exc()
            # if not UtilClient.empty(err.code) and not UtilClient.empty(err.message):
            # err 中含有 code 和 message 属性,可帮助开发定位问题
            # pass

    def get_process_code(self, pro_name):
        """
            获取流程得 code
        :param pro_name:
        :return:
        """
        if os.path.exists(process_path):
            print('获取历史数据')
        else:
            self.get_userVisibilities()
        with open(process_path, 'r+') as f:
            res = ast.literal_eval(f.read())
            return res[pro_name]

    def get_instanceIds_query(self, process_code, next_token, max_results, start_time, end_time):
        """
        获取审批实例ID列表
        :return:
        """
        print('获取审批实例ID列表')
        client = DingTalkClass.create_client()
        list_process_instance_ids_headers = dingtalkworkflow__1__0_models.ListProcessInstanceIdsHeaders()
        list_process_instance_ids_headers.x_acs_dingtalk_access_token = self.access_token['access_token']
        list_process_instance_ids_request = dingtalkworkflow__1__0_models.ListProcessInstanceIdsRequest(
            process_code=process_code,
            next_token=next_token,
            max_results=max_results,
            start_time=start_time,
            end_time=end_time
        )
        try:
            res = client.list_process_instance_ids_with_options(list_process_instance_ids_request,
                                                                list_process_instance_ids_headers,
                                                                util_models.RuntimeOptions())

            all_sl_list = res.body.result.list
            return all_sl_list
        except Exception as err:
            print(err)
            if not UtilClient.empty(err.code) and not UtilClient.empty(err.message):
                # err 中含有 code 和 message 属性,可帮助开发定位问题
                pass

    def get_processInstances(self, process_instance_id):
        """
            获取单个审批实例详情
        :return:
        """
        client = DingTalkClass.create_client()
        get_process_instance_headers = dingtalkworkflow__1__0_models.GetProcessInstanceHeaders()
        get_process_instance_headers.x_acs_dingtalk_access_token = self.access_token['access_token']
        get_process_instance_request = dingtalkworkflow__1__0_models.GetProcessInstanceRequest(
            process_instance_id=process_instance_id
        )
        try:
            res = client.get_process_instance_with_options(get_process_instance_request, get_process_instance_headers,
                                                           util_models.RuntimeOptions())
            data = []
            for one in ast.literal_eval(res.body.result.form_component_values[0].value):
                data.append({two['label']: two['value'] for two in one['rowValue']})
            return data
        except Exception as err:
            if not UtilClient.empty(err.code) and not UtilClient.empty(err.message):
                # err 中含有 code 和 message 属性,可帮助开发定位问题
                pass


def start():
    # 获取配置参数
    appkey = 'AppKey'
    appsecret = 'AppSecret'
    ding_cls = DingTalkClass(appkey, appsecret)
    ding_cls.get_token()  # 获取token
    # 查询数据的开始时间和结束时间
    start_time = '2024-01-01 20:08:43'
    end_time = '2024-01-07 20:08:43'
    # 流程名称
    process_name = '流程名称'
    print('start_time:', start_time, 'end_time:', end_time)
    start_time_c = strtime_to_timestamp(start_time)  # 1678032000000
    end_time_c = strtime_to_timestamp(end_time)
    data = []
    print('process_name', process_name)
    process_code3 = ding_cls.get_process_code(process_name)
    print('process_code3', process_code3)
    # 前20条
    process_list = ding_cls.get_instanceIds_query(process_code3, 0, 20, start_time_c, end_time_c)  # 查询时间下得表单
    for one in process_list:
        one_process_instance_id = one
        res3 = ding_cls.get_processInstances(one_process_instance_id)  # 查询时间下得表单
        data.extend(res3)
    print(data)
    print('钉钉数据{}条'.format(len(data)))
    return data


if __name__ == '__main__':
    start()



总结

以上就是今天要讲的内容,本文仅仅简单介绍了python获取钉钉数据流方式

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

上官浩炀

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值