Chromeの拡張機能作ってますか?
めんどくさい繰り返しの作業、惰性でやってないですか?
エンジニアとしては無駄は省きたいわけですよ。DRY
怠惰たれ、ということでツール作って遊びながら便利ツールを作るTIPSを共有しようと思います。
Vue.jsを使ってChrome Extensionを作り、Salesforceにリクエストを投げるところまでできるようにします。
テンプレ生成ツール
vue-web-extensionというツールを使うと、Vue.jsを使ったChrome Extensionのテンプレを生成することができます。
vueのcliをインストールしていない場合はまず以下のコマンドを実行。
npm i -g @vue/cli-init
次のコマンドで、Chrome Extensionのテンプレを生成
vue init kocal/vue-web-extension helloworld-tool
初期設定の入力を求められるので、今回は以下のようにしました。
? Project name helloworld-tool
? Project description A Vue.js web extension
? Author XXXX XXXX <xxx@xxx.com>
? License
? Use Mozilla's web-extension polyfill? (https://github.com/mozilla/webextension-polyfill) No
? Provide an options page? (https://developer.chrome.com/extensions/options) No
? Install vue-router? Yes
? Install vuex? No
? Install axios? Yes
? Install ESLint? No
? Install Prettier? No
? Automatically install dependencies? npm
vue-cli · Generated "helloworld-tool".
初期化が完了したら、パッケージをインストールして、ビルドします。
cd helloworld-tool
npm install
npm run build
ビルドが完了したら、Chromeに追加してみましょう。
Chromeの Setting > Extensions > 右上のDeveloper Modeをオン > 左上のLoad Unpackedからプロジェクトの中のdistディレクトリを選択します。
すると、ポップアップでHello world!と表示されたのと、右上に緑色のアイコンが追加されているはずです。緑色のアイコンをクリックするとHelloWorld!と表示されるようになっていると思います。
JSforceでSalesforceと連携
さあ、テンプレが整ったので修正を加えていきましょう。
まずはSalesforceと連携できるライブラリのJSforceをインストール。
npm install jsforce
Chrome Extensionから外部にリクエストを投げる場合は
src/manifest.json に許可するドメインを追加する必要があります。
SalesforceのAPIを実行する場合、以下のようにログイン用のドメイン(test.salesforce.comはSandbox、login.salesforce.comは本番)とログイン後のドメインを記載しておく必要があります。ログイン後のドメイン(XXX.salesforce.com)は各自ご確認後に更新してください。
"permissions": [
"https://test.salesforce.com/",
"https://login.salesforce.com/",
"https://XXX.salesforce.com/"
]
開発中は以下のコマンドで変更を反映しつづけることができるので実行しておきましょう。
Chrome Extensionは随時更新されます。
npm run watch:dev
まずは起動時に表示されるアラートが邪魔なので消しておきましょう。
src/background.js
alert('Hello world!') // 削除
次に、SaleforceのAPIを呼び出した結果を表示する画面を作りましょう。
Show.vueを作ります。
パスワードとセキュリティトークンを繋げることで認証が通ります。
こちらで実装していることの概要ですが、elementへマウントされたタイミングでSalesforceにリクエストを投げて、Accountオブジェクトのレコードを1件取得して、そのレコードのNameを表示します。SalesforceのAPIの実行中はローディングの画面を表示します。また、レコードが見つからなかった場合やその他でエラーが発生した場合はエラーを画面に表示するようにしています。
src/popup/router/pages/Show.vue
<template>
<div>
<div v-if="isLoading">Loading...</div>
<div v-else>
<div v-if="errors.length">
<ul>
<li v-for="(error, index) in errors" :key="index">
{{ error }}
</li>
</ul>
</div>
<div v-else>Name : {{ name }}</div>
</div>
</div>
</template>
<script>
export default {
data () {
return {
name: '',
isLoading: true,
errors: [],
}
},
mounted: function () {
let vm = this;
let jsforce = require('jsforce');
let conn = new jsforce.Connection({
// for sandbox if necessary
loginUrl : 'https://test.salesforce.com'
});
conn.login('hoge@fuga.com', 'PasswordSecurityToken', function(err, res) {
if (err) {
vm.isLoading = false;
vm.errors.push('SYSTEM ERROR');
return console.error(err);
}
conn.query("SELECT Id, Name FROM Account LIMIT 1", function(err, res) {
if (err) {
vm.errors.push('SYSTEM ERROR');
return console.error(err);
}
if (res.records.length === 0) {
errors.push('NOT FOUND');
return;
}
vm.name = res.records[0]['Name'];
}).then(function(){
vm.isLoading = false;
});
});
}
}
</script>
vue-routerでページ遷移できるようにルーティングを修正します。
showを追加しています。
src/popup/router/routes.js
import PageIndex from './pages/Index'
import Show from './pages/Show'
export default [
{
path: '/',
component: PageIndex
},
{
path: '/show',
component: Show
}
]
また、初期画面からSalesforceへのリクエスト画面へ遷移できるリンクを初期画面に追加しておきます。
src/popup/router/pages/Index.vue
<template>
<div>
<p>Hello world!</p>
<router-link to="/show">Get Salesforce Data</router-link>
</div>
</template>
<script>
export default {
data () {
return {}
}
}
</script>
これで、Chrome ExtensionからSalesforceのデータを取得する準備ができました。
ビルドを実行して、緑のアイコンをクリックしてChrome Extensionを実行してみましょう。
“Get Salesforce Data”のリンクをクリックすると、画面が遷移してローディング画面の後に、1件AccountレコードのNameが画面に出てきたかと思います。Accountにレコードがない場合はエラーが表示されるはずです。
Wonderful Chrome Extension Life!
いかがだったでしょうか、簡単にChrome Extensionのテンプレが作成できましたね。
またSalesforceのAPIを呼び出すのも、楽でしたね。
Salesforceを使わなくてもvue-web-extensionは使い勝手がいいですので、独自の便利ツールを作ってみてはいかがでしょうか!
コメント
こちらのvue-web-extensionを利用したいのですが、下記のようにbackground.jsに定義しているはずのstart()という関数がIndex.vue(popup.jsとなります)のメソッドから呼び出せません。
ビルド後のbackground.jsを確認すると確かにstartという関数が存在していないのですが、これはビルドによって関数名が変わってしまうせいなのでしょうか。
対処法が分からず行き詰っております。
何かお分かりになる方がいらっしゃいましたらご回答いただけますと助かります。
エラー内容
TypeError: chrome.extension.getBackgroundPage(…).start is not a function