【Salesforce】ApexクラスでLeadをコンバートさせたい
😎(筆者)「外部からリードをコンバートさせたいなぁ...まあ簡単にできるだろ!!」
(1h後...)
😎 「思ったよりめんどかったやんけ!」
今回、ふと思い出したので備忘録的に記載します。
コード
「設定」 > 「カスタムコード」 > 「Apexクラス」から設定できます。
// リードの検索
Lead ToBeConvertedLead = [select Id from Lead where Id = :leadId];
// LeadConvertオブジェクトを作成
Database.LeadConvert lc = new Database.LeadConvert();
lc.setLeadId(ToBeConvertedLead.id);
// コンバート処理
LeadStatus convertStatus = [SELECT Id, MasterLabel FROM LeadStatus WHERE IsConverted=true LIMIT 1];
lc.setConvertedStatus(convertStatus.MasterLabel);
参照: LeadConvertクラス
解説
- リードの検索
// リードの検索
Lead ToBeConvertedLead = [select Id from Lead where Id = :leadId];
[ ... ]
の記法は、SOQLのステートメントに記載してあります。
Apexクラス内ではこの記法を使っておけば、SQL-likeな検索をかけられますね。
- LeadConvertオブジェクトを作成
// LeadConvertオブジェクトを作成
Database.LeadConvert lc = new Database.LeadConvert();
lc.setLeadId(ToBeConvertedLead.id);
LeadConvertオブジェクトを作成し、コンバート対象リードのIdをオブジェクトに渡しています。
この時点ではまだコンバート処理は行われていません。
ちなみに、setLeadId
は必須項目です。
参照: setLeadId
- コンバート処理
// コンバート処理
LeadStatus convertStatus = [SELECT Id, MasterLabel FROM LeadStatus WHERE IsConverted=true LIMIT 1];
lc.setConvertedStatus(convertStatus.MasterLabel);
ここでは、convertStatus
にId
とMasterLabel
を格納し、MasterLabel
だけsetConvertedStatus
に渡しています。
「じゃあなんでIdも格納してんの?」ってなりますよね。(私もそうなりました。)
調べたところId
はSELECTしなくても動いたので、よくわかりませんでした。
公式の気まぐれですかね。
そして、setConvertedStatus
した時点で、コンバート処理が走ります。
MasterLabelとApiNameについて
筆者の場合は前述の通り、MasterLabel
を使うとエラーが出てしまいました。
調べてみると、StackExchangeに同じ問題が取り上げられていました。
投稿者: They are using MasterLabel for setting the status while conversion. In one of our customer org they had the api name different from the Masterlabel and while i was passing the MasterLabel it always threw a invalid status error. Once i had the api name and Master label as same the error disappeared. So is it best to use api name instead or MasterLabel?
ガバガバ和訳: 「公式ドキュメント通りMasterLabel
使うとエラー出るが、ApiName
にすると動くんだよ。どうしてだ?」
回答者: That's correct, you should use the API Name. Using the masterLabel will throw an exception at runtime. The only exception would be if the masterLabel and apiName are the same (typically when the status is a single word), but this isn't something you can rely on.
ガバg(ry: 「ApiName
使っとけ。」
😎 「これじゃ納得いかんな...(英語よくわからんし!)」
そこで、実際にMasterLabel
とApiName
を取得し、レスポンスを比較してみることにしました。
すると..
// MasterLabel
client.query("SELECT Id, MasterLabel FROM LeadStatus WHERE IsConverted=true LIMIT 1").first
=> {... , "MasterLabel"=>"Hogehoge"} // 頭文字大文字
// LeadStatus
client.query("SELECT Id, ApiName FROM LeadStatus WHERE IsConverted=true LIMIT 1").first
=> {... , "ApiName"=>"hogehoge"} // 頭文字小文字
(レスポンスの値は仮のものです。)
-
MasterLabel
→ リードのStatus
の「値」を取得する -
ApiName
→ リードのStatus
の「API参照名」を取得する
という点で異なることがわかりました。
(少なくとも筆者の場合は)「API参照名」を使ってコンバートしなければいけなかった、ということですね。
また、LeadStatusのドキュメントにも、以下の通り書いてありました。
MasterLabel
説明
このリード状況値の表示ラベル。この表示値は、翻訳されない内部ラベルです。
ApiName
説明
選択リストの値を一意に識別します。これにより ID や主表示ラベルを使用せずに選択リストの値を取得できます。
「翻訳されない内部ラベル」 = Status
の「API参照名」
「選択リストの値」 = Status
の「値」
とも読み取れて 😎「???」 となりましたが...
おわりに
今回使用したLeadConvertのメソッドを見ると、色々なことができそうですね。
訂正箇所などございましたら、ご指摘いただけますと幸いです。
Discussion