草食系男子がChatGPTとLINE Notifyを使って本気で婚活する話

## 1. 意中のあの子をレストランに誘いたいけど、どうやって誘ったらいいかわからない！
ChatGPTにどうすればいいか聞けって？というわけで聞いてみたところ
![スクリーンショット 2023-11-14 003059.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3554996/8a2326f3-d0df-3cd6-35d7-4828546eb4ad.png)
丁寧に教えてもらった。ありがたい時代だ。
とにかく「レストランに誘え」と言いたいようだ。
ふむふむ、いけそうな気がしてきたぞ。

***まだPCのモニターとしか向き合っていません。***

## 2. デートの場所としてレストランのリストを作る！
スマートに誘うためにLINEにあらかじめ候補となるレストランのリストを作りたい。
名古屋駅から500m圏内の個室のあるお店をリストアップしてLINE Notifyで自分に送るようにコードを作成した。
<details><summary> 作成したコード</summary>

```js

// ホットペッパーAPIのエンドポイント
const hotpepperEndpoint = 'https://webservice.recruit.co.jp/hotpepper/gourmet/v1/';

// 名古屋駅の緯度経度
const nagoyaStationLocation = {
  latitude: 35.170694,
  longitude: 136.881637,
};

// ホットペッパーAPIのアクセストークン（例：実際のものを使用してください）
const hotpepperApiKey = '*********';

// ホットペッパーAPIを使用してレストラン情報を取得する関数
const getRestaurantData = async () => {
  const url = new URL(hotpepperEndpoint);
  url.searchParams.append('key', hotpepperApiKey);
  url.searchParams.append('lat', nagoyaStationLocation.latitude);
  url.searchParams.append('lng', nagoyaStationLocation.longitude);
  url.searchParams.append('range', '2'); // 500メートル以内
  url.searchParams.append('private_room', '1'); // 個室あり
  url.searchParams.append('format', 'json');

  const response = await fetch(url);
  const data = await response.json();
  return data.results.shop;
};

// LINE Notifyに通知を送信する関数
const sendNotify = async (message, access_token) => {
  const url = 'https://notify-api.line.me/api/notify';
  const headers = {
    'Content-Type': 'application/x-www-form-urlencoded',
    'Authorization': `Bearer ${access_token}`,
  };
  const encodedMessage = `message=${encodeURIComponent(message)}`;
  
  await fetch(url, {
    method: 'POST',
    headers: headers,
    body: encodedMessage,
  });
};

// メインの処理
const main = async () => {
  try {
    // レストラン情報を取得
    const restaurantData = await getRestaurantData();

    // レストラン情報から店名だけを抽出
    const shopNames = restaurantData.map(restaurant => restaurant.name);

    // LINE Notifyにメッセージを送信（コメントアウトされた部分）
    const access_token = '*********';
    const message = `名駅から500メートル以内の個室のあるレストラン一覧:\n${shopNames.join('\n')}`;
    await sendNotify(message, access_token);

    console.log('通知が送信されました。');
  } catch (error) {
    console.error('エラーが発生しました:', error.message);
  }
};

// メイン処理を実行
main();
```
</details>

***届いたLINE***
![LINE_capture_721583806.922010.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3554996/cc11284b-4ac8-e711-9307-5cf677a28602.jpeg)
すごい！！このリストがあればデートに誘えるぞ！！
こういうお店のリストを持っているのはもはやチャラ男！草食系男子卒業か！？

***まだPCのモニターとしか向き合っていません。***

・・・
あれ？？
お店の数が思ったより少ない。
500m以内だと候補が少なすぎるのか。

違う！！
ホットペッパーのAPIリファレンスをよく見直すと
抽出できる店の数の初期値が10店舗になっていた。
抽出できる店の数を100店舗に拡大して再度トライ。
![スクリーンショット 2023-11-16 012031.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3554996/d3b4f8ab-0437-6e56-f861-75ab7167bd95.png)


<details><summary>変更後のコード</summary>

```js
// ホットペッパーAPIを使用してレストラン情報を取得する関数
const getRestaurantData = async () => {
  const url = new URL(hotpepperEndpoint);
  url.searchParams.append('key', hotpepperApiKey);
  url.searchParams.append('lat', nagoyaStationLocation.latitude);
  url.searchParams.append('lng', nagoyaStationLocation.longitude);
  url.searchParams.append('range', '2'); // 500メートル以内
  url.searchParams.append('private_room', '1'); // 個室あり
  url.searchParams.append('count', '100');//100店舗まで抽出
  url.searchParams.append('format', 'json');

  const response = await fetch(url);
  const data = await response.json();
  return data.results.shop;
};
```
</details>

***届いたLINE***
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">ホットペッパー のAPIからLINE Notofyを使って名駅から500m圏内の個室のあるお店のリストを送るコードをjavascriptで作りました。<a href="https://twitter.com/hashtag/protoout?src=hash&amp;ref_src=twsrc%5Etfw">#protoout</a><a href="https://twitter.com/hashtag/%E5%A9%9A%E6%B4%BB?src=hash&amp;ref_src=twsrc%5Etfw">#婚活</a><a href="https://twitter.com/hashtag/%E3%83%87%E3%83%BC%E3%83%88?src=hash&amp;ref_src=twsrc%5Etfw">#デート</a><a href="https://twitter.com/hashtag/%E5%90%8D%E5%8F%A4%E5%B1%8B?src=hash&amp;ref_src=twsrc%5Etfw">#名古屋</a> <a href="https://t.co/vT8WX3ST3G">pic.twitter.com/vT8WX3ST3G</a></p>&mdash; Yokki (@K822Dr) <a href="https://twitter.com/K822Dr/status/1724831676281602304?ref_src=twsrc%5Etfw">November 15, 2023</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

