channel.go 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. package service
  2. import (
  3. "fmt"
  4. "net/http"
  5. "one-api/common"
  6. "one-api/dto"
  7. "one-api/model"
  8. "one-api/setting/operation_setting"
  9. "strings"
  10. )
  11. func formatNotifyType(channelId int, status int) string {
  12. return fmt.Sprintf("%s_%d_%d", dto.NotifyTypeChannelUpdate, channelId, status)
  13. }
  14. // disable & notify
  15. func DisableChannel(channelId int, channelName string, reason string) {
  16. success := model.UpdateChannelStatusById(channelId, common.ChannelStatusAutoDisabled, reason)
  17. if success {
  18. subject := fmt.Sprintf("通道「%s」(#%d)已被禁用", channelName, channelId)
  19. content := fmt.Sprintf("通道「%s」(#%d)已被禁用,原因:%s", channelName, channelId, reason)
  20. NotifyRootUser(formatNotifyType(channelId, common.ChannelStatusAutoDisabled), subject, content)
  21. }
  22. }
  23. func EnableChannel(channelId int, channelName string) {
  24. success := model.UpdateChannelStatusById(channelId, common.ChannelStatusEnabled, "")
  25. if success {
  26. subject := fmt.Sprintf("通道「%s」(#%d)已被启用", channelName, channelId)
  27. content := fmt.Sprintf("通道「%s」(#%d)已被启用", channelName, channelId)
  28. NotifyRootUser(formatNotifyType(channelId, common.ChannelStatusEnabled), subject, content)
  29. }
  30. }
  31. func ShouldDisableChannel(channelType int, err *dto.OpenAIErrorWithStatusCode) bool {
  32. if !common.AutomaticDisableChannelEnabled {
  33. return false
  34. }
  35. if err == nil {
  36. return false
  37. }
  38. if err.LocalError {
  39. return false
  40. }
  41. if err.StatusCode == http.StatusUnauthorized {
  42. return true
  43. }
  44. if err.StatusCode == http.StatusForbidden {
  45. switch channelType {
  46. case common.ChannelTypeGemini:
  47. return true
  48. }
  49. }
  50. switch err.Error.Code {
  51. case "invalid_api_key":
  52. return true
  53. case "account_deactivated":
  54. return true
  55. case "billing_not_active":
  56. return true
  57. case "pre_consume_token_quota_failed":
  58. return true
  59. }
  60. switch err.Error.Type {
  61. case "insufficient_quota":
  62. return true
  63. case "insufficient_user_quota":
  64. return true
  65. // https://docs.anthropic.com/claude/reference/errors
  66. case "authentication_error":
  67. return true
  68. case "permission_error":
  69. return true
  70. case "forbidden":
  71. return true
  72. }
  73. lowerMessage := strings.ToLower(err.Error.Message)
  74. search, _ := AcSearch(lowerMessage, operation_setting.AutomaticDisableKeywords, true)
  75. if search {
  76. return true
  77. }
  78. return false
  79. }
  80. func ShouldEnableChannel(err error, openaiWithStatusErr *dto.OpenAIErrorWithStatusCode, status int) bool {
  81. if !common.AutomaticEnableChannelEnabled {
  82. return false
  83. }
  84. if err != nil {
  85. return false
  86. }
  87. if openaiWithStatusErr != nil {
  88. return false
  89. }
  90. if status != common.ChannelStatusAutoDisabled {
  91. return false
  92. }
  93. return true
  94. }