Python3.7配合Django2.0來調(diào)用釘釘(dingding)在線api實時監(jiān)測員工考勤打卡情況

原文轉載自「劉悅的技術博客」https://v3u.cn/a_id_147

新冠疫情期間,大多數(shù)公司為了避免交叉感染都或多或少的采用了遠程辦公的方式,這顯然是一個明智的選擇,基本上釘釘(dingding)作為一個遠程辦公平臺來用的話,雖然差強人意,但是奈何市面上沒有啥更好的選擇,矬子里拔將軍,也還是可以湊合用的,不過遠程辦公有個問題,就是每天需要檢查員工的考勤,居家辦公雖然靈活,但是大家究竟有沒有辦公,則是另外一回事,釘釘提供的解決方案就是考勤在線打卡功能,但是檢查出勤釘釘在移動端就有點費勁,需要在釘釘app里點擊至少5次,還不能實時刷新,pc端的釘釘oa系統(tǒng)做的更爛,還不如移動端來得方便,另外如果你在一家上千人的企業(yè)里,這家企業(yè)有大大小小幾十個部門,你又非常倒霉的擔任這家公司的人事主管,每天按部門來出員工考勤報表就不是一件容易事了,所以利用釘釘開放的接口,使用Django自己打造一套實時監(jiān)控員工考勤的web平臺是我們本次的目的。

項目背景是一家普通科技公司,大概有五個部門,每個部門100人左右

image

首先進入釘釘開放平臺 :open-dev.dingtalk.com

在企業(yè)內(nèi)部開發(fā)中,選擇小程序,新建一個小程序應用,這里其實也還有別的選擇,比如h5微應用,主要是小程序兼容性更好一點。

填寫應用的名稱、簡介、Logo等基本信息這些按下不表,按照要求填寫即可,也不必非得填寫真實信息,這里有個坑就是一定不要忘了配置安全域名或者ip,安全域名是當我們的檢測平臺上線的時候部署的域名,應用可以跟指定的域名進行網(wǎng)絡通信,如果不配置的話,請求釘釘接口會報403錯誤。

image

另外還有一個坑,也就是釘釘默認開放的接口僅限于基礎權限接口

image

如果需要考勤或者簽到接口的話,還得單獨點擊申請,這就有點讓人看不懂了,那么多接口,全都得靠用鼠標點擊開通,不開通就用不了,這個用戶體驗真是讓人非常酸爽,產(chǎn)品設計成這樣,釘釘?shù)膒m難辭其咎。

image

OK,前置準備工作就已經(jīng)就緒了,現(xiàn)在我們只要根據(jù)官方文檔來寫接口就可以了,選擇服務端api文檔:https://ding-doc.dingtalk.com/doc#/serverapi2/gh60vz

釘釘考勤打卡的接口說明是這樣的:

該接口用于返回企業(yè)內(nèi)員工的實際打卡記錄。比如,企業(yè)給一個員工設定的排班是上午9點和下午6點各打一次卡,但是員工在這期間打了多次,該接口會把所有的打卡記錄都返回。

如果只要獲取打卡結果數(shù)據(jù),不需要詳情數(shù)據(jù),可使用獲取打卡結果接口。

請求方式:POST(HTTPS)

請求地址:https://oapi.dingtalk.com/attendance/listRecord?access_token=ACCESS_TOKEN

請求包結構體:

{
"userIds": ["001","002"],
"checkDateFrom": "yyyy-MM-dd hh:mm:ss",
"checkDateTo": "yyyy-MM-dd hh:mm:ss",
"isI18n":"false"
}

這里每個接口都需要一個access_token用來鑒權,這個token是用id和秘鑰通過接口交換回來的,具體在應用詳情里可以獲取

image

這里我們封裝成方法

import requests  
  
appkey = '你的key'  
appsecret = '你的秘鑰'  
  
api_url = "https://oapi.dingtalk.com/gettoken?appkey=%s&appsecret=%s"%(appkey,appsecret)  
  
def get_token():  
    res = requests.get(api_url)  
    if res.status_code == 200:  
        str_res = res.text  
        token = (json.loads(str_res)).get('access_token')  
        return token

搞定了token,還需要獲取您的部門下所有員工的員工id,因為考勤接口參數(shù)只能接受員工id,而非部門id

