may the VBA be with you

Excel VBAとか業務自動化とか

Yahoo!ニュースの見出しをChrome拡張とGASでいじってみる

はじめに

Chrome拡張って面白いですよね。
こちらの記事でGASとの連携もできそうだということがわかり、思いついたのが「Googleシートの値をYahoo!ニュースの見出しに表示できたら面白いかも!」でした。
qiita.com
思いついてしまったので、実装してみます。

必要なもの

見出しが8個あるので、googleシートのA1~A8セルに表示したいものを入れておきます
f:id:vba-belle-equipe:20210606141034p:plain

GAS側

doGetだけ作って、Webアプリとして公開しておきます

function doGet(e){
  
  //値をシートから取得
  const ss = SpreadsheetApp.getActiveSpreadsheet();
  const sheet = ss.getSheets()[0];
  const range = sheet.getRange(1,1,8,1);    //A1~A8までのrangeを指定
  const values = range.getValues();  
  let res = {};  //chrome拡張側に渡すオブジェクト
  for(let i = 0; i < 8; i++){
    let propName = "str" + (i + 1);
    res[propName] = values[i][0];
  }

  // エクステンションにレスポンスを返す
  const output = ContentService.createTextOutput();
  output.setMimeType(ContentService.MimeType.JSON);
  output.setContent(JSON.stringify(res));
  return output;
}

Chrome拡張側

manifest.json
background.js
content.js

の3つのファイルを同じフォルダに置いて、Chrome拡張機能として読み込ませます

manifest.json
{
  "manifest_version": 2,
  "name": "yahooニュース見出し変える",
  "version": "1.0",
  "permissions": [
    "https://script.google.com/*"
  ],
  "content_scripts": [
    {
      "matches": [
        "https://www.yahoo.co.jp/*"
      ],
      "js": [
        "content.js"
      ]
    }
  ],
  "background": {
    "scripts": [
      "background.js"
    ],
    "presistent": false
  }
}
background.js
chrome.runtime.onMessage.addListener(
  function (request, sender, callback) {
    console.log(`バックグラウンドで受け取ったもの: ${request.message}`);

    // 「ウェブアプリ」としてデプロイしてるGASのURL
    const gasUrl = [自分のURLを入れる];

    fetch(gasUrl)
    .then(response => {
      return response.text();
    })
    .then(json => {
      console.log(`GASからのレスポンス: ${json}`);
      callback(JSON.parse(json));
    });

    // 非同期を同期的に扱うためのtrue
    return true;
  }
);
content.js
console.log("content.js開始");

chrome.runtime.sendMessage({
  message: ""
}, response => {

  console.log(`backgroundからの戻り値: ${JSON.stringify(response)}`);

  //aria-label属性があるタグをfor文で回して
  //値が「主要 ニュース」となっているdivを対象にする
  let tags = document.querySelectorAll('[aria-label]');
  for (let i = 0; tags.length; i++){
    let str = tags[i].getAttribute("aria-label");
    if(str == "主要 ニュース"){
      let spans = tags[i].getElementsByTagName('span');
      let cnt = 0;

      //見出しっぽいspanを文字数や除外文字列でなんとなく指定する
      for (let j = 0; spans.length; j++) {
        let buf = spans[j].textContent;
        if(buf.length > 10 && buf.slice( -2 )!="更新"){
          cnt++;
          let propName = "str" + cnt;
          spans[j].textContent = response[propName];
          //8個セットできたら抜ける
          if(cnt >= 8){
            break;
          }
        }
      }
      break;
    }    
  }
});

結果

f:id:vba-belle-equipe:20210606141128p:plain
うまくいきました。

念のため言いますが、世の中の、他の人が見ているYahoo!ニュースの見出しは変わりません。

解説など

基本的な作りはほぼお手本の通りなので、リンク先をご参照ください。
qiita.com

見出しの文字列データはオブジェクトのキー(str1,str2....)に値(A1, A2... のセルの値)をセットして渡しています。

注意事項など

  • Chrome以外に、Edgeでも一応動くみたいです
  • 試してみる場合は、自己責任でお願いします(特に、他の人が該当ブラウザを使う場合は気をつけてください)
  • サイトのタグ構成とかは変わると思われるので、いつまでも動くものではないです