Apexをローカル環境で動かすのめっちゃムズイし現実逃避したくなったので
SalesforceのワークフロールールをApexトリガに変換するヤーツを作りました。
できること
- ワークフローのメタデータのXMLからApexトリガのコードを自動生成します
- 今のところワークフロー+項目自動更新しか対応していません
- 数式は70%くらい対応してますが、対応してないものに関してはボチボチやっていきます
- ゆくゆくはプロセスビルダーとかもApex化しようと思ってます
- あんまりテストしていないので不具合あればissue切ってもらうかPRくだしあ
使い方
$ npm install -g salesforce2apex
からの
$ salesforce2apex -o {object名} -f {ワークフローのメタデータへのパス}
って感じで叩くと標準出力にトリガーのコードが出力されます。トリガー名は{オブジェクト名のCamelCase} + Trigger
になります。
例えばこんな感じなワークフローメタデータを食わせると
<?xml version="1.0" encoding="UTF-8"?>
<Workflow xmlns="http://soap.sforce.com/2006/04/metadata">
<fieldUpdates>
<fullName>test</fullName>
<field>TextTest__c</field>
<formula>iF(true, "BBB", "CCC")</formula>
<name>test</name>
<notifyAssignee>false</notifyAssignee>
<operation>Formula</operation>
<protected>false</protected>
<reevaluateOnChange>true</reevaluateOnChange>
</fieldUpdates>
<fieldUpdates>
<fullName>test2</fullName>
<field>TextTest__c</field>
<formula>"AAA"</formula>
<name>test2</name>
<notifyAssignee>false</notifyAssignee>
<operation>Formula</operation>
<protected>false</protected>
<reevaluateOnChange>true</reevaluateOnChange>
</fieldUpdates>
<rules>
<fullName>TestWorkFlow</fullName>
<actions>
<name>test</name>
<type>FieldUpdate</type>
</actions>
<active>true</active>
<criteriaItems>
<field>TestObject__c.TextTest__c</field>
<operation>equals</operation>
<value>AAA</value>
</criteriaItems>
<triggerType>onAllChanges</triggerType>
</rules>
<rules>
<fullName>TestWorkFlow2</fullName>
<actions>
<name>test2</name>
<type>FieldUpdate</type>
</actions>
<active>true</active>
<criteriaItems>
<field>TestObject__c.TextTest__c</field>
<operation>equals</operation>
<value>BBB</value>
</criteriaItems>
<triggerType>onAllChanges</triggerType>
</rules>
</Workflow>
こういうApexトリガが出力されます(インデントの調整が甘いです)
trigger TestObjectTrigger on TestObject__c (before update, before insert) {
if (Trigger.isBefore && (Trigger.isInsert || Trigger.isUpdate)) {
for (TestObject__c newRecord : Trigger.New) {
TestObject__c oldRecord = Trigger.oldMap.get(newRecord.id);
if (newRecord.TextTest__c == 'AAA') {
String tmp1;
if (true) {
tmp1 = 'BBB';
} else {
tmp1 = 'CCC';
}
newRecord.TextTest__c = tmp1;
}
if (newRecord.TextTest__c == 'BBB') {
newRecord.TextTest__c = 'AAA';
}
}
}
}
仕組み
- えーと、XMLパースしてApexコード出すだけw
- 数式だけはきちっとAST作ってツリー辿ってApexコード化する必要があった
- ので、Salesforce数式をAST化するヤーツ作った
- CLI化はoclif使ったよ
- ジェネレータで一通り作ってくれるしCLIに必要なあれこれも揃っているのでとても便利
補足
- メールアラート対応しないの?
- 変数バインドとか面倒だしそもそもワークフロールールでメール自動送信とか危ない橋だと思っているので私自身は対応しない予定ですが、PRが来れば取り込むかなーという感じ
- タイムトリガ対応しないの?
- バッチクラスとか必要で面倒だし、そもそもタイムトリガはアンチパターンだと思ってるので対応しない
- 数式のビルドはSalesforceにまかせて通っている前提で書いているので、apexのローカル実行基盤よりも数百倍楽だった