Windows搭建PaddleOCR+飞书Webhook自动打卡通知机器人:识别、推送与远程触发完整教程

前言

很多办公自动化项目真正麻烦的不是“写一段脚本”,而是要把几个不同环节串起来:图片从哪里来、OCR怎么识别、识别结果怎么通知、出了问题又从哪一步排查。

这篇文章演示的是一条比较典型的Windows自动化链:把打卡截图放进指定目录,用PaddleOCR读取图片文字,再通过飞书Webhook把识别结果推送到群聊。基础链跑通以后,再用Flask提供一个HTTP触发接口,最后通过cpolar把本地5000端口扩展到外网访问。

整套流程适合用来练习OCR、Webhook、Python请求和Web接口之间的组合,也可以改造成巡检截图识别、表单截图通知、任务完成证明推送等其他办公自动化工具。

下面从Python环境、飞书机器人和测试图片开始,一步一步把这条链跑通。

downloaded-image (5)

1.先明确这个机器人到底做什么

这篇文章在Windows 10/11环境中搭建一套“截图识别 + 飞书通知”的自动化流程。它不会替你完成企业考勤系统本身的签到,而是把已有的打卡截图或证明图片交给Python识别,再把结果推送到飞书群。

最终流程:

把打卡截图放入指定文件夹 → Python调用PaddleOCR识别图片中的文字 → 将识别结果通过飞书Webhook发送到群聊。

你需要准备:

  • 一台 Windows 10/11 电脑
  • 一个飞书账号(免费)
  • 一张用于测试的打卡截图或证明图片
  • 网络畅通

2.安装Python并确认环境

先安装Python。原文推荐Python 3.11:

image-20260429164605110下载Python 3.11.x安装包。

下载完成后,双击安装包。
安装时注意勾选:

  • Add Python to PATH(关键!)
  • Install launcher for all users

点击 “Install Now”
安装完成后,按 Win + R,输入cmd回车,运行:

python --version

如果能够正常输出Python版本号,说明环境已经可用。

image-20260429164721445

3.创建飞书自定义机器人并测试Webhook

3.1 创建机器人

