Mark Hammer's Blog

SalesforceやTrailheadに関する情報を投稿しているブログです。

項目が空白値でも一時停止要素ありのフローを動作させる

注意

この投稿は Known Issues: Pause element in Schedule Triggered Flow not considering Null value for $Record global variable while checking in Decision element の事象が解消していないことを前提としています。
Known Issueが解決済みの場合は本内容で記載した対応は不要と思われますので、一度Known Issueサイトをご確認ください。

はじめに

フローの要素の1つ、一時停止要素
通常の更新を行うだけならあまり使わない要素ですが、フロー内でコールアウト実行を行う場合は必須の要素となっています。

参考:Salesforceヘルプ: スケジュールトリガーフローに関する考慮事項 より

スケジュールトリガフローは、待機要素を実行した後にのみコールアウトを実行できます。たとえば、待機要素がないと、フローは外部オブジェクトへのアクセス、コールアウトを実行する Apex アクションの実行、または外部サービス登録から生成されたアクションの実行ができません。

この一時停止要素ですが、上述したKnown Issueにより、以下の状況では「$Record.XX__c の値が設定されていないか、割り当てられていないため、フローでこの値にアクセスできませんでした。」というエラーが発生しフローが起動しません。

  • 開始要素の「オブジェクト」でレコードを取得している。
  • 一時停止要素後に「$Record.XX__c」のように$Record変数の項目値を取得しており、かつ実際のレコードではその項目に空白値が入っている。

エラーとなるフロー例の全体像

レコードの更新要素の内容($Record.test2__cが空白値の項目です)

デバッグ画面でのエラー

この問題はWorkaroundがなく、Salesforceサポートに問い合わせても「回避方法はありませんので、一時停止要素の後に空白値がありえる項目にはアクセスしないでください。」と言われます。
ちなみにこの問題は「空白値へのアクセス」がエラーのトリガーとなるため、 IF(ISBLANK({!$Record.XX__c}), "a", {!$Record.XX__c}) のように空白値の項目にアクセスする数式を使うだけでもエラーになります。
…と言われても「一時停止要素の後には空白値がありえる項目には一切アクセスしない」というのは制約が強すぎて不便極まりないです。

ということで、本エラーを回避する方法を調べました。

エラー回避方法

結論としては単純で、以下を行えばOKです。

  • 開始要素の「オブジェクト」でレコードを取得しない。
  • 処理に使用するレコードは「レコードの取得」要素で最初に取得し、ループ内で「一時停止→レコード更新内容の割り当て→レコード更新用コレクション変数に追加」を行い、ループ後にレコード更新を行う。

エラーを回避するフローの全体像

レコード更新内容の割り当て部分

レコード更新用コレクション変数への追加部分

「レコードの更新」要素部分

この場合、ループごとに一時停止が行われますが空白値を含む項目にアクセスしてもエラーにはならず、最後まで処理が流れます。

参考になれば幸いです。

フローのコンテキストによる動作の違い

はじめに

フローのコンテキストには以下の3つがあります。

  • ユーザコンテキスト
    • レコードアクセス権は組織の共有設定、ロール階層等によって決まる。(ユーザが見えないレコードはフローでも取得できない)
    • 実行ユーザのプロファイルおよび権限セットによって、フローのオブジェクト権限および項目レベルのアクセス権が決まる。
  • システムコンテキスト(共有あり)
    • レコードアクセス権は組織の共有設定、ロール階層等によって決まる。(ユーザが見えないレコードはフローでも取得できない)
    • 実行ユーザのプロファイルおよび権限セットは無視され、フローはシステム権限でアクセス可能な全オブジェクト、全項目にアクセスできる。
  • システムコンテキスト(共有なし)
    • システム権限でレコードにアクセスする。(ユーザが見えないレコードでもフローで取得可)
    • 実行ユーザのプロファイルおよび権限セットは無視され、フローはシステム権限でアクセス可能な全オブジェクト、全項目にアクセスできる。

フロー画面での表示

このフローのコンテキストの動作の違いを明確にする機会がありましたので、実際に動作を調べた結果を書いていきます。

調査

概要

まずは以下の画面フローを作成します。

フローチャート

そして以下の条件それぞれで画面フローを実行し、どのような動作になるかを確認します。

  • レコードAをフロー実行ユーザが「見える/見えない」
    • レコードBはフロー実行ユーザが「見える」で固定
  • 「産業コード」項目をフロー実行ユーザが「読み書き不可/読みのみ可/読み書き可」
  • フローコンテキストが「ユーザ/システム(共有あり)/システム(共有なし)」

