背景と適用シナリオ
皆さん、こんにちは!Salesforce 開発者です。Salesforce の標準機能は非常に強力ですが、時には定型的な業務を自動化したり、独自のビジネスプロセスを実装したりするために、コードの力が必要になることがあります。特に、Salesforce Knowledge (セールスフォースナレッジ) の運用において、そのニーズは顕著です。
Salesforce Knowledge は、顧客や社内ユーザー向けに情報を提供する強力なナレッジベース・プラットフォームです。しかし、多くの企業では以下のような課題に直面します。
- 大量の記事移行: 既存の CMS やファイルサーバーから何百、何千もの記事を Salesforce Knowledge に移行したい。手作業での登録は非現実的です。
- 外部システムとの連携: 製品のリリース情報を管理する外部システムと連携し、新機能に関するナレッジ記事を自動で作成・更新したい。
- 独自の承認プロセスの実装: 標準の承認プロセスでは要件を満たせず、特定の条件に基づいて記事の公開を自動化する、より複雑なロジックを Apex で実装したい。
- カスタム UI の提供: 標準のナレッジ作成画面ではなく、特定のユーザーグループに最適化された、よりシンプルな入力フォームを Visualforce や Lightning Web Components (LWC) で構築したい。
このようなシナリオでは、開発者として Apex や SOQL を駆使してナレッジ記事をプログラムで操作する能力が不可欠となります。この記事では、Salesforce 開発者の視点から、ナレッジ記事のデータモデルを理解し、Apex を用いてナレッジの作成、照会、公開といった一連の操作を自動化する方法について、具体的なコード例を交えながら詳しく解説していきます。
原理説明
Salesforce Knowledge をプログラムで操作する前に、その根幹をなすデータモデルを理解することが重要です。Knowledge は他の標準オブジェクトとは少し異なる、バージョン管理の概念を持つ特殊な構造をしています。
ナレッジのオブジェクトモデル
Salesforce Knowledge の中核をなすのは、Knowledge Article Version (ナレッジ記事バージョン) オブジェクトです。API 参照名は Knowledge__kav
です。このオブジェクトが、記事のタイトル、内容、URL名といった具体的な情報を保持しています。
重要な点は、私たちが操作する対象は「記事そのもの」ではなく、「記事の特定のバージョン」であるということです。一つの記事には、Draft (ドラフト)、Online (公開済み)、Archived (アーカイブ済み) といった複数のバージョンが存在し得ます。
また、組織で複数のArticle Type (記事タイプ) を定義している場合、それぞれが Knowledge__kav
から派生したカスタムオブジェクトとして扱われます。例えば、「FAQ」という記事タイプを作成した場合、その API 参照名は FAQ__kav
となります。これらのオブジェクトには、記事タイプ固有のカスタム項目が含まれます。
ナレッジのライフサイクルと Apex
ナレッジ記事のライフサイクルは、通常「ドラフト作成 → 公開 → (更新のために新ドラフト作成) → 公開 → アーカイブ」という流れをたどります。開発者として、この各フェーズにプログラムで介入する必要があります。
- 作成 (Create): 新しいナレッジ記事を作成するには、
Knowledge__kav
(またはFAQ__kav
のようなカスタム記事タイプ) のレコードを DML のinsert
を使って作成します。この時点では、記事はドラフトバージョンとして作成されます。 - 照会 (Query): 記事を検索するには SOQL (Salesforce Object Query Language) を使用します。特定のステータス (例: 公開済み) の記事や、特定のデータカテゴリに属する記事を絞り込んで取得することが可能です。
- 公開 (Publish): ドラフトバージョンの記事を公開するには、標準の DML 操作ではなく、専用の Apex クラスである
KbManagement.PublishingService
を使用する必要があります。これがナレッジ管理の自動化における最も重要なポイントの一つです。 - 更新 (Update): 公開済みの記事を直接編集することはできません。更新するには、まず公開済みの記事を元に新しいドラフトバージョンを作成し、そのドラフトを編集してから再度公開する、という手順を踏みます。
このバージョン管理の仕組みと、公開処理に専用のクラスが必要であることを理解することが、ナレッジ開発の第一歩となります。
サンプルコード
ここでは、Salesforce Developer 公式ドキュメントに基づいたコード例を用いて、具体的な実装方法を見ていきましょう。
1. SOQL を使用した公開済みナレッジの検索
まずは、現在公開されているナレッジ記事を検索する基本的な SOQL クエリです。ここでは、言語が日本語で、特定のデータカテゴリに属する記事を検索する例を示します。
// 公開済み(Online)で言語が日本語(ja)の記事を検索 List<Knowledge__kav> articles = [ SELECT Id, Title, Summary, UrlName FROM Knowledge__kav WHERE PublishStatus = 'Online' AND Language = 'ja' ]; // 取得した記事のタイトルをデバッグログに出力 for (Knowledge__kav article : articles) { System.debug('公開中の記事タイトル: ' + article.Title); } // データカテゴリを指定して検索する例 // 'All' というデータカテゴリグループの 'Laptops' というカテゴリに属する記事を検索 // WITH DATA CATEGORY 句を使用します List<Knowledge__kav> articlesWithDataCategory = [ SELECT Id, Title FROM Knowledge__kav WHERE PublishStatus = 'Online' AND Language = 'ja' WITH DATA CATEGORY All AT Laptops ]; for (Knowledge__kav article : articlesWithDataCategory) { System.debug('カテゴリ内の記事タイトル: ' + article.Title); }
詳細な注釈:
Knowledge__kav
: すべての記事バージョンの情報を持つ SObject です。PublishStatus = 'Online'
: この条件で、現在公開されているバージョンのみをフィルタリングします。ドラフトは 'Draft'、アーカイブ済みは 'Archived' となります。Language = 'ja'
: マルチ言語ナレッジが有効な場合、言語コードで記事を絞り込みます。WITH DATA CATEGORY
: データカテゴリを使用して記事をフィルタリングするための専用句です。複雑なカテゴリ構造にも対応できます。
2. Apex を使用した新しいナレッジ記事(ドラフト)の作成
次に、Apex を使って新しいナレッジ記事をドラフトとして作成するコードです。ここでは、「FAQ」というカスタム記事タイプ (API 参照名: FAQ__kav
) を想定しています。
// FAQ__kav はカスタム記事タイプの API 参照名と仮定 FAQ__kav newArticleVersion = new FAQ__kav(); // 必須項目であるタイトルとURL名を設定 // UrlName は組織内で一意である必要があります newArticleVersion.Title = 'API を使用した記事の作成方法'; newArticleVersion.UrlName = 'how-to-create-article-via-api'; // カスタム項目 (記事タイプに独自に追加した項目) を設定 newArticleVersion.Question__c = 'Apex を使ってナレッジ記事を作成できますか?'; newArticleVersion.Answer__c = 'はい、DML insert 操作を使用してドラフト記事を作成できます。'; // DML を使用してレコードを挿入 try { Database.SaveResult sr = Database.insert(newArticleVersion, false); if (sr.isSuccess()) { System.debug('ドラフト記事が正常に作成されました。ID: ' + sr.getId()); } else { for (Database.Error err : sr.getErrors()) { System.debug('記事の作成に失敗しました: ' + err.getMessage()); } } } catch (DmlException e) { System.debug('DML 例外が発生しました: ' + e.getMessage()); }
詳細な注釈:
FAQ__kav
: ここではカスタム記事タイプを使用しています。もし標準のナレッジのみを使用している場合はKnowledge__kav
を使用します。Title
,UrlName
: これらはナレッジ記事の必須項目です。特にUrlName
は一意性を保つ必要があるため、プログラムで生成する際は注意が必要です。Question__c
,Answer__c
: FAQ 記事タイプに独自に定義したカスタム項目の例です。リッチテキストエリアの場合、HTML タグを含んだ文字列をセットします。Database.insert(record, allOrNone)
:allOrNone
パラメータをfalse
に設定することで、部分的な成功を許容し、エラーが発生したレコードのみを失敗として処理できます。これにより、バルク処理時の堅牢性が向上します。
3. Apex を使用したナレッジ記事の公開
作成したドラフト記事を公開するには、KbManagement.PublishingService
クラスを使用します。これはナレッジ管理の自動化において最も重要な部分です。
// 公開したいドラフト記事の ID を取得 (ここでは前のステップで作成したと仮定) // 実際には SOQL などで対象のドラフト記事IDを取得します String articleVersionId = 'ka0XXXXXXXXXXXXXXX'; // 有効な Knowledge__kav レコードの ID に置き換えてください // 記事 ID が有効か確認 if (String.isNotBlank(articleVersionId)) { try { // KbManagement.PublishingService を使用して記事を公開 // 第2引数を true にすると、即時公開されます String publishedArticleVersionId = KbManagement.PublishingService.publishArticle(articleVersionId, true); System.debug('記事が正常に公開されました。新しい公開バージョンの ID: ' + publishedArticleVersionId); } catch (Exception e) { System.debug('記事の公開中にエラーが発生しました: ' + e.getMessage()); } } else { System.debug('記事IDが無効です。'); }
詳細な注釈:
KbManagement.PublishingService.publishArticle(articleVersionId, immediate)
: この静的メソッドが公開処理の核心です。- 第1引数
articleVersionId
: 公開したいドラフトバージョンのKnowledge__kav
レコード ID を渡します。 - 第2引数
immediate
:true
を指定すると即時公開されます。false
を指定すると、スケジュールされた日時に公開されます(事前に公開スケジュールを設定しておく必要があります)。
- 第1引数
- 戻り値: 公開が成功すると、新しく作成された公開済みバージョンのレコード ID が返されます。ドラフトバージョンの ID とは異なることに注意してください。
- エラーハンドリング: 権限不足や無効な記事ステータスの場合に例外がスローされるため、
try-catch
ブロックで適切に処理することが不可欠です。
注意事項
ナレッジをプログラムで操作する際には、いくつかの重要な注意点があります。
-
権限 (Permissions):
コードを実行するユーザーには、適切な権限が必要です。プロファイルや権限セットで、対象の記事タイプに対する「作成」「参照」「編集」「削除」権限に加えて、「記事の管理」システム権限や「記事の公開」アプリ権限が必要になる場合があります。権限が不足していると、DML 操作や
publishArticle
メソッドの呼び出しで例外が発生します。 - API 制限 (API Limits): すべての Apex コードと同様に、ナレッジ操作も Governor Limits (ガバナ制限) の対象となります。特に、大量の記事を一度に作成・更新・公開するバッチ処理を実装する際は、SOQL クエリの発行回数 (100回/トランザクション)、DML ステートメントの発行回数 (150回/トランザクション)、CPU 時間などを考慮した、バルク対応の設計が必須です。
-
バージョン管理 (Versioning):
公開済みの記事 (
PublishStatus = 'Online'
) は直接編集できません。更新する場合は、KbManagement.PublishingService.editOnlineArticle(articleId, unpublish)
を呼び出して新しいドラフトを作成するか、手動で新しいドラフトを作成し、それを編集・公開するフローを実装する必要があります。常にバージョンを意識した開発を心がけてください。 -
テストクラス (Test Classes):
ナレッジを操作する Apex トリガーやクラスには、網羅的なテストクラスを作成することが不可欠です。
KbManagement.PublishingService
のような特殊なメソッドのテストでは、Test.startTest()
とTest.stopTest()
の間でメソッドを呼び出すことが推奨されます。また、テストデータとしてナレッジ記事を作成し、そのライフサイクル全体(作成→公開→アーカイブ)をテストするようにしましょう。
まとめとベストプラクティス
本記事では、Salesforce 開発者の視点から、Apex と SOQL を用いて Salesforce Knowledge をプログラムで管理する方法を解説しました。
重要なポイントは以下の通りです。
- ナレッジのデータモデルはバージョンベースであり、
Knowledge__kav
オブジェクトがその中核を担います。 - 記事の作成は標準の DML
insert
で行い、ドラフトバージョンが作成されます。 - 記事の公開には、専用の
KbManagement.PublishingService.publishArticle()
メソッドを使用する必要があります。 - SOQL で記事を検索する際は、
PublishStatus
やWITH DATA CATEGORY
句を効果的に利用します。
最後に、ナレッジ開発におけるベストプラクティス (Best Practices) をいくつか紹介します。
- コードのバルク化 (Bulkification): 大量の記事を扱うことを常に想定し、リストやマップを活用して一度の DML や SOQL で複数のレコードを処理できるように設計してください。
- エラー処理の徹底: DML 操作や API 呼び出しは必ず
try-catch
ブロックで囲み、失敗した場合のログ記録やリカバリ処理を実装してください。Database.SaveResult
を活用して、部分的な失敗にも対応できるようにしましょう。 - UrlName の一意性担保:
UrlName
は一意である必要があります。記事タイトルから自動生成するロジックを組む場合、重複を避けるためにタイムスタンプやランダムな文字列を追加するなどの工夫が必要です。 - 責務の分離: ナレッジ記事の操作ロジックは、再利用可能なサービスクラスにまとめましょう。これにより、トリガー、バッチ、LWC のコントローラーなど、様々な場所から同じロジックを呼び出すことができ、保守性が向上します。
Salesforce Knowledge のプログラムによる操作は、ビジネスプロセスの自動化と効率化に大きく貢献します。この記事で紹介した知識とコードを基に、ぜひ皆さんのプロジェクトでも活用してみてください。
コメント
コメントを投稿