打开 飞书 App(或网页版 https://www.feishu.cn)

image-20260429164832509

创建一个新群聊,点击右上角 设置→ 「群机器人」 → 「添加机器人」

52ef582d3ad0e0c9219ded6341d89a53

9e3a7a8429b5a80e81062502b55ecf13

f1aa9d7241bc56b7e7b9b6e150613374

选择 「自定义机器人」

d2463f3ee5316faba8214668839a7d26

名称可以自定义,例如:打卡通知

a24ba87c931b5a00b94165e36279d931

安全设置按原文选择“自定义关键词”,关键词填写:打卡成功。

image-20260429165006021

点击「添加」,复制 Webhook 地址(一长串 URL,以 https://open.feishu.cn/open-apis/bot/v2/hook/ 开头)

30602fa39ac4c5ea5466321371a6de2c

原文使用了“自定义关键词”安全规则,因此后续机器人消息必须包含打卡成功,否则Webhook请求会被拒绝。

3.2 先单独验证Webhook是否可用

先不要急着接OCR,直接用PowerShell发送一条测试消息,确认飞书机器人链路正常:

$webhook = "https://open.feishu.cn/open-apis/bot/v2/hook/你的完整hook地址"
$body = @{
    msg_type = "text"
    content = @{
        text = "打卡成功:手动测试消息"
    }
} | ConvertTo-Json

# 关键:设置编码为 UTF-8
Invoke-RestMethod -Uri $webhook -Method Post -Body $body -ContentType 'application/json; charset=utf-8'

655e50190a78cc2f41d5dde574f2a241

如果群里能够收到消息,说明Webhook配置没有问题:

d96f3ceee0f03215569343fd0cca84a7

4.创建项目目录和测试图片

在桌面或其他位置创建项目目录clock_in_bot。

进入该文件夹

1dba8a513dc6e49d79983bea75a9ae25

再创建子目录clock_in_images,专门存放待识别图片:

image-20260429165541584

把一张测试截图放进clock_in_images目录,并命名为test.png。后面的Python代码会直接读取这个文件名。

image-20260429165616159

5.安装PaddleOCR和网络请求依赖

进入你的项目文件夹:

cd C:\Users\admin\Desktop\clock_in_bot

安装PaddleOCR、PaddlePaddle、requests、Pillow和OpenCV。原文使用清华源:

pip install paddlepaddle paddleocr requests pillow opencv-python -i https://pypi.tuna.tsinghua.edu.cn/simple

安装完成后先单独测试PaddleOCR能否导入。如果输出OCR OK!,说明基础依赖已经可用:

python -c "from paddleocr import PaddleOCR; print('OCR OK!')"

6.编写OCR识别与飞书推送脚本

在clock_in_bot目录中新建test.py,注意文件后缀必须是.py。

image-20260429170332089

右键 → “编辑”(用记事本打开),粘贴以下代码:

下面这段代码按步骤检查文件夹、OCR初始化、图片读取、文字识别以及飞书推送,方便出错时快速定位:

import os
import time
from paddleocr import PaddleOCR
import requests

# === 第 0 步:配置 ===
print("第 0 步:加载配置...")
FEISHU_WEBHOOK = "替换成你的飞书Webhook地址"
IMAGE_FOLDER = "./clock_in_images"
TEST_IMAGE = os.path.join(IMAGE_FOLDER, "test.png")  # 放一张叫 test.png 的图进去

print(f"  Webhook: {FEISHU_WEBHOOK}")
print(f"  图片路径: {TEST_IMAGE}")
print("-" * 50)

# === 第 1 步:确保文件夹存在 ===
print("第 1 步:创建图片文件夹...")
os.makedirs(IMAGE_FOLDER, exist_ok=True)
print("✅ 文件夹已准备好")
print("-" * 50)

# === 第 2 步:初始化 OCR ===
print("第 2 步:初始化 PaddleOCR(可能需要1-2分钟)...")
try:
    ocr = PaddleOCR(lang="ch", use_gpu=False, show_log=False)
    print("✅ OCR 初始化成功")
except Exception as e:
    print(f"❌ OCR 初始化失败: {e}")
    exit(1)
print("-" * 50)

# === 第 3 步:检查图片是否存在 ===
print("第 3 步:检查测试图片是否存在...")
if not os.path.isfile(TEST_IMAGE):
    print(f"❌ 图片不存在!请放一张截图并命名为: {TEST_IMAGE}")
    exit(1)
else:
    print("✅ 图片存在")
print("-" * 50)

# === 第 4 步:执行 OCR 识别 ===
print("第 4 步:开始 OCR 识别...")
try:
    result = ocr.ocr(TEST_IMAGE, cls=True)
    text = ""
    if result and result[0]:
        for line in result[0]:
            if line and len(line) > 1:
                word = line[1][0]
                if isinstance(word, str):
                    text += word + " "
    text = text.strip() or "[未识别到文字]"
except Exception as e:
    print(f"💥 OCR 异常详细信息: {e}")
    text = "[OCR 异常]"
print("-" * 50)

# === 第 5 步:构造消息(强制包含关键词)===
print("第 5 步:构造飞书消息...")
message = f"打卡成功\n【OCR结果】\n{text}"
print(f"📤 消息内容:\n{message}")
print("-" * 50)

# === 第 6 步:发送到飞书 ===
print("第 6 步:发送消息到飞书...")
try:
    resp = requests.post(
        FEISHU_WEBHOOK,
        json={"msg_type": "text", "content": {"text": message}},
        timeout=10,
        headers={"Content-Type": "application/json; charset=utf-8"}
    )
    result = resp.json()
    print(f"📡 飞书返回: {result}")

    if result.get("code") == 0:
        print("✅ 成功!请去飞书群查看消息")
    else:
        print(f"❌ 失败!原因: {result.get('msg', '未知错误')}")
        print("⚠️ 常见原因:关键词不匹配(必须包含“打卡成功”)")
except Exception as e:
    print(f"💥 网络或请求异常: {e}")
print("-" * 50)

print("🔚 测试结束。按回车退出...")
input()

运行前必须修改Webhook地址

找到这一行:

FEISHU_WEBHOOK = "替换成你的飞书Webhook地址"

把占位内容替换为自己的完整Webhook地址,并保留字符串两侧的双引号。

7.运行脚本并验证识别结果

进入你的项目文件夹:

cd C:\Users\admin\Desktop\clock_in_bot

运行前面创建的test.py:

python test.py

首次运行PaddleOCR时可能会下载模型文件,需要等待初始化完成。

image-20260429171947912

运行完成后,检查飞书群是否收到包含OCR结果的通知:

如果识别和Webhook都正常,脚本会读取test.png中的文字,并把结果发送到飞书群。

image-20260429172234161

如果需要继续调试,也可以使用VS Code运行脚本:

这样查看终端输出和修改代码会更方便:

992a6ee4fdbecb1339bde85055dde6aa

到这里,“截图 → OCR → 飞书通知”这条基础链路已经跑通。

8.扩展成可通过HTTP触发的Flask服务

如果希望从浏览器或其他设备触发这套流程,可以再用Flask封装一个简单Web服务,并暴露/clockin接口。

访问这个接口时,由Flask调用前面的OCR与飞书通知脚本。

  • 原文脚本路径示例:C:\Users\admin\Desktop\clock_in_bot\test.py
# 1.py
from flask import Flask
import subprocess
import os

app = Flask(__name__)

# 主页(可选,用于测试服务是否在线)
@app.route('/')
def home():
    return "✅ 打卡机器人在线!访问 /clockin 触发打卡。"

# 核心打卡接口
@app.route('/clockin')
def clock_in():
    try:
        # 替换为你的实际打卡脚本路径(建议用绝对路径)
        script_path = r"C:\Users\admin\Desktop\clock_in_bot\test.py"
        result = subprocess.run(
            ["python", script_path],
            cwd=os.path.dirname(script_path),  # 设置工作目录
            capture_output=True,
            text=True,
            timeout=60  # 防止卡死
        )
        output = result.stdout + "\n" + result.stderr
        return f"<pre>✅ 打卡执行完成:\n{output}</pre>"
    except Exception as e:
        return f"<pre>❌ 打卡失败: {str(e)}</pre>"

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=5000, debug=False)

image-20260429175438874

Flask启动后,通过IP:5000可以先确认服务是否在线:

image-20260429175557497

再访问/clockin触发前面的Python脚本。

image-20260429175641662

Flask服务默认运行在本机5000端口。如果还需要从外部网络访问,可以再通过cpolar为这个Web服务创建公网入口。这样远程设备访问公网地址的/clockin路径时,就会触发本机脚本。由于这个接口会执行自动化任务,公网开放后不建议直接裸奔,至少要增加访问控制或随机Token,避免被陌生人反复触发。

9.安装cpolar,为Flask服务增加公网入口

9.1 cpolar在这里负责什么?

cpolar在这篇文章里只负责一件事:把本地Flask的5000端口映射到公网,让其他设备能够访问这个Web接口。

9.2 按原文步骤部署cpolar

原文后续使用cpolar Web UI来创建隧道。

环境说明:本文前面的项目运行环境是Windows,但原始资料在这里给出的sudo curl、systemctl属于Linux命令,与Windows环境并不一致。由于原资料没有提供对应的Windows版cpolar安装步骤,下面保留原命令作为原文参考,不要在Windows PowerShell中直接照抄执行;Windows环境应改用与Windows匹配的cpolar安装方式。

原文给出的安装命令如下:

sudo curl https://get.cpolar.sh | sh

image-20250725104019896

安装后按原文继续检查cpolar服务状态:

sudo systemctl status cpolar

22e5adfaf290a17fc3384bb296055259

cpolar服务启动后,通过IP:9200进入Web管理界面并登录账号:

登录后即可在Web界面中创建和管理隧道。

8a6698b1bf26d64ba3645827fbfb1c29

10.把本地5000端口映射到公网

登录cpolar Web UI后,进入“隧道管理 → 创建隧道”:

  • 隧道名称:可自定义,本例使用了:daka,注意不要与已有的隧道名称重复
  • 协议:http
  • 本地地址:5000
  • 域名类型:随机域名
  • 地区:选择China Top

image-20260430104547712

创建完成后,在“在线隧道列表”中查看生成的公网地址,并用其他设备测试访问。

image-20260430104603841

如果页面能正常打开,说明公网访问链路已经打通。

image-20260430104621768

11.需要长期使用时再配置固定公网地址

如果希望长期保持同一个访问入口,可以继续配置固定二级子域名。

image-20250918151358733

进入“预留”,选择保留二级子域名,地区按原文选择China Top,名称可以自定义。原文示例使用daka。

image-20260430104713350

随后回到“隧道管理 → 隧道列表”,找到前面创建的隧道并点击编辑。

image-20260430104744233

把刚刚保留的二级子域名配置到当前隧道:

  • 域名类型:选择二级子域名
  • Sub Domain:填写保留成功的二级子域名
  • 地区: China Top

点击更新

image-20260430104824269

更新完成后重新打开“在线隧道列表”,确认随机地址已经切换为固定二级子域名。

image-20260430104842235

最后用其他设备测试固定地址。如果能够正常打开Flask页面,就说明固定公网入口已经配置完成。

image-20260430104904788

总结

这篇文章最终串起来的是一条完整的Windows自动化链:

  • PaddleOCR负责从测试截图中提取文字;
  • Python + requests负责整理结果并调用飞书Webhook;
  • 飞书自定义机器人负责把识别结果发送到群聊;
  • Flask把本地脚本封装成/clockin HTTP接口;
  • cpolar再把本地5000端口映射到公网,方便其他设备访问。

基础版本其实并不复杂,真正重要的是分阶段验证:先确认Python能运行,再单独测试Webhook,然后测试PaddleOCR,最后才把几部分合起来。这样一旦报错,不需要在一大段代码里盲猜。

需要注意,本文脚本处理的是已有截图和通知流程,并不等同于替代企业考勤系统本身的签到行为。如果继续把/clockin接口开放到公网,建议再增加Token、账号认证或IP限制,避免接口被陌生人反复触发。

Logo

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。

更多推荐