基于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

相关文章

在 Go 项目中使用 LevelDB 进行数据存储

LevelDB 是一个由 Google 开发的高性能键值存储库,广泛应用于需要快速读写操作的场景。本文将介绍如何在 Go 项目中使用 LevelDB 作为数据存储,并通过示例代码展示如何初始化数...

详解Go语言依赖注入工具wire最佳实践介绍与使用

wire是一个强大的依赖注入工具,通过代码生成的方式实现了高效的依赖注入。本文详细介绍了wire的入门级和高级使用技巧,并通过示例代码展示了其强大的功能。无论是简单的依赖注入,还是复杂的依赖图生...

Go语言中copy命令讲解 切片之间复制元素

在Go语言中,copy函数是一个非常常用的内置函数,用于在切片(slice)之间复制元素。理解copy函数的用法和机制对于高效处理数据操作至关重要1. copy函数的基本用法copy函数的基本语...

深入理解 Go 语言中的 goto:用法与最佳实践

在学习编程语言时,goto 一直是一个颇具争议的概念。它常常因为“跳跃式”的行为被认为会让代码混乱且难以维护,但在 Go 语言中,goto 被保留并提供了一些实际的应用场景。今天我们将深入探讨 ...

Go并发编程与调度器及并发模式详解

Go语言以其简洁的语法和强大的并发能力,成为现代网络编程和微服务架构的热门选择。本文将深入探讨Go的并发编程模型,调度器的工作机制,以及多种并发模式的实现和应用,帮助开发者更好地理解并发编程的设...

图片Base64编码

CSR生成

图片无损放大

图片占位符

Excel拆分文件