結果

レコードAが 「産業コード」項目の
アクセス権限
コンテキスト
ユーザ システム(共有あり) システム(共有なし)
見えない 読み書き不可 項目アクセス不可による
レコード取得時エラー
正常終了するが
レコードAの項目値を
取得できないため
空データで更新
正常更新
見えない 読みのみ可 項目アクセス不可による
レコード更新時エラー
正常終了するが
レコードAの項目値を
取得できないため
空データで更新
正常更新
見えない 読み書き可 正常終了するが
レコードAの項目値を
取得できないため
空データで更新
正常終了するが
レコードAの項目値を
取得できないため
空データで更新
正常更新
見える 読み書き不可 項目アクセス不可による
レコード取得時エラー
正常更新 正常更新
見える 読みのみ可 項目アクセス不可による
レコード更新時エラー
正常更新 正常更新
見える 読み書き可 正常更新 正常更新 正常更新

おまけ

今回の投稿はTrailheadの Secure Application Lifecycle Management Superbadge Unit にて"We can't find the expected running contexts for the 'Product Creation' and 'Price Book Entry Creation' flows"エラーがすぐ解決できなかったことが原因でした。 trailhead.salesforce.com

このエラーは以下のTrailblazer Communityでの投稿でも多くのユーザを悩ませているようです。
Trailblazer Community: Secure Application Lifecycle Management Superbadge Unit

前述の調査結果の通り、ユーザのオブジェクトアクセス・項目アクセス権限を適用する場合はユーザコンテキスト、オブジェクトアクセス・項目アクセス権限を無視したい場合はシステムコンテキストということ、そして権限は必要最低限のものを与える(「共有あり」、「共有なし」どちらでもいいなら「共有あり」を選ぶ)を理解すれば解けます。
私のように「項目アクセスできなくてもフローによる更新が必要?よしシステムコンテキスト(共有なし)を適用だ」という思考ではダメです。

参考資料

認定JavaScriptデベロッパー試験勉強で使用したもの

先日、JavaScriptデベロッパー多肢選択試験に合格しました。

他のSalesforce資格試験は当然ながらSalesforceに関する知識を問われますが、この試験で問われるのはJavaScriptの知識だけで、Lightning Web Component含めSalesforceに関する知識は問われません。
(Salesforceに関する知識はJavaScriptデベロッパー資格取得のもう一つの条件であるLightning Web Component Specialist SuperBadgeで問われます。)

ここでは、勉強に使用した資料を書いていきます。

試験勉強用GitHubリポジトリ

github.com

Exercisesフォルダに試験ポイントスタディ(有償研修)にて使用すると思われるコードが入っています。
他の試験ポイントスタディ研修の資料は(恐らく)外部公開されていないことを考えると、太っ腹な対応といえます。
ソースコードのダウンロードはGitクライアントを用意しなくても[Code] ⇒ [Download ZIP]からダウンロードできます。

動作確認方法

VSCodeでリポジトリ内のコードの動作を確認する方法として以下があります。

VSCode上でのデバッグ機能

まずエクスプローラーからソースコードを開きます。

次に左端の「実行とデバッグ」アイコン(三角形と虫のアイコン)をクリックし、「実行とデバッグ」をクリックします。

すると、ブラウザが起動するとともにVSCode上にデバッグ用アイコンが表示されます。

アイコンの内容は以下だけ覚えておけば十分です。

  • 一番左:一気に全部のコードを実行する。
  • 左から2番目:1行ずつコードを実行する。
  • 右から2番目:最初(debuggerの行)からやり直す。
  • 一番右:デバッグを終了する。
VSCodeのLive Server拡張機能

左端の「拡張機能」アイコン(四角形4つで右上だけ飛び出しているアイコン)をクリックし、検索窓に「live server」と入力して最初に表示されるLive Server拡張機能をインストールします。

インストール後、右下に「Go Live」と書かれたアイコンがあるので、これをクリックすることでWebサーバが起動します。停止したい場合はもう一度クリックします。

その他詳細は「live server VSCode 拡張機能」で検索すれば調べられると思います。

使用するツール

Lesson2、Lesson3はVSCode上でのデバッグ機能、Lesson4~Lesson6はLive Server拡張機能を使用したほうが良いと思います。
なお、Lesson7はNode.jsのインストールが必要になります。

MDN Web Docs

developer.mozilla.org

