# Using Go to call OpenAI's Chat API

Go (Golang) is a fast and efficient programming language, perfect for building reliable applications. It can also be used to interact with AI services like OpenAI.

In this blog post, I'll show you how to use Go to call OpenAI's Chat Completions API. We'll create a simple application that generates a social media posts for a real estate agent, demonstrating how easy it is to integrate Go with OpenAI's powerful AI models.

### Create Chat completion API

This is the API contract provided by OpenAI which we will use. You can check out the detailed reference in their documentation.  
[https://platform.openai.com/docs/api-reference/chat/create](https://platform.openai.com/docs/api-reference/chat/create)

```bash
curl https://api.openai.com/v1/chat/completions \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $OPENAI_API_KEY" \
  -d '{
    "model": "gpt-3.5-turbo",
    "messages": [
      {
        "role": "system",
        "content": "You are a helpful assistant."
      },
      {
        "role": "user",
        "content": "Hello!"
      }
    ]
  }'
```

Let's break down the code and explain each part.

#### 1\. Package Import

```go
import (
	"bytes"
	"encoding/json"
	"fmt"
	"io"
	"net/http"
	"os"
)
```

We import necessary packages for handling HTTP requests, JSON encoding, reading environment variables, and I/O operations.

#### 2\. Defining the Payload and Message Structs

```go
// Payload struct defines the structure of the payload to send to OpenAI
type Payload struct {
	Model    string    `json:"model"`
	Messages []Message `json:"messages"`
}

// Message struct defines the structure of individual messages
type Message struct {
	Role    string `json:"role"`
	Content string `json:"content"`
}
```

These structs define the structure of our payload and individual messages. The `Payload` struct includes the model name and a slice of `Message` structs. Each `Message` struct includes a role (e.g., system, user) and content.

#### 3\. Main Function

The main function contains the core logic for sending a request to OpenAI's API and handling the response.

##### a. Setting Up the API URL and Key

```go
url := "https://api.openai.com/v1/chat/completions"
apiKey := os.Getenv("OPENAI_API_KEY") // Replace this with your actual API key
```

We define the API endpoint and retrieve the API key from environment variables.

##### b. Creating the Payload

```go
messages := []Message{
	{
		Role:    "system",
		Content: "you are a real estate assistant and you will always answer in tagalog",
	},
	{
		Role:    "user",
		Content: "give me a social media post about investing in real estate",
	},
}
data := Payload{
	Model:    "gpt-3.5-turbo",
	Messages: messages,
}
```

We create a slice of messages defining the system's behavior and the user's request. These are packed into the `Payload` struct.

##### c. Marshaling the Payload to JSON

```go
jsonData, err := json.Marshal(data)
if err != nil {
	panic(err) // we panic for now, you can handle this properly later on
}
```

We convert the `Payload` struct into JSON format using `json.Marshal`.

##### d. Creating the HTTP Request

```go
req, err := http.NewRequest("POST", url, bytes.NewBuffer(jsonData))
if err != nil {
	panic(err) // we panic for now, you can handle this properly later on
}

// Set headers
req.Header.Set("Authorization", "Bearer "+apiKey)
req.Header.Set("Content-Type", "application/json")
```

We create a new POST request, set the authorization header with the API key, and specify the content type as JSON.

##### e. Sending the Request and Handling the Response

```go
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
	panic(err)
}
defer func(Body io.ReadCloser) {
	err := Body.Close()
	if err != nil {

	}
}(resp.Body)

// Read response
body, err := io.ReadAll(resp.Body)
if err != nil {
	panic(err)
}

fmt.Println("Response:", string(body))
```

We send the request using an HTTP client and read the response. The response body is then printed to the console.

Here's the complete code for our project:

```go
package main

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

// Payload struct defines the structure of the payload to send to OpenAI
type Payload struct {
	Model    string    `json:"model"`
	Messages []Message `json:"messages"`
}

// Message struct defines the structure of individual messages
type Message struct {
	Role    string `json:"role"`
	Content string `json:"content"`
}

func main() {
	url := "https://api.openai.com/v1/chat/completions"
	apiKey := os.Getenv("OPENAI_API_KEY") // Replace this with your actual API key

	// Setup the payload
	messages := []Message{
		{
			Role:    "system",
			Content: "you are a real estate assistant and you will always answer in tagalog",
		},
		{
			Role:    "user",
			Content: "give me a social media post about investing in real estate",
		},
	}
	data := Payload{
		Model:    "gpt-3.5-turbo",
		Messages: messages,
	}

	// Marshal data into JSON
	jsonData, err := json.Marshal(data)
	if err != nil {
		panic(err)
	}

	// Create a new request using http
	req, err := http.NewRequest("POST", url, bytes.NewBuffer(jsonData))
	if err != nil {
		panic(err)
	}

	// Set headers
	req.Header.Set("Authorization", "Bearer "+apiKey)
	req.Header.Set("Content-Type", "application/json")

	// Send req using http Client
	client := &http.Client{}
	resp, err := client.Do(req)
	if err != nil {
		panic(err)
	}
	defer func(Body io.ReadCloser) {
		err := Body.Close()
		if err != nil {

		}
	}(resp.Body)

	// Read response
	body, err := io.ReadAll(resp.Body)
	if err != nil {
		panic(err)
	}

	fmt.Println("Response:", string(body))
}
```

### Running the Code

To run this code, ensure you have set the `OPENAI_API_KEY` environment variable with your actual OpenAI API key. This can be done in your terminal:

```bash
export OPENAI_API_KEY="your-api-key-here"
```

Then, execute your Go program:

```bash
go run main.go
```

Here is a sample response you will receive when you run this Go program

```json
{
  "id": "chatcmpl-9c6K8Ic00b3k9dycy4BuIZ5T5z7Z8",
  "object": "chat.completion",
  "created": 1718867800,
  "model": "gpt-3.5-turbo-0125",
  "choices": [
    {
      "index": 0,
      "message": {
        "role": "assistant",
        "content": "Naghahanap ka ba ng magandang investment? I-invest mo na sa real estate! Siguradong tataas ang value nito habang tumatagal. Mag-invest na sa real estate ngayon! 🏡💰 #RealEstateInvesting #MagandangInvestment #EdukasyonTungoSaTagumpay"
      },
      "logprobs": null,
      "finish_reason": "stop"
    }
  ],
  "usage": {
    "prompt_tokens": 36,
    "completion_tokens": 78,
    "total_tokens": 114
  },
  "system_fingerprint": null
}
```

In this blog post, we have walked through the process of creating a simple application using Go. This application interacts with OpenAI's Chat API, providing responses in Tagalog. This example can be a starting point for more complex integrations and customizations, enabling you to build powerful AI-driven applications.  
  
If you're interested in learning more about integrating Go with Generative AI, follow this blog for more tutorials and insights. This is just the start!  
  
I do live coding in [Twitch](https://twitch.tv/donvitocodes) and [Youtube](https://youtube.com/donvitocodes). You can follow me if you'd like to ask me questions when I go live. I also post in [LinkedIn](https://www.linkedin.com/comm/mynetwork/discovery-see-all?usecase=PEOPLE_FOLLOWS&followMember=melvinvivas), you can connect with me there as well.
