🐂🐎 牛马专列:飞书打工提醒机器人 – 第二辑(点餐消息卡片优化、天气提醒、进度条)

有时候,打工人需要的不只是下班倒计时,还有一丝贴心的关怀。于是,我在之前的 牛马专列 基础上加了新功能——天气提醒点餐消息卡片工作进度条和好玩的随机提示语

它还是那个每天准时冒出来「催更」的飞书机器人,但现在它更懂你。

代码地址:https://github.com/rainding0311/lark_webhook_reminder/tree/main


新功能一:午餐提醒卡片优化 🍱

为了让午餐提醒更方便,牛马专列增加了 交互按钮。你可以在飞书消息里直接跳转到外卖平台,一键下单。

核心函数

def send_card_with_buttons(header_title, color, text_content, buttons):
    payload = {
        "msg_type": "interactive",
        "card": {
            "config": {"wide_screen_mode": True},
            "elements": [
                {"tag": "div", "text": {"tag": "lark_md", "content": text_content}},
                {"tag": "action", "actions": buttons}
            ],
            "header": {"title": {"tag": "plain_text", "content": header_title}, "template": color}
        }
    }
    try:
        response = requests.post(
            WEBHOOK_URL,
            headers={"Content-Type": "application/json"},
            data=json.dumps(payload),
            timeout=5
        )
        if response.status_code == 200:
            log(f"[{header_title}] 消息卡片发送成功")
        else:
            log(f"[{header_title}] 发送失败:{response.status_code} - {response.text}")
    except requests.exceptions.RequestException as e:
        log(f"[{header_title}] 网络请求异常: {e}")

午餐提醒调用示例

def lunch_reminder():
    now = datetime.datetime.now()
    earned = calc_earned(now)
    text_content = (
        f"📅 现在是 {now.strftime('%Y-%m-%d %H:%M')}\n"
        "🍱 马上到饭点啦,记得点外卖或者准备午餐~\n"
        f"💰 今天已经挣了 **{earned:.2f} 元**"
    )

    buttons = [
        {"tag": "button", "text": {"tag": "plain_text", "content": "🛵 去饿了么"}, "url": "https://h5.ele.me", "type": "default"},
        {"tag": "button", "text": {"tag": "plain_text", "content": "🍔 去美团"}, "url": "https://h5.waimai.meituan.com/waimai/mindex/home", "type": "default"}
    ]

    send_card_with_buttons("🍜 饭点提醒", "blue", text_content, buttons)

这样卡片不仅提醒你吃饭,还能一键跳转到外卖平台,快速下单。


新功能二:天气提醒 🌤🌆

牛马专列现在支持 08:30 提醒今日天气18:00 提醒明日天气,让你出门和规划下班后活动都心里有数。

天气数据获取

使用 Open-Meteo API 获取 7 天天气:

LAT = 31.16
LON = 121.38
WEATHER_API = f"https://api.open-meteo.com/v1/forecast?latitude={LAT}&longitude={LON}&daily=temperature_2m_max,temperature_2m_min,precipitation_sum&timezone=Asia%2FShanghai"

def fetch_weather():
    try:
        resp = requests.get(WEATHER_API, timeout=5)
        if resp.status_code == 200:
            return resp.json()
        else:
            log(f"天气接口失败: {resp.status_code}")
            return None
    except Exception as e:
        log(f"天气接口异常: {e}")
        return None

生成天气提示文本

def weather_message(date_str, temp_max, temp_min, precipitation):
    tips = []
    if temp_max >= 37:
        tips.append("🔥 高温预警,注意防晒防中暑")
    elif temp_min <= 5:
        tips.append("❄️ 气温偏低,注意保暖")
    if precipitation >= 1:
        tips.append("☔️ 记得带伞")
    if not tips:
        tips.append("😊 天气不错,心情舒畅")
    return [
        f"📅 日期:{date_str}",
        f"🌡️ 最高温:{temp_max}°C,最低温:{temp_min}°C",
        f"🌧️ 降水量:{precipitation}mm",
        "💡 " + ",".join(tips)
    ]

