Salesforce Service Consoleをマスターする:Lightning Console JavaScript API活用開発ガイド

背景と応用シーン

Salesforce のエコシステムにおいて、Service Console (サービスコンソール) は、特にカスタマーサービス、サポート、営業担当者など、複数の顧客情報やレコードを同時に、かつ迅速に処理する必要があるユーザーの生産性を飛躍的に向上させるために設計された強力なインターフェースです。従来の Salesforce UI が一度に一つのレコードを表示することに主眼を置いているのに対し、Service Console はタブベースのワークスペースを提供し、ユーザーがコンテキストを失うことなく、関連するレコード(例えば、取引先責任者、ケース、商談など)をプライマリタブやサブタブとして同時に開いて作業することを可能にします。

例えば、あるサポートエージェントが顧客からの電話を受けているシナリオを想像してみてください。エージェントはまず顧客の取引先責任者レコードをプライマリタブで開き、その下に今回の問い合わせ内容であるケースレコードをサブタブとして開きます。会話の中で過去の関連ケースや、現在進行中の商談について言及があった場合、エージェントはさらに別のサブタブでそれらのレコードを開くことができます。これにより、画面を切り替えることなく、必要なすべての情報に一つの画面からアクセスでき、顧客対応の質とスピードを大幅に改善することができます。

この強力な Service Console の標準機能だけでも十分に効率的ですが、Salesforce 開発者の真価が発揮されるのは、このコンソール体験をビジネスプロセスに合わせてさらにカスタマイズする場面です。例えば、「特定の条件を満たすケースが作成されたら、自動的に関連ナレッジ記事をサブタブで開く」「ボタン一つで、現在開いている商談に関連するすべての取引先担当者連絡先を一覧表示し、選択した連絡先をサブタブで開く」といったカスタム機能を実装することで、手作業を削減し、業務プロセスを自動化できます。これを実現するための中核技術が、Lightning Console JavaScript API です。本記事では、Salesforce 開発者の視点から、この API を活用して Service Console の能力を最大限に引き出す方法について、原理から具体的な実装までを詳しく解説します。


原理説明

Service Console の動的なタブ操作は、クライアントサイドの JavaScript API を通じて行われます。開発者が Lightning Web Components (LWC) や Aura Components 内でこの API を呼び出すことで、コンソール内のタブの作成、クローズ、フォーカス、更新などをプログラムで制御できます。

現在、LWC での Service Console 操作において推奨される方法は、lightning/platform-workspace-api モジュールを使用することです。これは、従来の Aura Component で使用されていた <lightning:workspaceApi> の後継であり、よりモダンでパフォーマンスに優れた LWC の標準的なアプローチです。

lightning/platform-workspace-api は、Wire サービスアダプタとして提供されており、コンポーネントに Workspace API のインスタンスをインポートして使用します。この API は非同期で動作し、ほとんどのメソッドは Promise を返します。これにより、タブ操作の成功・失敗をハンドルし、後続の処理を確実に行うことができます。

主な Workspace API の機能

  • openTab(options): 新しいプライマリワークスペースタブを開きます。レコードページ、URL、LWC など、様々なコンテンツを開くことができます。
  • openSubtab(options): 現在フォーカスされているプライマリタブの下に、新しいサブタブを開きます。これも同様に、多様なコンテンツを指定可能です。
  • getFocusedTabInfo(): 現在アクティブなタブ(またはその親タブ)に関する情報を取得します。タブの ID やレコード ID などを取得でき、他の API メソッドの引数として利用することが多いです。
  • closeTab({tabId}): 指定された ID のタブを閉じます。
  • refreshTab({tabId}): 指定されたタブのコンテンツをリフレッシュします。データの変更を画面に反映させたい場合に便利です。
  • setTabLabel({tabId, label}): タブの表示ラベルを動的に変更します。例えば、ケースの優先度に応じてラベルを変更するなど、視覚的なフィードバックを与えるのに役立ちます。
  • setTabIcon({tabId, icon, iconAlt}): タブのアイコンを変更します。これも視覚的な識別性を高めるために有効です。

これらのメソッドを LWC のイベントハンドラ(ボタンクリックなど)に組み込むことで、「ユーザーがある操作をしたら、コンソールがこのように振る舞う」というインタラクティブな体験を構築できます。例えば、あるレコードの詳細ページに配置したカスタム LWC のボタンをクリックすると、そのレコードに関連する別のレコードを新しいサブタブで開く、といったワークフローが簡単に実装できます。


