Skip to content

优化消息推送逻辑,增加图片推送,支持onebot推送#169

Merged
megumiss merged 12 commits intomasterfrom
push_image
Mar 3, 2026
Merged

优化消息推送逻辑,增加图片推送,支持onebot推送#169
megumiss merged 12 commits intomasterfrom
push_image

Conversation

@megumiss
Copy link
Copy Markdown
Owner

@megumiss megumiss commented Feb 3, 2026

Summary by Sourcery

重构通知系统,使其支持国际化(i18n)、图片附件,并新增一个专门用于每日完成情况通知的任务,同时集成 OneBot11 和 SMTP 图片支持。

新功能:

  • 添加 OneBot11 提供方实现,以支持通过兼容 OneBot v11 的端点进行文本和图片推送。
  • 引入可配置的 Notify 定时任务,将每日完成情况通知与每日任务执行分离发送。
  • 添加 SMTP 消息解析器,使通知中的图片能够作为电子邮件附件发送。

增强改进:

  • 将通知处理重构为集中式的基于 i18n 的助手,从语言特定的模板和配置中生成标题与内容。
  • 扩展招募 SSR 通知和崩溃处理,以便在推送消息和 Windows 通知气泡中附加相关截图。
  • 统一并简化 Linux/Windows 的通知派发逻辑,包括对 SMTP 和桌面通知等提供方特定图片处理方式的支持。
Original summary in English

Summary by Sourcery

Revamp the notification system to be i18n-aware, support image attachments, and add a dedicated daily completion notify task while integrating OneBot11 and SMTP image support.

New Features:

  • Add OneBot11 provider implementation to support text and image push via OneBot v11-compatible endpoints.
  • Introduce a configurable Notify scheduler task to send daily completion notifications separately from daily task execution.
  • Add SMTP message parser to include images as email attachments in notifications.

Enhancements:

  • Refactor notification handling into a centralized i18n-based helper that derives titles and contents from language-specific templates and config.
  • Extend recruit SSR notifications and crash handling to attach relevant screenshots to push messages and Windows toasts.
  • Unify and simplify Linux/Windows notification dispatching, including support for provider-specific image handling such as SMTP and desktop notifications.

@megumiss megumiss changed the title 增加异常/抽卡图片推送 优化消息推送逻辑,增加图片推送,支持onebot推送 Feb 28, 2026
@megumiss
Copy link
Copy Markdown
Owner Author

megumiss commented Mar 2, 2026

@sourcery-ai review

@sourcery-ai
Copy link
Copy Markdown

sourcery-ai Bot commented Mar 2, 2026

Reviewer's Guide

将通知处理重构为一个集中式、支持国际化(i18n)的辅助工具,带可选图片支持;将其接入招募 SSR、崩溃以及每日任务完成等流程;新增 OneBot11 Provider 和 SMTP 图片附件支持;同时新增专门的 Notify 任务/调度器,并进行了一些清理修复。

统一 handle_notify 流程(包含 SSR 招募图片和 OneBot11)的时序图

