config.go 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278
  1. package config
  2. import (
  3. "fmt"
  4. "log"
  5. "os"
  6. "strconv"
  7. "strings"
  8. "sync"
  9. "time"
  10. "gopkg.in/yaml.v3"
  11. "github.com/eryajf/chatgpt-dingtalk/pkg/logger"
  12. )
  13. type Credential struct {
  14. ClientID string `yaml:"client_id"`
  15. ClientSecret string `yaml:"client_secret"`
  16. }
  17. // Configuration 项目配置
  18. type Configuration struct {
  19. // 日志级别,info或者debug
  20. LogLevel string `yaml:"log_level"`
  21. // gpt apikey
  22. ApiKey string `yaml:"api_key"`
  23. // 运行模式
  24. RunMode string `yaml:"run_mode"`
  25. // 请求的 URL 地址
  26. BaseURL string `yaml:"base_url"`
  27. // 使用模型
  28. Model string `yaml:"model"`
  29. // 使用绘画模型
  30. ImageModel string `yaml:"image_model"`
  31. // 会话超时时间
  32. SessionTimeout time.Duration `yaml:"session_timeout"`
  33. // 最大问题长度
  34. MaxQuestionLen int `yaml:"max_question_len"`
  35. // 最大答案长度
  36. MaxAnswerLen int `yaml:"max_answer_len"`
  37. // 最大文本 = 问题 + 回答, 接口限制
  38. MaxText int `yaml:"max_text"`
  39. // 默认对话模式
  40. DefaultMode string `yaml:"default_mode"`
  41. // 代理地址
  42. HttpProxy string `yaml:"http_proxy"`
  43. // 用户单日最大请求次数
  44. MaxRequest int `yaml:"max_request"`
  45. // 指定服务启动端口,默认为 8090
  46. Port string `yaml:"port"`
  47. // 指定服务的地址,就是钉钉机器人配置的回调地址,比如: http://chat.eryajf.net
  48. ServiceURL string `yaml:"service_url"`
  49. // 限定对话类型 0:不限 1:单聊 2:群聊
  50. ChatType string `yaml:"chat_type"`
  51. // 哪些群组可以进行对话
  52. AllowGroups []string `yaml:"allow_groups"`
  53. // 哪些outgoing群组可以进行对话
  54. AllowOutgoingGroups []string `yaml:"allow_outgoing_groups"`
  55. // 哪些用户可以进行对话
  56. AllowUsers []string `yaml:"allow_users"`
  57. // 哪些用户不可以进行对话
  58. DenyUsers []string `yaml:"deny_users"`
  59. // 哪些Vip用户可以进行无限对话
  60. VipUsers []string `yaml:"vip_users"`
  61. // 指定哪些人为此系统的管理员,必须指定,否则所有人都是
  62. AdminUsers []string `yaml:"admin_users"`
  63. // 钉钉机器人在应用信息中的AppSecret,为了校验回调的请求是否合法,如果你的服务对接给多个机器人,这里可以配置多个机器人的secret
  64. AppSecrets []string `yaml:"app_secrets"`
  65. // 敏感词,提问时触发,则不允许提问,回答的内容中触发,则以 🚫 代替
  66. SensitiveWords []string `yaml:"sensitive_words"`
  67. // 自定义帮助信息
  68. Help string `yaml:"help"`
  69. // AzureOpenAI 配置
  70. AzureOn bool `yaml:"azure_on"`
  71. AzureApiVersion string `yaml:"azure_api_version"`
  72. AzureResourceName string `yaml:"azure_resource_name"`
  73. AzureDeploymentName string `yaml:"azure_deployment_name"`
  74. AzureOpenAIToken string `yaml:"azure_openai_token"`
  75. // 钉钉应用鉴权凭据
  76. Credentials []Credential `yaml:"credentials"`
  77. }
  78. var (
  79. config *Configuration
  80. once sync.Once
  81. )
  82. // LoadConfig 加载配置
  83. func LoadConfig() *Configuration {
  84. once.Do(func() {
  85. // 从文件中读取
  86. config = &Configuration{}
  87. data, err := os.ReadFile("config.yml")
  88. if err != nil {
  89. log.Fatal(err)
  90. }
  91. err = yaml.Unmarshal(data, &config)
  92. if err != nil {
  93. log.Fatal(err)
  94. }
  95. // 如果环境变量有配置,读取环境变量
  96. logLevel := os.Getenv("LOG_LEVEL")
  97. if logLevel != "" {
  98. config.LogLevel = logLevel
  99. }
  100. apiKey := os.Getenv("APIKEY")
  101. if apiKey != "" {
  102. config.ApiKey = apiKey
  103. }
  104. runMode := os.Getenv("RUN_MODE")
  105. if runMode != "" {
  106. config.RunMode = runMode
  107. }
  108. baseURL := os.Getenv("BASE_URL")
  109. if baseURL != "" {
  110. config.BaseURL = baseURL
  111. }
  112. model := os.Getenv("MODEL")
  113. if model != "" {
  114. config.Model = model
  115. }
  116. sessionTimeout := os.Getenv("SESSION_TIMEOUT")
  117. if sessionTimeout != "" {
  118. duration, err := strconv.ParseInt(sessionTimeout, 10, 64)
  119. if err != nil {
  120. logger.Fatal(fmt.Sprintf("config session timeout err: %v ,get is %v", err, sessionTimeout))
  121. return
  122. }
  123. config.SessionTimeout = time.Duration(duration) * time.Second
  124. } else {
  125. config.SessionTimeout = time.Duration(config.SessionTimeout) * time.Second
  126. }
  127. maxQuestionLen := os.Getenv("MAX_QUESTION_LEN")
  128. if maxQuestionLen != "" {
  129. newLen, _ := strconv.Atoi(maxQuestionLen)
  130. config.MaxQuestionLen = newLen
  131. }
  132. maxAnswerLen := os.Getenv("MAX_ANSWER_LEN")
  133. if maxAnswerLen != "" {
  134. newLen, _ := strconv.Atoi(maxAnswerLen)
  135. config.MaxAnswerLen = newLen
  136. }
  137. maxText := os.Getenv("MAX_TEXT")
  138. if maxText != "" {
  139. newLen, _ := strconv.Atoi(maxText)
  140. config.MaxText = newLen
  141. }
  142. defaultMode := os.Getenv("DEFAULT_MODE")
  143. if defaultMode != "" {
  144. config.DefaultMode = defaultMode
  145. }
  146. httpProxy := os.Getenv("HTTP_PROXY")
  147. if httpProxy != "" {
  148. config.HttpProxy = httpProxy
  149. }
  150. maxRequest := os.Getenv("MAX_REQUEST")
  151. if maxRequest != "" {
  152. newMR, _ := strconv.Atoi(maxRequest)
  153. config.MaxRequest = newMR
  154. }
  155. port := os.Getenv("PORT")
  156. if port != "" {
  157. config.Port = port
  158. }
  159. serviceURL := os.Getenv("SERVICE_URL")
  160. if serviceURL != "" {
  161. config.ServiceURL = serviceURL
  162. }
  163. chatType := os.Getenv("CHAT_TYPE")
  164. if chatType != "" {
  165. config.ChatType = chatType
  166. }
  167. allowGroups := os.Getenv("ALLOW_GROUPS")
  168. if allowGroups != "" {
  169. config.AllowGroups = strings.Split(allowGroups, ",")
  170. }
  171. allowOutgoingGroups := os.Getenv("ALLOW_OUTGOING_GROUPS")
  172. if allowOutgoingGroups != "" {
  173. config.AllowOutgoingGroups = strings.Split(allowOutgoingGroups, ",")
  174. }
  175. allowUsers := os.Getenv("ALLOW_USERS")
  176. if allowUsers != "" {
  177. config.AllowUsers = strings.Split(allowUsers, ",")
  178. }
  179. denyUsers := os.Getenv("DENY_USERS")
  180. if denyUsers != "" {
  181. config.DenyUsers = strings.Split(denyUsers, ",")
  182. }
  183. vipUsers := os.Getenv("VIP_USERS")
  184. if vipUsers != "" {
  185. config.VipUsers = strings.Split(vipUsers, ",")
  186. }
  187. adminUsers := os.Getenv("ADMIN_USERS")
  188. if adminUsers != "" {
  189. config.AdminUsers = strings.Split(adminUsers, ",")
  190. }
  191. appSecrets := os.Getenv("APP_SECRETS")
  192. if appSecrets != "" {
  193. config.AppSecrets = strings.Split(appSecrets, ",")
  194. }
  195. sensitiveWords := os.Getenv("SENSITIVE_WORDS")
  196. if sensitiveWords != "" {
  197. config.SensitiveWords = strings.Split(sensitiveWords, ",")
  198. }
  199. help := os.Getenv("HELP")
  200. if help != "" {
  201. config.Help = help
  202. }
  203. azureOn := os.Getenv("AZURE_ON")
  204. if azureOn != "" {
  205. config.AzureOn = azureOn == "true"
  206. }
  207. azureApiVersion := os.Getenv("AZURE_API_VERSION")
  208. if azureApiVersion != "" {
  209. config.AzureApiVersion = azureApiVersion
  210. }
  211. azureResourceName := os.Getenv("AZURE_RESOURCE_NAME")
  212. if azureResourceName != "" {
  213. config.AzureResourceName = azureResourceName
  214. }
  215. azureDeploymentName := os.Getenv("AZURE_DEPLOYMENT_NAME")
  216. if azureDeploymentName != "" {
  217. config.AzureDeploymentName = azureDeploymentName
  218. }
  219. azureOpenaiToken := os.Getenv("AZURE_OPENAI_TOKEN")
  220. if azureOpenaiToken != "" {
  221. config.AzureOpenAIToken = azureOpenaiToken
  222. }
  223. credentials := os.Getenv("DINGTALK_CREDENTIALS")
  224. if credentials != "" {
  225. config.Credentials = []Credential{}
  226. for _, idSecret := range strings.Split(credentials, ",") {
  227. items := strings.SplitN(idSecret, ":", 2)
  228. if len(items) == 2 {
  229. config.Credentials = append(config.Credentials, Credential{ClientID: items[0], ClientSecret: items[1]})
  230. }
  231. }
  232. }
  233. })
  234. // 一些默认值
  235. if config.LogLevel == "" {
  236. config.LogLevel = "info"
  237. }
  238. if config.RunMode == "" {
  239. config.RunMode = "http"
  240. }
  241. if config.Model == "" {
  242. config.Model = "gpt-3.5-turbo"
  243. }
  244. if config.DefaultMode == "" {
  245. config.DefaultMode = "单聊"
  246. }
  247. if config.Port == "" {
  248. config.Port = "8090"
  249. }
  250. if config.ChatType == "" {
  251. config.ChatType = "0"
  252. }
  253. if !config.AzureOn {
  254. if config.ApiKey == "" {
  255. panic("config err: api key required")
  256. }
  257. }
  258. if config.MaxQuestionLen == 0 {
  259. config.MaxQuestionLen = 4096
  260. }
  261. if config.MaxAnswerLen == 0 {
  262. config.MaxAnswerLen = 4096
  263. }
  264. if config.MaxText == 0 {
  265. config.MaxText = 4096
  266. }
  267. return config
  268. }