#獲取用戶id  

token = get_token()  
  
#獲取用戶id  
res = requests.get('https://oapi.dingtalk.com/user/simplelist?access_token=%s&department_id=235636048' % token)  
str_res = res.text  
res = json.loads(str_res)  
ids = []  
id_name = {}  
for val in res['userlist']:  
    ids.append(val['userid'])  
    id_name[val['userid']] = val['name']  
  
n = 50  #大列表中幾個數(shù)據(jù)組成一個小列表  
l = ids  
biglist = [l[i:i + n] for i in range(0, len(l), n)]


最后請求考勤接口即可

result_all = []  
  
#請求打卡接口  
for x in biglist:  
    res = requests.post('https://oapi.dingtalk.com/attendance/list?access_token=%s' % token,json ={'access_token':token,'workDateFrom':'%s 00:00:00' % mydate,'workDateTo':'%s 10:00:00' % mydate,'userIdList':str(x),'offset':0,'limit':50})  
    str_res = res.text  
    #print(str_res)  
    res = json.loads(str_res)  
    for xy in res['recordresult']:  
        result_all.append(xy)  
  
slist = []  
for val in result_all:  
    if val['timeResult'] == 'NotSigned':  
        print(val['timeResult'])  
        mydic = {}  
        mydic[id_name[val['userId']]] = '未打卡'  
        slist.append(mydic)

完整的后臺Django后臺接口

import requests  
from rest_framework.response import Response  
from rest_framework.views import APIView  
import time  
  
appkey = '你的key'  
appsecret = '你的秘鑰'  
  
api_url = "https://oapi.dingtalk.com/gettoken?appkey=%s&appsecret=%s"%(appkey,appsecret)  
  
def get_token():  
    res = requests.get(api_url)  
    if res.status_code == 200:  
        str_res = res.text  
        token = (json.loads(str_res)).get('access_token')  
        return token  
  
class GetQianHandler(APIView):  
  
    def get(self,request):  
  
  
        mydate = request.GET.get('date',None)  
  
        if mydate == None:  
  
            return Response({'message':'需要傳遞日期'})  
  
          
        dt_start = '%s 00:00:00' % mydate  
        dt_end = '%s 23:59:59' % mydate  
        ts_start = int(time.mktime(time.strptime(dt_start, "%Y-%m-%d %H:%M:%S"))) * 1000  
        ts_end = int(time.mktime(time.strptime(dt_end, "%Y-%m-%d %H:%M:%S"))) * 1000  
  
        token = get_token()  
  
        #獲取用戶id  
        res = requests.get('https://oapi.dingtalk.com/user/simplelist?access_token=%s&department_id=235636048' % token)  
        str_res = res.text  
        res = json.loads(str_res)  
        ids = []  
        id_name = {}  
        for val in res['userlist']:  
            ids.append(val['userid'])  
            id_name[val['userid']] = val['name']  
  
        n = 50  #大列表中幾個數(shù)據(jù)組成一個小列表  
        l = ids  
        biglist = [l[i:i + n] for i in range(0, len(l), n)]  
  
        result_all = []  
  
        print('workDateFrom %s 00:00:00' % mydate)  
  
        #請求打卡接口  
        for x in biglist:  
            res = requests.post('https://oapi.dingtalk.com/attendance/list?access_token=%s' % token,json ={'access_token':token,'workDateFrom':'%s 00:00:00' % mydate,'workDateTo':'%s 10:00:00' % mydate,'userIdList':str(x),'offset':0,'limit':50})  
            str_res = res.text  
            #print(str_res)  
            res = json.loads(str_res)  
            for xy in res['recordresult']:  
                result_all.append(xy)  
  
        slist = []  
        for val in result_all:  
            if val['timeResult'] == 'NotSigned':  
                print(val['timeResult'])  
                mydic = {}  
                mydic[id_name[val['userId']]] = '未打卡'  
                slist.append(mydic)  
  
        return Response(slist)

這樣,就可以愉快的通過線上平臺來實時監(jiān)測部門員工考勤了,效果是這樣的:

image

原文轉載自「劉悅的技術博客」 https://v3u.cn/a_id_147

?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

友情鏈接更多精彩內(nèi)容