Salesforceのヘルプ、開発者ドキュメントに相当するサイトです。
GitHubリポジトリ内のコードで分からないことがあればここで調べましょう。

セマンティックバージョニング資料

semver.org

docs.npmjs.com

docs.npmjs.com

サーバーサイドJavaScriptセクション範囲です。
1問出るか出ないかですが、覚えれば確実に取れる問題で内容も少ないので覚えておいて損はないです。
「セマンティック バージョニング 2.0.0」の概要は最低覚えてください。
可能であればsemverにある~(チルダ、tilde)と^(キャレット、caret)の両演算子も覚えるとよいです。上のサイトだと英語で分からないという人は検索をかけるとQiitaとかの日本語資料が出るのでそれを参照してください。

Trailheadトレイル:Study for the Salesforce JavaScript Developer I Exam

trailhead.salesforce.com

試験セクションごとに例題とフラッシュカード(単語帳)が用意されています。
このページの問題と単語帳の意味の確認だけでなく、間違った人用に用意されている資料URLも全部アクセスして一通り見ましょう。
各モジュールの最初にモジュールの全内容がPDF形式でダウンロードできるリンクも用意されているので、利用しましょう。

SSOのMFAをSalesforce側で実施しながらAPIログインのMFAを回避する方法の検証

はじめに

SalesforceのMFAが「契約上必須」から「機能上必須」に切り替わりそうなタイミングですが、皆様はMFA対応を進めていらっしゃいますでしょうか。
さて、SalesforceにSSO経由でログインする際もMFAが必要となりましたが、SSO経由の場合はIdP側、SP側(Salesforce)どちらかでMFA対応を行えばよいことになっています。
しかし、Salesforce側でMFA対応を行うには現状プロファイル設定にて [ログインに必要なセッションセキュリティレベル] を [高保証] に設定するしかないのですが、この設定を行うとAPIログイン時にもMFAを求められ、「ユーザ名、パスワード入力方式(Password Authentication)ではデータローダでログインできない」といった状況が発生します。

以前行った検証はこちら↓
sfblog.markhammer.net

このためSSO経由ログインを行う場合はIdP側でのMFA対応が必須と考えていました。
しかし「何か方法がないかな…」と思いながら設定画面を眺めていた時に思いついた方法で今回動作したので、その内容を書いていきます。

検証

今回は以下すべての条件を満たすことを目標にします。

  • SSO経由でSalesforceにログインした場合に、Salesforce側でMFAを行う。
  • データローダでユーザ名、パスワード入力方式(Password Authentication)のログインを行ってもMFAなしでログインできる。
  • Salesforceログイン画面経由でログインした場合はMFAを行う。

結論

以下すべての設定を行えば全条件を満たせました。

  • プロファイル設定にて [ログインに必要なセッションセキュリティレベル] を [高保証] に設定する。
  • プロファイル設定、または権限セットにて「ユーザインターフェースログインの多要素認証」権限を付与する。またはセッションの設定にて「Salesforce 組織へのすべての直接 UI ログインに多要素認証 (MFA) が必要」を有効化する。
  • セッションの設定のセッションセキュリティレベルにて「高保証」に「多要素認証」と「ユーザ名とパスワード」を設定する。

「セッションセキュリティレベル」設定画面

検証の流れ

そもそも [ログインに必要なセッションセキュリティレベル] を [高保証] にしたときにユーザ名・パスワード形式のAPIログインが失敗するのは、セッションセキュリティレベルにて「高保証」に「多要素認証」しかないことが原因です。
しかし、セッションセキュリティレベルにて「高保証」に「ユーザ名とパスワード」も設定できるのを見て、【「高保証」に「ユーザ名とパスワード」を追加すればAPIログインも成功するはず。ログイン画面経由のMFA対応は「ユーザインターフェースログインの多要素認証」権限付与でできるのでは】と思い、試してみました。
以下、試した流れです。

  • 検証①:プロファイル設定にて [ログインに必要なセッションセキュリティレベル] を [高保証] に設定し、セッションセキュリティレベルの「高保証」を「多要素認証」だけにする
    • この場合、SSOログイン時にSalesforce側でMFAを行うことは成功しましたが、データローダでユーザ名、パスワード入力方式によるログインを行うと失敗しました。(前述の投稿と同じ動作)
  • 検証②:検証①+セッションセキュリティレベルの「高保証」を「多要素認証」と「ユーザ名とパスワード」にする
    • この場合、データローダでユーザ名、パスワード入力方式によるログインは成功しましたが、Salesforceログイン画面経由でログインした場合はMFAなしになりました。
      これはセッションセキュリティレベルの「高保証」に「ユーザ名とパスワード」が追加されたため、ログイン画面経由でもMFA不要になったことが原因です。
  • 検証③:検証②+権限セットにて「ユーザインターフェースログインの多要素認証」権限を付与する
    • この場合、Salesforceログイン画面経由でログインした場合でもMFA必須になりました。
      「ユーザインターフェースログインの多要素認証」権限はログインに必要なセッションセキュリティレベルの高保証とは別枠で判断されるようです。
      この状態でデータローダログインを試すと成功し、またSSO経由ログインでもSalesforce側でMFAが必要な動作になりました。
  • 検証④:検証②+セッションの設定にて「Salesforce 組織へのすべての直接 UI ログインに多要素認証 (MFA) が必要」を有効にする
    • この方法でも検証③同様、3条件全てを満たすことができました。

