Twitterでハッシュタグ検索した状態のタイムラインを自動更新するChromeの拡張機能をChatGPTに作ってもらった

サッカーの日本代表戦見ようと思ったんですが、ニコニコ実況が今サーバーダウンしちゃってるんですよね。。。
Twitter見るかーと思ったんですが、Tweetdeck有料化しちゃったし、手動で更新し続けるのもめんどいなーということで自動更新する拡張機能を探してみました。

<br>

以下の拡張機能があったんですが、これはホームだけっぽいんですよね。。。

https://chromewebstore.google.com/detail/twittertimelineloader/ipmgjpmedafkmmadinmeoannpofakpbh?hl=ja

ということで自分で作ってみることにしました

# やりたいこと

↓のようにハッシュタグを検索した状態でタイムラインを更新したい

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/325108/8a9d518a-103d-19de-9e8f-434954f3cfc9.png)


# ざっくりとした仕様

前提として、Twitterは一番上までスクロールすると最新のポストが読み込まれるという仕様があるため、これを利用します。

- 一定間隔で画面をスクロールさせる（ちょっと下にスクロールしてすぐに一番上に戻す）
- 更新間隔は指定できるようにしたい

※スクロールさせるので画面がちらつくが、自分用なので許容します


# 作ってみた

これくらいなら自分で一から書かなくてもイケそう！って思ってChatGPTにお願いしてみました。
何回かやり取りしてうまく動くようになったので、最終的なコードを載せておきます。
※自分では1文字も書いてません


```manifest.json
{
  "manifest_version": 3,
  "name": "My Chrome Extension",
  "version": "1.0",
  "description": "This is a simple Chrome extension that scrolls the page every 15 seconds.",
  "permissions": ["activeTab", "scripting"],
  "action": {
    "default_popup": "popup.html",
    "default_icon": {
      "16": "icons/icon16.png",
      "48": "icons/icon48.png",
      "128": "icons/icon128.png"
    }
  }
}

```

```popup.html
<!DOCTYPE html>
<html>

<head>
    <title>My Chrome Extension</title>
    <style>
        body {
            width: 300px;
            font-family: Arial, sans-serif;
        }
    </style>
</head>

<body>
    <h1>Hello, World!</h1>
    <p>This is a simple Chrome extension popup.</p>
    <label for="interval">Scroll Interval (seconds):</label>
    <input type="number" id="interval" value="30">
    <button id="startScroll">Start Scrolling</button>
    <button id="stopScroll">Stop Scrolling</button>
    <script src="popup.js"></script>
</body>

</html>
```

```popup.js
let scrollInterval;

document.getElementById('startScroll').addEventListener('click', () => {
    const intervalInput = document.getElementById('interval');
    const interval = parseInt(intervalInput.value) * 1000;  // 秒数をミリ秒に変換
    chrome.tabs.query({ active: true, currentWindow: true }, (tabs) => {
        if (tabs[0]) {
            chrome.scripting.executeScript({
                target: { tabId: tabs[0].id },
                func: startScrolling,
                args: [interval]
            });
        } else {
            console.error("No active tab found");
        }
    });
});

document.getElementById('stopScroll').addEventListener('click', () => {
    chrome.tabs.query({ active: true, currentWindow: true }, (tabs) => {
        if (tabs[0]) {
            chrome.scripting.executeScript({
                target: { tabId: tabs[0].id },
                func: stopScrolling
            });
        } else {
            console.error("No active tab found");
        }
    });
});

function startScrolling(interval) {
    if (!window.scrollInterval) {
        window.scrollInterval = setInterval(() => {
            window.scrollBy(0, 1000);  // 1000pxスクロール
            setTimeout(() => {
                window.scrollTo(0, 0);  // 一番上まで即座にスクロール
            }, 100);  // 100ミリ秒後に上までスクロール
        }, interval);
    }
}

function stopScrolling() {
    if (window.scrollInterval) {
        clearInterval(window.scrollInterval);
        window.scrollInterval = null;
    }
}
```

自分で対応が必要だったもの

- iconsディレクトリを作成
- 上記ディレクトリ内にicon16.png／icon48.png／icon128.pngを作成
  - 適用な画像ファイルをいれておけばOK

# 動かしてみる

## インストール

「拡張機能を管理　⇒　パッケージ化されていない拡張機能を読み込む」でコードが格納されたディレクトリを選択します

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/325108/3dff4fe1-73c2-f44c-0182-6175505d5343.png)


# 拡張機能を実行

拡張機能が追加されるため、Twitter画面で追加した拡張機能を開きます

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/325108/f9bf944c-2c7a-eeaa-f153-866a76c24dca.png)

任意の秒数を入力し、「Start Scrolling」で自動スクロールが開始されます。

※間隔が短いとすぐにTwitterAPI上限に達してしまうため注意

# 最後に

いやーChatGPTすごいですねー。

サッカー始まってから作り始めたんですが、後半が始まるころには普通に使えたので自分で一から作るのに比べたら全然早い！

昔より応答速度も速くなったし、こうしてほしいという要望もちゃんと取り込んでくれるし、エラーが起きてもエラーメッセージ張り付けてこんなエラー起きたんだけど？っていうと解決策も盛り込んでくれる。

まだ完全に信用はできないものの、プロトタイプ作ってもらう分には全然使っていけると思います。