mirror of
https://github.com/Mrs4s/go-cqhttp.git
synced 2025-05-05 03:23:49 +08:00
feat(config): separate config & server (#1212)
* feat(server): add RegisterCustom * feat(config): seprate config & server * fix: make lint happy * fix: make lint happy * fix: ParseEnv nil pointer error * typo(config): generateConfig hint * fix(config): panic on range overflow
This commit is contained in:
parent
3eade331bf
commit
26a7a1f0b6
@ -8,11 +8,12 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
"sync"
|
||||||
"github.com/Mrs4s/go-cqhttp/internal/param"
|
|
||||||
|
|
||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
"gopkg.in/yaml.v3"
|
"gopkg.in/yaml.v3"
|
||||||
|
|
||||||
|
"github.com/Mrs4s/go-cqhttp/internal/param"
|
||||||
)
|
)
|
||||||
|
|
||||||
// defaultConfig 默认配置文件
|
// defaultConfig 默认配置文件
|
||||||
@ -69,68 +70,11 @@ type Config struct {
|
|||||||
Database map[string]yaml.Node `yaml:"database"`
|
Database map[string]yaml.Node `yaml:"database"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// MiddleWares 通信中间件
|
// Server 的简介和初始配置
|
||||||
type MiddleWares struct {
|
type Server struct {
|
||||||
AccessToken string `yaml:"access-token"`
|
Brief string
|
||||||
Filter string `yaml:"filter"`
|
Default string
|
||||||
RateLimit struct {
|
ParseEnv func() (string, *yaml.Node)
|
||||||
Enabled bool `yaml:"enabled"`
|
|
||||||
Frequency float64 `yaml:"frequency"`
|
|
||||||
Bucket int `yaml:"bucket"`
|
|
||||||
} `yaml:"rate-limit"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// HTTPServer HTTP通信相关配置
|
|
||||||
type HTTPServer struct {
|
|
||||||
Disabled bool `yaml:"disabled"`
|
|
||||||
Host string `yaml:"host"`
|
|
||||||
Port int `yaml:"port"`
|
|
||||||
Timeout int32 `yaml:"timeout"`
|
|
||||||
LongPolling struct {
|
|
||||||
Enabled bool `yaml:"enabled"`
|
|
||||||
MaxQueueSize int `yaml:"max-queue-size"`
|
|
||||||
} `yaml:"long-polling"`
|
|
||||||
Post []struct {
|
|
||||||
URL string `yaml:"url"`
|
|
||||||
Secret string `yaml:"secret"`
|
|
||||||
}
|
|
||||||
|
|
||||||
MiddleWares `yaml:"middlewares"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// PprofServer pprof性能分析服务器相关配置
|
|
||||||
type PprofServer struct {
|
|
||||||
Disabled bool `yaml:"disabled"`
|
|
||||||
Host string `yaml:"host"`
|
|
||||||
Port int `yaml:"port"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// WebsocketServer 正向WS相关配置
|
|
||||||
type WebsocketServer struct {
|
|
||||||
Disabled bool `yaml:"disabled"`
|
|
||||||
Host string `yaml:"host"`
|
|
||||||
Port int `yaml:"port"`
|
|
||||||
|
|
||||||
MiddleWares `yaml:"middlewares"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// WebsocketReverse 反向WS相关配置
|
|
||||||
type WebsocketReverse struct {
|
|
||||||
Disabled bool `yaml:"disabled"`
|
|
||||||
Universal string `yaml:"universal"`
|
|
||||||
API string `yaml:"api"`
|
|
||||||
Event string `yaml:"event"`
|
|
||||||
ReconnectInterval int `yaml:"reconnect-interval"`
|
|
||||||
|
|
||||||
MiddleWares `yaml:"middlewares"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// LambdaServer 云函数配置
|
|
||||||
type LambdaServer struct {
|
|
||||||
Disabled bool `yaml:"disabled"`
|
|
||||||
Type string `yaml:"type"`
|
|
||||||
|
|
||||||
MiddleWares `yaml:"middlewares"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// LevelDBConfig leveldb 相关配置
|
// LevelDBConfig leveldb 相关配置
|
||||||
@ -183,161 +127,58 @@ func Parse(path string) *Config {
|
|||||||
_ = n.Encode(dbConf)
|
_ = n.Encode(dbConf)
|
||||||
return *n
|
return *n
|
||||||
}()
|
}()
|
||||||
accessTokenEnv := os.Getenv("GCQ_ACCESS_TOKEN")
|
|
||||||
if os.Getenv("GCQ_HTTP_PORT") != "" {
|
for _, s := range serverconfs {
|
||||||
node := &yaml.Node{}
|
if s.ParseEnv != nil {
|
||||||
httpConf := &HTTPServer{
|
name, node := s.ParseEnv()
|
||||||
Host: "0.0.0.0",
|
if node != nil {
|
||||||
Port: 5700,
|
config.Servers = append(config.Servers, map[string]yaml.Node{name: *node})
|
||||||
MiddleWares: MiddleWares{
|
|
||||||
AccessToken: accessTokenEnv,
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
param.SetExcludeDefault(&httpConf.Disabled, param.EnsureBool(os.Getenv("GCQ_HTTP_DISABLE"), false), false)
|
|
||||||
param.SetExcludeDefault(&httpConf.Host, os.Getenv("GCQ_HTTP_HOST"), "")
|
|
||||||
param.SetExcludeDefault(&httpConf.Port, int(toInt64(os.Getenv("GCQ_HTTP_PORT"))), 0)
|
|
||||||
if os.Getenv("GCQ_HTTP_POST_URL") != "" {
|
|
||||||
httpConf.Post = append(httpConf.Post, struct {
|
|
||||||
URL string `yaml:"url"`
|
|
||||||
Secret string `yaml:"secret"`
|
|
||||||
}{os.Getenv("GCQ_HTTP_POST_URL"), os.Getenv("GCQ_HTTP_POST_SECRET")})
|
|
||||||
}
|
}
|
||||||
_ = node.Encode(httpConf)
|
|
||||||
config.Servers = append(config.Servers, map[string]yaml.Node{"http": *node})
|
|
||||||
}
|
|
||||||
if os.Getenv("GCQ_WS_PORT") != "" {
|
|
||||||
node := &yaml.Node{}
|
|
||||||
wsServerConf := &WebsocketServer{
|
|
||||||
Host: "0.0.0.0",
|
|
||||||
Port: 6700,
|
|
||||||
MiddleWares: MiddleWares{
|
|
||||||
AccessToken: accessTokenEnv,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
param.SetExcludeDefault(&wsServerConf.Disabled, param.EnsureBool(os.Getenv("GCQ_WS_DISABLE"), false), false)
|
|
||||||
param.SetExcludeDefault(&wsServerConf.Host, os.Getenv("GCQ_WS_HOST"), "")
|
|
||||||
param.SetExcludeDefault(&wsServerConf.Port, int(toInt64(os.Getenv("GCQ_WS_PORT"))), 0)
|
|
||||||
_ = node.Encode(wsServerConf)
|
|
||||||
config.Servers = append(config.Servers, map[string]yaml.Node{"ws": *node})
|
|
||||||
}
|
|
||||||
if os.Getenv("GCQ_RWS_API") != "" || os.Getenv("GCQ_RWS_EVENT") != "" || os.Getenv("GCQ_RWS_UNIVERSAL") != "" {
|
|
||||||
node := &yaml.Node{}
|
|
||||||
rwsConf := &WebsocketReverse{
|
|
||||||
MiddleWares: MiddleWares{
|
|
||||||
AccessToken: accessTokenEnv,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
param.SetExcludeDefault(&rwsConf.Disabled, param.EnsureBool(os.Getenv("GCQ_RWS_DISABLE"), false), false)
|
|
||||||
param.SetExcludeDefault(&rwsConf.API, os.Getenv("GCQ_RWS_API"), "")
|
|
||||||
param.SetExcludeDefault(&rwsConf.Event, os.Getenv("GCQ_RWS_EVENT"), "")
|
|
||||||
param.SetExcludeDefault(&rwsConf.Universal, os.Getenv("GCQ_RWS_UNIVERSAL"), "")
|
|
||||||
_ = node.Encode(rwsConf)
|
|
||||||
config.Servers = append(config.Servers, map[string]yaml.Node{"ws-reverse": *node})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return config
|
return config
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var serverconfs []*Server
|
||||||
|
var mu sync.Mutex
|
||||||
|
|
||||||
|
// AddServer 添加该服务的简介和默认配置
|
||||||
|
func AddServer(s *Server) {
|
||||||
|
mu.Lock()
|
||||||
|
serverconfs = append(serverconfs, s)
|
||||||
|
mu.Unlock()
|
||||||
|
}
|
||||||
|
|
||||||
// generateConfig 生成配置文件
|
// generateConfig 生成配置文件
|
||||||
func generateConfig() {
|
func generateConfig() {
|
||||||
fmt.Println("未找到配置文件,正在为您生成配置文件中!")
|
fmt.Println("未找到配置文件,正在为您生成配置文件中!")
|
||||||
sb := strings.Builder{}
|
sb := strings.Builder{}
|
||||||
sb.WriteString(defaultConfig)
|
sb.WriteString(defaultConfig)
|
||||||
fmt.Print(`请选择你需要的通信方式:
|
hint := "请选择你需要的通信方式:"
|
||||||
> 1: HTTP通信
|
for i, s := range serverconfs {
|
||||||
> 2: 正向 Websocket 通信
|
hint += fmt.Sprintf("\n> %d: %s", i, s.Brief)
|
||||||
> 3: 反向 Websocket 通信
|
}
|
||||||
> 4: pprof 性能分析服务器
|
hint += `
|
||||||
> 5: 云函数服务
|
请输入你需要的编号(0-9),可输入多个,同一编号也可输入多个(如: 233)
|
||||||
请输入你需要的编号,可输入多个,同一编号也可输入多个(如: 233)
|
您的选择是:`
|
||||||
您的选择是:`)
|
fmt.Print(hint)
|
||||||
input := bufio.NewReader(os.Stdin)
|
input := bufio.NewReader(os.Stdin)
|
||||||
readString, err := input.ReadString('\n')
|
readString, err := input.ReadString('\n')
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal("输入不合法: ", err)
|
log.Fatal("输入不合法: ", err)
|
||||||
}
|
}
|
||||||
|
rmax := len(serverconfs)
|
||||||
|
if rmax > 10 {
|
||||||
|
rmax = 10
|
||||||
|
}
|
||||||
for _, r := range readString {
|
for _, r := range readString {
|
||||||
switch r {
|
r -= '0'
|
||||||
case '1':
|
if r >= 0 && r < rune(rmax) {
|
||||||
sb.WriteString(httpDefault)
|
sb.WriteString(serverconfs[r].Default)
|
||||||
case '2':
|
|
||||||
sb.WriteString(wsDefault)
|
|
||||||
case '3':
|
|
||||||
sb.WriteString(wsReverseDefault)
|
|
||||||
case '4':
|
|
||||||
sb.WriteString(pprofDefault)
|
|
||||||
case '5':
|
|
||||||
sb.WriteString(lambdaDefault)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ = os.WriteFile("config.yml", []byte(sb.String()), 0o644)
|
_ = os.WriteFile("config.yml", []byte(sb.String()), 0o644)
|
||||||
fmt.Println("默认配置文件已生成,请修改 config.yml 后重新启动!")
|
fmt.Println("默认配置文件已生成,请修改 config.yml 后重新启动!")
|
||||||
_, _ = input.ReadString('\n')
|
_, _ = input.ReadString('\n')
|
||||||
}
|
}
|
||||||
|
|
||||||
const httpDefault = ` # HTTP 通信设置
|
|
||||||
- http:
|
|
||||||
# 服务端监听地址
|
|
||||||
host: 127.0.0.1
|
|
||||||
# 服务端监听端口
|
|
||||||
port: 5700
|
|
||||||
# 反向HTTP超时时间, 单位秒
|
|
||||||
# 最小值为5,小于5将会忽略本项设置
|
|
||||||
timeout: 5
|
|
||||||
# 长轮询拓展
|
|
||||||
long-polling:
|
|
||||||
# 是否开启
|
|
||||||
enabled: false
|
|
||||||
# 消息队列大小,0 表示不限制队列大小,谨慎使用
|
|
||||||
max-queue-size: 2000
|
|
||||||
middlewares:
|
|
||||||
<<: *default # 引用默认中间件
|
|
||||||
# 反向HTTP POST地址列表
|
|
||||||
post:
|
|
||||||
#- url: '' # 地址
|
|
||||||
# secret: '' # 密钥
|
|
||||||
#- url: http://127.0.0.1:5701/ # 地址
|
|
||||||
# secret: '' # 密钥
|
|
||||||
`
|
|
||||||
|
|
||||||
const lambdaDefault = ` # LambdaServer 配置
|
|
||||||
- lambda:
|
|
||||||
type: scf # scf: 腾讯云函数 aws: aws Lambda
|
|
||||||
middlewares:
|
|
||||||
<<: *default # 引用默认中间件
|
|
||||||
`
|
|
||||||
|
|
||||||
const wsDefault = ` # 正向WS设置
|
|
||||||
- ws:
|
|
||||||
# 正向WS服务器监听地址
|
|
||||||
host: 127.0.0.1
|
|
||||||
# 正向WS服务器监听端口
|
|
||||||
port: 6700
|
|
||||||
middlewares:
|
|
||||||
<<: *default # 引用默认中间件
|
|
||||||
`
|
|
||||||
|
|
||||||
const wsReverseDefault = ` # 反向WS设置
|
|
||||||
- ws-reverse:
|
|
||||||
# 反向WS Universal 地址
|
|
||||||
# 注意 设置了此项地址后下面两项将会被忽略
|
|
||||||
universal: ws://your_websocket_universal.server
|
|
||||||
# 反向WS API 地址
|
|
||||||
api: ws://your_websocket_api.server
|
|
||||||
# 反向WS Event 地址
|
|
||||||
event: ws://your_websocket_event.server
|
|
||||||
# 重连间隔 单位毫秒
|
|
||||||
reconnect-interval: 3000
|
|
||||||
middlewares:
|
|
||||||
<<: *default # 引用默认中间件
|
|
||||||
`
|
|
||||||
|
|
||||||
const pprofDefault = ` # pprof 性能分析服务器, 一般情况下不需要启用.
|
|
||||||
# 如果遇到性能问题请上传报告给开发者处理
|
|
||||||
# 注意: pprof服务不支持中间件、不支持鉴权. 请不要开放到公网
|
|
||||||
- pprof:
|
|
||||||
# pprof服务器监听地址
|
|
||||||
host: 127.0.0.1
|
|
||||||
# pprof服务器监听端口
|
|
||||||
port: 7700
|
|
||||||
`
|
|
||||||
|
@ -16,9 +16,33 @@ import (
|
|||||||
"github.com/Mrs4s/go-cqhttp/modules/servers"
|
"github.com/Mrs4s/go-cqhttp/modules/servers"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const pprofDefault = ` # pprof 性能分析服务器, 一般情况下不需要启用.
|
||||||
|
# 如果遇到性能问题请上传报告给开发者处理
|
||||||
|
# 注意: pprof服务不支持中间件、不支持鉴权. 请不要开放到公网
|
||||||
|
- pprof:
|
||||||
|
# pprof服务器监听地址
|
||||||
|
host: 127.0.0.1
|
||||||
|
# pprof服务器监听端口
|
||||||
|
port: 7700
|
||||||
|
`
|
||||||
|
|
||||||
|
// pprofServer pprof性能分析服务器相关配置
|
||||||
|
type pprofServer struct {
|
||||||
|
Disabled bool `yaml:"disabled"`
|
||||||
|
Host string `yaml:"host"`
|
||||||
|
Port int `yaml:"port"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
config.AddServer(&config.Server{
|
||||||
|
Brief: "pprof 性能分析服务器",
|
||||||
|
Default: pprofDefault,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
// runPprof 启动 pprof 性能分析服务器
|
// runPprof 启动 pprof 性能分析服务器
|
||||||
func runPprof(_ *coolq.CQBot, node yaml.Node) {
|
func runPprof(_ *coolq.CQBot, node yaml.Node) {
|
||||||
var conf config.PprofServer
|
var conf pprofServer
|
||||||
switch err := node.Decode(&conf); {
|
switch err := node.Decode(&conf); {
|
||||||
case err != nil:
|
case err != nil:
|
||||||
log.Warn("读取pprof配置失败 :", err)
|
log.Warn("读取pprof配置失败 :", err)
|
||||||
|
@ -8,7 +8,10 @@ import (
|
|||||||
"github.com/Mrs4s/go-cqhttp/internal/base"
|
"github.com/Mrs4s/go-cqhttp/internal/base"
|
||||||
)
|
)
|
||||||
|
|
||||||
var svr = make(map[string]func(*coolq.CQBot, yaml.Node))
|
var (
|
||||||
|
svr = make(map[string]func(*coolq.CQBot, yaml.Node))
|
||||||
|
nocfgsvr = make(map[string]func(*coolq.CQBot))
|
||||||
|
)
|
||||||
|
|
||||||
// Register 注册 Server
|
// Register 注册 Server
|
||||||
func Register(name string, proc func(*coolq.CQBot, yaml.Node)) {
|
func Register(name string, proc func(*coolq.CQBot, yaml.Node)) {
|
||||||
@ -19,6 +22,15 @@ func Register(name string, proc func(*coolq.CQBot, yaml.Node)) {
|
|||||||
svr[name] = proc
|
svr[name] = proc
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// RegisterCustom 注册无需 config 的自定义 Server
|
||||||
|
func RegisterCustom(name string, proc func(*coolq.CQBot)) {
|
||||||
|
_, ok := nocfgsvr[name]
|
||||||
|
if ok {
|
||||||
|
panic(name + " server has existed")
|
||||||
|
}
|
||||||
|
nocfgsvr[name] = proc
|
||||||
|
}
|
||||||
|
|
||||||
// Run 运行所有svr
|
// Run 运行所有svr
|
||||||
func Run(bot *coolq.CQBot) {
|
func Run(bot *coolq.CQBot) {
|
||||||
for _, l := range base.Servers {
|
for _, l := range base.Servers {
|
||||||
@ -28,4 +40,7 @@ func Run(bot *coolq.CQBot) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
for _, fn := range nocfgsvr {
|
||||||
|
go fn(bot)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -24,11 +24,30 @@ import (
|
|||||||
|
|
||||||
"github.com/Mrs4s/go-cqhttp/coolq"
|
"github.com/Mrs4s/go-cqhttp/coolq"
|
||||||
"github.com/Mrs4s/go-cqhttp/global"
|
"github.com/Mrs4s/go-cqhttp/global"
|
||||||
|
"github.com/Mrs4s/go-cqhttp/internal/param"
|
||||||
"github.com/Mrs4s/go-cqhttp/modules/api"
|
"github.com/Mrs4s/go-cqhttp/modules/api"
|
||||||
"github.com/Mrs4s/go-cqhttp/modules/config"
|
"github.com/Mrs4s/go-cqhttp/modules/config"
|
||||||
"github.com/Mrs4s/go-cqhttp/modules/filter"
|
"github.com/Mrs4s/go-cqhttp/modules/filter"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// HTTPServer HTTP通信相关配置
|
||||||
|
type HTTPServer struct {
|
||||||
|
Disabled bool `yaml:"disabled"`
|
||||||
|
Host string `yaml:"host"`
|
||||||
|
Port int `yaml:"port"`
|
||||||
|
Timeout int32 `yaml:"timeout"`
|
||||||
|
LongPolling struct {
|
||||||
|
Enabled bool `yaml:"enabled"`
|
||||||
|
MaxQueueSize int `yaml:"max-queue-size"`
|
||||||
|
} `yaml:"long-polling"`
|
||||||
|
Post []struct {
|
||||||
|
URL string `yaml:"url"`
|
||||||
|
Secret string `yaml:"secret"`
|
||||||
|
}
|
||||||
|
|
||||||
|
MiddleWares `yaml:"middlewares"`
|
||||||
|
}
|
||||||
|
|
||||||
type httpServer struct {
|
type httpServer struct {
|
||||||
HTTP *http.Server
|
HTTP *http.Server
|
||||||
api *api.Caller
|
api *api.Caller
|
||||||
@ -51,6 +70,68 @@ type httpCtx struct {
|
|||||||
postForm url.Values
|
postForm url.Values
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const httpDefault = ` # HTTP 通信设置
|
||||||
|
- http:
|
||||||
|
# 服务端监听地址
|
||||||
|
host: 127.0.0.1
|
||||||
|
# 服务端监听端口
|
||||||
|
port: 5700
|
||||||
|
# 反向HTTP超时时间, 单位秒
|
||||||
|
# 最小值为5,小于5将会忽略本项设置
|
||||||
|
timeout: 5
|
||||||
|
# 长轮询拓展
|
||||||
|
long-polling:
|
||||||
|
# 是否开启
|
||||||
|
enabled: false
|
||||||
|
# 消息队列大小,0 表示不限制队列大小,谨慎使用
|
||||||
|
max-queue-size: 2000
|
||||||
|
middlewares:
|
||||||
|
<<: *default # 引用默认中间件
|
||||||
|
# 反向HTTP POST地址列表
|
||||||
|
post:
|
||||||
|
#- url: '' # 地址
|
||||||
|
# secret: '' # 密钥
|
||||||
|
#- url: http://127.0.0.1:5701/ # 地址
|
||||||
|
# secret: '' # 密钥
|
||||||
|
`
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
config.AddServer(&config.Server{
|
||||||
|
Brief: "HTTP通信",
|
||||||
|
Default: httpDefault,
|
||||||
|
ParseEnv: func() (string, *yaml.Node) {
|
||||||
|
if os.Getenv("GCQ_HTTP_PORT") != "" {
|
||||||
|
// type convert tools
|
||||||
|
toInt64 := func(str string) int64 {
|
||||||
|
i, _ := strconv.ParseInt(str, 10, 64)
|
||||||
|
return i
|
||||||
|
}
|
||||||
|
accessTokenEnv := os.Getenv("GCQ_ACCESS_TOKEN")
|
||||||
|
node := &yaml.Node{}
|
||||||
|
httpConf := &HTTPServer{
|
||||||
|
Host: "0.0.0.0",
|
||||||
|
Port: 5700,
|
||||||
|
MiddleWares: MiddleWares{
|
||||||
|
AccessToken: accessTokenEnv,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
param.SetExcludeDefault(&httpConf.Disabled, param.EnsureBool(os.Getenv("GCQ_HTTP_DISABLE"), false), false)
|
||||||
|
param.SetExcludeDefault(&httpConf.Host, os.Getenv("GCQ_HTTP_HOST"), "")
|
||||||
|
param.SetExcludeDefault(&httpConf.Port, int(toInt64(os.Getenv("GCQ_HTTP_PORT"))), 0)
|
||||||
|
if os.Getenv("GCQ_HTTP_POST_URL") != "" {
|
||||||
|
httpConf.Post = append(httpConf.Post, struct {
|
||||||
|
URL string `yaml:"url"`
|
||||||
|
Secret string `yaml:"secret"`
|
||||||
|
}{os.Getenv("GCQ_HTTP_POST_URL"), os.Getenv("GCQ_HTTP_POST_SECRET")})
|
||||||
|
}
|
||||||
|
_ = node.Encode(httpConf)
|
||||||
|
return "http", node
|
||||||
|
}
|
||||||
|
return "", nil
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
func (h *httpCtx) Get(s string) gjson.Result {
|
func (h *httpCtx) Get(s string) gjson.Result {
|
||||||
j := h.json.Get(s)
|
j := h.json.Get(s)
|
||||||
if j.Exists() {
|
if j.Exists() {
|
||||||
@ -163,7 +244,7 @@ func checkAuth(req *http.Request, token string) int {
|
|||||||
|
|
||||||
// runHTTP 启动HTTP服务器与HTTP上报客户端
|
// runHTTP 启动HTTP服务器与HTTP上报客户端
|
||||||
func runHTTP(bot *coolq.CQBot, node yaml.Node) {
|
func runHTTP(bot *coolq.CQBot, node yaml.Node) {
|
||||||
var conf config.HTTPServer
|
var conf HTTPServer
|
||||||
switch err := node.Decode(&conf); {
|
switch err := node.Decode(&conf); {
|
||||||
case err != nil:
|
case err != nil:
|
||||||
log.Warn("读取http配置失败 :", err)
|
log.Warn("读取http配置失败 :", err)
|
||||||
|
@ -13,6 +13,17 @@ import (
|
|||||||
"golang.org/x/time/rate"
|
"golang.org/x/time/rate"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// MiddleWares 通信中间件
|
||||||
|
type MiddleWares struct {
|
||||||
|
AccessToken string `yaml:"access-token"`
|
||||||
|
Filter string `yaml:"filter"`
|
||||||
|
RateLimit struct {
|
||||||
|
Enabled bool `yaml:"enabled"`
|
||||||
|
Frequency float64 `yaml:"frequency"`
|
||||||
|
Bucket int `yaml:"bucket"`
|
||||||
|
} `yaml:"rate-limit"`
|
||||||
|
}
|
||||||
|
|
||||||
func rateLimit(frequency float64, bucketSize int) api.Handler {
|
func rateLimit(frequency float64, bucketSize int) api.Handler {
|
||||||
limiter := rate.NewLimiter(rate.Limit(frequency), bucketSize)
|
limiter := rate.NewLimiter(rate.Limit(frequency), bucketSize)
|
||||||
return func(_ string, _ api.Getter) global.MSG {
|
return func(_ string, _ api.Getter) global.MSG {
|
||||||
|
@ -81,7 +81,7 @@ var cli *lambdaClient
|
|||||||
|
|
||||||
// runLambda type: [scf,aws]
|
// runLambda type: [scf,aws]
|
||||||
func runLambda(bot *coolq.CQBot, node yaml.Node) {
|
func runLambda(bot *coolq.CQBot, node yaml.Node) {
|
||||||
var conf config.LambdaServer
|
var conf LambdaServer
|
||||||
switch err := node.Decode(&conf); {
|
switch err := node.Decode(&conf); {
|
||||||
case err != nil:
|
case err != nil:
|
||||||
log.Warn("读取lambda配置失败 :", err)
|
log.Warn("读取lambda配置失败 :", err)
|
||||||
@ -155,6 +155,28 @@ type lambdaInvoke struct {
|
|||||||
} `json:"requestContext"`
|
} `json:"requestContext"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const lambdaDefault = ` # LambdaServer 配置
|
||||||
|
- lambda:
|
||||||
|
type: scf # scf: 腾讯云函数 aws: aws Lambda
|
||||||
|
middlewares:
|
||||||
|
<<: *default # 引用默认中间件
|
||||||
|
`
|
||||||
|
|
||||||
|
// LambdaServer 云函数配置
|
||||||
|
type LambdaServer struct {
|
||||||
|
Disabled bool `yaml:"disabled"`
|
||||||
|
Type string `yaml:"type"`
|
||||||
|
|
||||||
|
MiddleWares `yaml:"middlewares"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
config.AddServer(&config.Server{
|
||||||
|
Brief: "云函数服务",
|
||||||
|
Default: lambdaDefault,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
func (c *lambdaClient) next() *http.Request {
|
func (c *lambdaClient) next() *http.Request {
|
||||||
r, err := http.NewRequest(http.MethodGet, c.nextURL, nil)
|
r, err := http.NewRequest(http.MethodGet, c.nextURL, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -5,6 +5,7 @@ import (
|
|||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"os"
|
||||||
"runtime/debug"
|
"runtime/debug"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
@ -19,6 +20,7 @@ import (
|
|||||||
|
|
||||||
"github.com/Mrs4s/go-cqhttp/coolq"
|
"github.com/Mrs4s/go-cqhttp/coolq"
|
||||||
"github.com/Mrs4s/go-cqhttp/global"
|
"github.com/Mrs4s/go-cqhttp/global"
|
||||||
|
"github.com/Mrs4s/go-cqhttp/internal/param"
|
||||||
"github.com/Mrs4s/go-cqhttp/modules/api"
|
"github.com/Mrs4s/go-cqhttp/modules/api"
|
||||||
"github.com/Mrs4s/go-cqhttp/modules/config"
|
"github.com/Mrs4s/go-cqhttp/modules/config"
|
||||||
"github.com/Mrs4s/go-cqhttp/modules/filter"
|
"github.com/Mrs4s/go-cqhttp/modules/filter"
|
||||||
@ -26,7 +28,7 @@ import (
|
|||||||
|
|
||||||
type webSocketServer struct {
|
type webSocketServer struct {
|
||||||
bot *coolq.CQBot
|
bot *coolq.CQBot
|
||||||
conf *config.WebsocketServer
|
conf *WebsocketServer
|
||||||
|
|
||||||
mu sync.Mutex
|
mu sync.Mutex
|
||||||
eventConn []*wsConn
|
eventConn []*wsConn
|
||||||
@ -71,9 +73,107 @@ var upgrader = websocket.Upgrader{
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const wsDefault = ` # 正向WS设置
|
||||||
|
- ws:
|
||||||
|
# 正向WS服务器监听地址
|
||||||
|
host: 127.0.0.1
|
||||||
|
# 正向WS服务器监听端口
|
||||||
|
port: 6700
|
||||||
|
middlewares:
|
||||||
|
<<: *default # 引用默认中间件
|
||||||
|
`
|
||||||
|
|
||||||
|
const wsReverseDefault = ` # 反向WS设置
|
||||||
|
- ws-reverse:
|
||||||
|
# 反向WS Universal 地址
|
||||||
|
# 注意 设置了此项地址后下面两项将会被忽略
|
||||||
|
universal: ws://your_websocket_universal.server
|
||||||
|
# 反向WS API 地址
|
||||||
|
api: ws://your_websocket_api.server
|
||||||
|
# 反向WS Event 地址
|
||||||
|
event: ws://your_websocket_event.server
|
||||||
|
# 重连间隔 单位毫秒
|
||||||
|
reconnect-interval: 3000
|
||||||
|
middlewares:
|
||||||
|
<<: *default # 引用默认中间件
|
||||||
|
`
|
||||||
|
|
||||||
|
// WebsocketServer 正向WS相关配置
|
||||||
|
type WebsocketServer struct {
|
||||||
|
Disabled bool `yaml:"disabled"`
|
||||||
|
Host string `yaml:"host"`
|
||||||
|
Port int `yaml:"port"`
|
||||||
|
|
||||||
|
MiddleWares `yaml:"middlewares"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// WebsocketReverse 反向WS相关配置
|
||||||
|
type WebsocketReverse struct {
|
||||||
|
Disabled bool `yaml:"disabled"`
|
||||||
|
Universal string `yaml:"universal"`
|
||||||
|
API string `yaml:"api"`
|
||||||
|
Event string `yaml:"event"`
|
||||||
|
ReconnectInterval int `yaml:"reconnect-interval"`
|
||||||
|
|
||||||
|
MiddleWares `yaml:"middlewares"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
config.AddServer(&config.Server{
|
||||||
|
Brief: "正向 Websocket 通信",
|
||||||
|
Default: wsDefault,
|
||||||
|
ParseEnv: func() (string, *yaml.Node) {
|
||||||
|
if os.Getenv("GCQ_WS_PORT") != "" {
|
||||||
|
// type convert tools
|
||||||
|
toInt64 := func(str string) int64 {
|
||||||
|
i, _ := strconv.ParseInt(str, 10, 64)
|
||||||
|
return i
|
||||||
|
}
|
||||||
|
accessTokenEnv := os.Getenv("GCQ_ACCESS_TOKEN")
|
||||||
|
node := &yaml.Node{}
|
||||||
|
wsServerConf := &WebsocketServer{
|
||||||
|
Host: "0.0.0.0",
|
||||||
|
Port: 6700,
|
||||||
|
MiddleWares: MiddleWares{
|
||||||
|
AccessToken: accessTokenEnv,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
param.SetExcludeDefault(&wsServerConf.Disabled, param.EnsureBool(os.Getenv("GCQ_WS_DISABLE"), false), false)
|
||||||
|
param.SetExcludeDefault(&wsServerConf.Host, os.Getenv("GCQ_WS_HOST"), "")
|
||||||
|
param.SetExcludeDefault(&wsServerConf.Port, int(toInt64(os.Getenv("GCQ_WS_PORT"))), 0)
|
||||||
|
_ = node.Encode(wsServerConf)
|
||||||
|
return "ws", node
|
||||||
|
}
|
||||||
|
return "", nil
|
||||||
|
},
|
||||||
|
})
|
||||||
|
config.AddServer(&config.Server{
|
||||||
|
Brief: "反向 Websocket 通信",
|
||||||
|
Default: wsReverseDefault,
|
||||||
|
ParseEnv: func() (string, *yaml.Node) {
|
||||||
|
if os.Getenv("GCQ_RWS_API") != "" || os.Getenv("GCQ_RWS_EVENT") != "" || os.Getenv("GCQ_RWS_UNIVERSAL") != "" {
|
||||||
|
accessTokenEnv := os.Getenv("GCQ_ACCESS_TOKEN")
|
||||||
|
node := &yaml.Node{}
|
||||||
|
rwsConf := &WebsocketReverse{
|
||||||
|
MiddleWares: MiddleWares{
|
||||||
|
AccessToken: accessTokenEnv,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
param.SetExcludeDefault(&rwsConf.Disabled, param.EnsureBool(os.Getenv("GCQ_RWS_DISABLE"), false), false)
|
||||||
|
param.SetExcludeDefault(&rwsConf.API, os.Getenv("GCQ_RWS_API"), "")
|
||||||
|
param.SetExcludeDefault(&rwsConf.Event, os.Getenv("GCQ_RWS_EVENT"), "")
|
||||||
|
param.SetExcludeDefault(&rwsConf.Universal, os.Getenv("GCQ_RWS_UNIVERSAL"), "")
|
||||||
|
_ = node.Encode(rwsConf)
|
||||||
|
return "ws-reverse", node
|
||||||
|
}
|
||||||
|
return "", nil
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
// runWSServer 运行一个正向WS server
|
// runWSServer 运行一个正向WS server
|
||||||
func runWSServer(b *coolq.CQBot, node yaml.Node) {
|
func runWSServer(b *coolq.CQBot, node yaml.Node) {
|
||||||
var conf config.WebsocketServer
|
var conf WebsocketServer
|
||||||
switch err := node.Decode(&conf); {
|
switch err := node.Decode(&conf); {
|
||||||
case err != nil:
|
case err != nil:
|
||||||
log.Warn("读取正向Websocket配置失败 :", err)
|
log.Warn("读取正向Websocket配置失败 :", err)
|
||||||
@ -103,7 +203,7 @@ func runWSServer(b *coolq.CQBot, node yaml.Node) {
|
|||||||
|
|
||||||
// runWSClient 运行一个反向向WS client
|
// runWSClient 运行一个反向向WS client
|
||||||
func runWSClient(b *coolq.CQBot, node yaml.Node) {
|
func runWSClient(b *coolq.CQBot, node yaml.Node) {
|
||||||
var conf config.WebsocketReverse
|
var conf WebsocketReverse
|
||||||
switch err := node.Decode(&conf); {
|
switch err := node.Decode(&conf); {
|
||||||
case err != nil:
|
case err != nil:
|
||||||
log.Warn("读取反向Websocket配置失败 :", err)
|
log.Warn("读取反向Websocket配置失败 :", err)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user