前口上
結構前ですが、Crystal用のHerokuのbuildpackを作りました。
https://github.com/msky026/heroku-buildpack-crystal
Crystal用のbuildbackは公式含め結構あるので、自分に合うのを使えばいいかと思いますが、個人的には色々と細かく設定できたほうがいいので(特に現在のcrystalは破壊的変更が多いのでバージョン指定が出来ないと辛いのと、frost用にビルドコマンドの指定が必要だったので)、自作してみました。
使い方等はこちらでも解説いただいたり、また技術書典で配布しました「Crystalの本(100円)」に記載していますので今回は端折ります。
crystalforce
さて本題ですが、Herokuに続いてCrystal用のsalesforceのREST APIクライアントを作りました。
というか、Ruby用のrestforceの仕様をベースに見よう見まねで作ってみました。
使い方については大体restforceの簡略版的なものになっていますので、先にこちらの記事を見ていると感覚がつかめると思います。
databasedotcom(gem)、restforceでsalesforceに繋いでみる
salesforceでの設定
sf側での設定手順はだいたい以下のとおりです。
- 接続 -> ビルド -> 作成 -> アプリケーション から 新規の接続アプリケーションを選択し、適当な名前で作成。
- コンシューマ鍵と、コンシューマ秘密鍵を生成。
- コールバックURLはhttp://localhost/callbackとかで。
- 各ユーザの「私の設定」から、アクセストークンの設定(設定したメールに届く)も必要。
作成した接続用アプリの権限も適宜設定しておいてください。
接続アプリケーションの、作成したアプリのOAuthポリシーで、「すべてのユーザは自己承認可能」とかになってないと繋がらないかもしれません。
crystalforceの使い方
取り敢えずインストールはcrystalではお馴染みの、shard.yml
に
dependencies:
crystalforce:
github: msky026/crystalforce
を書いてshards install
で。
使用するときは、ソースに
require "crystalforce"
と書くと使えます。
認証
salesforceに接続するときは以下の設定をします。
client = Crystalforce.new({
:username => "foo",
:password => "bar",
:security_token => "security_token",
:client_id => "client_id",
:client_secret => "client_secret"
})
- username メールアドレス形式のsalesforceのID
- password salesforceアカウントのパスワード
- security_token salesforceアカウントのトークン
- client_id 接続アプリケーションのコンシューマ鍵
- client_secret 接続アプリケーションのコンシューマ秘密鍵
追加オプションで
- api_version salesforceのAPIバージョンを指定(34.0とか割と新しめのにしとくとベター)
- host sandboxに繋ぐときは「test.salesforce.com」を設定
今のところ接続は、上記設定方法のみです。
(restforceはもっといろんな方法ができましたけども)
CRUD
基本的な機能は今のところ、query発行、削除、更新、作成、のCRUDのみです。
query
データを取得したいときはこんな感じです。
testobj = client.query("select Id, Name__c from Testobj__c")
上記で以下の様な結果が返ってきます。
[{"attributes" => {"type" => "Testobj__c", "url" => "/services/data/v34.0/sobjects/Testobj__c/a011000000hhd2oAAA"}, "Id" => "fafdafafad", "Name" => "typeb_1"}, {"attributes" => {"type" => "Testobj__c", "url" => "/services/data/v34.0/sobjects/Testobj__c/a011000000hhd2oAAA"}, "Id" => "a011000000hhd2oAAA", "Name" => "a1"}, {"attributes" => {"type" => "Testobj__c", "url" => "/services/data/v34.0/sobjects/Testobj__c/a011000000ku88tAAA"}, "Id" => "a011000000ku88tAAA", "Name" => "typea_1"}, {"attributes" => {"type" => "Testobj__c", "url" => "/services/data/v34.0/sobjects/Testobj__c/a011000000mLzZ7AAK"}, "Id" => "a011000000mLzZ7AAK", "Name" => "testobj222"}]
クエリに指定したIdとNameをtestobj["Id"]やtestobj["Name"]で参照できます。
query_all
testobj = client.query_all("select Id, Name__c from Testobj__c")
上記でもクエリの結果が取得できますが、queryとの違いは隠しパラメータが見えるかどうかです。
create
以下の手順でデータの作成が行えます。
# Add a new account
client.create('Account', {:Name => 'Foobar Inc.'})
# => '0016000000MRatd'
update
データの更新は以下の用に設定します。
# Update the Account with `Id` '0016000000MRatd'
client.update('Account', '0016000000MRatd', {:Name => 'Whizbang Corp'})
# => true
destroy
最後に削除は以下のとおりです。
# Delete the Account with `Id` '0016000000MRatd'
client.destroy('Account', '0016000000MRatd')
# => true
今後考えていること
restforceでやってたことで、クエリ結果のパラメータをオブジェクトのように参照できないかとか。
例えば、
testobj = client.query("select Id, Name__c from Testobj__c")
の結果はtestobj.Idとかの形で参照できないか、です。ただしこれはrestforceでもMashというツールを使っていることで実現しているのでCrystalでは別の方法が必要ですが。