【サンプルあり】Salesforceでカスタマーサポート業務を支援するアイデアの紹介

Norifumi Fujimaki

Rewa Tech

技術コラム

サービス

カスタマーサポート業務を担当していると、「問い合わせ対応がもっとスムーズにできたら」「手作業が多くて時間がかかる」といった悩みを感じることはありませんか?Salesforceの標準機能だけでは、どうしても「ここがもう少し便利だったら…」と思う場面が出てきてしまいます。

本記事では、そんな現場の「ちょっと困る」を解消するためのアイデアと具体例を紹介します。LWCやApexを活用した、実際に使えるサンプルコード付きの具体的なアイデアを通じて、Salesforceの機能をぐっと使いやすくカスタマイズする方法をお伝えします。

使いこなせば、電話応対中のストレスを減らし、情報の記録ミスを防ぎ、若手メンバーの成長もサポートできるでしょう。

Salesforceをもっと自分たちの業務にフィットさせ、現場の困りごとを自分たちで解決できる自信と具体的なアイデアを、この記事を読んで手に入れませんか?

Salesforceでのカスタマーサポート業務

Salesforceでカスタマーサポートを行う際の出発点として、「ケースオブジェクト」は欠かせません。問い合わせの記録・管理に加え、Knowledgeと連携させることで、よくある質問への対応も効率的に行えるようになります。

標準機能のカスタマイズによって、独自のステータス管理やエスカレーションルールの設定など、ある程度の業務要件には十分対応でき、自社の運用に合わせた設計が可能です。

しかし、日々の業務において「この入力、毎回手作業でやっていて非効率だな…」「ボタン一つで完結できたら楽なのに」と感じるシーンも出てきます。こうした場面では、標準機能のカスタマイズでは足りず、フローやコーディングといった、もう一段階踏み込んだ工夫が求められます。

次のセクションでは、そのような「標準機能では手が届かない“もう一歩先”」を実現する、便利な拡張アイデアをご紹介します。

Salesforceの項目をボタン1つでコピーする

日々のカスタマーサポートや営業活動の中で、「Salesforceに表示されている製品番号やメールアドレスをコピーして、別システムで検索したい」といった場面は意外と多くありますよね。特に電話対応中だと、マウスで文字を選択してコピーするという単純な操作も、地味に手間取ってしまうことがあります。

そこでおすすめしたいのが、「ボタン1つでSalesforceの特定項目をクリップボードにコピーできる」機能です。とてもシンプルな仕組みですが、実際に使ってみると、業務の流れがスムーズになり、対応にも集中しやすくなります。

この機能は、Salesforceの標準機能だけでは実現が難しいため、LWC(Lightning Web Components)とApexを組み合わせて構築します。実装の方針は次のとおりです。

  • Lightningページ上にLWCを配置し、ユーザーがすぐに使えるようにする
  • LWC側でボタンを表示し、クリック時にクリップボードへ項目の値をコピーする処理を実装
  • Apexを使ってSalesforce上のデータを取得し、LWCに渡すことで、リアルタイムにコピーできる内容を反映

少しの工夫で、現場の「ちょっと困る」を解消できる、そんなSalesforceらしい小技として、ぜひ取り入れてみてください。

サンプルコード

「ケースに紐づいている取引先責任者の名前をコピー」することを目的としたサンプルとしたコードです。

  • LWC:JavaScript
import { LightningElement, api } from 'lwc'; 
import getContactName from '@salesforce/apex/ClipboardController.getContactName'; 
import { ShowToastEvent } from 'lightning/platformShowToastEvent'; 

export default class ClipboardSample extends LightningElement { 
  api recordId; 

  async handleClick() { 
    try { 
      const contactName = await getContactName({ recordId: this.recordId }); 

      if (contactName) { 
        await navigator.clipboard.writeText(contactName); 
        this.showToast('成功', '取引先責任者の名前をクリップボードにコピーしました。', 'success'); 
      } else { 
        this.showToast('注意', '取引先責任者の名前が未入力または取引先責任者が紐づいておりません。', 'info'); 
      } 
    } catch (error) { 
      this.showToast('エラー', 'レコードの取得またはコピーに失敗しました。', 'error'); 
      console.error(error); 
    } 
  } 

  showToast(title, message, variant) { 
     this.dispatchEvent(new ShowToastEvent({ title, message, variant }));
  } 
}
  • LWC:HTML
<template>
  <lightning-card>
    <div class="base">
      <lightning-button variant="brand-outline" label="取引先責任者の名前をコピー" onclick={handleClick}></lightning-button>
    </div>
    </lightning-card>
</template>
  • LWC:CSS
.base { 
  display: flex; 
  justify-content: center; 
}
  • Apex