示例代码

ここでは、最も一般的なユースケースの一つである「取引先レコードページに配置した LWC から、関連する特定の取引先責任者レコードを新しいサブタブとして開く」コンポーネントを作成します。このコードは Salesforce Developer の公式ドキュメントに基づいています。

この LWC は、ボタンをクリックすると、現在フォーカスされているタブ(取引先レコード)のサブタブとして、ハードコードされた取引先責任者レコードを開きます。

1. HTML (openContactSubtab.html)

<template>
    <lightning-card title="Workspace API Subtab Demo" icon-name="custom:custom14">
        <div class="slds-m-around_medium">
            <p class="slds-m-bottom_small">下のボタンをクリックすると、関連する取引先責任者のレコードが新しいサブタブで開きます。</p>
            <lightning-button
                label="関連する取引先責任者を開く"
                onclick={openContactTab}
                variant="brand">
            </lightning-button>
        </div>
    </lightning-card>
</template>

2. JavaScript (openContactSubtab.js)

import { LightningElement, wire } from 'lwc';
// Workspace API モジュールをインポートします
import { WorkspaceAPI } from 'lightning/platformWorkspaceApi';
import { ShowToastEvent } from 'lightning/platformShowToastEvent';

export default class OpenContactSubtab extends LightningElement {
    // Wire サービスを使用して WorkspaceAPI のインスタンスを取得します
    @wire(WorkspaceAPI)
    workspaceAPI;

    // ボタンクリック時に呼び出される非同期関数
    async openContactTab() {
        // Workspace API が利用可能かチェックします
        if (!this.workspaceAPI) {
            this.showToast('Error', 'Workspace API is not available.', 'error');
            return;
        }

        try {
            // 1. 現在フォーカスされているタブの情報を取得します。
            //    この情報から親となるプライマリタブのIDを取得する必要があります。
            const focusedTabInfo = await this.workspaceAPI.getFocusedTabInfo();
            const parentTabId = focusedTabInfo.tabId;

            // 2. openSubtab メソッドを呼び出して新しいサブタブを開きます。
            //    このメソッドは Promise を返し、新しく開かれたタブの ID を解決します。
            const newTabId = await this.workspaceAPI.openSubtab({
                parentTabId: parentTabId, // どのプライマリタブの下に開くかを指定
                recordId: '003R0000005o6VPIAY', // ここではデモ用に特定の取引先責任者IDをハードコード
                label: 'Sample Contact', // サブタブに表示されるラベル
                focus: true // 新しく開いたタブにフォーカスを移動させるか
            });

            // 成功した場合のトースト通知
            this.showToast('Success', `新しいサブタブ (ID: ${newTabId}) が開かれました。`, 'success');

        } catch (error) {
            // エラーハンドリング
            console.error('Error opening subtab:', error);
            this.showToast('Error', `サブタブを開けませんでした: ${error.body.message}`, 'error');
        }
    }

    // ユーザーにフィードバックするためのトースト通知ヘルパー関数
    showToast(title, message, variant) {
        const event = new ShowToastEvent({
            title: title,
            message: message,
            variant: variant,
        });
        this.dispatchEvent(event);
    }
}

3. Meta-XML (openContactSubtab.js-meta.xml)

このコンポーネントを取引先レコードページで利用できるように設定します。

<?xml version="1.0" encoding="UTF-8"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>58.0</apiVersion>
    <isExposed>true</isExposed>
    <targets>
        <target>lightning__RecordPage</target>
    </targets>
    <targetConfigs>
        <targetConfig targets="lightning__RecordPage">
            <objects>
                <object>Account</object>
            </objects>
        </targetConfig>
    </targetConfigs>
</LightningComponentBundle>

このコンポーネントをデプロイし、Lightning アプリケーションビルダーで任意の取引先レコードページに配置すると、「関連する取引先責任者を開く」ボタンが表示されます。このボタンをクリックすると、Service Console 上で現在の取引先タブの隣に、指定された取引先責任者のレコードが新しいサブタブとしてスムーズに開かれます。


注意事項

Lightning Console JavaScript API を利用する際には、いくつかの重要な点に注意する必要があります。

コンテキスト依存性

