Name | nonebot-plugin-scheduled-broadcast JSON |
Version |
0.1.5
JSON |
| download |
home_page | |
Summary | A customizable, adapter-independent, event-based scheduled broadcaster aiming for all nonebot2 adapters. |
upload_time | 2023-11-10 15:14:19 |
maintainer | |
docs_url | None |
author | |
requires_python | >=3.8 |
license | MIT |
keywords |
nonebot2
scheduler
broadcast
|
VCS |
|
bugtrack_url |
|
requirements |
No requirements were recorded.
|
Travis-CI |
No Travis.
|
coveralls test coverage |
No coveralls.
|
# <div align="center"> Nonebot Plugin Scheduled Broadcast </div>
<p align="center">
<a href="https://pypi.python.org/pypi/nonebot-plugin-scheduled-broadcast">
<img src="https://img.shields.io/pypi/v/nonebot-plugin-scheduled-broadcast.svg?color=blue" alt="pypi">
</a>
<a href="https://codecov.io/gh/T0nyX1ang/nonebot-plugin-scheduled-broadcast" >
<img src="https://codecov.io/gh/T0nyX1ang/nonebot-plugin-scheduled-broadcast/graph/badge.svg?token=AUFO081ZBW"/>
</a>
<a href="./LICENSE">
<img src="https://img.shields.io/github/license/T0nyX1ang/nonebot-plugin-scheduled-broadcast.svg?color=blue" alt="license">
</a>
</p>
<div align="center"> ✨ 一款可配置的, 不依赖具体适配器的, 基于事件的定时广播插件. ✨ </div>
## 特性
* 基于一般事件 `nonebot.adapters.Event` 构造, 从而支持全部协议的信息发送.
* 定时广播由文件配置, 基于 `apscheduler` 提供类 `crontab` 的配置参数.
## 安装
### 使用 `nb-cli` 安装
* 在 `nonebot2` 项目的根目录下打开命令行, 输入以下指令即可安装:
```bash
nb-cli plugin install nonebot-plugin-scheduled-broadcast
```
### 使用包管理器安装
* 使用 `pdm` 安装:
```bash
pdm add nonebot-plugin-scheduled-broadcast
```
* 使用 `poetry` 安装:
```bash
poetry add nonebot-plugin-scheduled-broadcast
```
* 使用 `pip` 安装: ~~(虽然不太推荐但大概率没事)~~
```bash
pip install nonebot-plugin-scheduled-broadcast
```
## 使用
### 启动广播
* 保证发送消息的 `id` 位于 `SUPERUSER` 用户组中.
* 在需要启动广播的地方发送:
```txt
启动广播/enablebc [-bid 广播ID]
```
* `广播ID` 是可选项, 如果用户没有输入 `广播ID`, 则会使用对应事件的 `session_id` 去掉 `user_id` 的结果作为 `广播ID`, 如果此时 `广播ID` 为空, 则不支持自动生成 `广播ID`.
* 如果是第一次使用, 机器人在执行上述命令后, 在 `nonebot2` 项目的根目录下生成一个名为 `broadcast_policy.json` 的配置文件.
* 如果该机器人下已经存在相同的 `广播ID`, 配置文件将会保留, 同时广播作业将被 `恢复`, 如果不需要手动修改配置文件, 不需要重启.
### 待触发指令的编写
* 由于本插件提供了一个装饰器, 可以按照如下方式编写待触发指令:
```python
from nonebot import require
from nonebot.adapters import Event
from nonebot.log import logger
require("nonebot_plugin_scheduled_broadcast")
from nonebot_plugin_scheduled_broadcast import broadcast
@broadcast('example')
async def _(self_id: str, event: Event):
"""Scheduled example broadcast."""
message = generate_your_message()
try:
bot = nonebot.get_bots()[self_id] # select the target bot
await bot.send(event=event, message=message) # send message
except Exception:
logger.error(traceback.format_exc()) # print logs
```
* 触发指令编写完成以后, 启动机器人即可.
### 配置待触发指令的广播时间
* 保证发送消息的 `id` 位于 `SUPERUSER` 用户组中.
* 在需要启动广播的地方发送:
```txt
设置广播/setbc 待触发指令 [-bid 广播ID] [-s 秒] [-m 分] [-h 时] [-w 周数] [-d 星期几] [-D 日] [-M 月] [-Y 年]
```
* `广播ID` 是可选项, 如果用户没有输入 `广播ID`, 则会使用对应事件的 `session_id` 去掉 `user_id` 的结果作为 `广播ID`, 如果此时 `广播ID` 为空, 则不支持自动生成 `广播ID`.
* 配置项支持**不含空格的** `apscheduler` 语法, 当配置项留空时, 将会使得该指令不被触发.
### 关闭广播
* 保证发送消息的 `id` 位于 `SUPERUSER` 用户组中.
* 在需要关闭广播的地方发送:
```txt
关闭广播/disablebc [-bid 广播ID]
```
* `广播ID` 是可选项, 如果用户没有输入 `广播ID`, 则会使用对应事件的 `session_id` 去掉 `user_id` 的结果作为 `广播ID`, 如果此时 `广播ID` 为空, 则不支持自动生成 `广播ID`.
* 停止广播之后, 对应 `广播ID` 中的 `enable` 将被置为 `false`, 为保持可复用性, 其余部分将不会改变, 同时广播作业将被 `暂停`, 如果不需要修改 `config` 中的内容, 不需要重启.
## 配置
* `broadcast_policy_location`: 代表配置文件的存放位置, 默认值为 `./broadcast_policy.json`
## 注意事项
* 由于每一个 `Event` 几乎不会相同, 建议不要在同一个地方多次执行 `启动广播` 命令, 可能会刷屏的.
* 由于用到了 `pickle` 的序列化和反序列化功能, 而该功能具有潜在的安全风险, **请谨慎对待来源不明的配置文件**. 如果不确定配置文件的安全性, 建议重新启动广播以生成新的 `广播ID`, 然后替换配置文件中的 `config` 键里面的内容.
* 目前版本使用了 `nonebot.driver.Driver` 中的 `on_bot_connect` 和 `on_bot_disconnect` 钩子函数用于检测 `Bot` 的连接与断开, 但是适配器 `adapter-console` 中检测断开的时机过晚, 导致终端退出时 `scheduler` 仍然在后台运行, **不建议**在生产环境引入该适配器.
### 配置文件的手动填写
* 一般而言, 配置文件不需要手动修改, 但是本指南仍然会介绍配置文件的结构:
```json
{
"self_id": {
"broadcast_id": {
"config": {
"example": {"second": "*/30"}
},
"data": "event data (b64encode)",
"hash": "event hash (sha256)",
"enable": true
},
"another broadcast_id": {
// ...
}
},
"another self_id": {
// ...
}
}
```
* `config` 的可用配置与 `apscheduler` 一致, 以下给出一个示例, 该示例表示, `example` 命令会在每天 `10:24`, 每隔 `10` 秒被触发:
```json
{
"config": {
"example": {
"hour": 10,
"minute": 24,
"second": "*/10"
}
}
}
```
## 协议
* 本项目使用 [MIT](./LICENSE) 协议
Raw data
{
"_id": null,
"home_page": "",
"name": "nonebot-plugin-scheduled-broadcast",
"maintainer": "",
"docs_url": null,
"requires_python": ">=3.8",
"maintainer_email": "",
"keywords": "nonebot2 scheduler broadcast",
"author": "",
"author_email": "Tony Xiang <tonyxfy@qq.com>",
"download_url": "https://files.pythonhosted.org/packages/83/73/2978709899696c89ff4dbc3490afb70792c89ada8102db6c5b57b5a036b0/nonebot_plugin_scheduled_broadcast-0.1.5.tar.gz",
"platform": null,
"description": "# <div align=\"center\"> Nonebot Plugin Scheduled Broadcast </div>\n\n<p align=\"center\">\n <a href=\"https://pypi.python.org/pypi/nonebot-plugin-scheduled-broadcast\">\n <img src=\"https://img.shields.io/pypi/v/nonebot-plugin-scheduled-broadcast.svg?color=blue\" alt=\"pypi\">\n </a>\n <a href=\"https://codecov.io/gh/T0nyX1ang/nonebot-plugin-scheduled-broadcast\" >\n <img src=\"https://codecov.io/gh/T0nyX1ang/nonebot-plugin-scheduled-broadcast/graph/badge.svg?token=AUFO081ZBW\"/>\n </a>\n <a href=\"./LICENSE\">\n <img src=\"https://img.shields.io/github/license/T0nyX1ang/nonebot-plugin-scheduled-broadcast.svg?color=blue\" alt=\"license\">\n </a>\n</p>\n\n<div align=\"center\"> \u2728 \u4e00\u6b3e\u53ef\u914d\u7f6e\u7684, \u4e0d\u4f9d\u8d56\u5177\u4f53\u9002\u914d\u5668\u7684, \u57fa\u4e8e\u4e8b\u4ef6\u7684\u5b9a\u65f6\u5e7f\u64ad\u63d2\u4ef6. \u2728 </div>\n\n## \u7279\u6027\n\n* \u57fa\u4e8e\u4e00\u822c\u4e8b\u4ef6 `nonebot.adapters.Event` \u6784\u9020, \u4ece\u800c\u652f\u6301\u5168\u90e8\u534f\u8bae\u7684\u4fe1\u606f\u53d1\u9001.\n* \u5b9a\u65f6\u5e7f\u64ad\u7531\u6587\u4ef6\u914d\u7f6e, \u57fa\u4e8e `apscheduler` \u63d0\u4f9b\u7c7b `crontab` \u7684\u914d\u7f6e\u53c2\u6570.\n\n## \u5b89\u88c5\n\n### \u4f7f\u7528 `nb-cli` \u5b89\u88c5\n\n* \u5728 `nonebot2` \u9879\u76ee\u7684\u6839\u76ee\u5f55\u4e0b\u6253\u5f00\u547d\u4ee4\u884c, \u8f93\u5165\u4ee5\u4e0b\u6307\u4ee4\u5373\u53ef\u5b89\u88c5:\n\n```bash\n nb-cli plugin install nonebot-plugin-scheduled-broadcast\n```\n\n### \u4f7f\u7528\u5305\u7ba1\u7406\u5668\u5b89\u88c5\n\n* \u4f7f\u7528 `pdm` \u5b89\u88c5:\n\n```bash\n pdm add nonebot-plugin-scheduled-broadcast\n```\n\n* \u4f7f\u7528 `poetry` \u5b89\u88c5:\n\n```bash\n poetry add nonebot-plugin-scheduled-broadcast\n```\n\n* \u4f7f\u7528 `pip` \u5b89\u88c5: ~~(\u867d\u7136\u4e0d\u592a\u63a8\u8350\u4f46\u5927\u6982\u7387\u6ca1\u4e8b)~~\n\n```bash\n pip install nonebot-plugin-scheduled-broadcast\n```\n\n## \u4f7f\u7528\n\n### \u542f\u52a8\u5e7f\u64ad\n\n* \u4fdd\u8bc1\u53d1\u9001\u6d88\u606f\u7684 `id` \u4f4d\u4e8e `SUPERUSER` \u7528\u6237\u7ec4\u4e2d.\n* \u5728\u9700\u8981\u542f\u52a8\u5e7f\u64ad\u7684\u5730\u65b9\u53d1\u9001:\n\n```txt\n \u542f\u52a8\u5e7f\u64ad/enablebc [-bid \u5e7f\u64adID]\n```\n\n* `\u5e7f\u64adID` \u662f\u53ef\u9009\u9879, \u5982\u679c\u7528\u6237\u6ca1\u6709\u8f93\u5165 `\u5e7f\u64adID`, \u5219\u4f1a\u4f7f\u7528\u5bf9\u5e94\u4e8b\u4ef6\u7684 `session_id` \u53bb\u6389 `user_id` \u7684\u7ed3\u679c\u4f5c\u4e3a `\u5e7f\u64adID`, \u5982\u679c\u6b64\u65f6 `\u5e7f\u64adID` \u4e3a\u7a7a, \u5219\u4e0d\u652f\u6301\u81ea\u52a8\u751f\u6210 `\u5e7f\u64adID`.\n* \u5982\u679c\u662f\u7b2c\u4e00\u6b21\u4f7f\u7528, \u673a\u5668\u4eba\u5728\u6267\u884c\u4e0a\u8ff0\u547d\u4ee4\u540e, \u5728 `nonebot2` \u9879\u76ee\u7684\u6839\u76ee\u5f55\u4e0b\u751f\u6210\u4e00\u4e2a\u540d\u4e3a `broadcast_policy.json` \u7684\u914d\u7f6e\u6587\u4ef6.\n* \u5982\u679c\u8be5\u673a\u5668\u4eba\u4e0b\u5df2\u7ecf\u5b58\u5728\u76f8\u540c\u7684 `\u5e7f\u64adID`, \u914d\u7f6e\u6587\u4ef6\u5c06\u4f1a\u4fdd\u7559, \u540c\u65f6\u5e7f\u64ad\u4f5c\u4e1a\u5c06\u88ab `\u6062\u590d`, \u5982\u679c\u4e0d\u9700\u8981\u624b\u52a8\u4fee\u6539\u914d\u7f6e\u6587\u4ef6, \u4e0d\u9700\u8981\u91cd\u542f.\n\n### \u5f85\u89e6\u53d1\u6307\u4ee4\u7684\u7f16\u5199\n\n* \u7531\u4e8e\u672c\u63d2\u4ef6\u63d0\u4f9b\u4e86\u4e00\u4e2a\u88c5\u9970\u5668, \u53ef\u4ee5\u6309\u7167\u5982\u4e0b\u65b9\u5f0f\u7f16\u5199\u5f85\u89e6\u53d1\u6307\u4ee4:\n\n```python\nfrom nonebot import require\nfrom nonebot.adapters import Event\nfrom nonebot.log import logger\n\nrequire(\"nonebot_plugin_scheduled_broadcast\")\n\nfrom nonebot_plugin_scheduled_broadcast import broadcast\n\n@broadcast('example')\nasync def _(self_id: str, event: Event):\n \"\"\"Scheduled example broadcast.\"\"\"\n message = generate_your_message()\n try:\n bot = nonebot.get_bots()[self_id] # select the target bot\n await bot.send(event=event, message=message) # send message\n except Exception:\n logger.error(traceback.format_exc()) # print logs\n```\n\n* \u89e6\u53d1\u6307\u4ee4\u7f16\u5199\u5b8c\u6210\u4ee5\u540e, \u542f\u52a8\u673a\u5668\u4eba\u5373\u53ef.\n\n### \u914d\u7f6e\u5f85\u89e6\u53d1\u6307\u4ee4\u7684\u5e7f\u64ad\u65f6\u95f4\n\n* \u4fdd\u8bc1\u53d1\u9001\u6d88\u606f\u7684 `id` \u4f4d\u4e8e `SUPERUSER` \u7528\u6237\u7ec4\u4e2d.\n* \u5728\u9700\u8981\u542f\u52a8\u5e7f\u64ad\u7684\u5730\u65b9\u53d1\u9001:\n\n```txt\n \u8bbe\u7f6e\u5e7f\u64ad/setbc \u5f85\u89e6\u53d1\u6307\u4ee4 [-bid \u5e7f\u64adID] [-s \u79d2] [-m \u5206] [-h \u65f6] [-w \u5468\u6570] [-d \u661f\u671f\u51e0] [-D \u65e5] [-M \u6708] [-Y \u5e74]\n```\n\n* `\u5e7f\u64adID` \u662f\u53ef\u9009\u9879, \u5982\u679c\u7528\u6237\u6ca1\u6709\u8f93\u5165 `\u5e7f\u64adID`, \u5219\u4f1a\u4f7f\u7528\u5bf9\u5e94\u4e8b\u4ef6\u7684 `session_id` \u53bb\u6389 `user_id` \u7684\u7ed3\u679c\u4f5c\u4e3a `\u5e7f\u64adID`, \u5982\u679c\u6b64\u65f6 `\u5e7f\u64adID` \u4e3a\u7a7a, \u5219\u4e0d\u652f\u6301\u81ea\u52a8\u751f\u6210 `\u5e7f\u64adID`.\n* \u914d\u7f6e\u9879\u652f\u6301**\u4e0d\u542b\u7a7a\u683c\u7684** `apscheduler` \u8bed\u6cd5, \u5f53\u914d\u7f6e\u9879\u7559\u7a7a\u65f6, \u5c06\u4f1a\u4f7f\u5f97\u8be5\u6307\u4ee4\u4e0d\u88ab\u89e6\u53d1.\n\n### \u5173\u95ed\u5e7f\u64ad\n\n* \u4fdd\u8bc1\u53d1\u9001\u6d88\u606f\u7684 `id` \u4f4d\u4e8e `SUPERUSER` \u7528\u6237\u7ec4\u4e2d.\n* \u5728\u9700\u8981\u5173\u95ed\u5e7f\u64ad\u7684\u5730\u65b9\u53d1\u9001:\n\n```txt\n \u5173\u95ed\u5e7f\u64ad/disablebc [-bid \u5e7f\u64adID]\n```\n\n* `\u5e7f\u64adID` \u662f\u53ef\u9009\u9879, \u5982\u679c\u7528\u6237\u6ca1\u6709\u8f93\u5165 `\u5e7f\u64adID`, \u5219\u4f1a\u4f7f\u7528\u5bf9\u5e94\u4e8b\u4ef6\u7684 `session_id` \u53bb\u6389 `user_id` \u7684\u7ed3\u679c\u4f5c\u4e3a `\u5e7f\u64adID`, \u5982\u679c\u6b64\u65f6 `\u5e7f\u64adID` \u4e3a\u7a7a, \u5219\u4e0d\u652f\u6301\u81ea\u52a8\u751f\u6210 `\u5e7f\u64adID`.\n* \u505c\u6b62\u5e7f\u64ad\u4e4b\u540e, \u5bf9\u5e94 `\u5e7f\u64adID` \u4e2d\u7684 `enable` \u5c06\u88ab\u7f6e\u4e3a `false`, \u4e3a\u4fdd\u6301\u53ef\u590d\u7528\u6027, \u5176\u4f59\u90e8\u5206\u5c06\u4e0d\u4f1a\u6539\u53d8, \u540c\u65f6\u5e7f\u64ad\u4f5c\u4e1a\u5c06\u88ab `\u6682\u505c`, \u5982\u679c\u4e0d\u9700\u8981\u4fee\u6539 `config` \u4e2d\u7684\u5185\u5bb9, \u4e0d\u9700\u8981\u91cd\u542f.\n\n## \u914d\u7f6e\n\n* `broadcast_policy_location`: \u4ee3\u8868\u914d\u7f6e\u6587\u4ef6\u7684\u5b58\u653e\u4f4d\u7f6e, \u9ed8\u8ba4\u503c\u4e3a `./broadcast_policy.json`\n\n## \u6ce8\u610f\u4e8b\u9879\n\n* \u7531\u4e8e\u6bcf\u4e00\u4e2a `Event` \u51e0\u4e4e\u4e0d\u4f1a\u76f8\u540c, \u5efa\u8bae\u4e0d\u8981\u5728\u540c\u4e00\u4e2a\u5730\u65b9\u591a\u6b21\u6267\u884c `\u542f\u52a8\u5e7f\u64ad` \u547d\u4ee4, \u53ef\u80fd\u4f1a\u5237\u5c4f\u7684.\n* \u7531\u4e8e\u7528\u5230\u4e86 `pickle` \u7684\u5e8f\u5217\u5316\u548c\u53cd\u5e8f\u5217\u5316\u529f\u80fd, \u800c\u8be5\u529f\u80fd\u5177\u6709\u6f5c\u5728\u7684\u5b89\u5168\u98ce\u9669, **\u8bf7\u8c28\u614e\u5bf9\u5f85\u6765\u6e90\u4e0d\u660e\u7684\u914d\u7f6e\u6587\u4ef6**. \u5982\u679c\u4e0d\u786e\u5b9a\u914d\u7f6e\u6587\u4ef6\u7684\u5b89\u5168\u6027, \u5efa\u8bae\u91cd\u65b0\u542f\u52a8\u5e7f\u64ad\u4ee5\u751f\u6210\u65b0\u7684 `\u5e7f\u64adID`, \u7136\u540e\u66ff\u6362\u914d\u7f6e\u6587\u4ef6\u4e2d\u7684 `config` \u952e\u91cc\u9762\u7684\u5185\u5bb9.\n* \u76ee\u524d\u7248\u672c\u4f7f\u7528\u4e86 `nonebot.driver.Driver` \u4e2d\u7684 `on_bot_connect` \u548c `on_bot_disconnect` \u94a9\u5b50\u51fd\u6570\u7528\u4e8e\u68c0\u6d4b `Bot` \u7684\u8fde\u63a5\u4e0e\u65ad\u5f00, \u4f46\u662f\u9002\u914d\u5668 `adapter-console` \u4e2d\u68c0\u6d4b\u65ad\u5f00\u7684\u65f6\u673a\u8fc7\u665a, \u5bfc\u81f4\u7ec8\u7aef\u9000\u51fa\u65f6 `scheduler` \u4ecd\u7136\u5728\u540e\u53f0\u8fd0\u884c, **\u4e0d\u5efa\u8bae**\u5728\u751f\u4ea7\u73af\u5883\u5f15\u5165\u8be5\u9002\u914d\u5668.\n\n### \u914d\u7f6e\u6587\u4ef6\u7684\u624b\u52a8\u586b\u5199\n\n* \u4e00\u822c\u800c\u8a00, \u914d\u7f6e\u6587\u4ef6\u4e0d\u9700\u8981\u624b\u52a8\u4fee\u6539, \u4f46\u662f\u672c\u6307\u5357\u4ecd\u7136\u4f1a\u4ecb\u7ecd\u914d\u7f6e\u6587\u4ef6\u7684\u7ed3\u6784:\n\n```json\n{\n \"self_id\": {\n \"broadcast_id\": {\n \"config\": {\n \"example\": {\"second\": \"*/30\"}\n },\n \"data\": \"event data (b64encode)\",\n \"hash\": \"event hash (sha256)\",\n \"enable\": true\n },\n \"another broadcast_id\": {\n // ...\n }\n },\n \"another self_id\": {\n // ...\n }\n}\n```\n\n* `config` \u7684\u53ef\u7528\u914d\u7f6e\u4e0e `apscheduler` \u4e00\u81f4, \u4ee5\u4e0b\u7ed9\u51fa\u4e00\u4e2a\u793a\u4f8b, \u8be5\u793a\u4f8b\u8868\u793a, `example` \u547d\u4ee4\u4f1a\u5728\u6bcf\u5929 `10:24`, \u6bcf\u9694 `10` \u79d2\u88ab\u89e6\u53d1:\n\n```json\n{\n \"config\": {\n \"example\": {\n \"hour\": 10,\n \"minute\": 24,\n \"second\": \"*/10\"\n }\n }\n}\n```\n\n## \u534f\u8bae\n\n* \u672c\u9879\u76ee\u4f7f\u7528 [MIT](./LICENSE) \u534f\u8bae\n",
"bugtrack_url": null,
"license": "MIT",
"summary": "A customizable, adapter-independent, event-based scheduled broadcaster aiming for all nonebot2 adapters.",
"version": "0.1.5",
"project_urls": null,
"split_keywords": [
"nonebot2",
"scheduler",
"broadcast"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "d8fe6abfa6a3c529ee4ac11997eb0015f4621a5d99743df575a930171a7be304",
"md5": "0dc34ec1d4f591640d8c39c583e5a6c8",
"sha256": "6c49a9f049d5b444fdd17aa8ad0bca41b59b382b5e850cf9c62060fe4c8d80c7"
},
"downloads": -1,
"filename": "nonebot_plugin_scheduled_broadcast-0.1.5-py3-none-any.whl",
"has_sig": false,
"md5_digest": "0dc34ec1d4f591640d8c39c583e5a6c8",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.8",
"size": 9348,
"upload_time": "2023-11-10T15:14:18",
"upload_time_iso_8601": "2023-11-10T15:14:18.797261Z",
"url": "https://files.pythonhosted.org/packages/d8/fe/6abfa6a3c529ee4ac11997eb0015f4621a5d99743df575a930171a7be304/nonebot_plugin_scheduled_broadcast-0.1.5-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "83732978709899696c89ff4dbc3490afb70792c89ada8102db6c5b57b5a036b0",
"md5": "5081d8b5140e82632f37dbf53f6824b8",
"sha256": "f552156402501670776969f5cb4a85830c2adf6290f4afd19e9ee02e0df7b8d0"
},
"downloads": -1,
"filename": "nonebot_plugin_scheduled_broadcast-0.1.5.tar.gz",
"has_sig": false,
"md5_digest": "5081d8b5140e82632f37dbf53f6824b8",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.8",
"size": 12178,
"upload_time": "2023-11-10T15:14:19",
"upload_time_iso_8601": "2023-11-10T15:14:19.826555Z",
"url": "https://files.pythonhosted.org/packages/83/73/2978709899696c89ff4dbc3490afb70792c89ada8102db6c5b57b5a036b0/nonebot_plugin_scheduled_broadcast-0.1.5.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2023-11-10 15:14:19",
"github": false,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"lcname": "nonebot-plugin-scheduled-broadcast"
}