Golang+LambdaでGhatGPTを活用したTwitterBotを作ってみた

# Summary
- `ChatGPT`が生成したテキストを1日3回つぶやくTwitterBotを作成しました
- 言語は`Go`で、`OpenAI API`と`TwitterAPI`用のライブラリを用いて実装しました
- `Lambda`+`EventBridge`を用いて定期実行しています

# Architecture & Deliverables
- 上記を図示すると以下のようになります
 
![architecture](https://raw.githubusercontent.com/RyuyaIshibashi/great-chatgpt-quotes-bot/master/chat_architecture.jpg)

- 実際の成果物は以下のアカウントです

  - [偉人ChatGPTの名言](https://twitter.com/great_chatgpt)

    <img width="60%" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/643664/45f50611-5230-974e-bdc6-d01fd564b0ed.png">



# Implementation Details
- 実装の詳細を解説します

## Call OpenAI API and creat a qute
- まずはOpenAI APIをコールしてテキストを生成する部分を解説します

### Library
- 以下のライブラリを使用しました
  - [sashabaranov/go-openai](https://github.com/sashabaranov/go-openai)

https://github.com/sashabaranov/go-openai


### Implemenataiton

- 実装は以下のようになります
  - ほぼライブラリのREADME通りです
  - プロンプトはなんちゃってなので、ご了承ください🙇

```go
import (
	"context"
	"fmt"
	"os"

	openai "github.com/sashabaranov/go-openai"
)

func generateQuote() (quote string, err error) {
    // OpenAI API　Keyを用いてClientを生成します
	client := openai.NewClient(os.Getenv("OPEN_AI_API_KEY"))

    // Clientに対してChatCompletionの生成を命じます
	resp, err := client.CreateChatCompletion(
		context.Background(),
		openai.ChatCompletionRequest{
			Model: openai.GPT3Dot5Turbo,
			Messages: []openai.ChatCompletionMessage{
				{
					Role: openai.ChatMessageRoleUser,
					Content: `あなたは架空の歴史上の偉人の名言をつぶやくTwitterBOTと仮定してください。
					その偉人は、困難に直面したり、障害に立ち向かう人々を勇気づけるための名言をたくさん残しています。
					あなたはTwitterBOTとして、その名言を以下の形式で1つだけつぶやいてください。
					なお、文字数は140字以下として下さい。
					'''
					「${名言}」 
					ChatGPT (${職業})
					'''
					
					${名言}はあなたの名言です。「ですます」調を使ってはいけません。
					
					${職業}はあなたの職業です。なお、「架空」「歴史上」「偉人」「成功者」「先人」という言葉は使ってはいけません。
					具体的な職業名を使ってください。
					`,
				},
			},
		},
	)

	if err != nil {
		return "", err
	}

    // 生成されたテキストを取得します
	quote = resp.Choices[0].Message.Content

	fmt.Printf("generateQuote result: %v\n", quote)
	return quote, nil
}
```

## Post a quote on Twitter
- 続いて、生成したテキストを用いてTweetを作成する部分です

### Library
- 以下のライブラリを使用しました
  - [michimani/gotwi](https://github.com/michimani/gotwi)

https://github.com/michimani/gotwi

### Implementation

- 実装は以下のようになります
  - こちらもほぼライブラリのREADME通りです
  - 認証はOAuth1.0を用いています

```go
import (
	"context"
	"fmt"
	"os"

	"github.com/michimani/gotwi"
	"github.com/michimani/gotwi/tweet/managetweet"
	"github.com/michimani/gotwi/tweet/managetweet/types"
)

func tweetQuote(quote string) (err error) {
    // OAuth1.0を用いて認証情報を作成します
	in := &gotwi.NewClientInput{
		AuthenticationMethod: gotwi.AuthenMethodOAuth1UserContext,
		OAuthToken:           os.Getenv("GOTWI_ACCESS_TOKEN"),
		OAuthTokenSecret:     os.Getenv("GOTWI_ACCESS_TOKEN_SECRET"),
	}

    // 認証情報を用いてクライアントを作成します
	c, err := gotwi.NewClient(in)
	if err != nil {
		return err
	}

    // ChatGPTが作成したテキストを用いてTwtterのつぶやき用のテキストを生成します
	p := &types.CreateInput{
		Text: gotwi.String(quote),
	}

    // 生成したテキストを用いてTweetを作成します
	res, err := managetweet.Create(context.Background(), c, p)
	if err != nil {
		return err
	}

	fmt.Printf("tweetQuote result: [%s] %s\n", gotwi.StringValue(res.Data.ID), gotwi.StringValue(res.Data.Text))

	return nil
}
```



# Miscellaneous
## Codebase
- 実際のコードベースは以下ですのでご参照ください

https://github.com/RyuyaIshibashi/great-chatgpt-quotes-bot

## Infrastructure
- LambdaにデプロイしてEventBridgeで定期実行する部分の解説は省略しますが、非常に簡単です
  - 以下の公式ドキュメント通りに実装するだけです
  - 上記のコードベースがそのままLambdaにアップロードできる形式になっているので、気になる方はお試しください

https://docs.aws.amazon.com/ja_jp/eventbridge/latest/userguide/eb-create-rule-schedule.html


## Conclusion
- ChatGPT界隈では`Python`ライブラリばかりが登場している気がしますが、`Go`でも素晴らしいライブラリのおかげで気軽に`OpenAI　API`を扱えました

- 「**ChatGPTを用いた何らかの処理を行うバッチ的なツールを作って、定期実行させる**」というアイデアは、
ChatGPTを業務活用するトライアルとしては悪くないと思いました