sequenceDiagram
    actor User
    participant DailyRecruit
    participant NotifyHelper
    participant NotifyI18N
    participant DeployConfig
    participant NotifyWinHandler
    participant NotifyLinuxHandler
    participant OnePushCore
    participant OneBot11

    User->>DailyRecruit: event_free_recruit()
    DailyRecruit->>DailyRecruit: appear(RECRUIT_CONFIRM)
    DailyRecruit->>DailyRecruit: appear(RECRUIT_NIKKE_SSR)
    DailyRecruit->>DailyRecruit: save_drop_image(device.image,DailyRecruit_ScreenshotPath) image_path
    DailyRecruit->>NotifyHelper: handle_notify(config,title_key=Recruit.title,content_key=Recruit.content,recruit_type_key=EventFree,image_path=image_path,always=Notification_WinOnePush)

    NotifyHelper->>DeployConfig: Language
    DeployConfig-->>NotifyHelper: lang
    NotifyHelper->>NotifyI18N: get_text(RecruitType.EventFree,lang)
    NotifyI18N-->>NotifyHelper: recruit_type
    NotifyHelper->>NotifyI18N: get_text(Recruit.title,lang,config_name)
    NotifyI18N-->>NotifyHelper: title
    NotifyHelper->>NotifyI18N: get_text(Recruit.content,lang,config_name,recruit_type)
    NotifyI18N-->>NotifyHelper: content

    alt Windows platform
        NotifyHelper->>NotifyWinHandler: handle_notify_win(title,content,image_path)
        NotifyWinHandler-->>NotifyHelper: ok
        alt always is True
            NotifyHelper->>NotifyLinuxHandler: handle_notify_linux(Notification_OnePushConfig,title,content,image_path)
            NotifyLinuxHandler->>OnePushCore: get_notifier(provider_name)
            OnePushCore-->>NotifyLinuxHandler: OneBot11
            NotifyLinuxHandler->>OneBot11: notify(endpoint,message_type,user_id,group_id,title,content,image_path)
            OneBot11->>OneBot11: POST text message
            OneBot11->>OneBot11: POST image message (base64)
            OneBot11-->>NotifyLinuxHandler: Response(status_code)
            NotifyLinuxHandler-->>NotifyHelper: success/fail
        end
    else NonWindows platform
        NotifyHelper->>NotifyLinuxHandler: handle_notify_linux(Notification_OnePushConfig,title,content,image_path)
        NotifyLinuxHandler->>OnePushCore: get_notifier(provider_name)
        OnePushCore-->>NotifyLinuxHandler: OneBot11 or other Provider
        NotifyLinuxHandler->>OneBot11: notify(...)
        OneBot11->>OneBot11: send text and optional image
        OneBot11-->>NotifyLinuxHandler: Response(status_code)
        NotifyLinuxHandler-->>NotifyHelper: success/fail
    end

    NotifyHelper-->>DailyRecruit: done
    DailyRecruit-->>User: SSR notification received
Loading

新通知流水线及 Provider 的类图

classDiagram
    class UI
    class Notify{
        +config
        +device
        +run()
    }

    class OnePushProvider{
        <<interface>>
        +params
        +notify(**kwargs) Response
    }

    class OneBot11{
        +name
        +_params
        +__init__()
        +notify(**kwargs) Response
    }

    class NotifyI18N{
        +I18N_NOTIFY
        +get_text(key,lang,**kwargs) str
    }

    class NotifyHelper{
        +handle_notify(config,title_key,content_key,**kwargs)
    }

    class NotifyWinHandler{
        +handle_notify_win(**kwargs) bool
    }

    class NotifyLinuxHandler{
        +handle_notify_linux(_config,**kwargs) bool
    }

    class SmtpImageParser{
        +smtp_image_parser(self,subject,title,content,From,user,To,image_path,**kwargs) EmailMessage
    }

    class DeployConfig{
        +Language
    }

    class NikkeConfig{
        +config_name
        +Notification_OnePushConfig
        +Notification_WinOnePush
        +Notification_WhenDailyTaskCompleted
        +Notification_WhenDailyTaskCrashed
    }

    class DailyRecruit{
        +config
        +device
        +save_drop_image(image,base_path) str
        +notify_push(type,image=None)
        +event_free_recruit(skip_first_screenshot=True)
        +ordinary_150gem_recruit(skip_first_screenshot=True)
        +social_point_recruit(skip_first_screenshot=True)
    }

    class MainRunner{
        +config
        +config_name
        +device
        +run(command,skip_first_screenshot=False)
        +save_error_log() str
        +_post_action()
        +notify()
    }

    UI <|-- Notify
    OnePushProvider <|-- OneBot11

    Notify ..> NotifyHelper : uses
    Notify ..> NikkeConfig : config

    DailyRecruit ..> NotifyHelper : notify_push()
    DailyRecruit ..> NikkeConfig : config

    MainRunner ..> NotifyHelper : handle_notify()
    MainRunner ..> NikkeConfig : config

    NotifyHelper ..> NotifyWinHandler : calls
    NotifyHelper ..> NotifyLinuxHandler : calls
    NotifyHelper ..> NotifyI18N : get_text()
    NotifyHelper ..> DeployConfig : read Language
    NotifyHelper ..> NikkeConfig : Notification_OnePushConfig

    NotifyLinuxHandler ..> OnePushProvider : get_notifier()
    NotifyLinuxHandler ..> SmtpImageParser : smtp_image_parser()

    OneBot11 ..|> OnePushProvider

    SmtpImageParser ..> EmailMessage
