menu Chancel's blog
rss_feed
Chancel's blog
有善始者实繁,能克终者盖寡。

让钉钉自动打卡的Bash脚本

作者:Chancel Yang, 创建:2019-10-11, 字数:5255, 已阅:1021, 最后更新:2019-10-11

这篇文章更新于 1651 天前,文中部分信息可能失效,请自行甄别无效内容。

最近公司更换了钉钉作为打卡,万幸的是仅做打卡,不做任何消息通知,点个赞!不过公司也没有开启快速打卡,所以放个备用手机在公司自动打卡的想法落空了,必须远程操作了,首先想到虚拟机,查了一下发现虚拟机会被钉钉屏蔽(不确定)出于稳定性考虑,真机更靠谱一些,再说工作了几年的人谁没个Android的老机器?结合Android的网络ADB调试,抱着这个想法完成了自动打卡的Bash脚本

条件要求

  • 一台能装钉钉的Android手机(手机版本不能太低,低于4.2adb缺少一些必要功能)
  • 一台支持Adb的设备
  • 可选
    1. Wifi - 用于网络调试,去掉usb线的困扰
    2. Root - 用于开机自动加载网络调试

本文基于远程网络调试,如果你没有wifi,需要手动更改提供的脚本(删掉adb网络连接设备部分即可)

代码已发布在 钉钉自动签到Bash脚本(超简Bash,可自定义修改扩展)- github.com,欢迎star

准备

准备1.usb调试模式

手机需要开启开发者模式,大部分Android手机只需要在关于手机里面点击内核版本5次即可,开启开发者选项之后进入开发者选项,并勾选usb调试模式

准备2.PC安装adb驱动

Linux大部分发行版自带adb驱动,Windows需要到Google下载Adb安装,Windows Adb下载地址

安装成功后,手机连接PC,在命令行界面下尝试输入 adb devices,如果能看到你的设备说明安装成功

准备3.网络调试(可选)

手机如果需要网络调试,必须得有Wifi这个就不说了,用usb连接手机之后,使用"adb shell tcpip 5555"可以打开手机adb网络调试模式,缺点是一旦重启手机网络调试模式就失效了。

如果想要重启仍然保持改效果,则需要使用RE文件管理器/ES文件管理器之类的修改/system/build.prop文件,并在文件最后增加

TEXT
adb.service.tcp.port=5555 # 端口可自定义,需要Root权限

adb与bash

关于制作这个脚本其实只需要了解一些简单的adb操作跟bash语法就没问题了,了解一些关于Bash脚本的基础知识,之前也有过一篇博文简单介绍过Bash的语法学习使用Bash制作一键备份文件夹和MySQL的通用脚本 - chancel.cn

至于adb操作,本文用到的也就以下几个操作,更加详细的可以参考 adb help 或adb文档,只要掌握下面几个adb操作,就可以调整本文提供的脚本了

TEXT
# 杀死adb连接
adb kill-server
# 连接网络调试手机
adb connect ip:port
# 查看当前连接的手机列表
adb devices
# 启动/停止app
adb shell am start -n package/Activity
adb shell am force-stop package
# 获取app启动的package/Activity名称(需要启动app后执行这句话)
"dumpsys window windows | grep "Current"
# 按电源键
adb shell input keyevent 26  
# 点击/拖动屏幕                                                                                                                                          adb shell input tap 540 1850
adb shell input swipe 500 700 500 50

编写

编写之前要确定打卡的基本流程

  1. adb连接手机
  2. adb点亮屏幕
  3. adb滑动屏幕解锁(如果手机系统支持直接进入主页面就更好了)
  4. adb启动APP
  5. APP界面内利用adb点击/滑动完成打卡操作
  6. adb关闭APP
  7. adb锁屏

请注意,因为手机分辨率大小不一,涉及到 点击/滑动操作的需要自行更改坐标 TIP

  • 测试坐标的方法很简单,在开发者选项里勾选指针位置,即可在屏幕上方看到当前点击的坐标位置,确定1个坐标位置就可以点击,2个坐标位置则可以实现滑动

基于以上流程,我们可以制作出一个简易但具备以上所有步骤的bash脚本(1080P分辨率测试通过)

TEXT
#!/bin/bash
########################################################################################################################
# @params phone_adb_url 手机网络调试地址
# @params dingding_package 钉钉的主页包名(如何获取查看下面说明)
# Tip:
#       手机打开钉钉,在adb模式下输入"dumpsys window windows | grep "Current"
#       输出为 mCurrentFocus=Window{424168a8 u0 com.alibaba.android.rimet/com.alibaba.android.rimet.biz.LaunchHomeActivity
#       com.alibaba.android.rimet/com.alibaba.android.rimet.biz.LaunchHomeActivity 即钉钉的包/主页
########################################################################################################################