public with sharing class ClipboardController {
  @AuraEnabled
  public static String getContactName(Id recordId) { 
    Case record = [SELECT Contact.Name FROM Case WHERE Id = :recordId LIMIT 1]; 
    return record.Contact.Name; 
  } 
}

実装イメージ

画像右側のボタン「取引先責任者の名前をコピー」をクリックすることで、取引先責任者の名前である「藤巻 至史」というテキストがクリップボードにコピーされます。コピーされた結果として、Salesforce内のメッセージが表示されるようになっております。

問合せ内容を追記する

カスタマーサポートの現場では、1回の対応で完結しない問い合わせも少なくありません。たとえば、お客様からの追加の質問や、対応に時間がかかる案件など、やり取りが何度かに分かれることもあります。

こうしたケースでは、「問い合わせ内容」や「対応履歴」といった項目に追加の情報を追記していく運用が一般的です。しかし、実際に追記していく中で、いくつかの課題にぶつかることがあります。

  • 最新情報を上に書くか、下に書くかといった記載ルールが人に依存していて、情報の並びがバラバラになる
  • 過去に書いた内容をうっかり削除や上書きしてしまう可能性がある
  • Salesforceの標準機能である履歴管理では、「いつ変更があったか」までは記録できても、実際に何が変更されたのかは確認できない

こうした運用上のモヤモヤを解消するには、「追記専用の入力画面」を別途用意し、既存の内容には触れずに、新しい情報だけを追加するというアプローチが有効です。

具体的には、次のような構成で実装します。

  • LightningページにLWCを配置し、レコードページ上で追記できるようにする
  • LWCでは、追記対象の項目の選択と、追加する内容を入力するテキストボックスを用意
  • Apexを使って、既存の項目データに新しい内容を追記する処理を行う

このような仕組みにすることで、更新の履歴が常に明確に残り、情報の整合性やチーム内での共有もスムーズになります。細かいけれど重要な“記録の質”を高めるために、ぜひ取り入れてみてはいかがでしょうか。

サンプルコード

ケースのテキストエリア / ロングテキストエリアの項目を選択できるようにし、選択した項目に対して最新情報を追記するサンプルコードです。

  • LWC:JavaScript

import { LightningElement, api, wire } from 'lwc'; 
import getLongTextAreaFields from '@salesforce/apex/CaseAddWriteController.getLongTextAreaFields'; 
import appendTextToField from '@salesforce/apex/CaseAddWriteController.appendTextToField'; 
import { ShowToastEvent } from 'lightning/platformShowToastEvent'; 

export default class AddWrite extends LightningElement { 
    @api recordId; 
    fieldOptions = []; 
    selectedField = ''; 
    inputText = ''; 

    @wire(getLongTextAreaFields) 
    wiredFields({ error, data }) { 
        if (data) { 
            this.fieldOptions = data.map(field => ({ 
                label: field.label, 
                value: field.apiName 
            })); 
        } else if (error) { 
            this.showToast('エラー', '項目情報の取得中にエラーが発生しました。', 'error'); 
        } 
    } 

    handleFieldChange(event) { 
        this.selectedField = event.detail.value; 

    } 

    handleTextChange(event) { 
        this.inputText = event.detail.value; 
    } 

    handleSave() { 
        if (!this.selectedField || !this.inputText) { 
            this.showToast('警告', '項目とテキストの両方を入力してください。', 'warning'); 
            return; 
        } 

        appendTextToField({ 
            caseId: this.recordId, 
            fieldApiName: this.selectedField, 
            newText: this.inputText 
        }) 
        .then(() => { 
            this.showToast('成功', '追記が完了しました。', 'success'); 
            this.inputText = ''; 
        }) 
        .catch(error => { 
            this.showToast('エラー', '保存処理中にエラーが発生しました。', 'error'); 
            console.error(error); 
        });
    } 

    showToast(title, message, variant) { 
        this.dispatchEvent(new ShowToastEvent({ title, message, variant })); 
    } 
}
  • LWC:HTML
<template>
  <lightning-card>
    <div class="slds-p-horizontal_medium slds-p-bottom_medium">
      <lightning-combobox name="fieldSelector" label="項目を選択" value={selectedField} options={fieldOptions} onchange={handleFieldChange}></lightning-combobox>
      <lightning-textarea label="追記する内容" value={inputText} onchange={handleTextChange} class="slds-m-top_medium"></lightning-textarea>
          <div class="button-container">
             <lightning-button label="保存" variant="brand" class="slds-m-top_medium" onclick={handleSave}></lightning-button>
          </div>
      </div>
   </lightning-card>
</template>
  • LWC:CSS
.button-container {
  display: flex;
  justify-content: right;
}
  • LWC:XML