Loading

文件级变更

Change Details Files
将通知构建统一到一个支持 i18n 的辅助工具中,并迁移现有调用点,包括崩溃处理、任务失败和每日任务完成通知。
  • 在 module.notify.init 中引入 handle_notify,它通过 get_text 解析 i18n key,使用 config_name 和其他动态参数格式化标题/内容,并使用完整的 config 对象分发到平台相关的处理器
  • 在 module.notify.i18n 中新增 I18N_NOTIFY 和 get_text 辅助函数,为崩溃、每日完成和招募通知提供 zh-CN、en-US 和 ja-JP 的本地化文案
  • 更新 main.run 中崩溃/错误分支以及循环任务失败通知,改为调用新的 handle_notify,并传入 title_key/content_key(或 content key 列表),同时传递任务和崩溃截图等上下文参数,而不是原始字符串
  • 将每日任务完成通知逻辑从 Daily.run 中移动到新的 Notify 任务(Notify UI 类)中,并将其调度器接入默认/覆盖 YAML 以及任务/菜单的连接
module/notify/__init__.py
module/notify/i18n.py
main.py
module/daily/daily.py
module/notify/notify.py
module/config/argument/default.yaml
module/config/argument/override.yaml
module/config/argument/task.yaml
module/config/manual_config.py
module/config/argument/args.json
module/config/argument/menu.json
config/template.json
module/config/i18n/en-US.json
module/config/i18n/ja-JP.json
module/config/i18n/zh-CN.json
为通知添加丰富的图片支持,覆盖招募掉落和崩溃/错误流程,包括 Windows toast、Linux/OnePush、SMTP 和 OneBot11。
  • 扩展每日招募的 notify_push,使其接受可选图片,并使用 Recruit.title/content key 以及 recruit_type_key 调用 handle_notify;同时仅在检测到 SSR 后才进行截图保存和发送通知
  • 修改 save_error_log 以返回最后保存的截图路径,使崩溃/错误通知可以通过 handle_notify 附带相关图片
  • 更新 handle_notify_win,当存在 image_path 时优先将其作为 toast 图标,否则回退到默认 ICON
  • 更新 handle_notify_linux,对 SMTP Provider 使用自定义 SMTP 消息解析器(smtp_image_parser)来附加 image_path,并将 image_path 传入 OnePush 的 notifier 配置中
  • 新增 smtp_image_parser,用于构造 EmailMessage,根据 mimetypes 推断正文和可选图片附件
module/daily_recruit/daily_recruit.py
main.py
module/notify/notify.py
module/notify/smtp.py
为 OnePush 引入 OneBot v11 Provider,可以通过兼容 OneBot 的端点发送文本和图片消息。
  • 添加 OneBot11 Provider 实现,校验 endpoint/message_type,推导正确的 send_private_msg/send_group_msg URL 和载荷,并使用 requests 发送文本与可选的 base64 编码图片消息
  • 在 module.notify.notify 中注册 OneBot11 Provider,将其以 'onebot11' 键插入 onepush.core._all_providers
module/notify/onebot11.py
module/notify/notify.py
调整任务调度和清理行为,以支持新的 Notify 任务,并确保跨平台一致地执行后置清理。
  • 添加 Nikke.notify 方法,用于实例化并运行 Notify UI 任务,使其与其他高层任务入口保持一致
  • 在默认和覆盖 YAML 中添加 Notify.Scheduler 条目(默认启用,但在 override 中隐藏),并将 Notify 加入 NKAS 任务组层级以及手动配置文档字符串中
  • 调整 get_next_task 的清理顺序,保证 _post_action 总是在 Windows 特定的设备释放之前调用,修复在非 Windows 平台上跳过清理的问题
main.py
module/config/argument/default.yaml
module/config/argument/override.yaml
module/config/argument/task.yaml
module/config/manual_config.py
对招募流程及相关代码路径进行轻微行为和样式修正。
  • 确保 SSR 招募通知只在确认检测到 RECRUIT_NIKKE_SSR 后触发:将截图保存和通知逻辑嵌入 appear(RECRUIT_NIKKE_SSR) 检查内部,适用于所有招募类型(EventFree、150Gem、SocialPoint)
  • 将保存的招募截图路径传入通知,使推送 Provider 能包含掉落图片
  • 规范 ordinary_150gem_recruit 中的间距和偏移量检查与点击,使代码更易读
