diff --git a/.idea/dataSources.xml b/.idea/dataSources.xml
new file mode 100644
index 0000000..64d01ce
--- /dev/null
+++ b/.idea/dataSources.xml
@@ -0,0 +1,12 @@
+
+
+
+
+ sqlite.xerial
+ true
+ org.sqlite.JDBC
+ jdbc:sqlite:$USER_HOME$/AppData/Local/nonebot2/nonebot_plugin_github_release_notifier/github_release_notifier.db
+ $ProjectFileDir$
+
+
+
\ No newline at end of file
diff --git a/README.md b/README.md
index 3dd1900..2e18469 100644
--- a/README.md
+++ b/README.md
@@ -22,7 +22,7 @@
**本项目为纯GitHub REST API实现,非webhook,不依赖相关服务**
-其他语言 | Other languages: [English](https://github.com/HTony03/nonebot_plugin_github_release_notifier/README_en.md)
+其他语言 | Other languages: [English](https://github.com/HTony03/nonebot_plugin_github_release_notifier/blob/main/README_en.md)
## 📖 介绍
@@ -60,19 +60,20 @@
在 nonebot2 项目的 `.env` 文件中添加下表中的必填配置:
-| 配置项 | 必填 | 默认值 | 说明 |
-|:-----:|:----:|:----:|:----:|
-| GITHUB_TOKEN | 否 | 空字符串 | 用于访问 GitHub API 的 Token |
-| GITHUB_RETRIES | 否 | 3 | 刷新最大重试次数 |
-| GITHUB_RETRY_DELAY | 否 | 5 | 每次刷新重试之间的延迟(秒) |
-| GITHUB_LANGUAGE | 否 | "en_us" | 发送的模板语言 |
-| GITHUB_SEND_FALIURE_GROUP | 否 | True | 失败时是否通知群聊 |
-| GITHUB_SEND_FALIURE_SUPERUSER | 否 | False | 失败时是否通知超级用户 |
-| GITHUB_DEFAULT_CONFIG_SETTING | 否 | True | 添加仓库时默认监控所有事件 |
-| GITHUB_SEND_IN_MARKDOWN | 否 | False | 是否以 Markdown 图片方式发送消息 |
-| GITHUB_SEND_DETAIL_IN_MARKDOWN | 否 | True | 是否以 Markdown 图片方式发送详细信息(pr/issue/release)|
-| GITHUB_UPLOAD_REMOVE_OLDER_VER | 否 | True | 上传 release 文件时是否移除旧版本( in development) |
-| GITHUB_THEME | 否 | "dark" | (针对issue/pull request comment)渲染页面风格 ["light","dark"] |
+| 配置项 | 必填 | 默认值 | 说明 |
+|:-----:|:----:|:-------:|:-----------------------------------------------------:|
+| GITHUB_TOKEN | 否 | 空字符串 | 用于访问 GitHub API 的 Token |
+| GITHUB_RETRIES | 否 | 3 | 刷新最大重试次数 |
+| GITHUB_RETRY_DELAY | 否 | 5 | 每次刷新重试之间的延迟(秒) |
+| GITHUB_LANGUAGE | 否 | "en_us" | 发送的模板语言 |
+| GITHUB_SEND_FALIURE_GROUP | 否 | True | 失败时是否通知群聊 |
+| GITHUB_SEND_FALIURE_SUPERUSER | 否 | False | 失败时是否通知超级用户 |
+| GITHUB_DEFAULT_CONFIG_SETTING | 否 | True | 添加仓库时默认监控所有事件 |
+| GITHUB_SEND_IN_MARKDOWN | 否 | False | 是否以 Markdown 图片方式发送消息 |
+| GITHUB_SEND_DETAIL_IN_MARKDOWN | 否 | True | 是否以 Markdown 图片方式发送详细信息(pr/issue/release) |
+| GITHUB_SEND_PREV_DETAILS | 否 | False | 是否发送添加repo前的数据 |
+| GITHUB_UPLOAD_REMOVE_OLDER_VER | 否 | True | 上传 release 文件时是否移除旧版本( in development) |
+| GITHUB_THEME | 否 | "dark" | (针对issue/pull request comment)渲染页面风格 ["light","dark"] |
`v0.1.9` 删除了对于`.env`添加群组repo的适配, 请使用指令使用相关功能
diff --git a/README_en.md b/README_en.md
index 0f4023f..2763f1f 100644
--- a/README_en.md
+++ b/README_en.md
@@ -58,19 +58,20 @@ Before use, ensure that the `SUPERUSERS` configuration item in NoneBot2 is set.
Add the following required configuration items to the `.env` file in your NoneBot2 project:
-| Config Item | Required | Default | Description |
-|:-----------:|:--------:|:-------:|:-----------:|
-| GITHUB_TOKEN | No | Empty string | Token for accessing the GitHub API |
-| GITHUB_RETRIES | No | 3 | Maximum retry attempts for refreshing |
-| GITHUB_RETRY_DELAY | No | 5 | Delay between each refresh retry (seconds) |
-| GITHUB_LANGUAGE | No | "en_us" | Language for sending templates |
-| GITHUB_SEND_FALIURE_GROUP | No | True | Notify group on failure |
-| GITHUB_SEND_FALIURE_SUPERUSER | No | False | Notify superuser on failure |
-| GITHUB_DEFAULT_CONFIG_SETTING | No | True | Monitor all events by default when adding a repo |
-| GITHUB_SEND_IN_MARKDOWN | No | False | Send messages as Markdown images |
-| GITHUB_SEND_DETAIL_IN_MARKDOWN | No | True | Send details (pr/issue/release) as Markdown images |
-| GITHUB_UPLOAD_REMOVE_OLDER_VER | No | True | Remove old versions when uploading release files (in development) |
-| GITHUB_THEME | No | "dark" | (For issue/pull request comments) Page rendering style ["light","dark"] |
+| Config Item | Required | Default | Description |
+|:-----------:|:--------:|:-------:|:-----------------------------------------------------------------------:|
+| GITHUB_TOKEN | No | Empty string | Token for accessing the GitHub API |
+| GITHUB_RETRIES | No | 3 | Maximum retry attempts for refreshing |
+| GITHUB_RETRY_DELAY | No | 5 | Delay between each refresh retry (seconds) |
+| GITHUB_LANGUAGE | No | "en_us" | Language for sending templates |
+| GITHUB_SEND_FALIURE_GROUP | No | True | Notify group on failure |
+| GITHUB_SEND_FALIURE_SUPERUSER | No | False | Notify superuser on failure |
+| GITHUB_DEFAULT_CONFIG_SETTING | No | True | Monitor all events by default when adding a repo |
+| GITHUB_SEND_IN_MARKDOWN | No | False | Send messages as Markdown images |
+| GITHUB_SEND_DETAIL_IN_MARKDOWN | No | True | Send details (pr/issue/release) as Markdown images |
+| GITHUB_SEND_PREV_DETAILS | No | False | Whether send previous details when adding a new repository |
+| GITHUB_UPLOAD_REMOVE_OLDER_VER | No | True | Remove old versions when uploading release files (in development) |
+| GITHUB_THEME | No | "dark" | (For issue/pull request comments) Page rendering style ["light","dark"] |
`v0.1.9` removed support for adding group repo via `.env`. Please use commands for related features.
diff --git a/src/nonebot_plugin_github_release_notifier/commands.py b/src/nonebot_plugin_github_release_notifier/commands.py
index 6e0431e..0ef5079 100644
--- a/src/nonebot_plugin_github_release_notifier/commands.py
+++ b/src/nonebot_plugin_github_release_notifier/commands.py
@@ -90,7 +90,7 @@ async def add_repo(
bot: Bot, event: GroupMessageEvent, args: Message = CommandArg()
):
"""Add a new repository mapping."""
- from .repo_activity_new import github
+ from .repo_activity_new import github, initialize_repo_timestamps
command_args = args.extract_plain_text().split()
if len(command_args) < 1:
await bot.send(event, "Usage: repo add [group_id]")
@@ -123,6 +123,10 @@ async def fetch_repo(repo: str) -> Response[FullRepository]:
config.github_default_config_setting,
None,
False)
+ if not config.github_send_prev_details:
+ # Initialize timestamps to prevent flooding on first check
+ await initialize_repo_timestamps(repo)
+
await bot.send(event, f"Added repository mapping: {group_id} -> {repo}")
logger.info(f"Added repository mapping: {group_id} -> {repo}")
diff --git a/src/nonebot_plugin_github_release_notifier/config.py b/src/nonebot_plugin_github_release_notifier/config.py
index 680400e..e28904d 100644
--- a/src/nonebot_plugin_github_release_notifier/config.py
+++ b/src/nonebot_plugin_github_release_notifier/config.py
@@ -90,6 +90,11 @@ class Config(BaseModel): # pylint: disable=missing-class-docstring
- release
"""
+ github_send_prev_details: bool = False
+ """
+ Whether send previous details when adding a new repository.
+ """
+
github_comment_check_amount: int = 20
"""
The amount of issues/prs to check for comment each time when refresh.
diff --git a/src/nonebot_plugin_github_release_notifier/db_action.py b/src/nonebot_plugin_github_release_notifier/db_action.py
index 494cc6e..cb54c9a 100644
--- a/src/nonebot_plugin_github_release_notifier/db_action.py
+++ b/src/nonebot_plugin_github_release_notifier/db_action.py
@@ -59,10 +59,10 @@ def _create_tables(cursor: sqlite3.Cursor) -> None:
CREATE TABLE IF NOT EXISTS group_config (
group_id TEXT,
repo TEXT,
- commits BOOLEAN,
- issues BOOLEAN,
- prs BOOLEAN,
- releases BOOLEAN,
+ commits BOOLEAN DEFAULT FALSE,
+ issues BOOLEAN DEFAULT FALSE,
+ prs BOOLEAN DEFAULT FALSE,
+ releases BOOLEAN DEFAULT FALSE,
release_folder TEXT,
send_release BOOLEAN DEFAULT FALSE,
send_issue_comment BOOLEAN DEFAULT FALSE,
diff --git a/src/nonebot_plugin_github_release_notifier/repo_activity_new.py b/src/nonebot_plugin_github_release_notifier/repo_activity_new.py
index 25a9850..db1dc8e 100644
--- a/src/nonebot_plugin_github_release_notifier/repo_activity_new.py
+++ b/src/nonebot_plugin_github_release_notifier/repo_activity_new.py
@@ -232,6 +232,115 @@ async def get_data(
return response
+async def initialize_repo_timestamps(repo: str) -> None:
+ """
+ Initialize last_processed timestamps for a newly added repository.
+
+ This prevents flooding by marking all existing commits/issues/PRs/releases
+ as already processed, so only new items created after adding the repo
+ will trigger notifications.
+
+ The function performs two types of initialization:
+ 1. Records timestamps of the latest items in the last_processed table
+ 2. Records issue/PR IDs and latest comment IDs in the issues/prs tables
+ - Uses id=0 as a special key to track the most recent issue/PR itself
+ - Uses id= to track the most recent comment on that issue/PR
+
+ :param repo: GitHub repository in "owner/repo" format
+ :type repo: str
+ """
+ last_processed = load_last_processed()
+
+ # Check if repo already has timestamps - if so, don't overwrite
+ if repo in last_processed:
+ logger.info(f"Repository {repo} already has timestamps, skipping initialization")
+ return
+
+ timestamps = {}
+ current_time = datetime.now(timezone.utc).isoformat()
+ owner, repository = repo.split('/')
+
+ # For each endpoint type, try to fetch the latest item and record its timestamp
+ for data_type, endpoint in [
+ ("commit", "commits"),
+ ("issue", "issues"),
+ ("pull_req", "pulls"),
+ ("release", "releases")
+ ]:
+ try:
+ data = await fetch_github_data(repo, endpoint)
+ if data and len(data) > 0:
+ # Get the timestamp of the most recent item
+ item = data[0]
+ if isinstance(item, Commit):
+ timestamp = item.commit.author.date if item.commit.author else None
+ elif isinstance(item, (Issue, PullRequest, PullRequestSimple)):
+ timestamp = item.created_at
+
+ # For issues endpoint, initialize tracking for both issues and PRs
+ # to prevent comment flooding
+ if endpoint == "issues":
+ for content_type in ["issues", "prs"]:
+ try:
+ # Filter to get only issues or only PRs
+ filtered_items = [
+ i for i in data
+ if (content_type == "prs" and i.pull_request) or
+ (content_type == "issues" and not i.pull_request)
+ ]
+
+ if filtered_items:
+ latest_filtered = filtered_items[0]
+ # Store the latest issue/PR ID in the database with special key id=0
+ # This tracks when a completely new issue/PR is created
+ save_commit_data(repo, str(latest_filtered.id), 0, content_type)
+
+ # Also store latest comment ID for this issue/PR if comments exist
+ try:
+ comments_resp = await github.rest.issues.async_list_comments(
+ owner=owner,
+ repo=repository,
+ issue_number=latest_filtered.number
+ )
+ comments = comments_resp.parsed_data
+ if comments:
+ latest_comment = comments[-1]
+ save_commit_data(repo, str(latest_comment.id), latest_filtered.id, content_type)
+ except Exception as e:
+ logger.debug(
+ f"Could not fetch comments for {content_type[:-1]} #{latest_filtered.number} "
+ f"during initialization: {e.__class__.__name__}"
+ )
+ except Exception as e:
+ logger.warning(
+ f"Failed to initialize {content_type} tracking for {repo}: "
+ f"{e.__class__.__name__}: {e}"
+ )
+
+ elif isinstance(item, Release):
+ timestamp = item.published_at
+ else:
+ timestamp = None
+
+ timestamps[data_type] = timestamp.isoformat() if timestamp else current_time
+ else:
+ # No items exist, use current time
+ timestamps[data_type] = current_time
+ except Exception as e:
+ logger.warning(
+ f"Failed to fetch {endpoint} for {repo} during initialization: "
+ f"{e.__class__.__name__}: {e}. Using current time."
+ )
+ timestamps[data_type] = current_time
+
+ # Save the timestamps
+ last_processed[repo] = timestamps
+ save_last_processed(last_processed)
+ logger.info(f"Initialized timestamps for repository {repo}")
+
+
+
+
async def process_issues_and_prs(
repo: str,
owner: str,