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

相关文章

从入门到放弃:使用 spf13/viper 管理 Go 应用配置

在现代软件开发中,配置管理是一个至关重要的环节。随着应用的复杂性增加,配置管理的需求也变得更加多样化和复杂化。Go 语言社区中,spf13/viper 是一个非常流行的配置管理库,它提供了一种强...

使用 spf13/cobra 构建强大的 Go 命令行应用

spf13/cobra 是 Go 语言中非常流行的一个库,用于创建命令行应用(CLI)。它提供了一种强大且易于使用的框架来开发支持复杂命令结构的应用程序。Cobra 库主要用于创建像 kubec...

Go语言Web框架 Fiber入门教程

Fiber 是一个基于 Go 语言的 Web 框架,灵感来源于 Express.js,旨在提供快速、简单且轻量级的开发体验。Fiber 的设计目标是让开发者能够快速构建高性能的 Web 应用,同...

Typecho插件开发手册

插件的基本结构在 Typecho 中,插件通常是一个独立的 PHP 文件,默认放置在usr/plugins/目录下。插件文件名即为插件名,插件类名也应与文件名相同。插件必须实现 Typecho_...

Go语言跨平台GUI工具包tk9.0

不得不说,这名字起的.....tk9.0是一个用Go语言编写的跨平台GUI工具包,它使用Tcl/Tk作为底层图形库,无需CGo,这意味着您可以使用它来创建原生跨平台应用程序,而无需依赖于C语言编...

图片Base64编码

CSR生成

图片无损放大

图片占位符

Excel拆分文件