Node.js からSalesforceを使う

一応誰かがすでにやっていることですが、ちゃんとしたのが無いので作りました。
GitHub - stomita/node-salesforce: Salesforce API Connection Library for Node.js Applications

インストール

npm 登録済みです。

$ npm install node-salesforce

利用方法

接続
var sf = require('node-salesforce');
var conn = new sf.Connection({
  serverUrl : 'https://na1.salesforce.com',
  accessToken : '<your oauth2 access token is here>'
});

Connectionオブジェクトの引数に、OAuth2の認証フローで得られた情報をそのまま渡してやります。今のところOAuth2のトークンやりとりについてはモジュールに含まれていません。

テスト用にユーザ名/パスワードでログインすることも可能です。

var sf = require('node-salesforce');
var conn = new sf.Connection({
  loginUrl : 'https://login.salesforce.com'
});
conn.login(username, password, function(err) {
  if (!err) {
    // console.log(conn.accessToken);

    //
    // ... logics after authentication ...
    //
  }
});

本来ならこの loginメソッドの実装は OAuth2に則って Resource Owner Password Credential でやるべきかもしれませんが、SOAP APIからだとClient ID/Client Secretが必要ないので、そちらを利用しています。

余談ですが、Salesforce API においては OAuth2 Access Token ≒ Session IDです。SOAP API や埋め込みタブのURLから得たSession ID は、そのままOAuth2 Access Tokenとして利用できます(また逆に、scopeを指定しないで取得したOAuth2 Access Token は SOAP APIのSession IDとしても使えます)。

検索

SOQLでの検索。
検索結果のレコードをイベント駆動的に扱うオプションがあります。autoFetchオプションを渡せばレコード件数が多い場合は自動的にqueryMoreするので、結果セットの取得をアプリケーション側で意識しなくても大丈夫です。

var records = [];
conn.query("SELECT Id, Name FROM Account")
  .on("record", function(record) {
    records.push(record);
  })
  .on("end", function(query) {
    console.log("total in database : " + query.totalSize);
    console.log("total fetched : " + query.totalFetched);
  })
  .run({ autoFetch : true, maxFetch : 4000 });

通常のコールバックスタイルでも利用できます。

var records = [];
conn.query("SELECT Id, Name FROM Account", function(err, result) {
  if (!err) {
    console.log("total : " + result.totalSize);
    console.log("fetched : " + result.records.length);
  }
});
CRUD操作

対応してます。

conn.sobject("Account").retrieve("0017000000hOMChAAO", function(err, account) {
  if (!err) {
    console.log("Name : " + account.Name);
  }
});
conn.sobject("Account").create({ Name : 'My Account #1' }, function(err, ret) {
  if (!err && ret.success) {
    console.log("Created record id : " + ret.id);
  }
});
conn.sobject("Account").update({ 
  Id : '0017000000hOMChAAO',
  Name : 'Updated Account #1'
}, function(err, ret) {
  if (!err && ret.success) {
    console.log('Updated Successfully : ' + ret.id);
  }
});
conn.sobject("Account").del('0017000000hOMChAAO', function(err, ret) {
  if (!err && ret.success) {
    console.log('Deleted Successfully : ' + ret.id);
  }
});

配列指定で複数レコードの一括操作もありますが、SOAP APIと違いレコードごとに一つ一つAPIリクエストを投げるので、注意。

// Multiple records creation consumes one API request per record.
// Be careful for the API quota.
conn.sobject("Account").create([{
  Name : 'My Account #1'
}, {
  Name : 'My Account #2'
}], 
function(err, rets) {
  if (!err) {
    for (var i=0; i<rets.length; i++) {
      if (rets[i].success) {
        console.log("Created record id : " + rets[i].id);
      }
    }
  }
});

未対応

describe系はまだです。

参考

なお、githubにある既存のライブラリでは、以下のものがあります。

https://github.com/gidzone/sfdc-node
=> express依存&あまり再利用考えてなさそうです。

https://github.com/durchblicker/SalesforceAPI
=> 作りかけっぽいかんじ。なんでnpmに登録したかな…

https://github.com/joshbirk/FDC-NODEJS-HEROKU
=> 多分これが一番まともだけど、なぜわざわざHEROKUってつけてるかな?


※ このエントリーはForce.com Advent Calendarに参加しています http://atnd.org/events/22909