Python sanic框架钉钉和第三方打卡机实现

同样还是需要开通钉钉应用这里就不错多说了

第一步:梳理逻辑流程

        前提:打卡的机器是使用postgres数据库,由于因为某些原因,钉钉userId 我已经提前获取到了存放到数据库里。

        1.用户打卡成功后,我们应该监听数据库进行查询,然后获取到打卡的时间,在通过钉钉的工作消息接口,发送消息给当前考勤打卡的用户,这样用户就可以知道我上班的打卡时间!

现在我们看看应该怎么去实现

先定义钉钉接口先Token:

appkey = ""
appsecret = ""
ding_url = "https://oapi.dingtalk.com/"async def dingTalkToken():async with httpx.AsyncClient() as client:response = await client.get(ding_url + 'gettoken', params={"appkey": appkey, "appsecret": appsecret})# 解析响应JSONresult = response.json()# 提取Access Tokenaccess_token = result.get("access_token")return access_token

钉钉工作消息接口

async def dingTalkTokenAsyncsend_v2(access_token, kqTime, userid):params = {"agent_id": ,"msg": {"msgtype": "text","text": {"content": "打卡成功:" + kqTime}},"userid_list": userid}async with httpx.AsyncClient() as client:response = await client.post(ding_url + 'topapi/message/corpconversation/asyncsend_v2?access_token=' + access_token, params=params)# 解析响应JSONresult = response.json()# 提取Access Tokenerrcode = result.get("errcode")return errcode

以上向钉钉工作发送消息的接口已经完成了

接下来就是核心代码:

async def check_notifications():print('执行')try:# 连接到数据库with psycopg2.connect(dbname=posql.dbname, user=posql.user, password=posql.password, host=posql.host,port=posql.port) as connection:# 创建一个游标对象,用于执行 SQL 语句with connection.cursor() as cursor:# 执行查询cursor.execute("LISTEN punch_event_channel")while True:connection.commit()  # 提交事务await asyncio.sleep(1)# 检查是否有通知connection.poll()  # 从服务器获取通知if connection.notifies:notify = connection.notifies[0]# 执行查询cursor.execute("这填写打卡系统的数据库使用ID去查询最新
SELECT * FROM table WHERE id = %s" % int(notify.payload))# 获取查询结果result = cursor.fetchone()columns = [desc[0] for desc in cursor.description]result_dict = dict(zip(columns, result))# 处理 datetime 对象的序列化result_dict['timestamp'] = result_dict.get('timestamp', None)if result_dict['timestamp']:result_dict['timestamp'] = datetime.fromisoformat(result_dict['timestamp'])kqTime = result_dict['att_date'] + ' ' + result_dict['att_time']# 获取用户IDuser_name = result_dict['person_name']sql_str = """EXEC GetUserDingByName @UserName = N'%s';""" % user_nameuser_id = query_user_info(sql_str)if user_id != 'null':# 发送HTTP POST请求获取Access Tokenaccess_token = await dingTalkToken()codes = await dingTalkTokenAsyncsend_v2(access_token, kqTime, user_id)print(f"考勤时间: " + result_dict['att_date'] + ' ' + result_dict['att_time'])breakelse:break# 去执行 钉钉推送模块# messages = '发送成功'else:print({"notify_payload": '没有消息'})await asyncio.sleep(1)except Exception as e:print({"error": str(e)})

解释一下代码:

 # 执行查询
cursor.execute("LISTEN punch_event_channel")

这里我是在考勤机器的数据库里做了一个punch_event_channel 的频道,而这个频道是我创建了一个触发函数用来触发最新数据库里的数据

接下来是创建触发函数

-- 创建触发器函数
CREATE OR REPLACE FUNCTION notify_punch_event()
RETURNS TRIGGER AS
$$
BEGINPERFORM pg_notify('punch_event_channel', 'new_punch_event');RETURN NEW;
END;
$$ LANGUAGE plpgsql;
-- 创建触发器,关联到表的 AFTER INSERT 事件上CREATE TRIGGER 触发器名称XXXXX
AFTER INSERT ON 表名
FOR EACH ROW 
EXECUTE PROCEDURE notify_punch_event();

在sql 工具执行这两句就可以了,替换成你自己的数据库

另外这里是我内部拿取钉钉Userid的数据库,我就不放代码了:

# 获取用户ID
user_name = result_dict['person_name']
sql_str = """EXEC GetUserDingByName @UserName = N'%s';""" % user_name
user_id = query_user_info(sql_str)

你们可以根据自己方式,来获取

最后,就是使用定时任务来

async def periodic_task():while True:await check_notifications()await asyncio.sleep(1)  # 1秒钟检查一次,可以根据需要调整间隔if __name__ == '__main__':# 启动定时任务app.add_task(periodic_task())# 启动 Sanic 应用app.run(host='0.0.0.0', port=8089, workers=8)

最后记得导入包

import psycopg2
import httpx
import pymssql # 这是sql server 数据库连接

如果写的好动动你们发财的小手点赞,对你有帮助也可以打赏请我喝杯咖啡,提提神,感谢各位兄弟了

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/582574.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

SuperMap iClient3D for WebGL实现浮动点效果

文章目录 前言一、update方法二、创建实体点三、效果 前言 基于SuperMap iClient3D for WebGL实现浮动点效果,原理就是不断改变实体的高度,这里我们选择使用CallbackProperty来实现。 一、update方法 var cc 0 var dd truevar update function() {i…

单文件超过4GB就无法拷贝到U盘?这个你一定要知道

前言 随着现在科技发展,小伙伴们所使用的数据也越变越大。还记得WindowsXP流行的时候,XP的镜像文件仅为几百MB大小。 但是现在随便一个系统就有可能超过4GB。 如果单个文件超过4GB就有可能没办法拷贝进U盘,在这里就需要给小伙伴们普及一下U…

python学习14

前言:相信看到这篇文章的小伙伴都或多或少有一些编程基础,懂得一些linux的基本命令了吧,本篇文章将带领大家服务器如何部署一个使用django框架开发的一个网站进行云服务器端的部署。 文章使用到的的工具 Python:一种编程语言&…

线上问题排查方案

在一次活动中,监控发现某个微服务中心服务的负载较高,数据库写入速度变慢,排查问题。 主要可从以下几个方面排查 1、生产日志级别 日志级别有 DEBUG、INFO、WARING、ERROR,检查生产环境的日志级别,日志打印多&#x…

浅谈IDC数据中心机房低压配电系统的组成与设计

随着我国移动互联网技术的不断发展,海量的数据资源日益庞大,IDC数据中心存储着这些大量的数据信息,其蕴含着巨大的研究和商业价值,因此数据中心IT设备的运行应具有较高的可靠性和稳定性。数据中心供配电系统是为机房内所有需要动力…

python关于hex读写的笔记

参考说明: 本文张部分参考如下连接文件 https://blog.csdn.net/marst437730201/article/details/128517936 嵌入式--Hex文件总结:Hex文件格式,Hex文件转bin文件_嵌入式芯片是hex吗-CSDN博客 1.了解hex文件 作为嵌入式软件工程师,h…

关于MySQL、分布式系统、SpringCloud面试题

前言 之前为了准备面试,收集整理了一些面试题。 本篇文章更新时间2023年12月27日。 最新的内容可以看我的原文:https://www.yuque.com/wfzx/ninzck/cbf0cxkrr6s1kniv MySQL 索引 说一下有哪些锁? 行锁有哪些? 性能优化 分库分表…

drf知识-08

Django之了解DRF框架 # 介绍:DRF全称 django rest framework # 背景: 在序列化与反序列化时,虽然操作的数据不尽相同,但是执行的过程却是相似的,也就是说这部分代码是可以复用简化编写的 增:校验请…

数组和字符串

1、概述 数组是在内存中连续的相同类型的变量空间数组属于构造数据类型 //数组定义 //数据类型 数组名[元素个数]{值1,值2,值3,……}; int arr[10]{9,8,7,6,5,4,3,2,1,0};//元素访问 //数组名[下标] //数组下标从0开始 for(int i0;i) {prin…

【《设计模式之美》】如何取舍继承与组合

文章目录 什么情况下不推荐使用继承?组合相比继承有哪些优势?使用组合、继承的时机 本文主要想了解: 为什么组合优于继承,多用组合少用继承。如何使用组合来替代继承哪些情况适用继承、组合。有哪些设计模式使用到了继承、组合。 …

项目——————————

C/C Linux Socket网络编程 TCP 与 UDP_c 语言tcp socket cleint read-CSDN博客C/C Socket - TCP 与 UDP 网络编程_c socket udp-CSDN博客 登录—专业IT笔试面试备考平台_牛客网

打地鼠游戏来了

主要利用js鼠标点击事件和window.setInterval()回调函数来进行实现的. 源码获取方式:链接:https://pan.baidu.com/s/1eW9qvX3zFH9qlH82-I4yOA 提取码:1233

信息安全概论快速复习(期末急救)

文章目录 1、DES中的S-盒输入输出问题 (不需要记住S-盒)2、Kerberos认证系统3、简答题(三题每题8分):课后习题第一章、第三章、第四章第一章:重点关注安全模型内容,有几种,有几个分级…

在matlab中进行地理坐标和像素坐标的相互转换

clc;close all;clear; %地理坐标和像素坐标的相互转换 [pic,R]geotiffread(boston.tif); %读取带地理坐标信息的tif影像 [m,n,~]size(pic);%像素坐标转换为地理坐标 figure(1),imshow(pic),title(不带地理坐标的静态图片); hold on; scatter(n/4,m/4,500,r.); %选择1/4处像素坐…

活动回顾 (下) | 机器学习系统趋势研判,大咖金句汇总

作者:三羊、李宝珠、李玮栋、Yudi、xixi 编辑:李宝珠 在大模型时代的浪潮中,机器学习系统正经历着前所未有的变革。模型规模的急剧膨胀,让我们见证了 AI 能力的巨大提升,然而这种提升不仅为各个领域带来了新的机遇&…

音视频的编码格式与封装格式

音视频的编码格式与封装格式是两个不同的概念,视频封装格式常见的有:mp4,rmvb,avi,mkv,mov,mpg,vob,3gp,asf,rmvb,wmv,div…

关于设计模式、Java基础面试题

前言 之前为了准备面试,收集整理了一些面试题。 本篇文章更新时间2023年12月27日。 最新的内容可以看我的原文:https://www.yuque.com/wfzx/ninzck/cbf0cxkrr6s1kniv 设计模式 单例共有几种写法? 细分起来就有9种:懒汉&#x…

lv13 内核模块动态添加新功能 6

1 动态加载法 即新功能源码与内核其它源码不一起编译,而是独立编译成内核的插件(被称为内核模块)文件.ko 1.1 新功能源码与Linux内核源码在同一目录结构下时 给新功能代码配置Kconfig(模块代码与上一级相同) 给新功能代码改写…

C++自学笔记006左值引用和右值引用

C自学笔记006左值引用和右值引用 无论左值引用还是右值引用,都是给对象取别名。 左值引用 左值引用就是对左值的引用,给左值取别名。 int& ref_data1 data1; int*& ref_ptr_data1 ptr_data1; int& ref_data2 *ptr_data2; const int&a…

基于SpringBoot的仓库管理系统

文章目录 项目介绍主要功能截图:部分代码展示设计总结项目获取方式🍅 作者主页:超级无敌暴龙战士塔塔开 🍅 简介:Java领域优质创作者🏆、 简历模板、学习资料、面试题库【关注我,都给你】 🍅文末获取源码联系🍅 项目介绍 基于SpringBoot的仓库管理系统,java项目…