これだけ候補があれば安心だ。
さっそく意中のあの子にLINEをしてみよう。
・・・
あれ？？
LINE知らなかった。
仕方ない。ChatGPTに聞いてみよう。
![スクリーンショット 2023-11-16 021025.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3554996/26e6d17e-0c71-1d05-194b-080c268f4a30.png)

ChatGPTに見放されてしまった。
意中のあの子をデートに誘うのはまだ先になりそうだ。

**最後までPCのモニターとしか向き合いませんでした。**

## 3. 今回のコード作成の手順
* LINE Notifyのトークンを発行する
* ホットペッパーのAPIキーを入手する
* ChatGPTにコードを書いてもらう
### 3-1. LINE Notifyのトークンを発行する
まずLINE Notifyにアクセスする。

<details><summary> 以下詳細な手順</summary>

https://notify-bot.line.me/ja/

![スクリーンショット 2023-11-14 110741.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3554996/804981f7-bf44-b4db-afa7-c1a5729b4740.png)
右上からログインをする。![スクリーンショット 2023-11-14 112032.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3554996/e3ea3cfc-7ee2-f335-51d3-f39e74a43a75.png)
マイページを開いて![スクリーンショット 2023-11-14 111710.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3554996/d242ed73-3169-3f2f-ed6f-70aaa3c79fa6.png)
トークンを発行するをクリックし
トークン名を適当に入力し
#### １：１でLINE Notifyから通知を受け取る
をチェックして発行するとトークンが受け取れる。
大事にメモしておく。
</details>

### 3-2. ホットペッパーのAPIキーを入手する
https://webservice.recruit.co.jp/register/

リクルートのユーザー登録を行うと登録したメールアドレス宛にAPIキーが送られてくる。

### 3-3. chatGPTにコードを書いてもらう
ここまで準備が整ったらコードを作成する。
![スクリーンショット 2023-11-14 142625.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3554996/fee7f5f9-ca25-d932-ccd2-0b2f05b9aaa8.png)
と聞いてみると早速作ってくれた。

<details><summary> ChatGPTの作成したコード</summary>

```js
const fetch = require('node-fetch'); // Node.js環境ではnode-fetchを使用

const hotpepperApiKey = 'YOUR_HOTPEPPER_API_KEY';
const lineNotifyToken = 'YOUR_LINE_NOTIFY_TOKEN';
const nagoyaStationLat = 35.170694;
const nagoyaStationLng = 136.881637;

const getRestaurants = async () => {
    try {
        const url = `https://webservice.recruit.co.jp/hotpepper/gourmet/v1/?key=${hotpepperApiKey}&format=json&lat=${nagoyaStationLat}&lng=${nagoyaStationLng}&range=5&keyword=個室`;

        const response = await fetch(url);
        if (!response.ok) {
            throw new Error(`Failed to fetch restaurant information. Status: ${response.status}`);
        }

        const data = await response.json();
        return data.results.shop;
    } catch (error) {
        console.error(error.message);
        return [];
    }
};

const sendLineNotify = async (message) => {
    try {
        const url = 'https://notify-api.line.me/api/notify';
        const headers = {
            'Content-Type': 'application/x-www-form-urlencoded',
            'Authorization': `Bearer ${lineNotifyToken}`,
        };

        const body = new URLSearchParams({ message });

        const response = await fetch(url, {
            method: 'POST',
            headers,
            body,
        });

        if (!response.ok) {
            throw new Error(`Failed to send LINE Notify. Status: ${response.status}`);
        }

        console.log('Notification sent successfully.');
    } catch (error) {
        console.error(error.message);
    }
};

const main = async () => {
    const restaurants = await getRestaurants();
    const filteredRestaurants = restaurants.filter(restaurant => restaurant.private_room === 'あり');

    if (filteredRestaurants.length > 0) {
        const message = '名古屋駅から500メートル以内の個室のあるレストランのリスト:\n' +
            filteredRestaurants.map(restaurant => `${restaurant.name} - ${restaurant.address}`).join('\n');

        await sendLineNotify(message);
    } else {
        console.log('個室のあるレストランは見つかりませんでした。');
    }
};

main();
```
</details>


少し間違っているところがあったのでリクルートのAPIリファレンスを参考に修正して、もともと手に入れていたAPIキーとトークンを入力し、完成となる。
エラーメッセージを入力することで訂正を細かく教えてくれるが、GPT3.5ではネット上のデータを完全に利用することは難しいようで、自力での学習や精通した専門家の意見が結局必要ということがわかった。

### 4. まとめ
LINE Notifyで欲しい情報をリストにしておくのは非常に便利なことがわかった。
飲食店の情報は無料のAPIが少ない中、ホットペッパーは無料であったため今回利用させてもらった。
ChatGPTはプログラミング分野はかなり得意であるが、使いこなすにはベースの知識が必須になる。
これからベースの知識のアップデートをして、意中のあの子をデートに誘っていきたい！！
最後まで読んでいただきありがとうございました。