DALL-E3 discord.js(v14)で触ってみた

## はじめに
こんばんは！ @Keichan_15 です！

全く…クリスマスイブにしては早すぎるんだよ！！(歓喜)(狂乱)

https://twitter.com/sama/status/1721403384392286339

ということで…、現地時間11/6に行われたOpenAI DevDay、中々凄かったですね～！:sunglasses:

GPT-4 TurboやJSON Modeの追加、Assistants APIなどの新機能が続々と紹介されました。

紹介された内容や新機能については、公式ブログや有志の方々によって公開されていますのでご興味のある方は是非！

https://openai.com/blog/new-models-and-developer-products-announced-at-devday

https://twitter.com/ctgptlb/status/1721622249848148287

さて、その中でも特に興奮したのが **DALL-E3のAPI公開** です！

GPT-Plus(課金ユーザー)の方はご存じの **画像生成AI** ですが、この度 **APIでも正式に利用可能になりました！**

類似の画像生成AIであれば `Stable Diffusion` 等が有名ですが、せっかくGPT-APIの課金ユーザーならば使ってみたいじゃないですか！`DALL-E3`を！！

ということで、本記事ではお馴染み **discord.js** を使用してどんなもんなのか試してみました！

結論、これすげえです…。:relaxed:
(あと値段高いキツイ…。財布の中身すぐ飛んじゃう:sweat_drops:)

## 環境
- WSL2(Ubuntu 20.04.5 LTS)
- Node.js(v16.18.0)
- discord.js(v14.13.0)
- dotenv(v16.3.1)
- openai(v4.17.0)

以前執筆した記事と環境は全く同じです。

https://qiita.com/Keichan_15/items/70907ff47c5e531f0462

## 完成版
![スクリーンショット 2023-11-09 200706.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2798073/8fad61a8-66af-503e-bc76-8206bf9ce430.png)

送信したメッセージから画像を生成し、Botがスレッドに生成した画像を送信しています。

~~ベランダ向かいにそびえ立つタワマンの中華建築感~~

## 実装
早速ですがコードを見ていきましょう！:v:

```javascript:index.js
import { Client, GatewayIntentBits } from 'discord.js';
import dotenv from 'dotenv';
import OpenAI from 'openai';

dotenv.config()

const openai = new OpenAI({
  apiKey: process.env.OPENAI_API_KEY,
})

const client = new Client({ intents: [
  GatewayIntentBits.Guilds,
  GatewayIntentBits.MessageContent,
  GatewayIntentBits.GuildMessages,
  GatewayIntentBits.GuildPresences,
  GatewayIntentBits.GuildMembers,
] });

client.once('ready', async () => {  
  console.log('ready!');
});

client.on('messageCreate', async (message) => {

  if (message.author.bot || message.channel.id != process.env.CHANNEL_ID) return;

  try {
    // 送信されたメッセージをpromptに設定
    const response = await openai.images.generate({
      model: "dall-e-3",
      prompt: message.content,
      n: 1,
      size: "1024x1024",
    });

    const thread = await message.startThread({
      name: message.content,
      autoArchiveDuration: 60,
    })

    // 作成したスレッド内に画像URLを送付
    await thread.send(response.data[0].url);
  } catch (err) {
    console.log(err);
  };
});

client.login(process.env.TOKEN);
```

実装自体は特段クセがあった感じでは無かったので、すんなり書けて良かったです。

以下、解説になります！

## 解説
基本的には以下のDocumentation & API Referenceを参考にしています。

https://platform.openai.com/docs/api-reference/images/create

https://platform.openai.com/docs/guides/images?context=node

```javascript
    const response = await openai.images.generate({
      model: "dall-e-3",
      prompt: message.content,
      n: 1,
      size: "1024x1024",
    });
```

`model` には今回発表された`DALL-E3`を設定しました。`DALL-E3`以前は`DALL-E2`が使用できたのですが、GPT-Plusで使用可能な`DALL-E3`がヤベエ！って聞いていたので使ってませんでした。

