Introduction
Hey There đ,
In this blog post, we'll create a practical CLI tool in Go that leverages OpenAI GPT API to generate personalized cold emails. By the end of this tutorial blog, you'll have a good understanding of CLI's and its integration with OpenAI API.
Prerequisites
To continue with the tutorial, you need to have Golang installed.
Getting Started đ
Let's get started by creating the main project directory gpt-mail
by using the following command.
mkdir gpt-mail //Creates a 'gpt-mail' directory
cd gpt-mail //Change directory to 'gpt-mail'
For building the CLI tool we'll be using the Cobra-cli Framework. For installing Cobra-CLI you can go to Cobra or run go install github.com/spf13/cobra-cli@latest
in the terminal.
Now initialize a mod file. (If you publish a module, this must be a path from which your module can be downloaded by Go tools. That would be your code's repository.)
go mod init github.com/<username>/gpt-mail //<username> is your github username
Cobra-cli init
This command initializes the CLI and creates a main.go
file along with cmd
folder containing root.go
.
Now, run the command Cobra-cli add generate
, this will create a file generate.go
in the cmd
folder for the command generate
.
Let's make a new file for the code that will execute after the command is called, for this create a folder lib
and a new file email.go
inside it.
Create a .env
file in the root directory i.e. gpt-mail
and save the OpenAI API Key that you created earlier in the file.
OPENAI_API_KEY=<YOUR_API_KEY>
Make the following changes in the root.go
file.
package cmd
import (
"os"
"github.com/spf13/cobra"
)
var rootCmd = &cobra.Command{
Use: "gpt-mail",
Short: "A AI-driven Tool for Generating Email",
}
func Execute() {
err := rootCmd.Execute()
if err != nil {
os.Exit(1)
}
}
func init() {
rootCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle")
}
In root.go
, function Execute
gets called from main.go
and it executes the rootCmd
. Use
is used to define the command to be used and Short
and Long
contains the information or description for the Command in short and long format respectively.
Update the variable generateCmd
in the generate.go file with the following code,
var generateCmd = &cobra.Command{
Use: "generate",
Short: "Command to Generate the Email",
Run: func(cmd *cobra.Command, args []string) {
res, err := lib.Email()
if err != nil {
log.Fatal(err)
}
fmt.Println("> Response: ")
fmt.Println("")
fmt.Println(res)
},
}
Here, we are calling the function Email
from the lib
package and getting the response.
Let's write the code for the main feature of our CLI tool i.e. integrating with OpenAI API and getting the response. Add the following code in the email.go
file created earlier,
package lib
import (
"bufio"
"context"
"fmt"
"log"
"os"
"github.com/joho/godotenv"
"github.com/sashabaranov/go-openai"
)
func Email() (string, error) {
godotenv.Load()
fmt.Print("> Enter the Subject for the Email : ")
reader := bufio.NewReader(os.Stdin)
Subject, err := reader.ReadString('\n')
if err != nil {
log.Fatal(err)
}
fmt.Print("> Enter the Audience for the Email : ")
Audience, err := reader.ReadString('\n')
if err != nil {
log.Fatal(err)
}
fmt.Print("> Enter the Purpose/Information for the Email : ")
Purpose, err := reader.ReadString('\n')
if err != nil {
log.Fatal(err)
}
prompt := fmt.Sprintf("Subject: %s Audience: %s Purpose/Information: %s\n", Subject, Audience, Purpose)
apiKey := os.Getenv("OPENAI_API_KEY")
if apiKey == "" {
log.Fatalln("Invalid API Key!!")
}
prompt_prefix := os.Getenv("Prompt_prefix")
client := openai.NewClient(apiKey)
resp, err := client.CreateChatCompletion(
context.Background(),
openai.ChatCompletionRequest{
Model: openai.GPT3Dot5Turbo,
Messages: []openai.ChatCompletionMessage{
{
Role: "user",
Content: prompt_prefix + prompt,
},
},
})
if err != nil {
fmt.Printf("Completion error: %v\n", err)
}
res := resp.Choices[0].Message.Content
return res, nil
}
- Firstly, we are taking user inputs for the Subject, Audience and Purpose of the Email.
- Then, we are creating a Prompt using the
prompt_prefix
and the user inputs for the email generation. For this, aprompt_prefix
string is created and its value is stored in the.env
file asPrompt_prefix="Generate the Cold Email content having "
. - For creating the client to interact with the API we are using the
github.com/sashabaranov/go-openai
package. To import this rungo get github.com/sashabaranov/go-openai
. - Here we are using the model as
GPT3Dot5Turbo
. For other models information visit https://platform.openai.com/docs/models . - After getting the response, return the response string.
Testing
Now, run the command go build .
to build a binary executable file for the CLI, it will be created as gpt-mail.exe
. Then, run the command ./gpt-mail
, this will run the gpt-mail.exe
file.
> ./gpt-mail
A AI-driven Tool for Generating Email
Usage:
gpt-mail [command]
Available Commands:
completion Generate the autocompletion script for the specified shell
generate Command to Generate the Email
help Help about any command
Flags:
-h, --help help for gpt-mail
-t, --toggle Help message for toggle
Use "gpt-mail [command] --help" for more information about a command.
Now, run the command ./gpt-mail generate
Example Input :
Subject : Job Inquiry
Audience : Hiring Manager, Recruiter
Purpose/Information : Inquiring about available job positions and expressing interest in joining the team.
Output :
> Response:
Dear [Hiring Manager/Recruiter],
I hope this email finds you well. I am writing to inquire about any job opportunities that may be available within your esteemed company. I have admired your organization's achievements and culture, and I am eager to contribute my skills and experience to your team.
I have recently completed my [degree/certification] in [relevant field], and I am excited to embark on a new professional journey. Through my studies and previous work experiences, I have developed a strong foundation in [specific skills or industry knowledge]. I believe that these skills, along with my passion for [specific industry or field], would make me a valuable asset to your company.
I have researched your company extensively, and I am particularly impressed by [specific accomplishment or project]. It is evident that your team is highly skilled and driven, and I would be honored to be a part of it.
Attached to this email, please find my resume for your perusal. I would greatly appreciate the opportunity to discuss how my qualifications align with any available job positions, and to learn more about the team and company culture. I am available at your convenience for a phone call or virtual meeting.
Thank you for considering my application. I look forward to the possibility of joining your team and contributing to your continued success.
Sincerely,
[Your Name]
[Contact Information]
Conclusion
You can find the complete code repository for this tutorial here.
To get more information about Golang concepts, projects, etc. and to stay updated on the Tutorials do follow Siddhesh on Twitter and GitHub.
Until then Keep Learning, Keep Building đđ
Top comments (0)