TECHNICAL BLOG

2021/10/25 # 使ってみた # ツール # 便利 # やってみた 2021/10 JXAでMac作業を効率化

今まで、開発画面・STG管理画面・AWSログインなどブラウザでアクセスするものは、Chromeブックマークかテキストに保存。

ローカル開発サーバの起動やSSH接続はシェルに。と適材適所という考えで、操作や情報が散り散りになっていました。

最初は特に不便を感じていなかったのですが、複数のプロジェクトに関わり1日の中で何度もSSHやAWSログインを切り替えるようになりました。

そうなってからは、もっとパパッと、かつ、間違えなく切り替えたいという欲求が出てきました。結果、JXAを使うことで効率化を図れたので、JXAについて紹介します。

スクリプトエディタ画面

JavaScript for Automation

まずMacにはAppleScriptという、Windows Script HostのMac版のようなものがあります。
AppleScriptはスクリプト言語で、ファイル操作やアプリ起動などが自由にできます。さらにMacに元から備わっている機能で、何もインストールしなくても使えます。

そして、JXAはAppleScriptのJavaScript版のようなもので、正式名称はJavaScript for Automationと言います。

2014年Yosemiteから搭載され、年数も経つので小慣れてきておりネットにも情報が増えてきました。

何が便利か?

ただ効率化するだけならシェルでも良さそうなものですが、JXAのどういうところが便利だと感じたかと言うと

  • 書くだけでいい。インストール作業がない
  • JavaScriptでかける
  • iTermもChromeも実行できる
  • 上部メニューバーからさっとクリックするだけで実行

色々なアプリを操作できるところはOS標準機能の強みですね。

上部メニューバー画像

JXAコードを/Users/xxxx/Library/Scriptsに置くだけで、メニューバーから実行できます。
結果、冒頭で説明させていただいたような作業が操作的に1箇所に集約でき、さらに手数少なく効率的であることがイメージできる思います。

それでは、JXAは実際どんなコードになるのか、以下2例紹介します。

SSH接続

ロジックとしては、iTermが起動していなくても、起動していても新しいiTermを立ち上げ、ウィンドウ > タブ > セッションと取得し、実行したいコマンドを流すだけです。

const sys = Application('com.apple.SystemEvents');

const iTerm2 = Application('iTerm');
// iTerm起動している場合
if(sys.processes['iTerm2'].exists()){
    // 新しいiTerm起動
    iTerm2.createWindowWithDefaultProfile();
}else{
    // 起動していないので、アプリ起動させる
    iTerm2.activate();
    delay(0.5);
}

const window = iTerm2.currentWindow();
const tab = window.currentTab();
const session = tab.currentSession();
// コマンド実行
session.write({text: 'ssh xxx@125.125.125.125 -i  ~/.ssh/sample.pem'});

やりたいこと次第ですが、例えばビルドコマンドを一つ一つ実行している作業を、自動化し確実で効率良くさせられると実感してもらえると思います。

AWSコンロール自動ログイン

まずこちらはChromeを対象としています。Apple EventsからのJavaScriptを許可してください。
許可せずに以下のコードを実行するとエラーとなり、実行されません。

スクリプトエラー

処理としては、AWSログイン画面を表示して、ページ内にJavaScriptを流し込みユーザ・パスワードを入力しています。

JavaScriptの流し込みは力技です。ログイン画面が変わってしまったら動作しなくなるでしょう。
その時は、入力フォームを解析し修正する必要があります。解析・修正するのは手間ですが、毎日手作業でログインするよりはマシだと思います。

const app = Application('Google Chrome');
app.activate();
const win = app.windows[0]

// AWSログインURL
const tab = app.Tab({url:'https://XXXXXXXXX.signin.aws.amazon.com/console'});
win.tabs.push(tab);

// ログインページ読み込み待ち
for(let i = 0; i < 30; i++){
    if(tab.loading()){
        delay(0.5);
        continue;
    }
    break;
}

// ページ内でJS実行
tab.execute({javascript: `
    document.getElementById('username').value = "ユーザID";
    document.getElementById('username').dispatchEvent(new Event('change'));
    document.getElementById('password').value = "パスワード";
    document.getElementById('password').dispatchEvent(new Event('change'));
`});

自動ログインと紹介させていただきましたが、上記コードでは自動的にログインはされません。
あくまでユーザ・パスワードが入力された状態になるだけで、ログインボタンは自分でクリックする必要があります。

これは、間違って別プロジェクトにログインしないための、個人的な工夫です。
ページ内用のJSコードにクリック処理を追加すれば、自動ログインできます。

終わりに

数行の実装で簡単にターミナルやブラウザを自動化できることを実感していただけたと思います。
また、世の中には便利なツールは色々ありますが、ツールのバグや悪意ある実装で情報流出が怖いという方にもオススメです。

ただし、本紹介のコードではパスワード等を直接埋め込んでいますので、間違ってgit等にコミットしたりSlackでそのまま展開しないなど、ソースコードの扱いには気をつけてください。

あくまで、自身のPC内に留めておくことが良いでしょう。

JXAに興味をもっていただけたら、ぜひ一度お試しください。