メインコンテンツへスキップ
見出し画像

プログラミングで推しクリエイターの新規投稿をGet!ポチッ

    プログラミングで、
    noteを使いやすくできるのでは?!


    1ヶ月ほど前に読んだ
    MitakaDaiさんの記事の内容が
    頭を離れなくなりました。

    詳細は記事を読んでいただきたいのですが、
    簡単に概要を記載するとこんな感じです。

    ・noteは相互フォローが多い
    ・フォロー数が膨大になると、
     推しクリエイターの記事が埋もれる

    この記事の後に、
    半端ない分析記事を出されていて、
    私の中では、

    "分析の達人"

    というイメージがつきました🤭

    🌟 半端ない分析記事
    【note】「フォロー戦略」と「フォロワー数」「スキ数」との関係性


    もともとは本田すのうさんが、

    「推しの記事は毎日見たいけれども、
     推しの最新記事が"フォロー中"のタブに
     埋もれてて気がつかないことがある。」

    というお悩みを
    話されていたことからはじまりました。


    1ヶ月間、
    モヤモヤしていたのですが、
    昨日ひらめきました。


    プログラミングで
    推しクリエイターの記事を
    出せないか?


    というわけで、作ったのがこちらです

    画像

    Chromeの拡張機能というのを使っています。

    右上のボタンを押すと、
    フォロー中のページに表示されている
    推しクリエイターの記事を抽出してくれます。

    Chrome拡張機能というのは、
    簡単に自作できて使い勝手がとても良いです。

    作り方は、
    インターネットの記事のほうが詳しいので、
    この記事では概要だけお伝えします。

    Chrome拡張機能は、
    4つのファイル構成となってます。

    • manifestファイル (権限や初期画面等の設定)

    • HTMLファイル (画面表示)

    • JavaScriptファイル (プログラム)

    • Imageファイル (アイコン)


    プログラムの流れと合わせて、
    簡単にご紹介します。


    まずは、
    manifestファイルです。

    ここでは権限の設定や、
    アイコンクリック時に開くHTMLファイルを
    指定しています。

    以下、実際のコードです。

    ・manifest.json

    {
      "manifest_version": 3,
      "name": "Data Fetcher",
      "version": "1.0",
      "permissions": [
        "activeTab",
        "tabs",
        "scripting",
        "storage"
      ],
      "background": {
        "service_worker": "background.js"
      },
      "action": {
        "default_popup": "popup.html"
      },
      "icons": {
        "48": "icon.png"
      },
      "host_permissions": ["http://*/*", "https://*/*"]
    }

    上記の"default_popup"という設定で、
    popup.htmlを設定しています。

    これにより、
    右上のボタンを押すと、
    ポップアップの画面が呼び出されています。

    画像

    ポップアップ画面を構成しているファイルは
    ホームページを制作したことがある方なら、
    馴染みのあるHTMLです。

    ・popup.html

    <!DOCTYPE html>
    <html>
    <head>
      <meta charset="UTF-8">
      <title>Fetch Data</title>
      <style>
        body { width: 300px; }
        button { margin: 20px; }
      </style>
    </head>
    <body>
      <button id="fetchData">推しメンタイムライン確認</button>
      <script src="popup.js"></script>
    </body>
    </html>

    とてもシンプルです。

    <button>タグでボタンを表示して、
    押された場合にpopup.jsを呼び出します。


    popup.jsのコードはこちら。

    ・popup.js

    document.getElementById('fetchData').addEventListener('click', () => {
    
      const initialUrl = "https://note.com/following";
    
      chrome.tabs.query({ url: initialUrl }, (tabs) => {
        if (tabs.length > 0) {
            // URLが既に開かれている場合、そのタブをアクティブにする
            chrome.tabs.update(tabs[0].id, { active: true });
            console.log('Tab created, ID: ' + tabs[0].id);
            chrome.runtime.sendMessage({ action: 'fetchData', tabId: tabs[0].id });
        } else {
            // URLが開かれていない場合、新しいタブで開く(未実装)
            // chrome.tabs.create({ url: initialUrl });
            // chrome.runtime.sendMessage({ action: 'fetchData', tabId: tab.id });
        }
    });
    });

    popup.htmlから呼び出されて、
    フォロー中のページ(https://note.com/following)の
    表示あり/なしを確認します。

    画像

    表示されていればその画面を利用し、
    表示されていなければ新規にページを開きます。

    今回は試しで作ったので、
    表示されている画面を利用するパターンだけを
    実装しました。


    "sendMessage"という処理に入ると、
    manifest.jsonで設定していた"service_worker"
    という設定のファイルを呼び出します。

    ・manifest.json

      "background": {
        "service_worker": "background.js"

    呼び出されるのは、
    設定されているbackground.jsとなります。

    実際のコードを載せますが、
    かなり長くなってます。

    作りたい方向けに全部載せてますので、
    説明を読みたい方はスキップしてください。

    ・background.js

    chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
      if (request.action === 'fetchData') {
        chrome.scripting.executeScript(
          {
            target: { tabId: request.tabId },
            function: fetchDataFromNote
          },
          (result) => {
            if (chrome.runtime.lastError) {
              console.error('Script execution failed:', chrome.runtime.lastError.message);
              return;
            }
    
            if (Array.isArray(result) && result.length > 0 && result[0].result) {
              const fetchedData = result[0].result;
              console.log('Script executed, result:', fetchedData);
    
              // データをループして処理する
              fetchedData.forEach(data => {
                console.log('Fetched Data:', data);
                // ここでデータの処理を行う(例: データを保存、表示など)
              });
    
              chrome.storage.local.set({ fetchedData: fetchedData });
              chrome.tabs.create({ url: 'data.html' });
            } else {
              console.error('No valid data returned from script execution');
            }
          }
        );
      }
    });
    
    function fetchDataFromNote() {
      const targetStrings = ["クロサキナオ", "lion", "みかん", "MitakaDai"]; // 複数の文字列を配列に設定
      const figures = document.querySelectorAll('#__layout > div > div:nth-child(1) > div:nth-child(3) > div > div.t-timeline-new__body > div.p-4.sm\\:px-6.sm\\:pt-1.sm\\:pb-6 > div.sm\\:hidden > figure');
    
      const data = Array.from(figures)
        .map(figure => {
          const spanElement = figure.querySelector('div.o-horizontalTimeLineNote__body > div.o-horizontalTimeLineNote__content.o-horizontalTimeLineNote__content--horizontal > div > div > div.o-horizontalTimeLineNote__user > a > span');
          const aElement = figure.querySelector('a');
    
          const spanText = spanElement ? spanElement.innerText : null;
          const aText = aElement ? aElement.href : null;
    
          return { spanText, aText };
        })
        .filter(item => (item.spanText !== null || item.aText !== null) &&
          (targetStrings.some(target => (item.spanText && item.spanText.includes(target))) || targetStrings.some(target => (item.aText && item.aText.includes(target)))));
    
      return data;
    }

    フォロー中のページから、
    気になるクリエイターの方を抽出します。

    クリエイターの方は、
    こんな感じで定義しています。

    const targetStrings = ["クロサキナオ", "lion", "みかん", "MitakaDai"]; // 複数の文字列を配列に設定


    どのようにフォロー中の画面から
    抽出するかというと、
    セレクタという仕様を使います。

    セレクタは、
    WEBページで指をさしたところから
    データを取得するイメージです。

    まず、
    クロサキナオさんの枠全体を指さします。

    画像

    枠全体を指さししたら、
    次に"名前"と"URL"を2つセットで取得します。

    画像

    この処理を推しメン全員分実行し、
    最後に結果を画面に表示してあげます。

    表示先はdata.htmlとしました。

    chrome.tabs.create({ url: 'data.html' });

    data.htmlもシンプルな実装ですが、
    取得したデータを成型するため、
    data.jsを呼び出すようにしています。

    ・data.html

    <!DOCTYPE html>
    <html>
    <head>
      <meta charset="UTF-8">
      <title>Fetched Data</title>
      <script src="data.js"></script>
    </head>
    <body>
      <h1>推しメンタイムライン更新リスト</h1>
      <ul id="dataList"></ul>
    </body>
    </html>

    data.jsを使い、
    "名前"と"URL"を分けて画面表示するよう
    設定し直してしています。

    ・data.js

    document.addEventListener('DOMContentLoaded', () => {
        chrome.storage.local.get('fetchedData', (result) => {
          const dataList = document.getElementById('dataList');
          const fetchedData = result.fetchedData || [];
      
          fetchedData.forEach(item => {
            const listItem = document.createElement('li');
            listItem.textContent = `名前: ${item.spanText || 'N/A'}, URL: ${item.aText || 'N/A'}`;
            dataList.appendChild(listItem);
          });
        });
      });

    結果、
    最終的にはこのような画面が表示されます。

    画像

    抽出対象としていた
    みかんさんとMitakaDaiさんは、
    ツールを動かした際に
    直近で投稿をしていなかったため、
    抽出されていません。

    クロサキナオさんとlionさんは、
    直近で投稿をしていたので表示されました。


    ただ、
    フォロー中のページには、
    50〜60件程度しか初期表示されていないので、
    抽出可能な量が少ないです。

    ページ内で下に何回かスクロールすると、
    多く記事が表示されるので良いかもしれませんね。

    まだ改善の余地はありますが、
    いったん基礎は出来上がりました。


    もしも作成してみたい方は、
    この記事にプログラムを載せていますので、
    下記の通り1つのフォルダに配置して、
    Chrome拡張機能に読み込ませてみてください。

    画像

    *icon.pngは下記をご利用ください。
     48px × 48pxならなんでもOKです。

    画像


    しかし、
    ここで重要なことに気づきます。


    noteって
    スマホで使う人が多いのでは?


    電車の中とかの空いてる時間で、
    読みたいですもんね。

    スマホで改良版を作ろうと思っていた矢先。

    調べていると、こんな記事が。


    noteアプリでクリエイターの更新通知を受け取れます

    なになに…?


    「noteアプリを使えば、
     推しクリエイターの記事が新規投稿された時に、
     通知がくるヨ。」




    も
    う
    あ
    っ
    た




    昨日の実装3〜4時間は
    いったいなんだったのか


    2023年9月にできていた機能だったとは。
    1年作るのが遅かったですね笑


    いかがでしたでしょうか。

    みなさんも、
    なにかに着手される前は
    ちゃんと調べてからにしましょう🤣

    でも、
    推しクリエイターの新規投稿以外にも
    便利にできる要素もあるかもしれませんので、
    今後もアイデアがあれば何か作ってみたいと思ってます。


    ばーこしってどんな人?



     
     
    IT業界歴13年のシステムエンジニアです😊 社内イベントやプレゼントが得意で笑顔を届けるためにコンテンツを発信しています✨過去の社内イベントでは「君に依頼してよかった!」、送別プレゼントでは渡した本人からはもちろんのこと、周囲の人から逆に欲しいという声を頂いた経験があります!

    あなたへのおすすめ