<?xml version="1.0" encoding="UTF-8"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
  <apiVersion>64.0</apiVersion>
  <isExposed>true</isExposed>
  <targets>
    <target>lightning__RecordPage</target>
  </targets>
  <targetConfigs>
    <targetConfig targets="lightning__RecordPage">
      <objects> 
        <object>Case</object>
      </objects>
    </targetConfig>
  </targetConfigs>
</LightningComponentBundle>
  • Apex
public with sharing class CaseAddWriteController { 
    @AuraEnabled(cacheable=true) 
    public static List<Map<String, String>> getLongTextAreaFields() { 
        List<Map<String, String>> fieldInfos = new List<Map<String, String>>(); 
        Schema.DescribeSObjectResult describeResult = Case.SObjectType.getDescribe(); 
        Map<String, Schema.SObjectField> fields = describeResult.fields.getMap(); 

        for (String fieldName : fields.keySet()) { 
            Schema.DescribeFieldResult fieldDesc = fields.get(fieldName).getDescribe(); 
            if (fieldDesc.getType() == Schema.DisplayType.TextArea && fieldDesc.isUpdateable()) {
                fieldInfos.add(new Map<String, String>{ 
                     'label' => fieldDesc.getLabel(), 
                     'apiName' => fieldName
                });
            }
        } 
        return fieldInfos;
    }
    @AuraEnabled
    public static void appendTextToField(Id caseId, String fieldApiName, String newText) {
        System.debug('fieldApiName:' + fieldApiName);
        String soql = 'SELECT Id, ' + fieldApiName + ' FROM Case WHERE Id = :caseId LIMIT 1';
        Case targetCase = Database.query(soql);
        String userName = UserInfo.getName();
        String now = String.valueOf(Datetime.now().format('yyyy/MM/dd HH:mm'));
        String separator = '\n\n' + userName + '(' + now + ')' + '\n=====================\n\n';

        String oldValue = (String)targetCase.get(fieldApiName);
        String updatedValue = newText + separator + (String.isBlank(oldValue) ? '' : oldValue);

        Case updateCase = new Case(Id = caseId);
        updateCase.put(fieldApiName, updatedValue);
        System.debug(updateCase);
        update updateCase;
    }
}

実装イメージ

画面右側のドロップダウン「項目を選択」から追記対象となる項目を選択し、その下のテキストボックスに内容を記載します。記載が完了したら、右下のボタン「保存」をクリックすることで、選択した項目に記載した内容を追記します。

選択した項目の一番上に追記した内容を記載し、過去のデータとは区切り線を入れて見やすくしております。また、保存ボタンを押下したユーザの名前と時間を自動で記録することで、追記の履歴をたどれるような処理を実装しています。

その他の事例

ここまで、業務効率を上げるための具体的なカスタマイズ事例をご紹介してきましたが、Salesforceでは他にも「これがあるだけで少し楽になる」「現場で助かる」といった、小さな工夫が数多くあります。

たとえば、チェックボックスにチェックを付けると、自動的にアイコンを表示してステータスを視覚的に分かりやすくする、という仕掛けもそのひとつです。一見すると地味な機能ですが、リストビューやレコード詳細画面で一目で状況が把握できるため、情報の見落としが減り、確認作業のスピードも上がります。

また、チェックリスト形式で入力と確認を同時に行えるカスタマイズも非常に有効です。たとえば、対応フローに沿ったチェックリストを用意し、それに従って作業を進めると、抜け漏れの防止に役立ちます。特にサポート部門に新しく配属されたばかりのメンバーや、経験の浅い若手にとっては、日々の業務を安心して進めるための“道しるべ”になります。

こうした工夫は、どれもSalesforceの標準機能だけでは実現が難しい部分ですが、少しのLWCやフローの活用で実装可能な範囲です。大掛かりなシステム開発ではなく、「現場の声に応じた小さな改善」を積み重ねていくことこそが、Salesforceの強みを最大限に引き出す活用法と言えるでしょう。

最後に

以上、カスタマーサポート業務を支援する、Salesforce拡張の実例をご紹介しました! 日々の「ちょっと面倒」を、少しの工夫でスマートに変えることができます。

標準機能にLWCやApexを掛け合わせれば、現場の声に応える仕組みは自分たちで作れます。 “手が届く”改善から始めて、Salesforceをもっと現場になじむ存在にしていきましょう!

弊社では、業務に即したSalesforceのカスタマイズや運用支援も承っております。 「こういうことできる?」と思ったら、ぜひお気軽にご相談ください!

それ、サンブリッジなら実現できます!
Salesforceで解決するビジネス課題

【ダウンロード資料】Salesforce導入・開発を検討されているお客様必見
数あるSalesforceベンダー企業のなかから、サンブリッジが選ばれる理由はなぜか。課題別にどんなソリューションがあるのかといった観点で、実際にサンブリッジが対応した事例やご利用企業様からの評価などをご紹介します。(全16ページ)

関連記事