【Salesforce自動操作 第6回】ページ読込完了時に処理を開始【vba, chrome拡張機能】

目次

前回のおさらい

前回までで、項目に値を設定する部分の実装がすべて完了しました。

今回やること

今まで右クリックメニューを選択し処理を開始していましたが、今回からページを開いたタイミングで処理が開始するよう修正を加えていきます。
合わせて、VBAからパラメータを受信することを想定した受け口を準備します。

ソースコード 修正箇所

    , "host_permissions": [
        "http://*/"
        , "https://*/"
      ]
    , "permissions": [
        "activeTab"
        , "scripting"
        , "contextMenus"
        , "debugger"
        , "tabs"
    ]

/**
 * インストールイベント
 */
/*
chrome.runtime.onInstalled.addListener(function() {
    const menu = chrome.contextMenus.create({
        type: "normal"
        , id: "contextmenu1"
        , title: "右クリックメニュー"
    });
});
*/

/**
 * 右クリックメニュー選択イベント
 */
/*
chrome.contextMenus.onClicked.addListener((info, tab) => {
    chrome.debugger.attach({tabId: tab.id}, '1.3');
    chrome.scripting.executeScript({
        target: { tabId: tab.id },
        files: ["contentsScript.js"]
      });
});
*/

/**
 * ページオープン/更新イベント
 */
chrome.tabs.onUpdated.addListener((tabId, changeInfo, tab) => {
    if (changeInfo.status !== 'complete') {
        if (tab.url === 'https://testcompany83-dev-ed.develop.lightning.force.com/lightning/o/Case/new?count=1') {
            chrome.debugger.attach({tabId: tab.id}, '1.3');
            chrome.scripting.executeScript({
                target: { tabId: tab.id },
                files: ["contentsScript.js"]
            });
            return;
        }
    }
});
/**
 * 一括登録
 * @param {object} params jsonデータ 
 */
async function bulkInput(params) {

    for (let i = 0; i < params.length; i++) { const p = params[i]; switch(p.type) { case 'search': await selectCombobox(p.name, p.value); break; case 'select': await selectPulldown(p.name, p.value); break; case 'text': await inputText(p.name, p.value); break; } } } async function main() { // ケース作成画面が表示されるまで待機する。 await asyncConditionalWait((args) => {
        return document.querySelector('.actionBody');
    });

    let params = [];
    params.push({type:'select' ,name:'優先度' ,value: 'High'});
    params.push({type:'text' ,name:'Web 会社名' ,value: 'ABCソリューション'});
    params.push({type:'search' ,name:'取引先責任者' ,value: '雪村アオイ'});
    await bulkInput(params);
}
main();

解説

chrome.tabs.onUpdated.addListener((tabId, changeInfo, tab) => { // (1)
    if (changeInfo.status !== 'complete') { // (2)
        if (tab.url === 'https://testcompany83-dev-ed.develop.lightning.force.com/lightning/o/Case/new?count=1') {
            //(中略) // (3)
     }
    }
}
  1. 右クリックメニューに関する処理をすべてコメントアウトし、代わりに、タブが新規オープン/更新されたときに呼ばれるイベントを追加しています。
  2. 読み込み時と読み込み完了時で2回呼ばれるため、完了時であるかの判定を取っています。
  3. 中略の部分の処理はchrome.contextMenus.onClicked.addListenerに記述していたコードと完全に同じです。

また、chrome.tabs.onUpdated.addListenerではページを参照するための権限が求められるため以下2点を追加しています。

    , "host_permissions": [
        "http://*/"
        , "https://*/"
      ]
    , "permissions": [
        , "tabs"
    ]
  • host_permissions:アクセスを許可するサイトのURLを指定する。本来であれば望ましくありませんが、全サイトを対象としています。
  • permissions:tabsを追加しています。
async function main() {
    // ケース作成画面が表示されるまで待機する。
    await asyncConditionalWait((args) => { // (1)
        return document.querySelector('.actionBody');
    });

    let params = []; // (2)
    params.push({type:'select' ,name:'優先度' ,value: 'High'});
    params.push({type:'text' ,name:'Web 会社名' ,value: 'ABCソリューション'});
    params.push({type:'search' ,name:'取引先責任者' ,value: '雪村アオイ'});
    await bulkInput(params);
}
  1. asyncConditionalWaitでページの表示が完了しているまで待機しています。Salesforceはブラウザとしてのページ読み込みが完了した後に中身のノードを動的生成しているため、ページ読み込みが完了した瞬間は入力項目のノードにアクセスをすることが出来ません。
  2. 前回までは、selectCombobox(),selectPulldown(),inputText()を個別に実行していましたが、一括で実行できるようパラメータをjson形式で渡しています。
    
        for (let i = 0; i < params.length; i++) {
            const p = params[i];
            switch(p.type) { // (3)
                case 'search':
                    await selectCombobox(p.name, p.value);
                    break;
                case 'select':
                    await selectPulldown(p.name, p.value);
                    break;
                case 'text':
                    await inputText(p.name, p.value);
                    break;
            }
        }
  3. typeの値によって、どのメソッドを呼ぶべきか分岐を取っています。

実行結果

  • ブラウザにケース作成画面のURLを指定し開きます。
    私の場合(https://testcompany83-dev-ed.develop.lightning.force.com/lightning/o/Case/new?count=1)
  • 「優先度」「Web 会社名」「取引先責任者」がすべて設定されていればOKです。

はまりやすいポイント

特になし。