钉钉离职OA审批提醒审批人审批通知脚本

钉钉离职OA审批提醒审批人审批通知脚本

个人博客

个人博客直达地址
网站不断完善中里面拥有大量的脚本,并且源码完全开放 欢迎纯白嫖。

效果图

在这里插入图片描述

概述

此脚本通过钉钉API自动化地发送离职审批通知。它会从指定的审批流程中获取相关审批实例,并在符合条件时,向相关人员发送离职通知。这对于企业人力资源管理尤其重要,能够确保在离职员工的最后工作日及时通知相关人员,便于工作交接。

功能说明

主要功能

  1. 获取钉钉Access Token

    • 脚本通过 get_access_token() 方法从钉钉服务器获取访问令牌(Access Token),以用于后续的API请求。
  2. 日期计算

    • 脚本计算当前日期时间以及两个月前的日期,并将这些日期转换为Unix时间戳(以毫秒为单位),以便在API请求中使用。
  3. 审批实例获取

    • 通过 Sample.create_client() 方法创建钉钉API客户端,循环获取指定审批流程的实例ID列表。
  4. 审批实例详情提取

    • 对于每个审批实例,脚本会提取表单中的“离职人员姓名”、“最后工作日”、“离职交接人”等关键信息,并判断是否需要发送通知。
  5. 钉钉消息发送

    • 在符合条件的情况下,脚本会自动向离职人员的交接人发送钉钉消息,提醒他们即将进行的交接工作。

使用方法

  1. 前置条件

    • 您需要具备钉钉企业管理员权限,并获取应用的 appkeyappsecret
    • 请将脚本中的 your_appkey_hereyour_appsecret_here 替换为实际的 appkeyappsecret
    • 替换脚本中的 your_process_code_here 为实际的审批流程代码。
    • 替换 your_webhook_url_herewww.your_url_here 为实际的钉钉Webhook URL和跳转链接。
  2. 运行脚本

    • 直接在终端运行此脚本,例如:python3 script.py
    • 脚本将自动执行,并在控制台输出相关信息和调试内容。
  3. 注意事项

    • 时间戳计算:脚本依赖于日期和时间的计算,确保系统时间设置正确。
    • API调用频率:如果钉钉API调用频率超出限制,可能会导致部分请求失败。
    • 网络连接:脚本需要稳定的网络连接以访问钉钉API。
    • 异常处理:脚本中包含异常处理逻辑,但建议定期查看日志以确保脚本运行正常。
    • 重复通知:脚本使用 sent_messages 集合来防止同一审批实例的重复通知。

代码块

#!/usr/bin/python3
# 导入所需库
import dingtalk.api
import re
import sys
from typing import List
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
from dateutil.relativedelta import relativedelta
from datetime import datetime, timedelta
from dateutil.parser import parse
from dateutil.parser._parser import ParserError
import time
import requests

start_time = time.time()

# 获取钉钉API的access_token
def get_access_token():
    req = dingtalk.api.OapiGettokenRequest("https://oapi.dingtalk.com/gettoken")
    req.appkey = "your_appkey_here"  # Replace with your actual appkey
    req.appsecret = "your_appsecret_here"  # Replace with your actual appsecret

    try:
        resp = req.getResponse()
        print(resp)  # 打印resp以查看返回值
        access_token = resp.get('access_token')
        return access_token
    except Exception as e:
        print(e)
        return None  # 在发生异常时返回None

access_token = get_access_token()
if access_token is not None:
    print("access_token的值为:" + access_token)
else:
    print("access_token的值为:None")

# 钉钉群机器人Webhook URL
webhook_url = "your_webhook_url_here"  # Replace with your actual webhook URL

# 定义当前日期时间、两个月前的日期
current_datetime = datetime.now()
current_date = current_datetime.date()
two_months_ago_date = current_date - relativedelta(months=2)

# 计算当前日期时间、当前日期、两个月前的日期的Unix时间戳(毫秒)
epoch = datetime(1970, 1, 1)
current_datetime_timestamp_ms = int((current_datetime - epoch).total_seconds()) * 1000
current_date_timestamp_ms = int((current_date - epoch.date()).total_seconds()) * 1000
two_months_ago_date_timestamp_ms = int((two_months_ago_date - epoch.date()).total_seconds()) * 1000

print("当前日期和时间:", current_datetime)
print("当前日期和时间的Unix时间戳(毫秒):", current_datetime_timestamp_ms)
print("当前日期:", current_date)
print("当前日期的Unix时间戳(毫秒):", current_date_timestamp_ms)
print("两个月前的日期:", two_months_ago_date)
print("两个月前的日期的Unix时间戳(毫秒):", two_months_ago_date_timestamp_ms)

