はじめに
Salesforce Migration Tools(Ant)の話です。ApexClassなどは*
が使えるので、簡単に全てのメタデータをダウンロードすることができますが、*
が使えないメタデータのダウンロードに苦労したことはないでしょうか。
その中でも特に面倒なFolder, Document, Dashboard, EmailTemplate, Reportのダウンロード方法を紹介します。
参考。Allows WildcardがNoのやつは爆発しろ。
https://developer.salesforce.com/docs/atlas.en-us.daas.meta/api_meta/meta_types_list.htm
ちなみにこのページ、日本語版だと「ダウンロー
ド」よりひどいことになります
https://developer.salesforce.com/docs/atlas.ja-jp.api_meta.meta/api_meta/meta_types_list.htm
listMetadata
*
が使える使えないに関係なく、Metadata APIにはlistMedatadaという機能があって、指定したメタデータタイプのコンポーネント一覧を取得することができます。
https://developer.salesforce.com/docs/atlas.ja-jp.api_meta.meta/api_meta/meta_listmetadata.htm
jsforceだとこんな感じで使えます。注意しないといけないのは、ListMetadataQueryは3つまでしか指定できないというところです。このせいでReportなどのlistMetadataが面倒なんです。
var connection = new jsforce.Connection()
connection.login(username, password)
.then(function() {
return connection.metadata.list([{type: 'ApexClass'}]);
})
.then(function(components) {
console.log(components);
})
フォルダのlistMetadata
Document, Dashboard, EmailTemplate, Reportはフォルダの中に入っており、listMetadataするときはフォルダを指定する必要があります。
connection.metadata.list([{type: 'Report', folder: 'MyReportFolder'}]);
じゃあこのフォルダはどうやって調べるかというと、相変わらず*
は使えないので、こんな風にします。
connection.metadata.list([{type: 'ReportFolder'}]);
これドキュメントに明確な記載がないと思いますが、以下のように対応しています。(EmailTemplateのフォルダがEmailTemplateFolderじゃないのはホントどうかと思います…)
コンポーネント | フォルダ |
---|---|
Document | DocumentFolder |
Dashboard | DashboardFolder |
EmailTemplate | EmailFolder |
Report | ReportFolder |
なお、フォルダをretrieveやdeployするときのpackage.xmlには、<name>ReportFolder</name>
ではなくて<name>Report</name>
の方の<types>
に記述します。
フォルダ内コンポーネントのlistMetadata
フォルダのlistMetadata→コンポーネントのlistMetadataとすれば、目的のコンポーネント一覧を取得できます。最初はこんなふうにかくと思いますが…
connection.metadata.list([{type: 'ReportFolder'}])
.then(function(folders) {
var query = folders.map(function(e) {
return {type: 'Report', folder: e.fullName}
});
return connection.metadata.list(query)
})
.then(function(reports) {
console.log(reports);
})
いくつか落とし穴があるので気をつけてください。
- ListMetadataQueryは3つまでです。上の例は、フォルダが3つ以内じゃないとダメです
- listMetadataの結果が0の場合、コールバックの引数はundefinedです。
- listMetadataの結果が1つの場合、コールバックの引数が配列になりません
作りました
Document, Dashboard, EmailTemplate, Report, DocumentFolder, DashboardFolder, EmailFolder, ReportFolderをlistMetdataして全部retrieveUnpackagedするサンプルを書きました。よろしければご利用ください。
Node.jsさえあれば動きます。npm install -g coffee-script
したあとnpm install
してください。実行はcoffee retrieve_folders.coffee
です。メタデータをretrieveUnpackagedして、unpackagedディレクトリに展開します。
以下の環境変数を設定してください。(SALESFORCE_HOSTは任意)dotenvを使っているので.env
というファイルを作ってそこに書いてもいいです。
SALESFORCE_USERNAME=ユーザ名
SALESFORCE_PASSWORD=パスワード+必要ならセキュリティトークン
SALESFORCE_HOST=login.salesforce.com
listMetadataを3個ずつ発行して統合するところがややこしくなっています。