基于Go语言实现chatGPT返回的内容接口直接输出组件

先说下,这个东西最开始是给typecho博客写插件的时候用的,我的构想是,插件中填写我生成的密钥(你可以搞成收费的...),然后通过这个Go后台,生成文章,而这个Go程序中则请求gpt生成文章内容并以JSON返回

但是吧... 现在免费GPT大把,我也没有做收费的打算,所以直接上代码吧,另外我将在最近开源我的typecho ai插件

package main

import (
    "bytes"
    "encoding/json"
    "fmt"
    "io/ioutil"
    "log"
    "net/http"
)

// 定义消息结构体
type Message struct {
    Role    string `json:"role"`
    Content string `json:"content"`
}

// OpenAI请求体结构
type OpenAIRequestBody struct {
    Model       string    `json:"model"`
    Messages    []Message `json:"messages"`
    Temperature float64   `json:"temperature"`
}

// OpenAI响应体结构
// 定义OpenAI响应体结构
type OpenAIResponse struct {
    ID      string `json:"id"`
    Object  string `json:"object"`
    Created int    `json:"created"`
    Model   string `json:"model"`
    Choices []struct {
        Index   int `json:"index"`
        Message struct {
            Role    string `json:"role"`
            Content string `json:"content"`
        } `json:"message"`
        FinishReason string `json:"finish_reason"`
    } `json:"choices"`
    Usage struct {
        PromptTokens     int `json:"prompt_tokens"`
        CompletionTokens int `json:"completion_tokens"`
        TotalTokens      int `json:"total_tokens"`
    } `json:"usage"`
}

// 验证 secretKey 是否正确
func validateSecretKey(secretKey string) bool {
    return secretKey == "954270"
}

// 处理生成文本的请求
func handleRequest(w http.ResponseWriter, r *http.Request) {
    // 允许跨域请求
    w.Header().Set("Access-Control-Allow-Origin", "*")             // 允许所有来源的请求
    w.Header().Set("Access-Control-Allow-Methods", "GET")          // 允许GET方法
    w.Header().Set("Access-Control-Allow-Headers", "Content-Type") // 允许的请求头

    // 验证请求方法是否为GET
    if r.Method != http.MethodGet {
        http.Error(w, `{"error": "Invalid request method"}`, http.StatusMethodNotAllowed)
        return
    }

    // 获取查询参数中的 secretKey 和 keywords
    secretKey := r.URL.Query().Get("secretKey")
    keywords := r.URL.Query().Get("keywords")

    // 验证 secretKey
    if !validateSecretKey(secretKey) {
        http.Error(w, `{"error": "Invalid secretKey"}`, http.StatusUnauthorized)
        return
    }

    // 验证 keywords 是否存在
    if keywords == "" {
        http.Error(w, `{"error": "Missing keywords"}`, http.StatusBadRequest)
        return
    }

    // 调用 OpenAI API
    responseText, err := callOpenAIAPI(keywords)
    if err != nil {
        http.Error(w, fmt.Sprintf(`{"error": "Failed to get response from OpenAI: %s"}`, err), http.StatusInternalServerError)
        return
    }

    // 构建返回的JSON数据
    response := map[string]interface{}{
        "data": responseText,
    }

    // 将数据编码为 JSON 并返回给前端
    w.Header().Set("Content-Type", "application/json")
    jsonResp, err := json.Marshal(response)
    if err != nil {
        http.Error(w, `{"error": "Failed to encode response"}`, http.StatusInternalServerError)
        return
    }

    w.Write(jsonResp)
}

// 调用OpenAI API并返回生成的文本
func callOpenAIAPI(keywords string) (string, error) {
    // 准备发送到OpenAI API的请求体
    openAIReqBody := OpenAIRequestBody{
        Model: "gpt-4-turbo",
        Messages: []Message{
            {
                Role:    "system",
                Content: "你是一名专业的技术博客主,请根据我的关键词生成完整的参考内容",
            },
            {
                Role:    "user",
                Content: keywords,
            },
        },
        Temperature: 0,
    }

    reqBodyBytes, err := json.Marshal(openAIReqBody)
    if err != nil {
        return "", err
    }

    // 构建HTTP请求,向OpenAI API发送请求
    req, err := http.NewRequest("POST", "https://api.openai.com/op/v1/chat/completions", bytes.NewBuffer(reqBodyBytes))
    if err != nil {
        return "", err
    }
    req.Header.Set("Authorization", "Bearer sk-换成你的密码")
    req.Header.Set("Content-Type", "application/json")

    // 发送请求并获取响应
    client := &http.Client{}
    resp, err := client.Do(req)
    if err != nil {
        return "", err
    }
    defer resp.Body.Close()

    // 读取响应体
    body, err := ioutil.ReadAll(resp.Body)
    if err != nil {
        return "", err
    }

    // 解析OpenAI API返回的JSON
    var openAIResp OpenAIResponse
    err = json.Unmarshal(body, &openAIResp)
    if err != nil {
        return "", err
    }
    // 返回生成的文本
    if len(openAIResp.Choices) > 0 {
        return openAIResp.Choices[0].Message.Content, nil
    }

    return "", fmt.Errorf("no response from OpenAI")
}

func main() {
    http.HandleFunc("/txt", handleRequest)
    fmt.Println("Server is running on port 8084...")
    log.Fatal(http.ListenAndServe(":8084", nil))
}

这个小东西的使用
http://xxx:8084/txt?secretKey=954270&keywords=关键词

代码中几处修改点:

  1. secretKey == "954270" 这个是我偷懒做的一个密钥,表示调用它先得用这个密钥,当前这是提供给用户的
  2. ("Authorization", "Bearer sk-换成你的密码") 这儿是换成你的openai的密钥,当然你要是用的第三方的代理的话,这儿就换成对应的.. 如果你用第三方的代理,上面的 https://api.openai.com这儿也可以做相应的替换
  3. 关于提示词prompt,默认的你是一名专业的技术博客主,请根据我的关键词生成完整的参考内容,这句话改掉就成...

好了,思路和实现都给了,如何扩展自由发挥吧

标签: Go, AI, 源代码, Typecho

相关文章

Typecho博客系统的xmlrpc的使用附PHP示例代码

XML-RPC 是一种远程过程调用(RPC)协议,它使用 XML 编码请求和响应,并通过 HTTP 进行传输。XML-RPC 允许客户端调用远程服务器上的方法,并获取返回结果。这种协议简单、轻量...

如何使用Go编写跨平台组件并让Java或PHP调用

在现代软件开发中,跨语言调用是一个常见的需求。假设我们有一个用Go语言编写的组件,我们希望Java或PHP能够直接调用这个组件中对外提供的方法。为了实现这一目标,我们可以使用以下几种方法:1. ...

Go 开发中的go:embed应用与最佳实践

go:embed 使用介绍go:embed 是 Go 语言的一项编译器指令,它允许在编译时将任意文件或目录嵌入到 Go 的二进制文件中。通过这种方式,开发者可以在不依赖外部文件的情况下直接在代码...

图片Base64编码

CSR生成

图片无损放大

图片占位符

Excel拆分文件