class Sample:
    def __init__(self):
        pass

    # 创建钉钉API客户端
    @staticmethod
    def create_client() -> dingtalkworkflow_1_0Client:
        config = open_api_models.Config()
        config.protocol = 'https'
        config.region_id = 'central'
        return dingtalkworkflow_1_0Client(config)

    # 主要功能实现
    @staticmethod
    def main(args: List[str]) -> None:
        client = Sample.create_client()
        list_process_instance_ids_headers = dingtalkworkflow__1__0_models.ListProcessInstanceIdsHeaders()
        list_process_instance_ids_headers.x_acs_dingtalk_access_token = access_token

        next_token = 0
        sent_messages = set()  # 用于存储已发送过的消息,防止重复发送

        # 循环获取审批实例列表
        while True:
            list_process_instance_ids_request = dingtalkworkflow__1__0_models.ListProcessInstanceIdsRequest(
                start_time=two_months_ago_date_timestamp_ms,
                end_time=current_datetime_timestamp_ms,
                process_code='your_process_code_here',  # Replace with your actual process code
                next_token=next_token,
                max_results=20
            )
            try:
                # 获取审批实例列表
                response = client.list_process_instance_ids_with_options(list_process_instance_ids_request,
                                                                         list_process_instance_ids_headers,
                                                                         util_models.RuntimeOptions())
                # 获取下一页的Token
                fenye = response.body.result.next_token
                print("nextToken 的值为:", fenye)
                if not fenye:
                    break

                # 获取审批实例的ID列表
                list_values = response.body.result.list
                print("processInstanceId的值为:", list_values)

                # 遍历审批实例
                for process_instance_id in list_values:
                    userid = ""
                    get_process_instance_headers = dingtalkworkflow__1__0_models.GetProcessInstanceHeaders()
                    get_process_instance_headers.x_acs_dingtalk_access_token = access_token
                    get_process_instance_request = dingtalkworkflow__1__0_models.GetProcessInstanceRequest(
                        process_instance_id=process_instance_id
                    )
                    try:
                        # 获取单个审批实例的详情
                        instance_response = client.get_process_instance_with_options(get_process_instance_request,
                                                                                     get_process_instance_headers,
                                                                                     util_models.RuntimeOptions())
                        # 获取表单中的值
                        form_component_values = instance_response.body.result.form_component_values
                        leaving_employee_name = ""
                        last_working_day = ""
                        handover_person = ""
                        for component in form_component_values:
                            if component.name == "离职人员姓名":
                                leaving_employee_name = component.value
                            elif component.component_type == "DDDateField":
                                if component.name == "最后工作日" or component.name == "最后工作日(不计算假期)":
                                    last_working_day = component.value
                            elif component.name == "离职交接人":
                                handover_person = component.value

                        # 解析最后工作日
                        last_working_day_dt = parse(last_working_day)

                        # 判断是否需要发送通知
                        if last_working_day_dt.date() == current_date and leaving_employee_name not in sent_messages:
                            qwe = str(instance_response)

                            # 从审批实例中提取当前审批人ID
                            pattern = r"'status': 'RUNNING', 'taskId': \d+, 'userId': '(\d+)'"
                            match = re.search(pattern, qwe)
                            if match:
                                userid = match.group(1)
                                print(userid)
                            else:
                                print("OA流程已完成", qwe)
                                continue
                            current_time = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
                            # 构造并发送钉钉消息
                            req = dingtalk.api.OapiMessageCorpconversationAsyncsendV2Request("https://oapi.dingtalk.com/topapi/message/corpconversation/asyncsend_v2")
                            req.agent_id = 2575041888  # Replace with your actual agent ID
                            req.userid_list = userid
                            req.msg = {
                                "msgtype": "action_card",
                                "action_card": {
                                    "title": "OA离职审批通知",
                                    "markdown": f"表单名称:员工离职审批  \n审批ID:{process_instance_id}  \n离职人员姓名:{leaving_employee_name}  \n最后工作日:{last_working_day}  \n离职交接人:{handover_person}  \n发送时间{current_time}",
                                    "btn_json_list": [
                                        {
                                            "title": "OA离职审批通知",
                                            "action_url": "www.your_url_here"  # Replace with your actual URL
                                        }
                                    ],
                                    "btn_orientation": "0",
                                },
                                "userid_list": f"{userid}",
                                "to_all_user": False,
                                "agent_id": 2575041888,  # Replace with your actual agent ID
                            }

                            try:
                                # 发送钉钉消息
                                resp = req.getResponse(access_token)
                                print(resp)
                            except Exception as e:
                                print(e)

                    except Exception as err:
                        print(f"遇到错误:{err}")
                        continue

            except Exception as err:
                if not UtilClient.empty(err.code) and not UtilClient.empty(err.message):
                    pass
                break

            next_token = fenye

end_time = time.time()
print(f"脚本执行总时间为: {end_time - start_time}秒")

if __name__ == '__main__':
    Sample.main(sys.argv[1:])

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

脚本小能手

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

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

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

打赏作者

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

抵扣说明:

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

余额充值