main.go 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. package main
  2. import (
  3. "context"
  4. "fmt"
  5. "net/http"
  6. "os"
  7. "os/signal"
  8. "path/filepath"
  9. "strings"
  10. "time"
  11. "github.com/eryajf/chatgpt-dingtalk/pkg/dingbot"
  12. "github.com/eryajf/chatgpt-dingtalk/pkg/logger"
  13. "github.com/eryajf/chatgpt-dingtalk/pkg/process"
  14. "github.com/eryajf/chatgpt-dingtalk/public"
  15. "github.com/xgfone/ship/v5"
  16. )
  17. func init() {
  18. public.InitSvc()
  19. }
  20. func main() {
  21. Start()
  22. }
  23. func Start() {
  24. app := ship.Default()
  25. app.Route("/").POST(func(c *ship.Context) error {
  26. var msgObj dingbot.ReceiveMsg
  27. err := c.Bind(&msgObj)
  28. if err != nil {
  29. return ship.ErrBadRequest.New(fmt.Errorf("bind to receivemsg failed : %v", err))
  30. }
  31. if msgObj.Text.Content == "" || msgObj.ChatbotUserID == "" {
  32. logger.Warning("从钉钉回调过来的内容为空,根据过往的经验,或许重新创建一下机器人,能解决这个问题")
  33. return ship.ErrBadRequest.New(fmt.Errorf("从钉钉回调过来的内容为空,根据过往的经验,或许重新创建一下机器人,能解决这个问题"))
  34. }
  35. // 去除问题的前后空格
  36. msgObj.Text.Content = strings.TrimSpace(msgObj.Text.Content)
  37. // 打印钉钉回调过来的请求明细
  38. logger.Info(fmt.Sprintf("dingtalk callback parameters: %#v", msgObj))
  39. // TODO: 校验请求
  40. if public.Config.ChatType != "0" && msgObj.ConversationType != public.Config.ChatType {
  41. _, err = msgObj.ReplyToDingtalk(string(dingbot.TEXT), "抱歉,管理员禁用了这种聊天方式,请选择其他聊天方式与机器人对话!")
  42. if err != nil {
  43. logger.Warning(fmt.Errorf("send message error: %v", err))
  44. return err
  45. }
  46. return nil
  47. }
  48. if len(msgObj.Text.Content) == 1 || msgObj.Text.Content == "帮助" {
  49. // 欢迎信息
  50. _, err := msgObj.ReplyToDingtalk(string(dingbot.MARKDOWN), public.Welcome)
  51. if err != nil {
  52. logger.Warning(fmt.Errorf("send message error: %v", err))
  53. return ship.ErrBadRequest.New(fmt.Errorf("send message error: %v", err))
  54. }
  55. } else {
  56. // 除去帮助之外的逻辑分流在这里处理
  57. switch {
  58. case strings.HasPrefix(msgObj.Text.Content, "#图片"):
  59. return process.ImageGenerate(&msgObj)
  60. default:
  61. msgObj.Text.Content, err = process.GeneratePrompt(msgObj.Text.Content)
  62. // err不为空:提示词之后没有文本 -> 直接返回提示词所代表的内容
  63. if err != nil {
  64. _, err = msgObj.ReplyToDingtalk(string(dingbot.TEXT), msgObj.Text.Content)
  65. if err != nil {
  66. logger.Warning(fmt.Errorf("send message error: %v", err))
  67. return err
  68. }
  69. return nil
  70. }
  71. logger.Info(fmt.Sprintf("after generate prompt: %#v", msgObj.Text.Content))
  72. return process.ProcessRequest(&msgObj)
  73. }
  74. }
  75. return nil
  76. })
  77. // 解析生成后的图片
  78. app.Route("/images/:filename").GET(func(c *ship.Context) error {
  79. filename := c.Param("filename")
  80. root := "./images/"
  81. return c.File(filepath.Join(root, filename))
  82. })
  83. port := ":" + public.Config.Port
  84. srv := &http.Server{
  85. Addr: port,
  86. Handler: app,
  87. }
  88. // Initializing the server in a goroutine so that
  89. // it won't block the graceful shutdown handling below
  90. go func() {
  91. logger.Info("🚀 The HTTP Server is running on", port)
  92. if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed {
  93. logger.Fatal("listen: %s\n", err)
  94. }
  95. }()
  96. // Wait for interrupt signal to gracefully shutdown the server with
  97. // a timeout of 5 seconds.
  98. quit := make(chan os.Signal, 1)
  99. // kill (no param) default send syscall.SIGTERM
  100. // kill -2 is syscall.SIGINT
  101. // kill -9 is syscall.SIGKILL but can't be catch, so don't need add it
  102. // signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
  103. signal.Notify(quit, os.Interrupt)
  104. <-quit
  105. logger.Info("Shutting down server...")
  106. // 5秒后强制退出
  107. ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
  108. defer cancel()
  109. if err := srv.Shutdown(ctx); err != nil {
  110. logger.Fatal("Server forced to shutdown:", err)
  111. }
  112. logger.Info("Server exiting!")
  113. }