lightning/platform-workspace-api は、Lightning Console Application (Lightning コンソールアプリケーション) 内でのみ機能します。標準のナビゲーションを持つアプリケーション(Sales アプリなど)のページでこの API を呼び出しても、Workspace API のインスタンスが利用できないため、機能しません。開発したコンポーネントは、必ず Service Console や Sales Console といったコンソールアプリケーション内でテストしてください。コード内で if (this.workspaceAPI) のように、API が利用可能かどうかをチェックするガード句を入れることは、良い習慣です。

権限 (Permissions)

API 自体に特別な権限は必要ありませんが、API を通じて実行されるアクションは、実行ユーザーの権限に依存します。例えば、ユーザーが特定のレコードへのアクセス権を持っていない場合、openTabopenSubtab でそのレコードを開こうとしても失敗します。同様に、オブジェクトに対する参照権限が必要です。エラーハンドリングを適切に行い、権限不足によるエラーが発生した際に、ユーザーに分かりやすいメッセージを表示することが重要です。

API 制限 (API Limits)

Workspace API はクライアントサイドで動作するため、Salesforce の日々の API コールリミット(REST/SOAP API の制限)は消費しません。しかし、ブラウザのパフォーマンスには影響を与える可能性があります。特に、一度に大量のタブをプログラムで開くような処理は、ユーザーのブラウザのメモリを圧迫し、パフォーマンスの低下を招く可能性があります。ユーザー体験を損なわないよう、タブを開くロジックは慎重に設計する必要があります。

非同期処理とエラーハンドリング (Error Handling)

ほとんどの Workspace API メソッドは Promise を返します。これは、処理が非同期で行われることを意味します。したがって、async/await.then().catch() を用いて、処理が完了するのを待ち、発生しうるエラーを適切に捕捉する必要があります。例えば、存在しないレコードIDでタブを開こうとした場合や、前述の権限不足の場合などに API はエラーを投げます。これをキャッチしてユーザーに通知するロジックは、堅牢なコンポーネントを開発する上で不可欠です。


まとめとベストプラクティス

Salesforce Service Console は、ユーザーの生産性を劇的に向上させるための強力なプラットフォームです。そして、Lightning Console JavaScript API (lightning/platform-workspace-api) は、開発者がその体験をさらに一歩進め、特定のビジネスニーズに合わせたカスタムワークフローを構築するための鍵となります。

本記事で解説したように、この API を利用することで、レコード間のナビゲーションを自動化し、必要な情報を適切なタイミングでユーザーに提示し、クリック数や画面遷移の手間を大幅に削減することが可能です。

ベストプラクティス

  1. ユーザー中心の設計を心がける: 技術的に可能だからといって、むやみにタブを開くのは避けましょう。常にユーザーのワークフローを考慮し、「どのタイミングで、どの情報を表示すれば、ユーザーの作業が最もスムーズになるか?」という視点で設計することが重要です。
  2. 明確なフィードバックを提供する: タブを開いたり閉じたりする際は、lightning/platformShowToastEvent を使用して、「〜を開きました」「処理が完了しました」といったフィードバックをユーザーに返しましょう。これにより、ユーザーは何が起こったのかを明確に理解できます。
  3. コンポーネントの再利用性を高める: 特定のレコードIDをハードコードするのではなく、@api プロパティやカスタムメタデータ型、Flow などを使って動的にIDを渡せるように設計することで、コンポーネントの再利用性が高まります。
  4. タブの視認性を向上させる: setTabLabelsetTabIcon を活用して、タブのコンテキストを視覚的に伝えましょう。例えば、優先度が「高」のケースを開くタブには警告アイコンを付けたり、完了したタスクのタブのラベルに「[完了]」というプレフィックスを追加したりすることで、ユーザーは一目でタブの状態を把握できます。
  5. 徹底したテスト: 開発したコンポーネントは、必ずターゲットとなる Service Console アプリケーション内で、様々なユーザープロファイルで十分にテストしてください。異なる権限やシナリオで期待通りに動作することを確認することが、本番環境でのトラブルを未然に防ぎます。

Lightning Console JavaScript API をマスターすることは、Salesforce 開発者として、単なるデータモデルやビジネスロジックの実装者から、優れたユーザー体験の設計者へとステップアップするための重要なスキルです。この強力なツールを駆使して、ユーザーが日々の業務に集中できる、よりスマートで効率的な Salesforce 環境を構築していきましょう。

コメント