module/daily_recruit/daily_recruit.py

Tips and commands

与 Sourcery 交互

  • 触发新评审: 在 Pull Request 中评论 @sourcery-ai review
  • 继续讨论: 直接回复 Sourcery 的评审评论。
  • 从评审评论生成 GitHub Issue: 在某条评审评论下让 Sourcery 创建 Issue;也可以直接回复该评论 @sourcery-ai issue,从中创建 Issue。
  • 生成 Pull Request 标题: 在 Pull Request 标题中任意位置写上 @sourcery-ai,即可随时生成标题。也可以在 Pull Request 中评论 @sourcery-ai title 来(重新)生成标题。
  • 生成 Pull Request 摘要: 在 Pull Request 正文任意位置写上 @sourcery-ai summary,即可在指定位置生成 PR 摘要。也可以在 Pull Request 中评论 @sourcery-ai summary 来(重新)生成摘要。
  • 生成 Reviewer's Guide: 在 Pull Request 中评论 @sourcery-ai guide,即可(重新)生成评审指南。
  • 一键解决所有 Sourcery 评论: 在 Pull Request 中评论 @sourcery-ai resolve,即可将所有 Sourcery 评论标记为已解决。如果你已经处理完所有评论且不想再看到它们,这会很有用。
  • 撤销所有 Sourcery 评审: 在 Pull Request 中评论 @sourcery-ai dismiss,即可撤销所有现有 Sourcery 评审。尤其适用于你希望从一次全新的评审开始的情况——记得之后再评论 @sourcery-ai review 触发新评审!

自定义你的体验

访问你的 控制面板 来:

  • 启用或禁用诸如 Sourcery 生成的 Pull Request 摘要、评审指南等功能。
  • 修改评审语言。
  • 添加、移除或编辑自定义评审指令。
  • 调整其他评审设置。

获取帮助

Original review guide in English

Reviewer's Guide

Refactors notification handling into a centralized, i18n-aware helper with optional image support, wires it into recruit SSR, crash, and daily-completion flows, and adds a new OneBot11 provider plus SMTP image attachment support, alongside a dedicated Notify task/scheduler and some cleanup fixes.

Sequence diagram for unified handle_notify flow with SSR recruit image and OneBot11

sequenceDiagram
    actor User
    participant DailyRecruit
    participant NotifyHelper
    participant NotifyI18N
    participant DeployConfig
    participant NotifyWinHandler
    participant NotifyLinuxHandler
    participant OnePushCore
    participant OneBot11

    User->>DailyRecruit: event_free_recruit()
    DailyRecruit->>DailyRecruit: appear(RECRUIT_CONFIRM)
    DailyRecruit->>DailyRecruit: appear(RECRUIT_NIKKE_SSR)
    DailyRecruit->>DailyRecruit: save_drop_image(device.image,DailyRecruit_ScreenshotPath) image_path
    DailyRecruit->>NotifyHelper: handle_notify(config,title_key=Recruit.title,content_key=Recruit.content,recruit_type_key=EventFree,image_path=image_path,always=Notification_WinOnePush)

    NotifyHelper->>DeployConfig: Language
    DeployConfig-->>NotifyHelper: lang
    NotifyHelper->>NotifyI18N: get_text(RecruitType.EventFree,lang)
    NotifyI18N-->>NotifyHelper: recruit_type
    NotifyHelper->>NotifyI18N: get_text(Recruit.title,lang,config_name)
    NotifyI18N-->>NotifyHelper: title
    NotifyHelper->>NotifyI18N: get_text(Recruit.content,lang,config_name,recruit_type)
    NotifyI18N-->>NotifyHelper: content

    alt Windows platform
        NotifyHelper->>NotifyWinHandler: handle_notify_win(title,content,image_path)
        NotifyWinHandler-->>NotifyHelper: ok
        alt always is True
            NotifyHelper->>NotifyLinuxHandler: handle_notify_linux(Notification_OnePushConfig,title,content,image_path)
            NotifyLinuxHandler->>OnePushCore: get_notifier(provider_name)
            OnePushCore-->>NotifyLinuxHandler: OneBot11
            NotifyLinuxHandler->>OneBot11: notify(endpoint,message_type,user_id,group_id,title,content,image_path)
            OneBot11->>OneBot11: POST text message
            OneBot11->>OneBot11: POST image message (base64)
            OneBot11-->>NotifyLinuxHandler: Response(status_code)
            NotifyLinuxHandler-->>NotifyHelper: success/fail
        end
    else NonWindows platform
        NotifyHelper->>NotifyLinuxHandler: handle_notify_linux(Notification_OnePushConfig,title,content,image_path)
        NotifyLinuxHandler->>OnePushCore: get_notifier(provider_name)
        OnePushCore-->>NotifyLinuxHandler: OneBot11 or other Provider
        NotifyLinuxHandler->>OneBot11: notify(...)
        OneBot11->>OneBot11: send text and optional image
        OneBot11-->>NotifyLinuxHandler: Response(status_code)
        NotifyLinuxHandler-->>NotifyHelper: success/fail
    end

    NotifyHelper-->>DailyRecruit: done
    DailyRecruit-->>User: SSR notification received
