首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >我给 WorkBuddy 装了个"闹钟":每天 0 点自动领 100 积分,一个月 3000 分雷打不动

我给 WorkBuddy 装了个"闹钟":每天 0 点自动领 100 积分,一个月 3000 分雷打不动

原创
作者头像
用户12814938
发布于 2026-10-16 00:15:57
发布于 2026-10-16 00:15:57
370
举报

我给 WorkBuddy 装了个"闹钟":每天 0 点自动领 100 积分,一个月 3000 分雷打不动

#WorkBuddy#

用 WorkBuddy 的朋友应该都知道它的成长计划:每天打开客户端,左下角会弹一个「立即领取」的每日积分入口,领了就是 100 积分。听起来很简单,但真要坚持 30 天一天不落,其实挺反人性的——忙起来忘了点、周末没开电脑、出差用另一台机器,一个月总能漏个几天。一个月按 30 天算就是 3000 积分的保底收益,漏一天少 100,攒盒子、开奖励的速度直接被拖慢。

我的思路很简单:既然 WorkBuddy 自带「定时任务」能力,为什么不让 AI 自己在每天凌晨替我把这 100 分领了?不碰协议、不做任何破解,就是用 UI 自动化老老实实替你点一次按钮。落地之后已经稳定跑了一段时间,实测日志在文末,当天 0 点 01 分触发、0 点 02 分领取成功,全程无人值守。

下面把完整方案拆开讲,脚本可以直接抄走。

一、整体设计:一条定时任务 + 双领取路径

先看架构。整个方案只有两个组件:

  1. WorkBuddy 定时任务:每天凌晨 00:01 触发一次(避开 0 点整的临界跳变),执行一条 python 命令;
  2. 领取脚本:用 uiautomation 找到并点击领取按钮,支持两条路径互为备份。

为什么要双路径?因为每天第一次打开 WorkBuddy 时,客户端左下角会弹「立即领取」弹窗(路径 A,最省事);但如果你当天已经打开过客户端、弹窗没了,就得走兜底路径——从个人菜单进「成长计划」,在网页的成长中心里找到领取按钮点掉(路径 B)。两条路径串行尝试,命中任意一条就收工,都领不到就写日志退出,绝不误点。

设计上还有三个刻意的小细节:

  • 幂等:脚本输出 RESULT=SUCCESS(今天领到了)或 RESULT=ALREADY(今天已经领过,页面没有可点的按钮),两种都算正常收工,重复跑不会出错;
  • 防误点:按钮匹配白名单只有「立即领取 / 领取 / 签到」几个词,同时内置黑名单(购买、升级、套餐、兑换积分、立即体验……),防止脚本在积分商城里手滑点到消费按钮——积分工具把自己积分花掉了就搞笑了;
  • 打不过就记录:任何一步找不到按钮,就自动截屏 + 导出控件树到日志目录,第二天回看日志就能定位是页面改版了还是当天状态特殊。

二、核心实现(约 100 行,无任何第三方服务)

脚本只依赖 uiautomation 和 Pillow 两个 pip 包。核心逻辑三步:

第一步:找到 WorkBuddy 客户端窗口。 桌面顶级窗口里按窗口名精确匹配,避免抓到浏览器里同名的页面:

代码语言:python
复制
def get_client():
    root = auto.GetRootControl()
    for c in root.GetChildren():
        try:
            if (c.Name or '') == 'WorkBuddy' and c.ClassName == 'Chrome_WidgetWin_1':
                return c
        except Exception:
            pass
    return None

第二步:路径 A——轮询等弹窗。 在 60 秒窗口里每 5 秒扫一次「立即领取」按钮,命中且可见就直接点:

代码语言:python
复制
def step1_popup(win, wait_sec=60):
    win.SetActive()
    deadline = time.time() + wait_sec
    while time.time() < deadline:
        for nm, ct, ctrl, r in find_buttons(win, ('立即领取',)):
            if visible(r) and click_ctrl(ctrl):
                return True
        time.sleep(5)
    return False

第三步:路径 B——进成长计划网页兜底。 先点个人菜单里的「成长计划」项,等 Edge 打开成长中心页面,再在页面控件树里扫「领取/签到」类的真按钮(排除纯文本)点下去:

代码语言:python
复制
def step3_claim_on_web(edge):
    for nm, ct, ctrl, r in find_buttons(edge, ('领取', '签到'), maxhits=30):
        if ct == 'TextControl':
            continue  # 纯文本说明文字不是按钮,跳过
        if click_ctrl(ctrl):
            return True
    return False  # 页面上没有可点按钮 = 今天已经领过

