{"id":50416521,"url":"https://github.com/musnows/kook-ticket-bot","last_synced_at":"2026-05-31T06:03:48.333Z","repository":{"id":47871141,"uuid":"515975385","full_name":"musnows/Kook-Ticket-Bot","owner":"musnows","description":"A Ticket Bot for KOOK (khl.py) 表单机器人，不会写代码也能自主化部署","archived":false,"fork":false,"pushed_at":"2025-03-25T00:16:04.000Z","size":916,"stargazers_count":29,"open_issues_count":0,"forks_count":8,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-03-25T01:23:49.229Z","etag":null,"topics":["api","bot","khl","kook","python"],"latest_commit_sha":null,"homepage":"https://kook.top/gpbTwZ","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mpl-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/musnows.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-07-20T12:36:02.000Z","updated_at":"2025-03-25T00:16:08.000Z","dependencies_parsed_at":"2024-06-27T17:15:13.269Z","dependency_job_id":"8d0bb4f9-910a-4bdd-aabd-066269a9a004","html_url":"https://github.com/musnows/Kook-Ticket-Bot","commit_stats":null,"previous_names":[],"tags_count":8,"template":false,"template_full_name":null,"purl":"pkg:github/musnows/Kook-Ticket-Bot","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/musnows%2FKook-Ticket-Bot","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/musnows%2FKook-Ticket-Bot/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/musnows%2FKook-Ticket-Bot/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/musnows%2FKook-Ticket-Bot/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/musnows","download_url":"https://codeload.github.com/musnows/Kook-Ticket-Bot/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/musnows%2FKook-Ticket-Bot/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33720900,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-05-31T02:00:06.040Z","response_time":95,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["api","bot","khl","kook","python"],"created_at":"2026-05-31T06:03:47.561Z","updated_at":"2026-05-31T06:03:48.326Z","avatar_url":"https://github.com/musnows.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Kook-Ticket-Bot\n\n## 1.说明\n\n![commit](https://img.shields.io/github/last-commit/musnows/Kook-Ticket-Bot) ![release](https://img.shields.io/github/v/release/musnows/Kook-Ticket-Bot) [![khl server](https://www.kaiheila.cn/api/v3/badge/guild?guild_id=3986996654014459\u0026style=0)](https://kook.top/gpbTwZ)\n\nA ticket bot for KOOK, **自托管**表单/工单系统机器人\n\n工作流程\n* 当用户B点击卡片消息的按钮后，创建一个只有用户B可见的文字频道\n* Bot会自动在该临时频道发送一条消息，并`@用户B` 和处理表单的 `@管理员`\n* 当处理完毕后，点击`关闭`按钮，Bot会删除该文字频道\n* 文字频道删除后，Bot会给预先`设置好的log频道`和`开启ticket的用户`发送一条记录信息，并在服务器后端保存该ticket的聊天记录；\n* 管理员可以使用`/tkcm`命令，指定ticket编号对该工单发表评论\n\n附加功能\n* 通过表情回应给用户添加对应角色\n* 设置Bot动态 `游戏/音乐`\n\n本README尽量详细，争取让没有写过python代码，但了解基本编程环境搭建的用户能配置成功并正常使用bot！\n\n\u003e 无须服务器和环境搭建，在replit上部署本bot！[WIKI教程](https://github.com/musnows/Kook-Ticket-Bot/wiki)。由于replit策略变动，此教程内容已失效。\n\n如果您对本README还有完善的建议，十分欢迎您[加入KOOK帮助频道](https://kook.top/gpbTwZ)与我联系，亦或者在仓库提出issue。\n\n## 2.帮助命令\n\nBot的帮助命令为 `/tkhelp`。\n\n![helpCmd](./screenshots/help_cmd.png)\n\n主要配置项均在配置文件中，后文有提及。\n\n## 3.安装和运行\n\n### 3.1 Python 运行\n\n使用本机器人之前，请先确认您的python版本高于`3.9`, 安装以下依赖项\n\n```\npip3 install -r requirements.txt\n```\n\n完成下方的配置后，就可以运行bot了。\n\n```\npython3 main.py\n```\n\n如果是linux系统需要bot后台运行，使用如下命令\n\n```\nnohup python3 -u main.py \u003e\u003e ./log/bot.log 2\u003e\u00261 \u0026\n```\n\n### 3.2 Docker 运行\n\n提供了一个docker容器供不太熟悉Linux命令行的用户使用，镜像名字为`musnows/kook-ticket-bot`。\n\n```\ndocker pull musnows/kook-ticket-bot:latest\n```\n\n在使用镜像创建容器之前，您需要参考后文的教程，在本地准备一个存放配置文件的目录（包括`config.json`和`TicketConf.json`，并将该目录映射到容器内的`/app/config`中。\n\n示例运行命令如下\n\n```bash\ndocker run -it -d \\\n  -v 本地配置文件路径:/app/config \\\n  --name=kook-ticket-bot \\\n  musnows/kook-ticket-bot:latest\n```\n\n如果您需要使用Webhook的方式对接机器人到kook，则还需要暴露容器内的40000端口。另外，您还需要开启宿主机服务器上该端口的防火墙，以保证外网可以正常连接这个端口。\n\n```bash\ndocker run -it -d \\\n  -v 本地配置文件路径:/app/config \\\n  -p 40000:40000 \\\n  --name=kook-ticket-bot \\\n  musnows/kook-ticket-bot:latest\n```\n\n如果您在创建docker容器后容器无法运行，且`docker logs 容器ID`的报错如下所示，这代表容器内的python没有办法通过DNS获取到kook服务器的IP地址。\n\n```\naiohttp.client_exceptions.ClientConnectorError: Cannot connect to host www.kookapp.cn:443 ssl:default [Name or service not known]\nCRITICAL:main.py:loading_channel:763 | [BOT.START] 获取频道失败，请检查TicketConf文件中的debug_channel和log_channel\n```\n\n一般这种情况都是DNS的配置问题，可以在run的时候加上如下命令设置DNS为字节跳动的公共DNS服务器。\n\n```\ndocker run -it -d \\\n  -v 本地配置文件路径:/app/config \\\n  -p 40000:40000 \\\n  --dns 180.184.1.1 \\\n  --name=kook-ticket-bot \\\n  musnows/kook-ticket-bot:latest\n```\n\n使用run启动容器后，请使用`docker ps`检查机器人的容器是否正常运行，并使用如下命令查看日志，判断机器人是否正常启动。如果机器人的容器没有终止，且日志没有报错，那就可以去kook频道中尝试使用`/tkhelp`帮助命令呼出机器人了。\n\n```\ndocker logs kook-ticket-bot\n```\n\n日志中出现如下两行，即为机器人正常启动。其中`fetch_public_channel success`为机器人启动成功标志。\n\n```\n[24-07-20 19:28:16] INFO:main.py:\u003cmodule\u003e:771 | [BOT] Start at 24-07-20 19:28:16\n[24-07-20 19:28:16] INFO:main.py:loading_channel:758 | [BOT.START] fetch_public_channel success\n```\n\n## 4.Config 配置项（必看）\n\n因为bot开机的时候就会打开下面的文件，若缺少字段，会影响bot的正常运行；\n\n目前在 [utils/file.py](./utils/file.py) 的底部打开了所有的**配置文件**，并添加了 `create_log_file()` 函数来自动创建不存在的数据文件。\n\n以下README中对配置文件的示例仅供参考，若运行后出现了自动创建文件失败的报错，请采用REAMDE中的描述手动创建配置文件！\n\n### 4.1 机器人 token 配置\n\n在 `./config` 路径中添加`config.json`，并在里面填入[config-exp.json](./config/config-exp.json)的内容来初始化你的Bot。这些信息请在kook的[开发者后台-应用](https://developer.kookapp.cn/app/index)中获取。\n\n```json\n{\n    \"token\":\"bot webhook token\",\n    \"verify_token\":\"bot webhook verify token\",\n    \"encrypt\":\"bot webhook encrypt token\",\n    \"ws\": true\n}\n```\n\n使用webhook方式会开启一个回调地址，该操作需要有`公网ip`的机器才能进行\n\n* 如果你的机器人部署在无法外网访问（无公网ip）的机器上，请采用websocket链接方式；\n* 如果你的机器人在云服务器上部署，可以采用webhook或websocket方式；\n\n配置文件`config.json`中的`\"ws\"`字段为websocket/webhook的选项，如果使用webhook，请将该配置项改为 `false`。\n\n* 修改本地配置后，记得在**kook机器人管理后台**修改机器人的链接配置；\n* webhook需要正确填写`\"verify_token\"`和`\"encrypt\"`配置项\n\n如果采用webhook的连接方式，需要在kook机器人后台填写回调地址（Callback Url）\n\n```bash\n# 默认情况下（记得开放服务器对应端口的防火墙）\n# 在main.py的开头，有机器人的初始化，内部有个port参数为端口\nhttp://公网ip:40000/khl-wh \n```\n\n填写 `Callback Url` 之后，点击`重试`按钮，测试webhook是否正常。如果右下角显示`配置成功`，且没有红色字体的报错，那就是ok了！\n\n如果多次点击重试后，依旧失败，请先尝试将url粘贴至浏览器，是否能正常访问。\n\n```\n如果浏览器显示\n405 method not allowed\n那么代表你的url是没有问题的，可以正常在外网访问\n```\n\n如果浏览器显示正常，但kook配置还是不行，请[加入KOOK帮助频道](https://kook.top/gpbTwZ)咨询！\n\n### 4.2 TicketConfig 工单配置\n\n在 `./config` 路径中新增`TicketConf.json`，并填入 [TicketConf-exp](./config/TicketConf-exp.json) 中的内容（也可以直接拷贝一份exp文件并重命名\n\n请注意，配置文件里面的键值都不能修改！\n\n\u003e 各类id获取办法：`kook设置-高级设置-打开开发者模式`；右键服务器头像，复制服务器id；右键用户头像即可复制用户id，右键频道/分组即可复制频道/分组id。\n\u003e \n\u003e ![kook开启开发者模式](./screenshots/kook_develop.png)\n\nticket机器人需要您创建一个**对全体成员不可见**的隐藏分组，设置该分组权限为`@全体成员-\u003e分组不可见`来隐藏；并给管理员角色设置权限，让管理员能看到这个分组。\n\n![设置隐藏分组](./screenshots/hide_chc.png)\n\n`admin_role`中的管理员角色，即为机器人发送的ticket消息中会`@`的角色组；且只有拥有管理员身份组的用户，才能`关闭ticket/给ticket写评论`。\n\n\u003cimg src=\"./screenshots/tk2.png\" wight=\"350px\" height=\"220px\" alt=\"bot发送附带关闭按钮的卡片\"\u003e\n\n`\"channel_id\"` 字段机器人自己会填写，不需要自己填\n\n#### 关于命令权限问题\n\n只有拥有`admin_role`中角色的用户才能操作bot的管理命令。\n\n举例：服务器有个`摸鱼`角色，如果你想让**张三**可以操作bot的管理命令，那就需要给**张三**添加上`摸鱼`角色，并进入服务器的设置-角色管理-右键`摸鱼`角色，复制角色id，并把这个id添加到`\"admin_role\"`中。\n\n\u003cimg src=\"./screenshots/role_id.png\" wight=\"300px\" height=\"200px\" alt=\"角色id获取\"\u003e\n\n假设`摸鱼`的角色id为114514，那么添加了之后的 `TicketConf.json` 配置文件应该如下\n\n```json\n{\n  \"guild_id\":\"ticket bot 所服务的服务器id\",\n  \"ticket\": {\n    \"admin_role\": [\n      \"114514\"\n    ],\n    \"category_id\": \"隐藏掉的频道分组id\",\n    \"channel_id\": {},\n    \"log_channel\": \"用于发送ticket日志的文字频道id\",\n    \"debug_channel\": \"用于发送bot出错信息的文字频道id\"\n  }\n}\n```\n\n这样才能让拥有`摸鱼`角色的用户**张三**操作`/ticket`命令。\n\n\n#### 单频道管理员（管理员分工）\n\n\u003e 注意：使用 `/aar` 命令设置的单频道管理员无法执行ticket命令\n\n目前机器人新增了单频道管理员配置，源于不同频道的ticket按钮，可以通知不同的管理员用户\n\n* 频道A和B都有ticket按钮\n* 在频道A执行 `/aar @角色甲` 的命令，会将角色甲添加入频道A ticket的管理员中\n* 此时用户点击频道A的ticket按钮，机器人会 @全局管理员 (配置文件`TicketConf[\"ticket\"][\"admin_role\"]`中的管理员) 和 @角色甲\n* 点击B的ticket按钮，只会 @全局管理员\n* 如果想添加**全局管理员**，命令为 `/aar @角色乙 -g`\n\n如果不想要全局管理员，配置文件中`\"admin_role\"`可以留空。此时只有 `master_id` 用户可以执行机器人管理命令，添加单频道管理员。\n\n#### 工单超时\n\n`TicketConf`中的如下字段是工单超时时间，当一个工单频道超过配置的时间（单位：小时）没有发送过消息，就会将该工单频道**锁定**（用户无法发送消息，但依旧看得到工单频道。管理员不受影响）\n\n~~~\n\"outdate\":48\n~~~\n\n目前实现了手动锁定工单，和重新激活工单的功能。\n\n### 4.3 TicketLog\n\n\u003e 新版本Log文件机器人会自动创建，以下的配置项只为留档参考，理论上无须手动创建文件。\n\n在 `code/log` 路径中新增 `TicketLog.json`，并填入以下字段\n\n```json\n{\n    \"TKnum\": 0,\n    \"data\": {},\n    \"msg_pair\": {},\n    \"TKchannel\": {},\n    \"user_pair\":{}\n}\n```\n\n* TKnum是ticket的编号计数，最高为8位数字，应该完全够用了\n* TKchannel是用于记录bot创建的ticket频道id，和ticket编号对应\n* msg_pair是一个键值对，用于记录bot在ticket频道发送的消息（关闭按钮），和ticket编号对应\n* data中是每一个编号的ticket的详细信息，包括开启时间、开启用户、关闭时间、关闭用户、管理员的评论等\n\n### 4.4 TicketMsgLog\n\n在 `code/log` 路径中新增 `TicketMsgLog.json`，并填入以下字段\n\n```json\n{\n  \"TKMsgChannel\": {},\n  \"data\": {}\n}\n```\n* TKMsgChannel是用于记录bot创建的ticket频道id，和ticket编号对应，用来判断ticket频道是否有过消息（避免出现没有发过消息就关闭ticket频道的情况）\n* data为消息记录，作为ticket频道的消息记录\n\n为了保存聊天记录，还需要创建 `code/log/ticket` 文件夹（机器人会自动创建）\n\nbot会在ticket关闭后，按照编号，保存 `code/log/ticket/编号.json` 文件，并删除 `TicketMsgLog.json` 中 `data` 字段里面的内容。\n\n----\n\n#### 下面是ticket功能的示例图\n\n用户先点击按钮，机器人会创建一个临时频道\n\n\u003cimg src=\"./screenshots/tk1.png\" wight=\"300px\" height=\"130px\" alt=\"ticket发起\"\u003e\n\n并在该频道内部发送一条消息，并at用户和管理员，附带一个只有管理员才能关闭的按钮\n\n\u003cimg src=\"./screenshots/tk2.png\" wight=\"350px\" height=\"220px\" alt=\"bot发送附带关闭按钮的卡片\"\u003e\n\nticket被关闭后，bot会向`TicketConf.json`中设置的log频道发送一张卡片\n\n\u003cimg src=\"./screenshots/tk3.png\" wight=\"350px\" height=\"220px\" alt=\"bot发送log卡片\"\u003e\n\n管理员用户可以使用`/tkcm`命令，给某个ticket添加备注信息，卡片消息会同步更新\n\n```\n/tkcm TICKET编号 备注内容\n示例\n/tkcm 00000000 这是一个测试\n```\n\n\u003cimg src=\"./screenshots/tk4.png\" wight=\"350px\" height=\"220px\" alt=\"tkcm\"\u003e\n\n----\n\n### 4.5 emoji/role 上角色功能\n\n这个功能的作用是根据一条消息的表情回应，给用户上对应的角色。类似于YY里的上马甲。\n\n\u003e 如果你不需要这个功能，请将`TicketConf.json`中的`\"emoji\"`字段删除，这样可以节省机器人的性能\n\n请确认您的bot角色拥有管理员权限，并处于其需要给予的角色之上。如图，TestBot只能给其他用户上在他下面的角色，否则Api会报错 `无权限`\n\n\u003cimg src=\"./screenshots/emoji_role_rules.png\" alt=\"emoji_role_rules\"\u003e\n\n要想使用本功能，请创建 `code/log/ColorID.json`文件，复制如下内容到其中（新版本后，机器人会自动创建此文件）\n\n```json\n{\n    \"data\":{}   \n}\n```\n\n并在 `code/TicketConf.json` 里面追加如下字段\n\n```json\n  \"emoji\": {\n    \"消息id\": {\n      \"channel_id\": \"该消息的频道id\",\n      \"data\": {},\n      \"msg_id\": \"消息id\"\n    }\n  }\n```\n\n随后要做的是，在`data`里面添加emoji和角色id的对照表\n\n\u003e 角色ID获取：设置内开启开发者模式后，进入服务器后台，右键角色复制id；\n\u003e\n\u003e 表情ID获取：\n\u003e * 在客户端内，选中表情后`ctrl+c`，即可复制出表情id\n\u003e * 在bot的代码中，打印[add_reaction的event消息](https://github.com/musnows/Kook-Ticket-Bot/blob/296f3bf477b8d5530934464fc7f8489d18c65379/code/main.py#L447-L452)获取表情id\n\n\u003cimg src=\"./screenshots/emoji_id.png\" wight=\"250px\" height=\"160px\" alt=\"复制表情id\"\u003e\n\n配置示例如下，左侧为表情，右侧为这个表情对应的角色id\n\n```json\n  \"emoji\": {\n    \"消息id\": {\n      \"data\": {\n        \"❤\": \"对应的角色id-1\",\n        \"🐷\": \"对应的角色id-2\",\n        \"💙\": \"对应的角色id-3\",\n        \"👍\": \"0（对应的是全体成员的角色）\",\n      },\n      \"msg_id\": \"消息id\"\n    }\n  }\n```\n\n如果你有多个消息（比如不同的角色逻辑），那就在后续追加字段\n\n```json\n  \"emoji\": {\n    \"消息id A\": {\n      \"data\": {\n        \"❤\": \"对应的角色id-1\",\n        \"🐷\": \"对应的角色id-2\",\n        \"💙\": \"对应的角色id-3\",\n        \"👍\": \"0（对应的是全体成员的角色）\",\n      },\n      \"msg_id\": \"消息id A\"\n    },\n    \"消息id B\": {\n      \"data\": {},\n      \"msg_id\": \"消息id B\"\n    }\n  }\n```\n\n如下，您需要自行编写一个对应的角色关系消息，然后右键复制该消息的消息id。\n卡片消息可以用官方的 [卡片编辑器](https://www.kookapp.cn/tools/message-builder.html#/card) 编辑后发送\n\n\u003cimg src=\"./screenshots/role2.png\" wight=\"250px\" height=\"160px\" alt=\"上角色的消息\"\u003e\n\n配置后，bot会根据配置文件中的`emoji:角色`对照表，给用户上对应的角色\n\n\u003cimg src=\"./screenshots/role1.png\" wight=\"350px\" height=\"210px\" alt=\"bot上角色\"\u003e\n\n### 4.6 gaming/singing 机器人在玩状态\n\n这两个命令都是用于控制机器人在玩状态的。其中机器人的游戏状态已经写死了几个游戏。\n\n使用如下代码，你可以创建一个你自己想要的游戏\n\n```python\nimport requests\n\nurl = \"https://www.kookapp.cn/api/v3/game/create\"\nbotoken = \"机器人 websocket token\"\nheader={f'Authorization': f\"Bot {botoken}\"}\nparams ={\n    \"name\":\"游戏名\",\n    \"icon\":\"游戏图标的url (可以将图片上传到kook后，点开大图，在右下角...处复制url)\"\n}\nret = requests.post(url,headers=header,data=params)\nprint(ret)\nprint(ret.text) # 返回值中有游戏的id\n```\n\n在最后的输出结果中，会包含游戏的id。关于此api字段的解释见[官方文档](https://developer.kookapp.cn/doc/http/game#%E6%B7%BB%E5%8A%A0%E6%B8%B8%E6%88%8F)\n\n假设新增的游戏id为`12345`，那么就需要在`gaming`所在函数中，添加如下代码\n\n~~~python\n  if game == 10: # 自己设定一个执行命令时需要的编号\n      ret = await status_active_game(12345) # xxx游戏的id\n      await msg.reply(f\"{ret['message']}，Bot上号xxx游戏啦！\")\n~~~\n\nkook的在玩状态同步及其缓慢，请耐心等待。\n\n## The end\n\n有任何问题，请添加`issue`，或加入我的交流服务器与我联系 [kook邀请链接](https://kook.top/gpbTwZ)\n\n如果你觉得本项目还不错，还请高抬贵手点个star✨，万般感谢！\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmusnows%2Fkook-ticket-bot","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmusnows%2Fkook-ticket-bot","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmusnows%2Fkook-ticket-bot/lists"}