Loading

Class diagram for the new notification pipeline and providers

classDiagram
    class UI
    class Notify{
        +config
        +device
        +run()
    }

    class OnePushProvider{
        <<interface>>
        +params
        +notify(**kwargs) Response
    }

    class OneBot11{
        +name
        +_params
        +__init__()
        +notify(**kwargs) Response
    }

    class NotifyI18N{
        +I18N_NOTIFY
        +get_text(key,lang,**kwargs) str
    }

    class NotifyHelper{
        +handle_notify(config,title_key,content_key,**kwargs)
    }

    class NotifyWinHandler{
        +handle_notify_win(**kwargs) bool
    }

    class NotifyLinuxHandler{
        +handle_notify_linux(_config,**kwargs) bool
    }

    class SmtpImageParser{
        +smtp_image_parser(self,subject,title,content,From,user,To,image_path,**kwargs) EmailMessage
    }

    class DeployConfig{
        +Language
    }

    class NikkeConfig{
        +config_name
        +Notification_OnePushConfig
        +Notification_WinOnePush
        +Notification_WhenDailyTaskCompleted
        +Notification_WhenDailyTaskCrashed
    }

    class DailyRecruit{
        +config
        +device
        +save_drop_image(image,base_path) str
        +notify_push(type,image=None)
        +event_free_recruit(skip_first_screenshot=True)
        +ordinary_150gem_recruit(skip_first_screenshot=True)
        +social_point_recruit(skip_first_screenshot=True)
    }

    class MainRunner{
        +config
        +config_name
        +device
        +run(command,skip_first_screenshot=False)
        +save_error_log() str
        +_post_action()
        +notify()
    }

    UI <|-- Notify
    OnePushProvider <|-- OneBot11

    Notify ..> NotifyHelper : uses
    Notify ..> NikkeConfig : config

    DailyRecruit ..> NotifyHelper : notify_push()
    DailyRecruit ..> NikkeConfig : config

    MainRunner ..> NotifyHelper : handle_notify()
    MainRunner ..> NikkeConfig : config

    NotifyHelper ..> NotifyWinHandler : calls
    NotifyHelper ..> NotifyLinuxHandler : calls
    NotifyHelper ..> NotifyI18N : get_text()
    NotifyHelper ..> DeployConfig : read Language
    NotifyHelper ..> NikkeConfig : Notification_OnePushConfig

    NotifyLinuxHandler ..> OnePushProvider : get_notifier()
    NotifyLinuxHandler ..> SmtpImageParser : smtp_image_parser()

    OneBot11 ..|> OnePushProvider

    SmtpImageParser ..> EmailMessage
Loading

File-Level Changes