find_buttons 是一个通用的控件树遍历器:递归走 UIA 树,按名称关键词收集 Button/Hyperlink/Text 控件,同时用黑名单过滤危险词。完整脚本在文末命令块里,整段复制就能用。

三、把定时任务挂上:两分钟的事

WorkBuddy 左侧栏有「定时任务」入口,点「新建」:

  • 执行内容:一条命令,比如 python wb_checkin.py(脚本保存路径自己定);
  • 触发周期:每天,时间我选了 00:01——刚过零点就领,等于每天"抢头香",就算你当天一整天不碰电脑,积分也已经到账了;
  • 保存后把开关打开即可。

建好之后在任务列表里能看到它每天"运行中"的状态卡片。我的任务列表里它已经连续多天 00:01 准时运行了。

四、实测效果

上线后我留了完整日志。最近一次运行(就是写这篇文章的当晚):

代码语言:txt
复制
[10-16 00:01:59] === wb_checkin start ===
[10-16 00:01:59] step1: wait popup claim button (60s)
[10-16 00:02:12] popup found: 立即领取 (268,937,332,961)[64x24]
[10-16 00:02:16] claimed via popup
RESULT=SUCCESS

从触发到领取成功 17 秒。前一天走的是路径 B(弹窗已被我手动打开客户端时关掉),脚本自己进成长计划页面完成检查。也就是说不管我当天用不用 AI、开不开客户端,这 100 分都稳了。

算一笔账:100 积分/天 × 30 天 = 每月 3000 积分保底,一年 36500+。以前手动领取总有遗漏,现在漏签率直接归零。这套"定时任务 + 双路径 UI 自动化"的架子是通用的,换个按钮文案就能用来做别的每日签到类自动化。

五、几个踩坑提醒

  1. 窗口必须可见:UIA 点击需要目标控件在屏幕可见区域内,别把 WorkBuddy 最小化到托盘后指望脚本能点(脚本里做了 ScrollIntoView 兜底,但物理上不可见仍然会失败);
  2. 纯文本 ≠ 按钮:网页里"完成对应任务后需手动点击领取按钮……"这种规则说明文字也含"领取"两个字,必须按控件类型过滤(只点 ButtonControl),否则会点空气;
  3. 黑名单一定要加:积分页面上全是"兑换积分""立即体验""升级套餐"这类消费入口,白名单匹配范围要窄,黑名单要挡在前面;
  4. 时间选 00:01 别选 00:00:跨零点瞬间系统任务调度器行为不稳定,晚一分钟换来确定性;
  5. 日志 + 截屏是生命线:自动化最怕的不是失败,是失败了没人知道。每次失败落一份控件树 dump 和截屏,第二天一眼定位。

文末命令块(可复制直接用)

完整脚本 wb_checkin.py(先装依赖:pip install uiautomation pillow):

代码语言:python
复制
# -*- coding: utf-8 -*-
# WorkBuddy 每日 100 积分自动领取(双路径)
# 路径A: 客户端左下角弹窗「立即领取」;路径B: 个人菜单->成长计划->网页领取
# 退出标记: stdout 最后输出 RESULT=SUCCESS / RESULT=ALREADY / RESULT=FAIL
import sys, time, traceback
from datetime import datetime
import uiautomation as auto

LOG = 'wb_checkin.log'   # 日志落在脚本同目录
BAD_KWS = ('购买', '升级', '套餐', '退回', '兑换积分', '立即体验', '加购')
GOOD_KWS = ('立即领取', '领取', '签到')

def log(msg):
    line = '[%s] %s' % (datetime.now().strftime('%m-%d %H:%M:%S'), msg)
    print(line, flush=True)
    try:
        open(LOG, 'a', encoding='utf-8').write(line + '\n')
    except Exception:
        pass

def get_client():
    root = auto.GetRootControl()
    for c in root.GetChildren():
        try:
            if (c.Name or '') == 'WorkBuddy' and c.ClassName == 'Chrome_WidgetWin_1':
                return c
        except Exception:
            pass
    return None

def find_buttons(scope, kws, maxhits=8):
    hits = []
    def walk(ctrl, d):
        if d > 20 or len(hits) >= maxhits:
            return
        try:
            nm = ctrl.Name or ''
            ct = ctrl.ControlTypeName
        except Exception:
            return
        if nm and ct in ('ButtonControl', 'HyperlinkControl', 'TextControl') \
                and any(k in nm for k in kws):
            if any(b in nm for b in BAD_KWS):
                return
            try:
                hits.append((nm[:40], ct, ctrl, ctrl.BoundingRectangle))
            except Exception:
                pass
            return
        try:
            for c in ctrl.GetChildren():
                walk(c, d + 1)
        except Exception:
            pass
    walk(scope, 0)
    return hits