注意事項

そもそもセッションセキュリティレベルの「高保証」は、このヘルプにもある通り機密情報の操作に制限をかけることを目的とした機能です。
「高保証」セッションセキュリティレベルを操作制限に使用している場合は今回の設定はおすすめできません。(実際に設定されているかは「ID検証」設定画面をご確認ください。)

また、今回はSSO経由ログイン時にMFAを求められましたが、Salesforceにとっては高保証のログイン方法でログインできればよいので、「SSO後通常のログイン画面同様ユーザ名とパスワードを求められ、入力すればMFAなしでログイン成功となる」場合がないとは言い切れません。
ただ「ユーザインターフェースログインの多要素認証」権限があるので、この場合は「通常のログイン画面同様ユーザ名とパスワードを求められる→MFAを求められる」流れになる、結果MFA対応OKになるのではないかと予想しています。
(この場合IdP側のパスワードとSalesforceのパスワード両方覚える必要があるので、手間的にNGとなりそうですが)

いずれにしても今回の検証内容はSalesforce側で今後変更されるかもしれない動作ですので、事前の検証を強くお勧めいたします。

認定 Platform アプリケーションビルダー資格の更新 (Winter '23)で"Please make sure the prework is configured in the playground."が出たら

はじめに

Winter '23の資格更新モジュールが出ていますが、認定 Platform アプリケーションビルダー資格の更新 (Winter '23)のハンズオンで「正しい設定をしているはずなのに"Please make sure the prework is configured in the playground."というエラーが出てクリアできない」という問題が起きたのでメモします。

内容

該当モジュールはこちらです。

trailhead.salesforce.com

このChallengeの課題を簡単に説明すると、

  • ユーザ管理設定の「有効期限のある権限セットおよび権限セットグループ」を有効にする(これがprework)
  • 有効期限のある権限セットを有効ユーザに設定する

になります。
詳細な課題内容を日本語で知りたい方は公式日本語訳を参照してください。

が、実際に正しい設定をしているはずなのに、"Please make sure the prework is configured in the playground."(「有効期限のある権限セットおよび権限セットグループ」が有効でない)というエラーが出る場合があります。

エラーメッセージ

対応策

この画面が出た場合は、一度ユーザ管理設定の「有効期限のある権限セットおよび権限セットグループ」を無効にし、再度有効に変えてからChallenge確認ボタンを押してください。

「有効期限のある権限セットおよび権限セットグループ」設定

参考

この事象について、Trailhead Playground作成時に「有効期限のある権限セットおよび権限セットグループ」が最初から有効になっていることが原因との考察があります。
(実際に私の環境も「有効期限のある権限セットおよび権限セットグループ」が最初から有効でした。)

また、問題なくChallenge成功したとの報告もあります。

ちなみに「有効期限のある権限セットおよび権限セットグループ」を有効にして、権限セットを有効期限なし、また30日以外の有効期限に設定すると"The expiration date is not correct."エラーになります。

正しい有効期限にしない場合のエラー

だったら「有効期限のある権限セットおよび権限セットグループ」の内容チェックせずに最初から権限セットの有効期限だけ確認すればよかったんじゃ…

Java18以降の環境でDataLoaderにてShift-JISを扱う方法

はじめに