08:30 提醒今日天气

def morning_weather_reminder():
    weather = fetch_weather()
    if not weather:
        return
    today = datetime.datetime.now().strftime("%Y-%m-%d")
    idx = weather["daily"]["time"].index(today)
    temp_max = weather["daily"]["temperature_2m_max"][idx]
    temp_min = weather["daily"]["temperature_2m_min"][idx]
    precipitation = weather["daily"]["precipitation_sum"][idx]
    content = weather_message(today, temp_max, temp_min, precipitation)
    send_card("🌤 今日天气提醒", content, header_title="🌤 今日天气提醒", color="blue")

18:00 提醒明日天气

def evening_weather_reminder():
    weather = fetch_weather()
    if not weather:
        return
    tomorrow = (datetime.datetime.now() + datetime.timedelta(days=1)).strftime("%Y-%m-%d")
    idx = weather["daily"]["time"].index(tomorrow)
    temp_max = weather["daily"]["temperature_2m_max"][idx]
    temp_min = weather["daily"]["temperature_2m_min"][idx]
    precipitation = weather["daily"]["precipitation_sum"][idx]
    content = weather_message(tomorrow, temp_max, temp_min, precipitation)
    send_card("🌆 明日天气提醒", content, header_title="🌆 明日天气提醒", color="purple")

新功能三:工作进度条、随机鼓励词

新增进度条 + 百分比(基于 9:00–18:00 工作时长 8 小时)

“再坚持一下”文案改成随机提示(从一个候选列表里随机挑选)

def work_reminder():
    now = datetime.datetime.now()
    earned = calc_earned(now)

    # 下班时间
    start_time = now.replace(hour=9, minute=0, second=0, microsecond=0)
    end_time = now.replace(hour=18, minute=0, second=0, microsecond=0)

    # 进度条比例
    total_seconds = (end_time - start_time).total_seconds()
    worked_seconds = max(0, (now - start_time).total_seconds())
    percent = min(1.0, worked_seconds / total_seconds if total_seconds > 0 else 0)
    progress_bar = make_progress_bar(percent)
    percent_str = f"{int(percent * 100)}%"

    # 倒计时
    remaining = end_time - now
    hours, remainder = divmod(int(remaining.total_seconds()), 3600)
    minutes, _ = divmod(remainder, 60)

    # 随机提示语
    tips = [
        "摸鱼都摸的有底气了",
        "收尾?小场面!干完直接润",
        "键盘都在摸鱼划水",
        "别催!活儿在收尾,我的奶茶外卖比我还急着下班",
        "再坚持一下,等会就能快乐下班"
        ]
    tip_text = random.choice(tips)

    send_card(
        title="⏳ 下班倒计时",
        content_lines=[
            f"📅 现在是 {now.strftime('%Y-%m-%d %H:%M')}",
            f"⏳ 距离下班还有 **{hours} 小时 {minutes} 分钟**",
            f"💰 今天已经挣了 **{earned:.2f} 元**",
            f"📊 工作进度:{progress_bar} {percent_str}",
            f"💡 {tip_text}"
        ],
        header_title="⏳ 下班倒计时",
        color="turquoise"
    )

提醒时间点概览

时间提醒卡片内容
08:30今日天气提醒 🌤
10:50午餐提醒(带按钮) 🍱
13:00-17:00下午每个整点下班倒计时提醒 ⏳
17:50下班前 10 分钟提醒 🏁
18:00明日天气提醒 🌆

快速运行

1. 安装依赖:

pip install requests

2. 运行脚本:

python3 work_reminder_v3.py

3. 建议用 systemd 或 nohup 常驻运行:

nohup python3 work_reminder_v3.py &

小结

牛马专列第二版不仅在饭点提醒上增加了交互按钮,让点餐更方便,还加入了天气提醒,让上班和下班的出行更智能。