phone_adb_url="192.168.10.120:5555"
dingding_package="om.alibaba.android.rimet/com.alibaba.android.rimet.biz.LaunchHomeActivity"

<<COMMENT
    $1 => 提示语
    $2 => 时间(秒)
COMMENT
wait_tip(){
    echo -n $1
    i=$2
    while(($i>1))
    do
        echo -n "."
        sleep 1s
        let i--
    done
    echo ""
}

# 连接手机
adb kill-server
adb connect $phone_adb_url
wait_tip "连接手机" 5

echo "手机adb连接列表"
adb devices
devices=`adb devices`
if [[ $devices =~ $phone_adb_url ]]
then
    echo "连接成功!"
else
    echo "错误:没有连接到设备"
    wait_tip "自动打卡失败,程序正在退出" 3
    exit 1
fi

# 初始化状态
adb shell am force-stop com.alibaba.android.rimet
wait_tip "初始化状态" 5

adb shell input keyevent 26                                                                                                                                                             
adb shell input swipe 500 700 500 50
wait_tip "解锁手机" 5

# 根据查找到的钉钉包名称启动钉钉
adb shell am start -n com.alibaba.android.rimet/com.alibaba.android.rimet.biz.LaunchHomeActivity
wait_tip "启动钉钉" 5
wait_tip "等待钉钉加载成功" 20

# 点击打卡界面,进入打卡,滑动界面,再点击打卡
adb shell input tap 540 1850
wait_tip "加载应用界面" 20
i=0
while(($i > 3))
do
    adb shell input swipe 500 300 500 1600              # 循环多次保证滑到最顶
    let i++
done
adb shell input swipe 500 1650 500 1000
adb shell input swipe 500 1650 500 1000
wait_tip "定位打卡入口" 5
adb shell input tap 140 450
wait_tip "进入打卡界面" 20

y=700
punch=0
echo -n "开始打卡"
while(($punch < 7))
do
    adb shell input tap 550 $y
    let y=y+100
    let punch++
    echo -n "."
    sleep 1s
done

# 关闭钉钉
adb shell am force-stop com.alibaba.android.rimet
wait_tip "打卡结束,正在关闭钉钉,拜拜!" 3

测试

如果你是1080P分辨率的手机,请在确认usb网络调试正常的情况下

保存上面编写的脚本到本地(假设保存为up.sh),并更改上方脚本的 phone_adb_url变量后直接执行脚本,然后观察手机执行效果即可

TEXT
chmod +x up.sh
./up.sh

如果一切正常,你就可以看到手机一步一步的完成了打卡过程

扩展

扩展1.自动打卡

将脚本设置为定时执行,保证手机待机(正常情况下手机单独开wifi不做其他设置的情况下待机5天是比较轻松的)且Wifi畅通的情况下,可以做到执行脚本后自动打卡

扩展2.远程打卡

上面的脚本只是完成了自动打卡,当然脚本可以设置为多次执行来保证成功效果,但心里总是没谱,再说定时执行很惹人怀疑,你总是那个点打卡是吧,如果你有一个vps或者内网穿透的方法,我们可以利用Python来做到远程打卡

写一个简单的Web服务器,基于Flask,首先安装Flask

TEXT
pip install flask

创建一个文件夹,将你的自动打卡脚本放置到目录下,创建一个 app.py,输入下面的内容

TEXT
from flask import Flask
import os

app = Flask(__name__)

@app.route('/',methods=["GET"])
def index():
     process = os.popen('/opt/goto_fucking_work/goto_fucking_work.sh')
     output = process.read()
     process.close()
     return output

app.run(host='0.0.0.0',port=30000)

运行 python app.py,访问http://127.0.0.1:30000/,程序会自动执行脚本

最后利用内网穿透暴露出端口,将程序保存在后台运行,只要你的设备不关机,访问该端口就可自动执行打卡程序还会输出执行结果!

你就变成一个勤奋上班的人了


[[replyMessage== null?"发表评论":"发表评论 @ " + replyMessage.m_author]]

account_circle
email
web_asset
textsms

评论列表([[messageResponse.total]])

还没有可以显示的留言...
[[messageItem.m_author]] [[messageItem.m_author]]
[[messageItem.create_time]]
[[getEnviron(messageItem.m_environ)]]
[[subMessage.m_author]] [[subMessage.m_author]] @ [[subMessage.parent_message.m_author]] [[subMessage.parent_message.m_author]]
[[subMessage.create_time]]
[[getEnviron(messageItem.m_environ)]]