💬

ServiceNowのレコードプロデューサーにメッセージを表示してみる

に公開

概要

ServiceNow のレコードプロデューサーを表示した際に、メッセージを表示するようにしてみます。

イメージとしては、問い合わせフォームを表示した際に期間限定のメッセージを表示するような用途を想定してます。例えば、「ゴールデンウィーク期間中の問い合わせは回答が連休明けになる」と表示するようなイメージです。

ポイント

ポイントは、カタログクライアントスクリプトで GlideAjax を使って文字列を取得し、メッセージとして画面に出力するところです。

レコードプロデューサーはレコード作成前のためにビジネスルールなどで前処理することはできません。また、カタログクライアントスクリプトはクライアントサイドで動作するため、GlideRecord で直接データを取得することができません。

そこで、GlideAjax でサーバーサイドのスクリプトを呼び出し、サーバーサイドで GlideRecord を利用して取得したレコードをクライアントサイドに返しています。

実際にやってみる

実際にメッセージを表示するところまで作成してみます。今回はレコードプロデューサーや各種の ServiceNow の構成要素の細かな作成方法までは説明しません。適宜、別の記事や NowLearning の教育資料などを参照してください。

なお、今回の検証は、Xanadu バージョンで試しています。

作業全体の流れ

複数の要素が登場するため、最初に作成全体の流れを説明します。

今回は以下の順番で作成してみます。

  1. メッセージ用のカスタムテーブルを作成する
  2. サーバー側処理としてスクリプトインクルードを作成する
  3. レコードプロデューサーとカタログクライアントスクリプトを作成する

メッセージ用のカスタムテーブルを作成する

メッセージを登録するカスタムテーブルを作成します。テーブルには、メッセージの他に表示を制御するための開始・終了日付とメッセージ種別を用意しました。

ラベル:Attention Message
テーブル名:u_attention_message

項目一覧

ラベル 名前 タイプ 桁数 必須
Message Text u_message_text 文字列 2000
Level u_level 選択リスト
Display From u_display_from 日付
Display To u_display_to 日付

レベル選択リストの中身は、以下のように設定してみました。

ラベル 順序
Info info 10
Error error 30

せっかくなので、作成したらテストメッセージデータを格納しておきます。

サーバー側処理としてスクリプトインクルードを作成する

先にサーバー側の処理を実装します。GlideAjax から呼び出せるように、いくつか注意が必要です。

1 つ目は、Ajax 呼び出しを許可するロールを設定する必要があります。広く付与することを想定して、専用のロールを作成してみました。作成したロールをユーザー、あるいはグループに対して付与する必要があります。多くのユーザーが所属するグループがあれば、そこへロールを付与するのがおすすめです。

ロール名:attention_message_viewer

このロールは、後で指定します。

2 つ目のポイントは GlideAjax から呼び出せるようにスクリプトインクルードの「Glide AJAX enabled」にチェックをつけることです。そうすることで、テンプレートとして AbstractAjaxProcessor を継承するコードが展開されます。その中に以下のようなコードを記述します。

var MessageLoader = Class.create();
MessageLoader.prototype = Object.extendsObject(global.AbstractAjaxProcessor, {
    type: 'MessageLoader',
    getMessages: function() {
        var gr = new GlideRecord('u_attention_message');
        // 表示開始・終了日を基準に絞り込み
        gr.addEncodedQuery('u_display_from<=javascript:gs.endOfToday()^u_display_to>=javascript:gs.beginningOfToday()');
        gr.query();
        while(gr.next()) {
            var msg = this.newItem('message');
            msg.setAttribute('level', gr.getValue('u_level'));
            msg.textContent = gr.getValue('u_message_text');
        }
    }
});

ここでのポイントは、addEncodedQuery で当日を基準に表示するメッセージを制御しているところです。

日付関連のクエリは間違えがちなので、以下のように画面操作でテーブルにフィルターを設定した後、「Copy query」で取得したクエリを addEncodedQuery の引数に指定することで間違いを回避することができます。

日付だけで扱う場合、時差が不具合の原因になることがありますが、この方法だとサービスポータルを表示しているユーザーのタイムゾーンに従って表示が制御されるので、例えば日本だけで利用する場合など、メッセージを設定する人とサービスポータルを表示する人が同じタイムゾーンにいるときにわかりやすくなります。

スクリプトインクルードを最初に保存するときにクライアントから呼び出しを許可するロールを聞かれるので、先程作成したロール(attention_message_viewer)を設定します。

レコードプロデューサーとカタログクライアントスクリプトを作成する

最後に実際にメッセージを表示したいレコードプロデューサーと、カタログクライアントスクリプトを作成していきます。

レコードプロデューサーは通常通り作成していき、関連リストからカタログクライアントスクリプトのタブを選び新規作成します。

カタログクライアントスクリプトを作成する際に、1 つ注意点があります。それは、UI Type を All か Mobile / Service Portal に設定しないとスクリプトが動作しないということです(Desktop だと実行されない)。

KB0623310 Some Catalog Client Scripts do not work in Service Portal because using unsupported APIs

この点に注意した上で、Type を onLoad にして、以下のようなスクリプトを記載します。

function onLoad() {
    var ga = new GlideAjax('MessageLoader');
    ga.addParam('sysparm_name', 'getMessages');
    ga.getXML(function(response) {
        var messages = response.responseXML.getElementsByTagName("message");
        if (messages) {
            Array.from(messages).forEach(function(message) {
                var level = message.getAttribute('level');
                if (level === 'error') {
                    g_form.addErrorMessage(message.textContent);
                } else {
                    g_form.addInfoMessage(message.textContent);
                }
            });
        }
    });
}

実際に、動作してみる

ここまで構築したものを実行すると、以下のように画面上部にメッセージが表示されます。表示されない場合、ユーザーにロール(今回の例では attention_message_viewer)が付与されていない可能性がありますので、確認してみてください。

メッセージは 4 秒ほどで自動で消えてしまいますが、この時間は変更できないようです。

今回は、g_form.addErrorMessage などでメッセージをホバー表示させてみましたが、表示が消えるのが気になる場合は、レコードプロデューサーにあらかじめ読み取り専用の「複数行テキストの変数」を用意して、そこへメッセージを表示してもいいかもしれません。UI ポリシーでメッセージがあるときだけ表示すれば、メッセージがあることに気が付きやすくなる気もします。

実際の環境に適用する場合は、もう少し工夫が必要だと思いますが、最低限このような仕組みでメッセージを表示できるので参考にしてください。

Discussion