2022/9に、Salesforceヘルプ:Zulu 18 以降をインストールすると、Windows 版のデータローダで文字化けが発生というヘルプが公開されました。
これはShift-JISのCSVファイルを使用すると文字化けが発生する、というもので、Java18以降のバージョンにて文字セットの指定がない場合、UTF-8をデフォルトの文字セットとして扱うという動作変更が原因です。
Java全体ではこの動作変更により「動作環境によってデフォルトの文字コードがバラバラな状態から固定できる」というメリットがあるようですが、DataLoaderでは起動時に文字セットの指定を行っていないため、Java18以降の環境ではDataLoaderはUTF-8以外は扱えない動作となりました。

現在、DataLoaderの動作環境はJava11以降となっているため、引き続きShift-JISのCSVを使用したい場合はJava11を使用する、というのがSFDCの見解のようですが、Java18以降でもこれまで通りDataLoaderを動作させる方法はないのか調査したところ、 -Dfile.encoding=COMPAT というオプションを付与することでこれまでと同様の動作にできるとのことでした。
ここではDataLoaderで -Dfile.encoding=COMPAT を使う方法と動作確認結果を書いていきます。

オプション付与の方法

環境変数を追加する

Java実行時にオプションを追加するための環境変数として JAVA_TOOL_OPTIONS があります。
この環境変数を使用して、DataLoader起動時に -Dfile.encoding=COMPAT オプションを追加します。
具体的にはコントロールパネル→システム→システムの詳細設定→環境変数の順にアクセスし、システム環境変数に以下の形で追加します。

システム変数として追加

追加した後にDataLoaderを起動すると、コマンドプロンプト(背景が黒い画面)に以下のようにオプションが設定されたことを表す文言が表示されます。

環境変数追加後のDataLoader起動画面

環境変数が追加できない、同じPCでJavaでの開発を行うので影響されたくないなどの理由がなければこちらの利用をお勧めします。

DataLoader起動用batファイルに記載する

DataLoaderとJavaを別にインストールするようになってから、DataLoaderインストールフォルダには dataloader.bat というDataLoader起動用ファイルが存在します。
そのファイルの中にある、 java から始まる行に -Dfile.encoding=COMPAT オプションを以下のように直接書き込みます。

DataLoader Ver56 でのdataloader.bat書き換え

こちらの場合、書き換える場所が分かりにくい*1、DataLoaderの新しいバージョンをインストールするごとに書き換えないといけないという問題があるため、環境変数追加の対応が難しい方のみ行うのがよいかなと思います。

動作確認

ここでは、 -Dfile.encoding=COMPAT オプション有無による動作の違いを確認します。

環境

  • OS: Windows11
  • Java: Zulu OpenJDK バージョン 19.0.1
  • DataLoader: バージョン 56.0.6

動作結果

Export

DataLoaderのオプション、 -Dfile.encoding=COMPAT オプションの有無とExportで出力される文字コードの一覧です。

DataLoaderオプション Javaオプションなし 環境変数追加 dataloader.bat編集
Write all CSVs with UTF-8 encoding 有効 UTF-8 UTF-8 UTF-8
Write all CSVs with UTF-8 encoding 無効 UTF-8 Shift-JIS Shift-JIS
Insert

〇はインポート後のSalesforce側の文字が正常なこと、×は文字化けしたことを表します。

  • CSVにShift-JISを使用
DataLoaderオプション Javaオプションなし 環境変数追加 dataloader.bat編集
Read all CSVs with UTF-8 encoding 有効 × × ×
Read all CSVs with UTF-8 encoding 無効 ×
  • CSVにUTF-8を使用
DataLoaderオプション Javaオプションなし 環境変数追加 dataloader.bat編集
Read all CSVs with UTF-8 encoding 有効
Read all CSVs with UTF-8 encoding 無効 × ×

まとめ

動作結果から、以下が分かりました。

  • Java18以降でJavaオプション -Dfile.encoding=COMPAT がない場合、"Read/Write all CSVs with UTF-8 encoding"オプションは意味をなさず、全てUTF-8で処理される
  • Javaオプション -Dfile.encoding=COMPAT を追加してDataLoaderを起動した場合、これまで通り"Read/Write all CSVs with UTF-8 encoding"オプションにチェックがなければShift-JIS、あればUTF-8で処理される

現状、このような面倒なことを考えずに済むJava11の利用をお勧めしますが、どうしてもJava18以降を使用しないといけないなどの事情がある場合は本投稿を参考にしていただければ幸いです。

参考資料

qiita.com

mail.openjdk.org

openjdk.org

www.gwtcenter.com

docs.oracle.com

*1:DataLoader Ver53のdataloader.batのコードは上記キャプチャと異なりました