├── .cargo
└── config.toml
├── .gitattributes
├── .github
└── workflows
│ └── build.yml
├── .gitignore
├── Cargo.toml
├── Dockerfile
├── LICENSE
├── build.rs
├── buildrc
└── redreply.rc
├── docs
├── .nojekyll
├── README.md
├── _coverpage.md
├── _navbar.md
├── _sidebar.md
├── adaptar
│ └── README.md
├── detailref
│ └── README.md
├── docsify
│ ├── docsify-copy-code.min.js
│ ├── docsify.min.js
│ ├── emoji.min.js
│ ├── search.min.js
│ └── vue.min.css
├── download
│ └── README.md
├── example
│ ├── README.md
│ ├── image-1.png
│ ├── image-2.png
│ └── image.png
├── favicon.png
├── idea
│ └── README.md
├── index.html
├── mqtt
│ ├── README.md
│ └── image.png
├── onebot
│ └── README.md
└── softarch.png
├── readme.md
├── res
├── axios.js
├── crontool.html
├── debug.html
├── favicon.ico
├── gobal_filter.html
├── index.html
├── index_old.html
├── live2d
│ ├── l2d.js
│ ├── models
│ │ └── pio
│ │ │ ├── model.moc
│ │ │ ├── model1.json
│ │ │ ├── model2.json
│ │ │ ├── model3.json
│ │ │ ├── motions
│ │ │ ├── Breath%20Dere1.mtn
│ │ │ ├── Breath%20Dere2.mtn
│ │ │ ├── Breath%20Dere3.mtn
│ │ │ ├── Breath1.mtn
│ │ │ ├── Breath2.mtn
│ │ │ ├── Breath3.mtn
│ │ │ ├── Breath4.mtn
│ │ │ ├── Breath5.mtn
│ │ │ ├── Breath6.mtn
│ │ │ ├── Breath7.mtn
│ │ │ ├── Breath8.mtn
│ │ │ ├── Fail.mtn
│ │ │ ├── Sleeping.mtn
│ │ │ ├── Success.mtn
│ │ │ ├── Sukebei1.mtn
│ │ │ ├── Sukebei2.mtn
│ │ │ ├── Sukebei3.mtn
│ │ │ ├── Touch%20Dere1.mtn
│ │ │ ├── Touch%20Dere2.mtn
│ │ │ ├── Touch%20Dere3.mtn
│ │ │ ├── Touch%20Dere4.mtn
│ │ │ ├── Touch%20Dere5.mtn
│ │ │ ├── Touch%20Dere6.mtn
│ │ │ ├── Touch1.mtn
│ │ │ ├── Touch2.mtn
│ │ │ ├── Touch3.mtn
│ │ │ ├── Touch4.mtn
│ │ │ ├── Touch5.mtn
│ │ │ ├── Touch6.mtn
│ │ │ └── WakeUp.mtn
│ │ │ └── textures
│ │ │ ├── default-costume.png
│ │ │ ├── pajamas-costume.png
│ │ │ └── school-costume.png
│ ├── pio.css
│ └── pio.js
├── login.html
├── obconnect.html
├── pkg_edit.html
├── pluscenter.html
├── script.js
├── style.css
├── up.html
├── version.txt
├── vue-quill.js
├── vue-quill.snow.prod.css
├── vue.js
└── watchlog.html
├── script
└── upload_web.py
└── src
├── botconn
├── email.rs
├── kook.rs
├── mod.rs
├── onebot11.rs
├── onebot115.rs
├── qq_guild_all.rs
├── qqguild_private.rs
├── qqguild_public.rs
├── satoriv1.rs
└── telegram.rs
├── cqapi
└── mod.rs
├── cqevent
├── do_group_inc.rs
├── do_group_msg.rs
├── do_other_evt.rs
├── do_private_msg.rs
└── mod.rs
├── cronevent
└── mod.rs
├── httpevent
└── mod.rs
├── httpserver
└── mod.rs
├── initevent
└── mod.rs
├── lib.rs
├── libload
└── mod.rs
├── main.rs
├── mqttclient
└── mod.rs
├── mytool
├── all_to_silk.rs
├── deal_flac.rs
├── deal_ogg.rs
├── deal_silk.rs
├── mod.rs
├── mp3_deal.rs
└── wav_deal.rs
├── onebot11s
└── mod.rs
├── pluscenter
└── mod.rs
├── pyserver
└── mod.rs
├── redlang
├── cqexfun.rs
├── exfun.rs
├── mod.rs
└── webexfun.rs
├── status
└── mod.rs
└── test
└── mod.rs
/.cargo/config.toml:
--------------------------------------------------------------------------------
1 | [target.aarch64-linux-android]
2 | rustflags = ["-C", "default-linker-libraries"]
3 |
4 | [target.x86_64-pc-windows-msvc]
5 | linker = "rust-lld.exe"
6 |
7 | [target.i686-pc-windows-msvc]
8 | linker = "rust-lld.exe"
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | *.js linguist-language=rust
2 | *.css linguist-language=rust
3 | *.html linguist-language=rust
4 | *.htm linguist-language=rust
5 | *.py linguist-language=rust
6 |
--------------------------------------------------------------------------------
/.github/workflows/build.yml:
--------------------------------------------------------------------------------
1 | name: Build Test
2 |
3 | on:
4 | workflow_dispatch:
5 | inputs:
6 | name:
7 | description: 'Log level'
8 | required: true
9 | default: 'warning'
10 |
11 | jobs:
12 | test:
13 | name: build project
14 | runs-on: ${{ matrix.os }}
15 | strategy:
16 | matrix:
17 | include:
18 | # Linux x86_64
19 | - os: ubuntu-latest
20 |
21 | # Windows
22 | - os: windows-latest
23 | steps:
24 | - name: Checkout
25 | uses: actions/checkout@master
26 |
27 | - name: install_ubuntu_dependencies
28 | if: startsWith(matrix.os, 'ubuntu-')
29 | run: |
30 | cargo install cross --git https://github.com/cross-rs/cross
31 |
32 | - name: build_ubuntu
33 | if: startsWith(matrix.os, 'ubuntu-')
34 | run: |
35 | CROSS_NO_WARNINGS=0 cross build --target i686-unknown-linux-musl --release
36 | CROSS_NO_WARNINGS=0 cross build --target x86_64-unknown-linux-musl --release
37 | CROSS_NO_WARNINGS=0 cross build --target aarch64-linux-android --release
38 | CROSS_NO_WARNINGS=0 cross build --target aarch64-unknown-linux-musl --release
39 |
40 | - name: build_windows
41 | if: startsWith(matrix.os, 'windows-')
42 | run: |
43 | rustup target add i686-pc-windows-msvc
44 | rustup target add x86_64-pc-windows-msvc
45 | cargo build --release --target i686-pc-windows-msvc
46 | cargo build --release --target x86_64-pc-windows-msvc
47 | shell: pwsh
48 |
49 | - name: before_ubuntu_upload
50 | if: startsWith(matrix.os, 'ubuntu-')
51 | run: |
52 | mkdir Release
53 | cp target/x86_64-unknown-linux-musl/release/redlang Release/redlang_linux_x86_64
54 | cp target/aarch64-linux-android/release/redlang Release/redlang_android_aarch64
55 | cp target/aarch64-unknown-linux-musl/release/redlang Release/redlang_linux_aarch64
56 | cp target/i686-unknown-linux-musl/release/redlang Release/redlang_linux_i686
57 |
58 | - name: before_windows_upload
59 | if: startsWith(matrix.os, 'windows-')
60 | run: |
61 | mkdir Release
62 | cp target/i686-pc-windows-msvc/release/redlang.exe Release/redlang_windows_i686.exe
63 | cp target/x86_64-pc-windows-msvc/release/redlang.exe Release/redlang_windows_x86_64.exe
64 | shell: pwsh
65 |
66 | - name: upload file1
67 | if: startsWith(matrix.os, 'windows-')
68 | uses: actions/upload-artifact@v4
69 | with:
70 | name: redlang_windows_i686.exe
71 | path:
72 | Release/redlang_windows_i686.exe
73 |
74 | - name: upload file2
75 | if: startsWith(matrix.os, 'windows-')
76 | uses: actions/upload-artifact@v4
77 | with:
78 | name: redlang_windows_x86_64.exe
79 | path:
80 | Release/redlang_windows_x86_64.exe
81 |
82 | - name: upload file3
83 | if: startsWith(matrix.os, 'ubuntu-')
84 | uses: actions/upload-artifact@v4
85 | with:
86 | name: redlang_linux_aarch64
87 | path:
88 | Release/redlang_linux_aarch64
89 |
90 | - name: upload file4
91 | if: startsWith(matrix.os, 'ubuntu-')
92 | uses: actions/upload-artifact@v4
93 | with:
94 | name: redlang_linux_i686
95 | path:
96 | Release/redlang_linux_i686
97 |
98 | - name: upload file5
99 | if: startsWith(matrix.os, 'ubuntu-')
100 | uses: actions/upload-artifact@v4
101 | with:
102 | name: redlang_android_aarch64
103 | path:
104 | Release/redlang_android_aarch64
105 |
106 | - name: upload file6
107 | if: startsWith(matrix.os, 'ubuntu-')
108 | uses: actions/upload-artifact@v4
109 | with:
110 | name: redlang_linux_x86_64
111 | path:
112 | Release/redlang_linux_x86_64
113 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | /target
2 | Cargo.lock
3 |
--------------------------------------------------------------------------------
/Cargo.toml:
--------------------------------------------------------------------------------
1 | [package]
2 | name = "redlang"
3 | version = "1.0.80"
4 | edition = "2021"
5 |
6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
7 |
8 | [dependencies]
9 | fancy-regex = "0.14.0"
10 | encoding = "0.2.33"
11 | getrandom = "0.3.3"
12 | base64 = "0.22.1"
13 | serde_json = "1.0.140"
14 | serde_derive = "1.0.219"
15 | serde = {version = "1.0.219",features = ["derive"]}
16 | uuid = {version = "1.16.0",features = ["v4","fast-rng"]}
17 | lazy_static = "1.5.0"
18 | chrono = "0.4.41"
19 | md-5 = "0.10.6"
20 | rcnb-rs = "0.1.0"
21 | rust-embed = {version="8.7.2",features = ["compression"]}
22 | image = "0.25.6"
23 | imageproc = "0.25.0"
24 | gif = "0.13.1"
25 | cron = "0.15.0"
26 | hyper = { version = "1", features = ["full"] }
27 | tokio = { version = "1.45.0", features = ["full"] }
28 | url = "2.5.4"
29 | futures-util = "0.3.31"
30 | hyper-tungstenite = "0.17.0"
31 | tokio-tungstenite = { version = "0.26.2", default-features = false, features = ["native-tls-vendored"] }
32 | scopeguard = "1.2.0"
33 | log = "0.4.27"
34 | tracing = "0.1.41"
35 | tracing-subscriber = { version = "0.3.19", features = ["env-filter","time","local-time"]}
36 | opener = "0.8.1"
37 | rusqlite = {version = "0.35.0",features = ["bundled","functions"]}
38 | sevenz-rust = "0.6.1"
39 | jsonpath-rust = "1.0.2"
40 | rusttype = "0.9.3"
41 | # markdown = "1.0.0-alpha.7"
42 | reqwest = {version = "0.12.15",default-features = false,features = ["native-tls-vendored","multipart"]}
43 | time = { version = "0.3.41", features = ["formatting", "macros"] }
44 | # headless_chrome = {version="1.0.5",default-features = false}
45 | webp = "0.3.0"
46 | sysinfo = "0.35.1"
47 | usvg = "0.45.1"
48 | resvg = { version = "0.45.1", default-features = false, features = [ "text", "raster-images" ] }
49 | fontdb = { version = "0.23.0", default-features = false, features = [ "fs" ] }
50 | flate2 = { version = "1.1.1",default-features = false}
51 | zhconv = {version = "0.3.3", features = ["opencc","compress"]}
52 | async-trait = "0.1.88"
53 | html5gum = "0.7.0"
54 | html-escape = "0.2.13"
55 | libloading = "0.8.7"
56 | tokio-util = { version = "0.7.15", default-features = false, features = [ "io" ] }
57 | http-body-util = "0.1.3"
58 | hyper-util = { version = "0.1.12", features = ["full"] }
59 | bytes = "1.10.1"
60 | zip = "4.0.0"
61 | crc64 = "2.0.0"
62 | headless_chrome = "1.0.17"
63 | path-clean = "1.0.1"
64 | rust-ini = "0.21.0"
65 | mlua = { version = "0.10.3", features = ["lua54", "vendored"] }
66 | ab_glyph = "0.2.29"
67 |
68 | claxon = "0.4.3"
69 | minimp3_fixed ="0.5.4"
70 | silk-rs-no-llvm = {git = "https://github.com/super1207/silk-rs-no-llvm"}
71 | lewton = "0.10.2"
72 |
73 | msedge-tts = {git = "https://github.com/super1207/msedge-tts"}
74 |
75 | imap = { git = "https://github.com/jonhoo/rust-imap"}
76 | native-tls = "0.2.14"
77 | mail-parser = "0.11.0"
78 | lettre = { version = "0.11.16",features = ["tokio1-native-tls"]}
79 |
80 | scraper = "0.23.1"
81 | tungstenite = "0.26.2"
82 | markdown = "1.0.0-alpha.21"
83 | rumqttc = {git = "https://github.com/super1207/rumqtt",default-features = false}
84 |
85 | [build-dependencies]
86 | embed-resource = "3.0.2"
87 |
88 |
89 | [target.'cfg(windows)'.dependencies]
90 | winreg = "0.55.0"
91 | xcap = "0.6.0"
92 | winconsole = "0.11.1"
93 | tray-icon = "0.20.1"
94 | fltk = { version = "1.4.33"}
95 |
96 | [profile.release]
97 | panic = "abort" # Strip expensive panic clean-up logic
98 | codegen-units = 1 # Compile crates one after another so the compiler can optimize better
99 | lto = true # Enables link to optimizations
100 | opt-level = "s" # Optimize for binary size
101 | strip = true # Remove debug symbols
102 |
103 |
--------------------------------------------------------------------------------
/Dockerfile:
--------------------------------------------------------------------------------
1 | # for ubuntu 24.04
2 | FROM ubuntu
3 | RUN sed -i 's/security.ubuntu.com/mirrors.ustc.edu.cn/g' /etc/apt/sources.list.d/ubuntu.sources
4 | RUN sed -i 's/archive.ubuntu.com/mirrors.ustc.edu.cn/g' /etc/apt/sources.list.d/ubuntu.sources
5 | RUN apt-get update -y \
6 | && echo "Asia\nShanghai" | apt install -y tzdata \
7 | && apt-get install unzip wget python3 python3-pip python3-venv -y \
8 | && wget https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb \
9 | && apt-get install -y ./google-chrome-stable_current_amd64.deb \
10 | && rm google-chrome-stable_current_amd64.deb \
11 | && wget -O /usr/share/fonts/simsun.ttf https://pfh-file-store.oss-cn-hangzhou.aliyuncs.com/simsun.ttf \
12 | && apt-get clean
13 | ADD "https://red.super1207.top/version/latest_nightly_version.php" skipcache
14 | RUN wget -O radlang.zip https://red.super1207.top/download/latest_nightly_linux_x86_64.php \
15 | && unzip radlang.zip \
16 | && rm radlang.zip \
17 | && chmod +x redlang_linux_x86_64
18 | EXPOSE 1207
19 | CMD if [ ! -f "/plus_dir/config.json" ]; \
20 | then echo '{"web_port":1207,"web_host":"0.0.0.0","ws_urls":[],"not_open_browser":true}' > /plus_dir/config.json; fi \
21 | && ./redlang_linux_x86_64
22 |
23 | # 构建镜像:
24 | # docker build -t super1207/redreply .
25 | # 创建并运行容器:
26 | # docker run --rm -p 1207:1207 -v ${pwd}:/plus_dir super1207/redreply
27 |
28 |
--------------------------------------------------------------------------------
/build.rs:
--------------------------------------------------------------------------------
1 | fn main() {
2 | let _ = embed_resource::compile("./buildrc/redreply.rc",embed_resource::NONE);
3 | }
--------------------------------------------------------------------------------
/buildrc/redreply.rc:
--------------------------------------------------------------------------------
1 | iconName ICON "../res/favicon.ico"
--------------------------------------------------------------------------------
/docs/.nojekyll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/super1207/redreply/11565df4c20e6714509bc99521d5a39610450fe1/docs/.nojekyll
--------------------------------------------------------------------------------
/docs/README.md:
--------------------------------------------------------------------------------
1 | # 强大的聊天自定义问答系统-红色问答
2 |
3 | ## 软件架构
4 |
5 | 
6 |
7 | ## 开始使用
8 |
9 | 1:下载项目release中的`redlang.exe`,双击并执行,会自动弹出一个网页。
10 |
11 | 2:在自动弹出的浏览器界面中,点击`连接平台协议`,然后按需求添加协议。
12 |
13 | 3:然后,你可以开始写脚本了,你可以查看[一些例子](/example/)。
14 |
15 | 4:有个交流群:920220179,有一大堆好看的。
16 |
17 | ## 平台协议推荐
18 |
19 | | 平台 | 协议 |
20 | |---|---|
21 | | 官方QQ频道私域 | 内置(推荐)、基于Gensokyo/onebot(其次推荐)、基于OlivOS(不推荐)、基于koishi/satori(不推荐)、基于satoricq/satori(不推荐) |
22 | | 官方QQ频道公域/群 | 内置(推荐)、基于Gensokyo/onebot(同样推荐)、基于OlivOS(不推荐)、基于koishi/satori(不推荐)、基于satoricq/satori(不推荐) |
23 | | 开黑啦kook | 内置(推荐)、基于kookonebot(不推荐)、基于satoricq/satori(同样推荐)、基于OlivOS(不推荐)、基于koishi/satori(不推荐) |
24 | | 三方QQ | 基于openshamrock(推荐)、基于llonebot(同样推荐)、基于Lagrange.Core/onebot(同样推荐)、基于opqonebot(不推荐)、基于go-cqhttp(不推荐)、基于chronocat(无测试) |
25 | | 米哈游大别野(已经没了) | 基于satoricq/satori(推荐)、基于OlivOS(不推荐)、基于koishi/satori(不推荐) |
26 | | 邮件 | 内置(推荐) |
27 | | telegram | 内置(推荐) |
28 |
29 | [推荐]:经过super1207仔细测试,使用/部署体验良好。
30 |
31 | [同样推荐]:经过其它人仔细测试,使用/部署体验良好、或super1207希望进行更多测试。
32 |
33 | [其次推荐]:经过仔细测试,使用/部署体验不那么好。
34 |
35 | [不推荐]:经过仔细测试但体验不好、或者未仔细测试、或者长时间未测试。
36 |
37 | [无测试]:没有经过测试,但是理论上可以运行。
38 |
39 |
40 |
41 |
42 | ## 语法参考文档
43 |
44 | [语法详细参考](/detailref/)
45 |
46 |
47 | ## 访问控制
48 |
49 | 访问控制对来自本机的访问无效。
50 |
51 | 在`config.json`中,若存在`web_password`这个字符串字段且不为空字符串,则访问webui时需要先输入密码登录,才能访问,输入此密码,将获得读写权限。
52 |
53 | 在`config.json`中,若存在`readonly_web_password`这个字符串字段且不为空字符串,则访问webui时需要先输入密码登录,才能访问,输入此密码,将获得只读权限。
54 |
55 | 如果要完全禁止他人访问,你必须同时设置这两个密码!!!
56 |
57 |
58 | ## 自行编译
59 |
60 | 注意,通常情况下,如果您不打算参与此项目的开发,就无需自行编译,请直接到release(或者github action)中去下载。
61 |
62 | 1:安装好[rust编译环境](https://www.rust-lang.org/)。
63 |
64 | 2:
65 | 在`windows`下,仅需要在项目目录下运行`cargo build`即可。
66 | 在`linux`下,编译过程参考github action
67 |
68 |
69 | ## 开源说明
70 |
71 | [GNU Affero General Public License](https://en.wikipedia.org/wiki/GNU_Affero_General_Public_License)
72 |
73 | 特别注意:
74 |
75 | 1:分发、使用此软件或其代码请明确告知用户此软件的原始开源地址:https://github.com/super1207/redreply
76 |
77 | 2:使用修改后的软件提供服务,或传播修改后的软件,请保持相同开源协议开源并明确指出修改内容,不得隐藏软件已经被修改的事实。
78 |
79 | 3:此软件不做质量保证,若因此软件或其修改版本造成任何损失,概不负责。
80 |
81 | 4:请合法使用。
82 |
83 |
84 | ## 其它重要事项
85 |
86 | 1:`红色问答`中很大一部分命令参考了`铃心自定义`,感谢铃心自定义的制作团队!
87 |
88 | 2:`红色问答`的`红色`两字,并无政治上意义,也没有其它特殊内涵,仅仅是因为`super1207`在项目开启的初期喜欢红色。
89 |
90 | 3:`红色问答`中大部分代码由`super1207`编写,但其语法和机制是很多人共同探讨出来的。
91 |
92 | 4:`红色问答`并没有设计自己的图标,而是采用`近月少女的礼仪`中的人物`樱小路露娜`作为标志,`super1207`已经尽可能的降低了图片清晰度,若仍然认为有可能侵权的行为,请立刻与我联系。
93 |
--------------------------------------------------------------------------------
/docs/_coverpage.md:
--------------------------------------------------------------------------------
1 |
2 |
3 | 
4 |
5 | # 红色问答 base
6 |
7 | > 一个神奇的自定义聊天文本处理工具。
8 |
9 | - 我们塑造了我们的工具,然后我们的工具塑造了我们。
10 | by John M. Culkin(1928-1993)
11 |
12 |
13 | [GitHub](https://github.com/super1207/redreply/)
14 | [Get Started](/?id=软件架构)
--------------------------------------------------------------------------------
/docs/_navbar.md:
--------------------------------------------------------------------------------
1 | * [:cn:简体](/)
2 | * [:cn:繁體](/zh-hant/)
--------------------------------------------------------------------------------
/docs/_sidebar.md:
--------------------------------------------------------------------------------
1 |
2 |
3 | * [首页](/)
4 | * [下载](/download/)
5 | * [一些例子](/example/)
6 | * [协议说明](/adaptar/)
7 | * [onebot网络接口](/onebot/)
8 | * [MQTT推送接口](/mqtt/)
9 | * [语法详细参考](/detailref/)
10 | * [设计理念](/idea/)
--------------------------------------------------------------------------------
/docs/adaptar/README.md:
--------------------------------------------------------------------------------
1 | # 适配器说明
2 |
3 | ## onebot11
4 |
5 | 以正向WS连接[ONEBOT11](https://github.com/botuniverse/onebot-11)
6 |
7 | 见[OpenShamrock](https://github.com/whitechi73/OpenShamrock)(推荐)、[go-cqhttp](https://github.com/Mrs4s/go-cqhttp)、[opqonebot](https://github.com/super1207/opqonebot)
8 |
9 | 如果是QQ平台,目前可以自定义音卡签名。在`config.json`同级目录,创建一个`adapter_onebot11_config.json`文件,内容为:
10 |
11 | ```json
12 | {
13 | "music_card_sign":"https://oiapi.net/API/QQMusicJSONArk"
14 | }
15 | ```
16 | 就可以自动使用独角兽的API来签名custom类型的音乐卡片了。
17 |
18 | ## olivos
19 |
20 | [OlivOS](https://github.com/OlivOS-Team/OlivOS) 平台的opk插件自动配置,测试中,进主页交流群了解更多信息...
21 |
22 | ## satori
23 |
24 | 可以连接[satorijs](https://github.com/satorijs) 或 [satoricq](https://github.com/super1207/satoricq)
25 |
26 | ## qq频道、群
27 | .
28 | 可以对接[QQ官方平台](https://q.qq.com/)
29 |
30 | 支持直接发送wav、flac、mp3、ogg(vorbis)格式的音频,无需配置ffmpeg。
31 |
32 | 支持QQ官方的markdown,可以这么发:`[CQ:qmarkdown,data=xxx]`。`xxx`是类似如下json
33 | ```json
34 | {
35 | "markdown": {
36 | "content": "# 标题 \n## 简介很开心 \n内容[🔗腾讯](https://www.qq.com)"
37 | }
38 | }
39 | ```
40 | 的base64编码。以上例子写做CQ码可以这么写:
41 | `[CQ:qmarkdown,data=ewogICJtYXJrZG93biI6IHsKICAgICJjb250ZW50IjogIiMg5qCH6aKYIFxuIyMg566A5LuL5b6I5byA5b+DIFxu5YaF5a65W+2gve20l+iFvuiur10oaHR0cHM6Ly93d3cucXEuY29tKSIKICB9Cn0=]`
42 |
43 | 支持在`markdown`同级位置放入`keyboard`。以下是一个同时放markdown和keyboard的例子。
44 | ```
45 | {
46 | "markdown": {
47 | "content": "# 标题 \n## 简介很开心 \n内容[🔗腾讯](https://www.qq.com)"
48 | },
49 | "keyboard": {
50 | "id": "123"
51 | }
52 | }
53 | ```
54 | 以上例子写做CQ码可以这么写:
55 | `[CQ:qmarkdown,data=ewogICAgIm1hcmtkb3duIjogewogICAgICAgICJjb250ZW50IjogIiMg5qCH6aKYIFxuIyMg566A5LuL5b6I5byA5b+DIFxu5YaF5a65W+2gve20l+iFvuiur10oaHR0cHM6Ly93d3cucXEuY29tKSIKICAgIH0sCiAgICAia2V5Ym9hcmQiOiB7CiAgICAgICAgImlkIjogIjEyMyIKICAgIH0KfQ==]`
56 |
57 | 更详细信息参考QQ的文档[markdown](https://bot.q.qq.com/wiki/develop/api-v2/server-inter/message/type/markdown.html)
58 | 、[keyboard](https://bot.q.qq.com/wiki/develop/api-v2/server-inter/message/trans/msg-btn.html)。
59 |
60 | ## 邮件
61 |
62 | 支持IMAP/SMTP邮件收发协议。支持接收纯文本的邮件,支持发送图文混合的邮件,触发方式`私聊触发`。
63 |
64 | ## KOOK
65 |
66 | 支持对接KOOK官方平台。
67 |
68 | ## telegram
69 |
70 | 支持对接telegram官方平台。目前只支持了基础的群组和私聊的图文收发、发送语音、发送自定义音卡,所以某些平台相关的命令暂时是不可用的,若有需要,请向我们反馈。
--------------------------------------------------------------------------------
/docs/docsify/docsify-copy-code.min.js:
--------------------------------------------------------------------------------
1 | /*!
2 | * docsify-copy-code
3 | * v3.0.0
4 | * https://github.com/jperasmus/docsify-copy-code
5 | * (c) 2017-2023 JP Erasmus
6 | * MIT license
7 | */
8 | !function(){"use strict";function e(o){return e="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},e(o)}!function(e,o){void 0===o&&(o={});var t=o.insertAt;if(e&&"undefined"!=typeof document){var n=document.head||document.getElementsByTagName("head")[0],c=document.createElement("style");c.type="text/css","top"===t&&n.firstChild?n.insertBefore(c,n.firstChild):n.appendChild(c),c.styleSheet?c.styleSheet.cssText=e:c.appendChild(document.createTextNode(e))}}(".docsify-copy-code-button,.docsify-copy-code-button>span{cursor:pointer;transition:all .25s ease}.docsify-copy-code-button{background:grey;background:var(--theme-color,grey);border:0;border-radius:0;color:#fff;font-size:1em;opacity:0;outline:0;overflow:visible;padding:.65em .8em;position:absolute;right:0;top:0;z-index:1}.docsify-copy-code-button>span{background:inherit;border-radius:3px;pointer-events:none}.docsify-copy-code-button>.error,.docsify-copy-code-button>.success{font-size:.825em;opacity:0;padding:.5em .65em;position:absolute;right:0;top:50%;transform:translateY(-50%);z-index:-100}.docsify-copy-code-button.error>.error,.docsify-copy-code-button.success>.success{opacity:1;right:100%;transform:translate(-25%,-50%)}.docsify-copy-code-button:focus,pre:hover .docsify-copy-code-button{opacity:1}.docsify-copy-code-button>[aria-live]{height:1px;left:-10000px;overflow:hidden;position:absolute;top:auto;width:1px}"),document.querySelector('link[href*="docsify-copy-code"]')&&console.warn("[Deprecation] Link to external docsify-copy-code stylesheet is no longer necessary."),window.DocsifyCopyCodePlugin={init:function(){return function(e,o){e.ready((function(){console.warn("[Deprecation] Manually initializing docsify-copy-code using window.DocsifyCopyCodePlugin.init() is no longer necessary.")}))}}},window.$docsify=window.$docsify||{},window.$docsify.plugins=[function(o,t){var n={buttonText:"Copy to clipboard",errorText:"Error",successText:"Copied"};o.doneEach((function(){var o=Array.from(document.querySelectorAll("pre[data-lang]"));t.config.copyCode&&Object.keys(n).forEach((function(o){var c=t.config.copyCode[o];"string"==typeof c?n[o]=c:"object"===e(c)&&Object.keys(c).some((function(e){var t=location.href.indexOf(e)>-1;return n[o]=t?c[e]:n[o],t}))}));var c=['"].join("");o.forEach((function(e){e.insertAdjacentHTML("beforeend",c)}))})),o.mounted((function(){var e=document.querySelector(".content");e&&e.addEventListener("click",(function(e){if(e.target.classList.contains("docsify-copy-code-button")){var o="BUTTON"===e.target.tagName?e.target:e.target.parentNode,t=document.createRange(),c=o.parentNode.querySelector("code"),i=o.querySelector("[aria-live]"),r=window.getSelection();t.selectNode(c),r&&(r.removeAllRanges(),r.addRange(t));try{document.execCommand("copy")&&(o.classList.add("success"),i.innerText=n.successText,setTimeout((function(){o.classList.remove("success"),i.innerText=""}),1e3))}catch(e){console.error("docsify-copy-code: ".concat(e)),o.classList.add("error"),i.innerText=n.errorText,setTimeout((function(){o.classList.remove("error"),i.innerText=""}),1e3)}(r=window.getSelection())&&("function"==typeof r.removeRange?r.removeRange(t):"function"==typeof r.removeAllRanges&&r.removeAllRanges())}}))}))}].concat(window.$docsify.plugins||[])}();
9 | //# sourceMappingURL=docsify-copy-code.min.js.map
--------------------------------------------------------------------------------
/docs/download/README.md:
--------------------------------------------------------------------------------
1 | ### [国内镜像](http://red.super1207.top)
2 |
3 | 更新可能不及时,并且下载不是很快,请耐心等待
4 |
5 | ### [github下载](https://github.com/super1207/redreply/releases)
6 |
7 | 官方稳定版本
8 |
9 | ### [github actions](https://github.com/super1207/redreply/actions)
10 |
11 | 新特性马上尝试,但是需要登录github
12 |
13 |
14 | ### 安装脚本(实验,暂不可用)
15 |
16 | 国内镜像的另一种使用方式,需要有bash环境
17 |
18 | ```
19 | curl -L http://red.super1207.top/redstart.sh | bash```
--------------------------------------------------------------------------------
/docs/example/README.md:
--------------------------------------------------------------------------------
1 | ## 调试脚本的方法(重要)
2 |
3 | > 红色问答倾向于使用真实的聊天平台环境来调试。
4 |
5 | 1. 创建如下图这样的一个脚本:
6 |
7 | 
8 | ```
9 | 【运行脚本【CQ反转义【子关键词】】】
10 | ```
11 |
12 | 2. 然后,在您的聊天平台,发送如下信息:
13 |
14 | 
15 |
16 | ```
17 | run【循环@5@hello【空格】】
18 | ```
19 |
20 | 3. 然后,您会看到如下的效果:
21 |
22 | 
23 |
24 | > PS:在没有连接平台协议的时候,你也可以通过界面上的[其它]->[调试]来方便地进行离线调试。
25 |
26 | ## 访问网络图片
27 |
28 | #### 代码
29 | ```
30 | 【图片【取元素【json解析【访问@https://api.gumengya.com/Api/DmImg】】@data@url】】
31 | ```
32 |
33 | #### 解释
34 | * [【访问】](/detailref/?id=访问)命令访问了一个网站,得到了json格式的字节集
35 |
36 | * [【json解析】](/detailref/?id=json解析)命令解析了字节集,得到了Redlang对象
37 |
38 | * [【取元素】](/detailref/?id=取元素)命令取了Red对象中的data->url字段,即图片链接
39 |
40 | * [【图片】](/detailref/?id=图片)命令,构造了一张图片。【图片】命令,其实是输出了平台支持的特殊格式的文本,您如果对此感到好奇,可以使用[【打印日志】](/detailref/?id=打印日志)命令查看。
41 |
42 | ## 如何向指定目标发送消息
43 |
44 | 消息来源决定回复目标。
45 |
46 | 在聊天事件中,回复会自动根据消息来源,发送到群聊或私聊中。
47 |
48 | 但是在定时任务、框架初始化事件中,没有消息来源。所以需要使用[【设置来源】](/detailref/?id=设置来源)命令。
49 |
50 | #### 定时器中发送群聊消息
51 |
52 | ```
53 | 【设置来源@机器人平台@onebot11】
54 | 【设置来源@机器人ID@xxxxx】
55 | 【设置来源@群ID@920220179】
56 | ```
57 |
58 | > PS:在某些具备两级群的平台,你可能还需要写【设置来源@群组ID@xxxxxxxxx】
59 |
60 | #### 定时器中发送私聊消息
61 |
62 | ```
63 | 【设置来源@机器人平台@onebot11】
64 | 【设置来源@机器人ID@xxxxx】
65 | 【设置来源@发送者ID@1875159423】
66 | ```
67 |
68 | #### 在群聊中发送私聊消息
69 | 将群ID清空,就可以进行私聊回复了。
70 | ```
71 | 【设置来源@群ID@】
72 | ```
73 |
74 |
75 | ## 多条回复
76 |
77 | 如果希望对同一条消息进行多次回复,有两种办法。【分页】和【输出流】是有些区别的,【分页】会在脚本运行结束的时候,同时发送多条消息。而【输出流】会在脚本运行的时候立刻发送,并且返回消息ID。
78 |
79 | #### 分页
80 | 使用[【分页】](/detailref/?id=分页)命令发送`你好`和`世界`两条消息。
81 |
82 | ```
83 | 你好【分页】世界
84 | ```
85 |
86 | #### 输出流
87 | 使用[【输出流】](/detailref/?id=输出流)命令发送`你好`和`世界`两条消息。
88 |
89 | ```
90 | 【隐藏【输出流@你好】】
91 | 【隐藏【输出流@世界】】
92 | ```
93 | 【输出流】会返回消息ID,这里用不到,所以使用[【隐藏】](/detailref/?id=隐藏)命令将返回的消息ID隐藏起来。
94 |
95 | ## 获取事件内容
96 |
97 | 如果需要获取消息事件中的消息,最方便的方法是使用[【子关键词】](/detailref/?id=子关键词)。
98 |
99 | 如果要获取一个事件中的所有内容,比如您希望获得事件产生的时间,您可以使用【取元素【事件内容】@time】,如果您不了解【事件内容】的结构,您可以使用【转文本【事件内容】】,将其输出出来观察。
100 |
101 | ## 数据类型转换
102 |
103 | 红色问答中支持`文本`,`字节集`,`数组`,`对象`这四种数据类型,然而可以输出的只有`文本`类型,所以,您需要使用[【转文本】](/detailref/?id=转文本)命令。
104 |
105 | #### 文本转文本
106 |
107 | ```
108 | 【转文本@你好】
109 | ```
110 | 输出```"你好"```,其实就是输出了json形式的文本,这在您需要手拼json的时候非常管用。
111 |
112 | #### 字节集转文本
113 |
114 | ```
115 | 【转文本【读文件@C://test.txt】@utf8】
116 | ```
117 | 读utf8格式的文本文件,得到的结果是字节集,然后转为文本。utf8是默认的,可以省略,如`【转文本【读文件@C://test.txt】】`,也可以是gbk,如`【转文本【读文件@C://test.txt】@gbk】`。
118 |
119 | #### 文本转字节集
120 | [【转字节集】](/detailref/?id=转字节集)命令可以实现将文本转为字节集。
121 |
122 | ```
123 | 【转字节集@你好@utf8】
124 | ```
125 | utf8是默认的,表示字节集类型,可以省略,如`【转字节集@你好】`,也可以是gbk,如`【转字节集@你好@gbk】`。
126 |
127 | #### 字节集转文本
128 |
129 | ```
130 | 【转文本@【转字节集@你好】@utf8】
131 | ```
132 |
133 | #### 数组转文本
134 |
135 | ```
136 | 【转文本【数组@1@2@3】】
137 | ```
138 | 输出`["1","2","3"]`,其实就是输出了json形式的文本。因为json中是不支持字节集的,所以你需要保证数组中没有字节集类型。
139 |
140 | #### 对象转文本
141 |
142 | ```
143 | 【转文本【对象@1@a@2@b@3@c】】
144 | ```
145 | 输出`{"1":"a","2":"b","3":"c"}`,其实就是输出了json形式的文本。因为json中是不支持字节集的,所以你需要保证对象中没有字节集类型。
146 |
147 | ## 欢迎新人
148 |
149 | 触发方式改为`群成员增加`
150 |
151 | #### 代码
152 |
153 | ```
154 | 【判等【当前群号】@@@【设置来源@群ID@【取元素【取群列表】@0@群ID】】】
155 | 【艾特】欢银【发送者昵称】,祝您度过美好的一天!
156 | ```
157 | #### 解释
158 |
159 | * 第一行代码,对群聊类型进行判断。
160 | 如果[【当前群号】](/detailref/?id=当前群号)为空,说明是类似qq频道那种两级群组。所以使用[【取群列表】](/detailref/?id=取群列表) + [【取元素】](/detailref/?id=取元素)命令获取当前群组的群列表并取出其中第一个群的群ID,将其设置为消息来源。
161 | 如果【当前群号】不为空,说明是类似QQ群那种群聊,什么也不用做。
162 |
163 | * 第二行代码,使用[【发送者昵称】](/detailref/?id=发送者昵称)获取新人的昵称,使用[【艾特】](/detailref/?id=艾特)来AT发送者。
--------------------------------------------------------------------------------
/docs/example/image-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/super1207/redreply/11565df4c20e6714509bc99521d5a39610450fe1/docs/example/image-1.png
--------------------------------------------------------------------------------
/docs/example/image-2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/super1207/redreply/11565df4c20e6714509bc99521d5a39610450fe1/docs/example/image-2.png
--------------------------------------------------------------------------------
/docs/example/image.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/super1207/redreply/11565df4c20e6714509bc99521d5a39610450fe1/docs/example/image.png
--------------------------------------------------------------------------------
/docs/favicon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/super1207/redreply/11565df4c20e6714509bc99521d5a39610450fe1/docs/favicon.png
--------------------------------------------------------------------------------
/docs/idea/README.md:
--------------------------------------------------------------------------------
1 | # 设计
2 |
3 | ## 插件模型
4 |
5 | ### 资源
6 |
7 | 红色问答的插件在磁盘上以文件夹形式存在,一个文件夹就是一个插件,一个插件拥有如下资源:
8 |
9 | * 名字:对于非`默认插件`,文件夹的名字就是插件名。插件作者不能决定,甚至不能获取自己的插件名,插件名由最终使用者决定,可随意修改,这么做,就可以绝对保证插件不会重名,因为文件系统不支持。
10 | * 磁盘资源:每个插件可以通过【应用目录】命令,来获得属于自己的磁盘路径,插件应该永远以这个路径为基础来进行文件目录操作。插件不应该记录这个路径,因为这个路径可能变化,比如插件改名的时候。
11 | * 网络资源:每个插件可以拥有自己的网络路径,格式是`http://host:port/user/插件名/自定义路径`。其中,只有`自定义路径`是由插件作者定义的。
12 | * 常量和自定义命令:每个插件拥有自己独立的常量和命令空间,在整个红色问答重启前,定义的常量和命令都是有效的。
13 | * 持久常量:持久常量属于`磁盘资源`,在【应用目录】下的`reddat.db`文件中。
14 | * 脚本文件:脚本文件依然属于`磁盘资源`。和传统软件不同,红色问答不区分代码目录和数据目录,这么做是为了简化概念。
15 |
16 | ### 生命周期
17 |
18 | 每个插件拥有独立的生命周期。
19 |
20 | * 插件加载:在红色问答启动,或者插件重载的时候,会从【应用目录】中读取scripts.json文件,这个文件包含若干脚本。然后,其中触发类型为`框架初始化`的脚本会先被执行一次。
21 | * 插件运行:在完成插件加载后,其它类型的脚本会由各种事件触发执行。
22 | * 插件卸载:让当前插件不再收到新事件,等待当前插件所有脚本执行完毕。注意,红色问答没有名为类似`框架卸载`的触发方式,这么设计依然是为了简化概念,红色问答只是一个`词库系统`。
23 | * 插件重载:先执行插件卸载,再执行插件加载。
24 |
25 | 你绝对不能编写一个长时间运行的脚本,否则会影响插件卸载和插件重载。即使你什么也没做,插件也可能自己卸载和重载以释放一些资源。
26 |
27 | 为了阻止复杂的问题发生,不建议在运行时修改插件的名字。
28 |
29 | ### 依赖管理
30 |
31 | 红色问答不进行依赖管理。具体来说就是,任意两个插件之间都感觉不到对方的存在,也不会存在相互依赖关系。红色问答提供了很多常用命令,并且也提供了运行python和安装python包的命令,还提供了lua解析器,大多数情况下你不依赖其它插件也可以完成插件编写。如果你的插件特别复杂,有大量的依赖关系,那么你不应该使用红色问答来编写。因为不进行依赖管理,所以,版本管理也没有太大意义,插件商店里的插件版本号,只是为了让你觉得插件作者还活着,但是唯一100%正确的更新插件的方法是关闭红色问答,然后删除旧插件文件夹,放入新插件文件夹。如果你想保留数据,你需要向插件作者确认数据在不同版本之间的兼容性。
32 |
33 | ### 默认插件
34 |
35 | 红色问答始终存在一个默认插件,用于在线调试等。它的【应用目录】在一个你很容易找到的地方,它的名字是一个空字符串,你可以认为它没有名字,反正前面说了,你获取不到插件的名字。这么做是为了简化概念,很多场景下,你只需要这么一个默认插件就行了,你可以忽略`插件`的概念,红色问答不是一个插件框架,而是一个词库系统,本身定位为插件。
36 |
37 | ## 适配器模型
38 |
39 | 适配器模型也可以叫做平台协议模型。
40 |
41 | 适配器用于连接真实的聊天平台,作用是触发事件、制造脚本运行环境。红色问答里面的平台相关的命令,会根据脚本运行环境来选择调用某适配器的的API。脚本的返回值也会根据脚本运行环境来选择返回给适配器的数据。简单来说,就是`适配器产生的事件决定脚本运行环境`,`脚本运行环境决定使用什么适配器的什么API`。另外,脚本运行环境也可以由脚本自己修改,以达到其它目的,比如清空`群ID`,就可以对群聊消息进行私聊回复、比如修改群`ID`,就可以让消息回复到其它群。
42 |
43 | 所有适配器都会支持一种类似onebot但不是onebot的统一的api和event格式,以保证大多数命令的通用性。这个格式目前是非公开的,之后会考虑公开。
44 |
45 | 红色问答编写平台协议的基本要求是:协议是某知名IM的官方协议、协议可以适配众多知名IM
46 |
47 |
48 | ## 用户体验
49 |
50 | 这里的用户指的是脚本开发者,红色问答是`全代码开发平台`,对比[低代码开发平台](https://baike.baidu.com/item/%E4%BD%8E%E4%BB%A3%E7%A0%81%E5%BC%80%E5%8F%91%E5%B9%B3%E5%8F%B0/23661682)。
51 |
52 | 红色问答要求用户具备编程基础:熟悉循环、判断、函数调用、数据类型等编程知识;具备数据库、网络、图像处理、操作系统等知识。
53 |
54 | 红色问答旨在简化开发方式,而不是降低开发门槛。简化的开发方式必然不能应对复杂的开发需求,但是总得有个倾向吧。我就想躺床上用一根指头在手机上指指点点就完成我的涩图插件。
55 |
56 | 红色问答运行在各种操作系统,各种架构上面,并且大多数功能不会损失。红色问答没有安装过程,本体只有一个可执行文件,双击即可获得大多数功能。你可以在box86、box64上运行,可以在wine上运行,可以在新版windows上、新版linux,新版android系统上运行,运行方式都统一为启动一个可执行文件。
57 |
58 | 红色问答同时兼容linux和windows的路径写法。是的,这对路径名有所限制,会导致不能在某些路径下面运行,间接也会影响插件名,但是我认为这是值得的。路径没事用啥特殊符号呀。
59 |
60 |
61 | ## 隐私保护
62 |
63 | 红色问答进行绝对的隐私保护。
64 |
65 | 要进行隐私保护,首先要定义什么是隐私。然而不同人有不同的定义。银行卡密码,名字,性别,年龄,身高,体重,电脑型号,软件使用时间,操作系统,软件有多少人在使用,这些都可以被定义为隐私。
66 |
67 | 绝对的隐私保护,意味着红色问答不会连接我的服务器,也尽可能不连接其它人的服务器,您的一切信息都不会传递给我。红色问答代码全部开源,您可以在github上查看。
68 |
69 | 注意:使用红色问答的插件商店,会向github或github代理地址发送信息。
70 | 注意:使用【上传文件】命令,会向[uhsea.com](https://uhsea.com/)发送信息。
71 | 注意:使用【TTS】命令,会向微软的服务器发送信息。
72 |
73 |
74 | ## 安全控制
75 |
76 | 红色问答不进行安全控制。红色问答不进行安全控制。红色问答不进行安全控制。所有密码,所有数据全部明文保存、明文传输,明文显示。网络服务完全不进行安全防护,一攻击就蓝屏给你看,然后把数据全部送出去。访问密码什么的都是骗人的,一打就穿。所以,任何情况下都不要在防火墙上公开红色问答所使用的端口号。一定不要用不信任的设备访问红色问答的端口号,因为包括密码在内的数据会直接明文放在浏览量的cookie里面。操作红色问答的时候,要注意观察周围环境。其它软件让你相信安全,红色问答让你相信不安全。
77 |
78 |
79 | ## 命令系统设计
80 |
81 | 红色问答的语法格式并没有什么令人惊艳的地方,甚至也不是特别方便,我也不是专业设计这个的,反正群友说什么设计我就怎么设计。不过,这也不是侧重点。
82 |
83 | 红色问答维护的是大量功能,以及一堆rust包的依赖关系。这是非常繁重的工作,每个rust包,以及它们的版本号都是精心挑选的。用较小的可执行文件体积,完成了大量功能。并行这些功能都能在几乎所有平台上正常运行。设计思路有点像python的蓄电池思想。红色问答开发的大部分时间,是在测试各个rust包之间的兼容性。
84 |
85 | 红色问答不具备垃圾回收机制,所以,长时间运行的脚本,可能会使用越来越多的内存空间,这也是上面提到的`你绝对不能编写一个长时间运行的脚本`的另一个原因。在脚本运行结束的时候,内存会释放。redlang不是一个中文编程语言(我仍然会这么宣传),而是一文本生成规则。
86 |
--------------------------------------------------------------------------------
/docs/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Document
6 |
7 |
8 |
9 |
10 |
11 |
12 | 稍等...亲~
13 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
--------------------------------------------------------------------------------
/docs/mqtt/README.md:
--------------------------------------------------------------------------------
1 | # 红色问答MQTT推送接口(草案)
2 |
3 | ## 概述
4 |
5 | 红色问答对外公开MQTT接口,红色问答作为消息发布者。红色问答会将收到的机器人平台事件转化为类似 [onebot11](https://github.com/botuniverse/onebot-11) 格式推送。同时也会公开API调用接口,让订阅者可以调用机器人平台的API。
6 |
7 | 除此之外,还可以连接多个红色问答,达到共享脚本和适配器的效果。
8 |
9 | 要使用此推送服务,您需要先自行准备一个支持 mqtt 5.0 的mqtt broker。
10 |
11 | ## 配置
12 |
13 | 
14 |
15 | 如上图,在红色问答的配置文件中,添加mqtt相关的配置,其中:
16 |
17 | `client_id`: 一个随机的字符串。使用uuid v4生成工具生成即可,作为红色问答的身份标记。
18 |
19 | `broker_host`: mqtt的broker服务器地址。要注意,目前仅支持mqtt 5.0的服务器,你可以自建broker服务器,也可以使用公用的免费服务器。但是要注意,公用的broker服务器是不安全的,仅用于测试。
20 |
21 | `broker_port`: mqtt的broker服务器端口号。
22 |
23 | `broker_username`: mqtt broker的用户名,如果没有可以不填或者填 `null`。
24 |
25 | `broker_password`: mqtt broker的密码,如果没有可以不填 `null`。
26 |
27 | `remote_clients`: 其它红色问答的 `client_id`,配置了之后,可以接收并处理其它红色问答推送的事件。如果想要处理所有远程红色问答的推送,可以写为:`"remote_clients":["+"]`。
28 |
29 | 配置好后,要重启红色问答才能生效。之后,红色问答会将收到的消息和事件进行推送。
30 |
31 | ## 消息推送
32 |
33 | 红色问答的推送的mqtt Topic为:
34 |
35 | `bot////event`
36 |
37 | `client_id`即为上文配置文件中配置的 `client_id` 。
38 |
39 | `platform` 和 `self_id` 可以分别通过 `【机器人平台】` 和 `【机器人ID】` 命令得到。
40 |
41 | 如下是一个例子:
42 |
43 | `bot/7c5e0089-c120-4cef-94e6-62a5c431b8b3/onebot11/1736293901/event`
44 |
45 | 您也可以通过 `bot/7c5e0089-c120-4cef-94e6-62a5c431b8b3/+/+/event` 来订阅所有bot。
46 |
47 | 推送的消息格式如下:
48 | ```json
49 | {
50 | "anonymous": null,
51 | "font": 0,
52 | "group_id": "920220179",
53 | "message": [
54 | {
55 | "data": {
56 | "qq": "1875159423"
57 | },
58 | "type": "at"
59 | },
60 | {
61 | "data": {
62 | "text": " .help 指令"
63 | },
64 | "type": "text"
65 | }
66 | ],
67 | "message_id": "474483251",
68 | "message_type": "group",
69 | "post_type": "message",
70 | "raw_message": "[CQ:at,qq=1736293901] .help 指令",
71 | "self_id": "1736293901",
72 | "sender": {
73 | ...
74 | ...
75 | },
76 | "sub_type": "normal",
77 | "time": 1745833334,
78 | "user_id": "1875159423"
79 | }
80 | ```
81 |
82 | 消息基本按照 [onebot11](https://github.com/botuniverse/onebot-11) 格式推送,但是要注意有如下不同:
83 |
84 | 1. 所有的id都改为了字符串
85 |
86 | 2. message字段一定为消息段数组格式
87 |
88 | 3. 所有的事件都会有一个`message_id`
89 |
90 | ## API调用
91 |
92 | ### 发起调用
93 |
94 | 红色问答公开的API Topic为
95 |
96 | `bot////api`
97 |
98 | 以上参数的含义同`消息推送`一节。
99 |
100 | 发送的数据如下:
101 |
102 | ```json
103 | {
104 | "action":"get_stranger_info",
105 | "message_id":"474483251",
106 | "params":{
107 | "user_id":"1875159423"
108 | }
109 | }
110 | ```
111 |
112 | 基本按照 [onebot11](https://github.com/botuniverse/onebot-11) 格式,但是要特别注意:
113 |
114 | 1. 所有的id都改为了字符串,您需要发送字符串格式的id
115 |
116 | 2. 可以在 `action` 同级添加 `message_id`,方便适配器进行消息追踪,但是这不是必须的。
117 |
118 | ### 接收回复
119 |
120 | 接收回复的方式按照 mqtt 5.0 规定的`response_topic`和`correlation_data`进行。
121 |
122 | 为防止可能的权限问题:
123 |
124 | 1. `response_topic` 建议设计为 `plus//response` ,其中,`plus_id` 为一个代表插件的uuid v4。
125 |
126 | 2. `correlation_data` 由插件自行决定。
127 |
128 | 要注意:回复的数据中的id也都为字符串格式。
--------------------------------------------------------------------------------
/docs/mqtt/image.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/super1207/redreply/11565df4c20e6714509bc99521d5a39610450fe1/docs/mqtt/image.png
--------------------------------------------------------------------------------
/docs/onebot/README.md:
--------------------------------------------------------------------------------
1 | # onebot网络接口(测试中,可能会不太稳定)
2 |
3 | ## 目的
4 |
5 | 红色问答公开onebot服务,可以将红色问答支持的任何协议转为onebot11接口服务,使得其它插件框架,如MiraiCQ,可以对接红色问答。
6 |
7 | 注:
8 |
9 | 红色问答目前直接支持的平台为:
10 | onebot11、olivos、satori、qq频道私区域(qqguild_private)、qq频道(qqguild_public)/群(qqgroup_public)公域、邮件、kook、telegram。
11 |
12 | 间接支持**几乎所有聊天平台**
13 |
14 | ## 连接
15 |
16 | 目前,仅支持正向WS。签权需要的access_token为红色问答的web密码,**本机使用不需要鉴权**。
17 |
18 | websocket地址:`ws://localhost:[redport]:/onebot/[机器人平台]/[机器人账号]`
19 |
20 | 如:`ws://localhost:1207/onebot/onebot11/1875159423`
21 |
22 | 当只有一个平台一个账号时,可以简写为(不推荐,没有测试过):
23 |
24 | `ws://127.0.0.1:1207/onebot`
25 |
26 | ## 局限性
27 |
28 | 1:对于qq官方频道那种,需要设置message_id才能回复的,会自动寻找最近的message_id进行回复,容易回复错人。
29 |
30 | 2:在具备两级群组的平台,如频道,获取群列表可能会失败。
31 |
32 | 3:每个message_id仅具备5分钟的有效时间。
--------------------------------------------------------------------------------
/docs/softarch.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/super1207/redreply/11565df4c20e6714509bc99521d5a39610450fe1/docs/softarch.png
--------------------------------------------------------------------------------
/readme.md:
--------------------------------------------------------------------------------
1 |
2 |
红色问答
3 |
4 |
5 |
6 |

7 |
8 |
9 | > 强大的聊天自定义问答系统
10 |
11 | ## 背景
12 |
13 | 受铃心自定义的启发,制作一个类似的自定义系统。
14 |
15 | 随着酷Q、先驱等机器人平台的停运,其上运行的铃心自定义也逐渐不再被其作者很好的维护。再加上各种跨平台的开源机器人平台的逐渐流行,一个 **全开源** 、**跨平台** 的自定义问答系统被期待着。
16 |
17 | 红色问答因此而出现。
18 |
19 | ## 展示
20 |
21 | > 红色问答使用浏览器作为界面,并且开箱即用,您可以躺在床上用手机一只手愉快地编写插件。
22 |
23 | 
24 |
25 |
26 | 
27 |
28 | ## 主要特色
29 |
30 | 1. 开源、免费、构建过程完全透明,红色问答并不属于某一个人!
31 |
32 | 2. 支持中文编程。
33 |
34 | 3. 支持多种聊天平台:QQ、telegram、KOOK、邮件、米哈游......
35 |
36 | 4. 支持多账号。
37 |
38 | 5. 支持多操作系统:Linux、Windows、FreeBSD、Android。
39 |
40 | 6. 支持分布式集群:基于MQTT 5.0,可以让多个红色问答共享适配器和插件。
41 |
42 | 7. 支持web ui可视化:在电脑或手机的浏览器里面增加、删除、查看、修改脚本。(注意,在床上躺着用手机写插件是红色问答的主线目标)
43 |
44 | 8. 支持热重载:增加、删除、查看、修改脚本后无须重启红色问答,只需点击保存按钮即可立刻生效。
45 |
46 |
47 | ## 文档
48 |
49 | > 你想要的,都在文档里面。
50 |
51 | [文档](https://super1207.github.io/redreply)
52 |
53 |
54 | ## 开源说明
55 |
56 | [GNU Affero General Public License](https://en.wikipedia.org/wiki/GNU_Affero_General_Public_License)
57 |
58 | 特别注意:
59 |
60 | 1:分发、使用此软件或其代码请明确告知用户此软件的原始开源地址:https://github.com/super1207/redreply
61 |
62 | 2:使用修改后的软件提供服务,或传播修改后的软件,请保持相同开源协议开源并明确指出修改内容,不得隐藏软件已经被修改的事实。
63 |
64 | 3:此软件不做质量保证,若因此软件或其修改版本造成任何损失,概不负责。
65 |
66 | 4:请合法使用。
67 |
68 | 5:有个交流群:920220179
69 |
70 |
--------------------------------------------------------------------------------
/res/crontool.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | 红色问答CRON校验
8 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
红色问答CRON校验
30 |
31 |
32 | CRON表达式:
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
87 |
88 |
89 |
90 |