ちなみに`DALL-E2`も使ってはみたんですが、同じプロンプトであっても画像の正確性や綺麗さが段違いな感じで驚きました。
画像の粗さが結構`DALL-E2`は浮彫りだった印象です。

`prompt` は入力した内容を設定するようにしました。メッセージの内容に基づいて画像を生成させています。

`size` には画像サイズを設定します。
設定できる画像サイズは以下の3パターンのみとなっているようです。

- 1024x1024
- 1024x1792
- 1792x1024

またresponseの中身は以下のようになっていました。

```:(response)
{
  created: 1699527245,
  data: [
    {
      revised_prompt: 'An enchanting depiction of a traditional Japanese landscape. A serene scene where a crystal-clear stream winds through a lush garden dotted with blooming Sakura trees. Delicate petals of the Sakura trees flutter in the soft breeze. A quaint wooden bridge arches gently over the stream, leading to a classic Japanese tea house nestled amidst the verdant foliage. Majestic Mount Fuji stands in the background, its snowy peak kissed by the glimmers of a warm sunset. A couple of people, a Middle-Eastern man and a Hispanic woman, dressed in colorful kimonos are walking leisurely across the bridge, immersing themselves in the tranquil environment.',
      url: 'https://oaidalleapiprodscus.blob.core.windows.net/private/org-VmrMZ0Gq6zZR0YCx21FiXbsx/user-Jkn3aqTwm6hEAxxBRohdXGsG/img-5cm3ddASIFZ5vsQObXrftsfg.png?st=2023-11-09T09%3A54%3A05Z&se=2023-11-09T11%3A54%3A05Z&sp=r&sv=2021-08-06&sr=b&rscd=inline&rsct=image/png&skoid=6aaadede-4fb3-4698-a8f6-684d7786b067&sktid=a48cca56-e6da-484e-a814-9c849652bcb3&skt=2023-11-09T09%3A05%3A24Z&ske=2023-11-10T09%3A05%3A24Z&sks=b&skv=2021-08-06&sig=XyBfF3eDf6CxSrGVGZRrr013RFw0zYKTnBHJEa3YKs8%3D'
    }
  ]
}
```

今回であれば`data[0].url`部分が生成された画像URLになるため、この値をBotに渡して返信させる必要があります。

今回はスレッド返信を行うため、記述は以下のようになります。

```javascript:index.js
    await thread.send(response.data[0].url);
```

以上でBotがプロンプトに沿った画像をスレッドに返信してくれるようになります！:metal:

## 便利だけど使い過ぎ注意…
画像生成AIを使用したことがある方は薄々ご存じだと思いますが、理想の画像を追求するには複数回プロンプトを打っては返って来て～の繰り返しになると思います。

ただ忘れてはならないのは、APIはタダではないということ…。:head_bandage:

今回使用したDALL-E3ですが、料金は **画像生成1枚当たり$0.04** になります。(1024x1024の場合)
これがエグくてですね、無闇やたらにバンバン使用すると普通に$5くらいまで1時間でいっちゃいます。。

その他、Model毎の料金体系については以下の公式ページをご参照くださいませ！

https://openai.com/pricing

## おわりに
いかがでしたでしょうか。

今回のOpenAI DevDayで紹介された数々の新機能、1つ1つ追うのは中々大変ですが、どれも魅力ある機能ばかりで開発者からすれば興奮が止まらないですよね～～！

また冒頭で紹介したAssistants APIも個人的に凄い気になっているので、今度はそこについても調べていけたら良いなと思っています！

皆さんも画像生成AIを駆使して、素敵な1枚を作っちゃいましょう～！:raised_hands:

ちなみに…
自身のQiitaのプロフィール画像を`DALL-E3`を使用して生成したモノに変えました！気付きました？:wink: