2014-11-02

CasperJSでSalesforceのレコード詳細画面を自動キャプチャ

プロファイルのキャプチャを取るのにChromeExtensionとかでキャプチャを手動で取っていたのを

何とかしたかったのでCasperJSで自動化してみました。

 

CasperJSはPhantomJSのユーティリティで、ヘッドレスなブラウザをAPI経由で操ってテストしたり

キャプチャを取ったりすることが出来るツールになります。

 

今回は

  1. SOQLを発行してレコードの一覧を取得

  2. 1で取得したレコードIDを元に各レコード詳細画面に遷移後、キャプチャを取得

という流れでキャプチャを取ってみます。

 

作成物はこちら

ちなみにSOQLで取得できて、取得したIDを使ってhttps://{ドメイン}/{取得したID}のURLで

アクセスできるオブジェクトであれば何でも取得できます(プロファイルのキャプチャもOKです)。

1. 指定オブジェクトのSalesforceIDの一覧を取得

nodejsでjsforce使って指定のレコードIDの一覧を取得します。

# レコード一覧を取得するcoffeescript
program = require("commander")
program
  .version('0.0.1')
  .option('-u, --username <username>', 'Salesforce Username')
  .option('-p, --password <password>', 'Salesforce Password')
  .option('-e, --env [env_type]', 'Salesforce Environment', 'prod')
  .option('-o, --output [outputfile]', 'OutputFile')
  .option('-q, --query [soql]', 'Query', 'SELECT id FROM Profile')
  .parse(process.argv);

fs = require("fs")
jsforce = require('jsforce')
endpoint = if program.env =='test' then 'https://test.salesforce.com' else 'https://login.salesforce.com'
connectOptions = {
  loginUrl : endpoint
}
conn = new jsforce.Connection(connectOptions)
conn.login program.username, program.password, (err, res) =>
  if err
    return console.error(err)
  conn.query(program.query)
      .stream()
      .pipe(process.stdout)

クレデンシャルや実行SOQLをパラメータで与えるためcommanderを利用。

2. SalesforceIDの一覧から詳細ページにアクセスしてキャプチャを取得

1でファイルに保存されたレコードIDの一覧をCasperJSに食わせてキャプチャを取得していきます。

本当は標準入力から取得したかったんですが、うまくいかなかった…。

# 実際にキャプチャを取得するcasperjsのcoffeescript
fs = require('fs')
casper = require('casper').create({
  viewportSize:{
    width: 1280
    height: 800
  }
})
username = casper.cli.options.un
password = casper.cli.options.pw
endpoint = if casper.cli.options.env == 'test' then "https://test.salesforce.com" else "https://login.salesforce.com"
infile = if casper.cli.options.infile then casper.cli.options.infile else 'profilelist.dat'

casper.start()
casper.open endpoint, {
  method: "post"
  data :{
    un: username
    pw: password
  }
}

stream = fs.open(infile, 'r')
casper.then ->
  @wait 3000, ->
    domain = /https:\/\/(.+?\.salesforce\.com)/.exec(@getCurrentUrl())
    # @echo domain[1]
    while !stream.atEnd()
      line = stream.readLine();
      if line == '' then continue
      @thenOpen "https://#{domain[1]}/#{line}", do (line)=>
        return =>
          @capture "#{line}.png"
          @echo @getCurrentUrl()

casper.run()

ログインのエンドポイント(https://login.salesforce.com or https://test.salesforce.com)に対して

un=&pw=のPOSTによる方式でログインを行い

そのあとはレコードIDの一覧から、https://{ドメイン}/{レコードID}のURLに

順々にアクセスしてキャプチャを保存するといった流れになります。

 

ログイン後3秒ほどWaitをかけているのは、ログイン後のSessionIDの割り当て(Cookieへの保存)と

最初のランディングに少々時間を要すためです。(もうちょっとスマートな方法があれば教えて下さい…。)

 

ちなみに、CasperJS(PhantomJS)を使っているのでWebKitベースなレンダリングでキャプチャされます。

IEのTridentを使ってキャプチャしたい場合は、TrifleJSを使用して上記スクリプトを書き換える必要があります。

TrifleJSはCasperJSがまだ対応していないみたいなので、PhantomJS形式で書く必要があり結構シンドイです。

このエントリーをはてなブックマークに追加