Change Details Files
Unify notification construction into an i18n-aware helper and migrate existing call sites to it, including crash handling, task failure, and daily-completion notifications.
  • Introduce handle_notify in module.notify.init that resolves i18n keys via get_text, formats titles/contents with config_name and other dynamic args, and dispatches to platform-specific handlers using the full config object
  • Add I18N_NOTIFY and get_text helper in module.notify.i18n to provide localized strings for crash, daily completion, and recruit notifications in zh-CN, en-US, and ja-JP
  • Update main.run crash/error branches and loop task-failure notifications to call the new handle_notify with title_key/content_key (or a list of content keys) and pass contextual arguments like task and crash screenshots instead of raw strings
  • Move daily-task-completed notification logic from Daily.run into a new Notify task (Notify UI class) and wire its scheduler into default/override YAML and task/menu wiring
module/notify/__init__.py
module/notify/i18n.py
main.py
module/daily/daily.py
module/notify/notify.py
module/config/argument/default.yaml
module/config/argument/override.yaml
module/config/argument/task.yaml
module/config/manual_config.py
module/config/argument/args.json
module/config/argument/menu.json
config/template.json
module/config/i18n/en-US.json
module/config/i18n/ja-JP.json
module/config/i18n/zh-CN.json
Add rich image support to notifications across recruit drops and crash/error flows, including Windows toast, Linux/OnePush, SMTP, and OneBot11.
  • Extend daily recruit notify_push to accept an optional image and call handle_notify with Recruit.title/content keys and recruit_type_key, and gate screenshot saving/notification strictly on SSR detection before saving and sending
  • Modify save_error_log to return the last saved screenshot path so crash/error notifications can include the relevant image via handle_notify
  • Update handle_notify_win to prefer an image_path as the toast icon when present, falling back to the default ICON otherwise
  • Update handle_notify_linux to attach image_path via a custom SMTP message parser (smtp_image_parser) for SMTP providers and to pass image_path into the OnePush notifier config
  • Introduce smtp_image_parser to construct an EmailMessage with the body and optional image attachment inferred from mimetypes
module/daily_recruit/daily_recruit.py
main.py
module/notify/notify.py
module/notify/smtp.py
Introduce a OneBot v11 provider for OnePush that can send text and image messages via OneBot-compatible endpoints.
  • Add OneBot11 Provider implementation that validates endpoint/message_type, derives correct send_private_msg/send_group_msg URL and payload, and sends text and optional base64-encoded image messages using requests
  • Register the OneBot11 provider in module.notify.notify by inserting it into onepush.core._all_providers under the 'onebot11' key
module/notify/onebot11.py
module/notify/notify.py
Adjust task scheduling and cleanup behavior to support the new Notify task and ensure post-action cleanup runs consistently across platforms.
  • Add a Nikke.notify method that instantiates and runs the Notify UI task, aligning with other high-level task entrypoints
  • Add Notify.Scheduler entries in default and override YAML (enabled by default but hidden in override) and include Notify in the NKAS task group hierarchy and manual config documentation string
  • Change get_next_task cleanup order so _post_action is always called before Windows-specific device teardown, fixing skipped cleanup on non-Windows platforms
main.py
module/config/argument/default.yaml
module/config/argument/override.yaml
module/config/argument/task.yaml
module/config/manual_config.py
Minor behavioral and style fixes in recruit flows and related code paths.
  • Ensure SSR recruit notifications only trigger after RECRUIT_NIKKE_SSR is positively detected by nesting screenshot saving and notification inside the appear(RECRUIT_NIKKE_SSR) check for all recruit types (EventFree, 150Gem, SocialPoint)
  • Pass saved recruit screenshot paths into notifications so push providers can include the drop image
  • Normalize spacing and offsets in ordinary_150gem_recruit checks and clicks for readability
module/daily_recruit/daily_recruit.py

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

Copy link
Copy Markdown

@sourcery-ai sourcery-ai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've found 1 issue, and left some high level feedback:

  • In OneBot11.notify, the missing endpoint case only logs an error but still proceeds and returns a Response with default status_code 0; consider short‑circuiting with a clear non‑200 status (e.g., 400) similar to the other validation branches so callers can reliably detect configuration errors.
  • The _post_action method now has a stray # 发送通知 comment and extra blank lines without any related logic; consider removing or wiring this up to real notification behavior to keep the method’s intent clear.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- In `OneBot11.notify`, the missing `endpoint` case only logs an error but still proceeds and returns a Response with default status_code 0; consider short‑circuiting with a clear non‑200 status (e.g., 400) similar to the other validation branches so callers can reliably detect configuration errors.