def visible(r):
    return r.width() > 8 and r.height() > 8 and r.top >= 0 and r.left >= 0

def click_ctrl(ctrl):
    try:
        r = ctrl.BoundingRectangle
        sw, sh = auto.GetScreenSize()
        if r.top < 0 or r.bottom > sh or r.left < 0 or r.right > sw:
            try:
                ctrl.GetScrollItemPattern().ScrollIntoView()
                time.sleep(1.2)
            except Exception:
                return False
        ctrl.Click()
        return True
    except Exception as e:
        log('click fail: %s' % e)
        return False

def step1_popup(win, wait_sec=60):
    """路径A: 等客户端弹窗「立即领取」"""
    log('step1: wait popup claim button (%ds)' % wait_sec)
    win.SetActive()
    deadline = time.time() + wait_sec
    while time.time() < deadline:
        for nm, ct, ctrl, r in find_buttons(win, ('立即领取',)):
            if visible(r) and click_ctrl(ctrl):
                time.sleep(3)
                return True
        time.sleep(5)
    log('step1: no popup')
    return False

def step2_open_growth(win):
    """路径B: 个人菜单 -> 成长计划 -> 等 Edge 成长中心窗口"""
    tgt = None
    for attempt in range(2):
        for nm, ct, ctrl, r in find_buttons(win, ('成长计划',), maxhits=20):
            if visible(r) and r.height() > 15 and r.top < 900:
                tgt = ctrl
                break
        if tgt:
            break
        try:
            mi = win.MenuItemControl(SubName='个人')
            if mi.Exists(3):
                r = mi.BoundingRectangle
                auto.Click((r.left + r.right) // 2, (r.top + r.bottom) // 2 + 5)
                time.sleep(2)
        except Exception:
            pass
    if not tgt:
        log('step2: growth menu not found')
        return None
    if not click_ctrl(tgt):
        return None
    time.sleep(10)
    root = auto.GetRootControl()
    for c in root.GetChildren():
        try:
            if 'WorkBuddy' in (c.Name or '') and 'Edge' in (c.Name or ''):
                time.sleep(4)
                return c
        except Exception:
            pass
    log('step2: growth-center Edge window not found')
    return None

def step3_claim_on_web(edge):
    """在成长中心网页找领取按钮"""
    log('step3: scan web page for claim buttons')
    hits = find_buttons(edge, GOOD_KWS, maxhits=30)
    for nm, ct, ctrl, r in hits:
        if ct == 'TextControl':
            continue
        if click_ctrl(ctrl):
            time.sleep(3)
            return True
    log('step3: no clickable claim button (probably already claimed)')
    return False

def main():
    auto.SetGlobalSearchTimeout(2)
    log('=== wb_checkin start ===')
    try:
        win = get_client()
        if win is None:
            log('FATAL: WorkBuddy client window not found')
            print('RESULT=FAIL', flush=True)
            return
        if step1_popup(win):
            log('claimed via popup')
            print('RESULT=SUCCESS', flush=True)
            return
        edge = step2_open_growth(win)
        if edge is not None and step3_claim_on_web(edge):
            log('claimed via web')
            print('RESULT=SUCCESS', flush=True)
        else:
            print('RESULT=ALREADY', flush=True)
    except Exception:
        log('EXCEPTION: %s' % traceback.format_exc())
        print('RESULT=FAIL', flush=True)

if __name__ == '__main__':
    main()

定时任务执行命令示例(Windows):

代码语言:bash
复制
python C:\tools\wb_checkin.py >> C:\tools\checkin_cron.log 2>&1

一条定时任务,两条兜底路径,三千积分按月到账。把它装上之后,你唯一还需要做的,是偶尔打开日志看看 AI 又一次默默替你干了活。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

目录
  • 我给 WorkBuddy 装了个"闹钟":每天 0 点自动领 100 积分,一个月 3000 分雷打不动
    • 一、整体设计:一条定时任务 + 双领取路径
    • 二、核心实现(约 100 行,无任何第三方服务)
    • 三、把定时任务挂上:两分钟的事
    • 四、实测效果
    • 五、几个踩坑提醒
    • 文末命令块(可复制直接用)
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档