A Zero-Cost Cloud Cron Job That Checks Into WorkBuddy and Pings Your WeChat
Preface
An automation solution that doesn't depend on a local computer, doesn't require buying your own server, and runs on time every day. Includes complete code, configuration steps, and 6 real-world troubleshooting records.
1. Overall Architecture
┌─────────────────┐
│ Gitee Go Timer │ (Triggers daily)
└────────┬────────┘
↓
┌─────────────────┐
│ Pull Private Repo │ (checkin.py + config.json)
└────────┬────────┘
↓
┌─────────────────┐
│ Execute Script │
└────────┬────────┘
↓
┌─────────────────┐
│ ServerChan → WeChat │ (Notifies personal WeChat)
└─────────────────┘
Core Advantages:
- Does not depend on a local computer; runs in the cloud
- Real-time WeChat notifications; check-in results are clear at a glance
- Extremely low maintenance cost (just update once before the token expires)
2. Preparation
2.1 Obtain accessToken
After logging into the WorkBuddy client, the login state is saved locally:
- macOS:
~/Library/Application Support/CodeBuddyExtension/Data/Public/auth/workbuddy-desktop.info
Open this file, and you will see something like:
{
"account": { "nickname": "Your Nickname", ... },
"auth": { "accessToken": "eyJhbGc...", "expiresIn": ... }
}
auth.accessToken is the token we need (this is the legitimate credential of your own account, involving no cracking).
⚠️ Security Tip: The accessToken is your login state. Absolutely do not commit it to a public repository. The solution below uses a private repository + config file to store it.
2.2 Register ServerChan (WeChat Notification)
Open sct.ftqq.com → Scan the QR code with WeChat to log in → See the SendKey on the page (a string of alphanumeric characters).
Effect: Calling the ServerChan interface can push messages to your WeChat (follow the "方糖" official account to receive them).
3. Check-in Script
Complete script checkin.py (pure Python standard library, zero dependencies):
#!/usr/bin/env python3
"""
WorkBuddy Daily Check-in Script
Supports local and cloud execution
"""
import json
import os
import sys
import urllib.request
import urllib.error
from pathlib import Path
from datetime import datetime
# ─── Configuration ───────────────────────────────────────────────
API_BASE = "https://copilot.tencent.com"
CHECKIN_STATUS_URL = f"{API_BASE}/billing/meter/checkin-status"
DAILY_CHECKIN_URL = f"{API_BASE}/billing/meter/daily-checkin"
SERVERCHAN_URL = "https://sctapi.ftqq.com/{sendkey}.send"
REQUEST_TIMEOUT = 15
# Local auth file (macOS)
_LOCAL_AUTH_FILE = (
Path.home()
/ "Library/Application Support/CodeBuddyExtension"
/ "Data/Public/auth/workbuddy-desktop.info"
)
# Cloud config file
_CLOUD_CONFIG_FILE = Path(__file__).parent / "config.json"
def log(msg: str):
print(f"[{datetime.now().strftime('%Y-%m-%d %H:%M:%S')}] {msg}", flush=True)
# ─── Token Reading ─────────────────────────────────────────
def load_access_token() -> tuple[str | None, str]:
"""Read token, priority: config.json > local auth > environment variable"""
# 1. Cloud config.json
if _CLOUD_CONFIG_FILE.exists():
try:
data = json.loads(_CLOUD_CONFIG_FILE.read_text(encoding="utf-8"))
token = data.get("access_token", "").strip()
name = data.get("account_name", "Cloud Account")
if token:
log(f" Using cloud config.json token (Account: {name})")
return token, name
except Exception as e:
log(f"⚠️ Failed to read config.json: {e}")
# 2. Environment variable
token = os.environ.get("WORKBUDDY_ACCESS_TOKEN", "").strip()
if token:
name = os.environ.get("WORKBUDDY_ACCOUNT_NAME", "Env Account")
log(f" Using environment variable token (Account: {name})")
return token, name
# 3. Local auth file
if not _LOCAL_AUTH_FILE.exists():
log("❌ No token source found, please configure config.json or environment variable")
return None, ""
try:
data = json.loads(_LOCAL_AUTH_FILE.read_text(encoding="utf-8"))
token = data.get("auth", {}).get("accessToken", "").strip()
name = data.get("account", {}).get("nickname", "Local Account")
if not token:
log("❌ accessToken not found in auth file")
return None, ""
log(f" Using local auth file token (Account: {name})")
return token, name
except Exception as e:
log(f"❌ Failed to read auth file: {e}")
return None, ""
# ─── API Calls ───────────────────────────────────────────
def _request(url: str, token: str) -> dict | None:
req = urllib.request.Request(
url,
headers={
"Authorization": f"Bearer {token}",
"Content-Type": "application/json",
"User-Agent": "WorkBuddy-Checkin/1.0",
},
)
try:
with urllib.request.urlopen(req, timeout=REQUEST_TIMEOUT) as resp:
return json.loads(resp.read().decode("utf-8"))
except urllib.error.HTTPError as e:
log(f" HTTP {e.code}: {e.reason}")
return None
except Exception as e:
log(f" Request failed: {e}")
return None
def get_checkin_status(token: str) -> dict | None:
return _request(CHECKIN_STATUS_URL, token)
def claim_daily_checkin(token: str) -> dict | None:
return _request(DAILY_CHECKIN_URL, token)
# ─── ServerChan Notification ─────────────────────────────────────
def send_wechat_notification(title: str, content: str, sendkey: str) -> bool:
"""Push message to WeChat"""
if not sendkey:
return False
url = SERVERCHAN_URL.format(sendkey=sendkey)
payload = urllib.parse.urlencode({"title": title, "desp": content}).encode()
req = urllib.request.Request(url, data=payload, method="POST")
try:
with urllib.request.urlopen(req, timeout=REQUEST_TIMEOUT) as resp:
result = json.loads(resp.read().decode("utf-8"))
if result.get("code") == 0:
log(f" ✅ WeChat notification sent")
return True
log(f" ⚠️ WeChat notification failed: {result.get('message')}")
return False
except Exception as e:
log(f" ⚠️ WeChat notification exception: {e}")
return False
# ─── Main Check-in Flow ─────────────────────────────────────────
def checkin() -> bool:
log("=" * 56)
log(f" WorkBuddy Daily Check-in — {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
log("=" * 56)
sendkey = os.environ.get("SERVERCHAN_SENDKEY", "")
if _CLOUD_CONFIG_FILE.exists():
try:
sendkey = sendkey or json.loads(
_CLOUD_CONFIG_FILE.read_text(encoding="utf-8")
).get("serverchan_sendkey", "")
except Exception:
pass
log("Step 1/3: Getting accessToken...")
token, account_name = load_access_token()
if not token:
log("❌ Cannot get accessToken, check-in terminated.")
send_wechat_notification(
"❌ WorkBuddy Check-in Failed", f"Account: {account_name}\naccessToken not found", sendkey
)
return False
log("\nStep 2/3: Querying check-in status...")
status_data = get_checkin_status(token)
if status_data and status_data.get("today_checked_in", False):
log("\nℹ️ Already checked in today, no need to repeat.")
send_wechat_notification(
"✅ WorkBuddy Already Checked In Today", f"Account: {account_name}\nTime: {datetime.now()}", sendkey
)
return True
log("\nStep 3/3: Claiming check-in points...")
result = claim_daily_checkin(token)
if result:
points = result.get("points", result.get("reward_points", ""))
log(f"\n✅ Check-in successful! Points earned: {points}")
send_wechat_notification(
"✅ WorkBuddy Check-in Successful",
f"Account: {account_name}\nPoints earned: +{points}\nTime: {datetime.now()}",
sendkey,
)
return True
log("\n❌ Check-in failed")
send_wechat_notification(
"❌ WorkBuddy Check-in Failed", f"Account: {account_name}\nPlease check if token has expired", sendkey
)
return False
if __name__ == "__main__":
sys.exit(0 if checkin() else 1)
Configuration File config.json
{
"access_token": "your_accessToken",
"account_name": "your_nickname",
"serverchan_sendkey": "your_SendKey"
}
4. Local Testing
# Method 1: Using environment variables
export WORKBUDDY_ACCESS_TOKEN="your_token"
export WORKBUDDY_ACCOUNT_NAME="your_nickname"
export SERVERCHAN_SENDKEY="your_SendKey"
python3 checkin.py
# Method 2: Using config.json (recommended)
# Place config.json in the same directory, then directly run python3 checkin.py
Expected Output:
[2026-08-03 14:00:00] ========================================================
[2026-08-03 14:00:00] WorkBuddy Daily Check-in — 2026-08-03 14:00:00
[2026-08-03 14:00:00] ========================================================
[2026-08-03 14:00:00] Step 1/3: Getting accessToken...
[2026-08-03 14:00:00] Using cloud config.json token (Account: Mr. X)
...
[2026-08-03 14:00:00] ✅ Check-in successful! Points earned: 100
[2026-08-03 14:00:00] ✅ WeChat notification sent
Open WeChat, and the "方糖" official account will immediately receive the push notification.
5. Cloud Deployment (Gitee Go)
5.1 Create a Private Repository
Log in to gitee.com → New Repository → Select Private (Important! Tokens cannot be public) → Name it workbuddy-checkin.
5.2 Push Code
cd workbuddy-checkin
git init
git remote add origin https://gitee.com/your_username/workbuddy-checkin.git
git add .
git commit -m "init: WorkBuddy Daily Check-in"
git push -u origin main
5.3 Configure Pipeline
Enter the repository → Pipelines (Gitee Go) → New Pipeline:
- Basic Info: Set the name to
WorkBuddy Daily Check-in - Process Orchestration:
- Delete the default "Host Deployment" step
- In the Python Build step, set the build command to:
python3 checkin.py - Select Python version
3.11
- Advanced Settings → Scheduled Trigger:
| Field | Value |
|---|---|
| Second | 0 |
| Minute | 5 |
| Hour | 9 |
| Day | * |
| Month | * |
| Week | ? |
| Year | * |
This expression = triggers daily at 09:05 Beijing time
5.4 Testing
Go back to the pipeline list → Click "Execute Now" → Check the log output + whether WeChat receives the notification.
Once it runs successfully in the cloud, the whole setup is fully automatic:
- Gitee Go runs automatically every day at 09:05
- After running, the check-in script automatically calls ServerChan
- You receive a notification on WeChat
- Does not depend on whether your local computer is on or off
6. Solution Comparison
| Solution | Pros | Cons |
|---|---|---|
| WorkBuddy Automation | Simplest configuration | Depends on local computer; high risk of missed check-ins |
| macOS launchd | Locally stable, can utilize PowerNap | Still depends on computer wake-up |
| Gitee Go + ServerChan ⭐ | Doesn't depend on computer, WeChat notifications | Requires a private repository |
| Tencent Cloud Function | Most accurate scheduling | Complex configuration, small cost |
| GitHub Actions | International, comprehensive docs | Slow access domestically |
My final choice: Gitee Go + ServerChan, fast domestic access, simple maintenance, timely notifications.
7. Final Words
The core idea is essentially upgrading "local automation" to "cloud automation":
- Any small task that needs periodic execution can follow this pattern
- Tokens / API Keys are managed using a private repository + config file
- Notifications use a "zero-cost" channel like ServerChan
Hope this helps. Feel free to discuss in the comments if you have questions 👇
Top 1 of 2 from juejin.cn, machine-translated. The original thread is authoritative.
I thought it was about Feishu check-in.
If you want to do it, you probably can. Let AI reverse-engineer and analyze it, then call the API, generate a skill, and turn it into an automation script.