- The `_post_action` method now has a stray `# 发送通知` comment and extra blank lines without any related logic; consider removing or wiring this up to real notification behavior to keep the method’s intent clear.

## Individual Comments

### Comment 1
<location path="module/notify/__init__.py" line_range="6-15" />
<code_context>
+def handle_notify(config, title_key: str, content_key, **kwargs):
</code_context>
<issue_to_address>
**issue (bug_risk):** Re-check whether not forwarding arbitrary kwargs to providers is acceptable or needs adjustment.

Previously, `handle_notify` passed all arbitrary kwargs to `handle_notify_linux`/providers, enabling provider-specific options (e.g., `subject`, custom headers, metadata). Now only `title`, `content`, and `image_path` are forwarded, while other kwargs are only used for i18n and then discarded.

If existing configs rely on those extra kwargs reaching providers, this becomes a breaking change. Either forward remaining non-internal kwargs as well (excluding things like `always`), or clearly document that only `title`, `content`, and `image_path` are passed through and update configs accordingly.
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment thread module/notify/__init__.py
Comment on lines +6 to +15
def handle_notify(config, title_key: str, content_key, **kwargs):
"""
处理通知,支持多语言。

Args:
config: NikkeConfig 实例,用于获取 onepush 配置和语言。
title_key (str): 标题的 i18n key。
content_key (str or list): 内容的 i18n key。
**kwargs:
image_path (str): 图片路径。
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue (bug_risk): Re-check whether not forwarding arbitrary kwargs to providers is acceptable or needs adjustment.

Previously, handle_notify passed all arbitrary kwargs to handle_notify_linux/providers, enabling provider-specific options (e.g., subject, custom headers, metadata). Now only title, content, and image_path are forwarded, while other kwargs are only used for i18n and then discarded.

If existing configs rely on those extra kwargs reaching providers, this becomes a breaking change. Either forward remaining non-internal kwargs as well (excluding things like always), or clearly document that only title, content, and image_path are passed through and update configs accordingly.

@megumiss
Copy link
Copy Markdown
Owner Author

megumiss commented Mar 2, 2026

@sourcery-ai review

Copy link
Copy Markdown

@sourcery-ai sourcery-ai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - 我发现了 1 个问题,并留下了一些整体性的反馈:

  • OneBot11.notify 中,当缺少 endpoint 时,你只记录了一条错误日志,但仍然继续构造 api_url;建议在构造的 mock Response 上设置一个非 200 的状态码,并立即返回,以避免向无效 URL 发送请求。
  • 新的 handle_notify 包装函数丢弃了大部分原始的 kwargs,只把 titlecontentimage_path 传递给 handle_notify_linux;如果你需要在每次调用时覆盖 provider 相关配置(例如自定义 endpoint/token/group_id),可以考虑在调用 handle_notify_linux 之前,显式允许这些参数并将它们合并进配置中。
给 AI 代理的提示
请根据下面的代码评审意见进行修改:

## 总体意见
-`OneBot11.notify` 中,当缺少 `endpoint` 时,你只记录了一条错误日志,但仍然继续构造 `api_url`;建议在构造的 mock `Response` 上设置一个非 200 的状态码,并立即返回,以避免向无效 URL 发送请求。
- 新的 `handle_notify` 包装函数丢弃了大部分原始的 kwargs,只把 `title``content``image_path` 传递给 `handle_notify_linux`;如果你需要在每次调用时覆盖 provider 相关配置(例如自定义 endpoint/token/group_id),可以考虑在调用 `handle_notify_linux` 之前,显式允许这些参数并将它们合并进配置中。

## 逐条评论

### 评论 1
<location path="module/notify/onebot11.py" line_range="34-37" />
<code_context>
+    def notify(self, **kwargs) -> Response:
+        """重写 notify 方法,接管完整的推送逻辑"""
+        # 读取新的参数格式
+        endpoint = kwargs.get('endpoint', '').rstrip('/')
+        token = kwargs.get('token', '')
+        message_type = kwargs.get('message_type', '')
+        user_id = kwargs.get('user_id')
+        group_id = kwargs.get('group_id')
+        
+        # 准备一个假的 Response 对象,用于兼容原 notify.py 的 status_code 校验逻辑
+        mock_resp = Response()
+
+        # 根据 message_type 校验必须的 ID 参数
+        if not endpoint:
+            logger.error("Notifier onebot11 require param 'endpoint'")
+        if message_type == 'private' and not user_id:
</code_context>
<issue_to_address>
**suggestion:** 当缺少 `endpoint` 时应尽早返回,而不是继续执行并最终触发失败的 HTTP 请求。

当前分支只是在 `endpoint` 缺失时记录一条日志,然后继续执行,构造出类似 `/send_group_msg` 的 URL,接着在 `requests.post` 中失败,并通过 `success = False` 变成一个笼统的 500。为了与 `user_id` / `group_id` / `message_type` 的校验逻辑保持一致,并提供更清晰的反馈,建议在缺少 `endpoint` 时设置 `mock_resp.status_code = 400` 并立即返回。

```suggestion
        # 根据 message_type 校验必须的 ID 参数
        if not endpoint:
            logger.error("Notifier onebot11 require param 'endpoint'")
            mock_resp.status_code = 400
            return mock_resp
        if message_type == 'private' and not user_id:
```
</issue_to_address>

Sourcery 对开源项目免费使用——如果你觉得这次评审有帮助,欢迎分享 ✨
帮我变得更有用!请对每条评论点 👍 或 👎,我会根据你的反馈改进评审质量。
Original comment in English

Hey - I've found 1 issue, and left some high level feedback:

  • In OneBot11.notify, when endpoint is missing you only log an error but still proceed to construct api_url; consider setting a non-200 status on the mock Response and returning immediately to avoid posting to an invalid URL.
  • The new handle_notify wrapper drops most original kwargs and only forwards title, content, and image_path to handle_notify_linux; if you need per-call overrides for provider options (e.g., custom endpoint/token/group_id), you may want to explicitly allow and merge those into the config before calling handle_notify_linux.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- In `OneBot11.notify`, when `endpoint` is missing you only log an error but still proceed to construct `api_url`; consider setting a non-200 status on the mock `Response` and returning immediately to avoid posting to an invalid URL.
- The new `handle_notify` wrapper drops most original kwargs and only forwards `title`, `content`, and `image_path` to `handle_notify_linux`; if you need per-call overrides for provider options (e.g., custom endpoint/token/group_id), you may want to explicitly allow and merge those into the config before calling `handle_notify_linux`.

## Individual Comments

### Comment 1
<location path="module/notify/onebot11.py" line_range="34-37" />
<code_context>
+    def notify(self, **kwargs) -> Response:
+        """重写 notify 方法,接管完整的推送逻辑"""
+        # 读取新的参数格式
+        endpoint = kwargs.get('endpoint', '').rstrip('/')
+        token = kwargs.get('token', '')
+        message_type = kwargs.get('message_type', '')
+        user_id = kwargs.get('user_id')
+        group_id = kwargs.get('group_id')
+        
+        # 准备一个假的 Response 对象,用于兼容原 notify.py 的 status_code 校验逻辑
+        mock_resp = Response()
+
+        # 根据 message_type 校验必须的 ID 参数
+        if not endpoint:
+            logger.error("Notifier onebot11 require param 'endpoint'")
+        if message_type == 'private' and not user_id:
</code_context>
<issue_to_address>
**suggestion:** Return early when `endpoint` is missing instead of falling through to a failing HTTP request.

This branch only logs the missing `endpoint` and then continues, building a URL like `/send_group_msg` and failing later in `requests.post`, which becomes a generic 500 via `success = False`. For consistency with the `user_id` / `group_id` / `message_type` validation and to give clearer feedback, set `mock_resp.status_code = 400` and return immediately when `endpoint` is missing.

```suggestion
        # 根据 message_type 校验必须的 ID 参数
        if not endpoint:
            logger.error("Notifier onebot11 require param 'endpoint'")
            mock_resp.status_code = 400
            return mock_resp
        if message_type == 'private' and not user_id:
```
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment thread module/notify/onebot11.py
@megumiss megumiss merged commit 4a70534 into master Mar 3, 2026
1 check passed
@megumiss megumiss deleted the push_image branch March 10, 2026 07:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant