diff --git a/api/anonymous.go b/api/anonymous.go
index 38662ad..cb0b63f 100644
--- a/api/anonymous.go
+++ b/api/anonymous.go
@@ -78,7 +78,7 @@ func GetAnonymousResponseWithCache(c *gin.Context, message string, web bool) (st
return "", "There was something wrong...", err
}
- cache.Set(c, fmt.Sprintf(":chatgpt:%s", message), utils.ToJson(AnonymousResponseCache{
+ cache.Set(c, fmt.Sprintf(":chatgpt-%v:%s", web, message), utils.ToJson(AnonymousResponseCache{
Keyword: key,
Message: res,
}), time.Hour*48)
diff --git a/api/card.go b/api/card.go
new file mode 100644
index 0000000..f1560d8
--- /dev/null
+++ b/api/card.go
@@ -0,0 +1,69 @@
+package api
+
+import (
+ "github.com/gin-gonic/gin"
+ "github.com/russross/blackfriday/v2"
+ "net/http"
+ "strings"
+)
+
+const maxColumnPerLine = 50
+
+func ProcessMarkdownLine(source []byte) string {
+ segment := strings.Split(string(source), "\n")
+ var result []rune
+ for _, line := range segment {
+ data := []rune(line)
+ length := len([]rune(line))
+ if length < maxColumnPerLine {
+ result = append(result, data...)
+ result = append(result, '\n')
+ } else {
+ for i := 0; i < length; i += maxColumnPerLine {
+ if i+maxColumnPerLine < length {
+ result = append(result, data[i:i+maxColumnPerLine]...)
+ result = append(result, '\n')
+ } else {
+ result = append(result, data[i:]...)
+ result = append(result, '\n')
+ }
+ }
+ }
+ }
+ return string(result)
+}
+
+func MarkdownConvert(text string) string {
+ if text == "" {
+ return ""
+ }
+
+ result := blackfriday.Run([]byte(text))
+ return string(result)
+}
+
+func CardAPI(c *gin.Context) {
+ var body AnonymousRequestBody
+ if err := c.ShouldBindJSON(&body); err != nil {
+ c.JSON(http.StatusBadRequest, gin.H{
+ "error": "invalid request body",
+ })
+ }
+ message := strings.TrimSpace(body.Message)
+ if len(message) == 0 {
+ c.JSON(http.StatusBadRequest, gin.H{
+ "error": "message is empty",
+ })
+ return
+ }
+
+ key, res, err := GetAnonymousResponseWithCache(c, message, body.Web)
+ if err != nil {
+ res = "There was something wrong..."
+ }
+
+ c.JSON(http.StatusOK, gin.H{
+ "message": MarkdownConvert(res),
+ "keyword": key,
+ })
+}
diff --git a/go.mod b/go.mod
index ba6cf29..6f42afd 100644
--- a/go.mod
+++ b/go.mod
@@ -36,6 +36,7 @@ require (
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/pelletier/go-toml/v2 v2.0.8 // indirect
github.com/pkoukk/tiktoken-go v0.1.5 // indirect
+ github.com/russross/blackfriday/v2 v2.1.0 // indirect
github.com/spf13/afero v1.9.5 // indirect
github.com/spf13/cast v1.5.1 // indirect
github.com/spf13/jwalterweatherman v1.1.0 // indirect
diff --git a/go.sum b/go.sum
index 65db482..0ad7135 100644
--- a/go.sum
+++ b/go.sum
@@ -203,6 +203,8 @@ github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZN
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8=
+github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk=
+github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/spf13/afero v1.9.5 h1:stMpOSZFs//0Lv29HduCmli3GUfpFoF3Y1Q/aXj/wVM=
github.com/spf13/afero v1.9.5/go.mod h1:UBogFpq8E9Hx+xc5CNTTEpTnuHVmXDwZcZcE1eb/UhQ=
github.com/spf13/cast v1.5.1 h1:R+kOtfhWQE6TVQzY+4D7wJLBgkdVasCEFxSUBYBYIlA=
diff --git a/main.go b/main.go
index 30b3105..4d388a1 100644
--- a/main.go
+++ b/main.go
@@ -24,6 +24,7 @@ func main() {
app.Use(auth.Middleware())
app.POST("/anonymous", api.AnonymousAPI)
+ app.POST("/card", api.CardAPI)
app.GET("/chat", api.ChatAPI)
app.POST("/login", auth.LoginAPI)
app.POST("/state", auth.StateAPI)
diff --git a/middleware/throttle.go b/middleware/throttle.go
index e0bf987..753739e 100644
--- a/middleware/throttle.go
+++ b/middleware/throttle.go
@@ -28,6 +28,7 @@ func (l *Limiter) RateLimit(ctx *gin.Context, rds *redis.Client, ip string, path
var limits = map[string]Limiter{
"/login": {Duration: 10, Count: 5},
"/anonymous": {Duration: 60, Count: 15},
+ "/card": {Duration: 1, Count: 5},
"/user": {Duration: 1, Count: 1},
"/package": {Duration: 1, Count: 2},
"/quota": {Duration: 1, Count: 2},
diff --git a/plugin/.gitignore b/plugin/.gitignore
new file mode 100644
index 0000000..706fd07
--- /dev/null
+++ b/plugin/.gitignore
@@ -0,0 +1,2 @@
+.idea
+.vscode
diff --git a/plugin/card.php b/plugin/card.php
new file mode 100644
index 0000000..f494e6c
--- /dev/null
+++ b/plugin/card.php
@@ -0,0 +1,109 @@
+", "
", $resp['message']));
+$msgHeight = substr_count($resp['message'], "\n") * 20 + strlen($msg) * 0.15 + substr_count($resp['message'], "
+
+
+
\ No newline at end of file
diff --git a/plugin/error.php b/plugin/error.php
new file mode 100644
index 0000000..4283d76
--- /dev/null
+++ b/plugin/error.php
@@ -0,0 +1,47 @@
+
+
+
+ Error
+ Error Card
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/plugin/favicon.ico b/plugin/favicon.ico
new file mode 100644
index 0000000..688435b
Binary files /dev/null and b/plugin/favicon.ico differ
diff --git a/plugin/utils.php b/plugin/utils.php
new file mode 100644
index 0000000..1c2f6f6
--- /dev/null
+++ b/plugin/utils.php
@@ -0,0 +1,31 @@
+[^\S ]+/', '/[^\S ]+', '/(\s)+/', '/> ', '/:\s+/', '/\{\s+/', '/\s+}/');
+ $replace = array('>', '<', '\\1', '><', ':', '{', '}');
+ return preg_replace($search, $replace, $buffer);
+}
+
+function fetch($message, $web): array|string|null
+{
+ $opts = array('http' =>
+ array(
+ 'method' => 'POST',
+ 'header' => 'Content-type: application/json',
+ 'content' => json_encode(array('message' => $message, 'web' => $web))
+ )
+ );
+
+ $context = stream_context_create($opts);
+ $response = @file_get_contents("http://localhost:8094/card", false, $context);
+ $ok = $response !== false;
+ return $ok ? json_decode($response, true) : null;
+}
+
+function get($param, $default = null)
+{
+ return $_GET[$param] ?? $default;
+}