メインコンテンツへスキップ
見出し画像

ServiceNowのメール起票でpriorityが設定されないのはなぜ? 標準Inbound Email Actionの中身を実機で読む


    サービスデスクの責任者から「メールで来た依頼だけ優先度が低いまま並び、対応が後回しになる」と相談を受けたとします。画面起票のIncidentにはpriorityが付くのに、メール経由は毎回同じ値。設定ミスを疑いたくなりますが、実際には壊れていません。標準のInbound Email Action「Create Incident」はpriorityに一度も代入しない仕様だからです。Zurich PDIでメールを処理させ、画面起票との入力の違いを実測します。

    検証環境:Zurich PDI / OOTB / 2026-08-15 確認

    Inbound Email Actionとは:受信したメールをどのテーブルのどんな操作に変換するかを定義する仕組みです。件名・条件でメールを振り分け、一致したアクションのスクリプトが実行されます。Incidentを新規作成する標準アクションが「Create Incident」です。サポート窓口をメールで受け付けるとき、ほとんどの環境がこの標準アクションをそのまま使っています。

    サービスデスクの相談:画面からはpriorityが付くのに、メールは毎回同じ値になる

    サービスデスクの責任者は、画面から自分でIncidentを起票するときはCaller・Short descriptionはもちろん、ImpactとUrgencyもたいてい選ぶよう指導しています。だからこそpriorityにも意味のある値が付くと考えていました。

    ところが月次のレポートを見ると、メール経由で自動生成されたIncidentだけが軒並み同じpriority(5 - Planning)に並んでいます。至急対応が必要な依頼が埋もれていないか不安になり、「メール受付の設定が壊れているのでは」という相談が上がってきました。不安は当然です。

    実際には壊れていません。標準のInbound Email Action「Create Incident」は、そもそもpriorityを一度も操作しない仕様だからです。何が違うのか、画面起票とメール起票それぞれの入力の経路を実機で追って確認します。

    priorityへの代入は1行もない。触れているのはimpactとurgencyだけ

    「Create Incident」のスクリプト全文を読むと、priorityという単語は一度も出てきません。impact・urgencyも、特定の条件下でしか変わりません。読めば数十秒で分かる、短いスクリプトです。

    • priorityはスクリプトのどこにも代入されない。impact×urgencyから自動計算されるだけ

    • impact・urgencyは既定で3-Low(据え置き)。メールにImportance: Highヘッダーが付いているときだけ、両方とも1に上書きされる

    • caller_idはgs.getUserID()が代入される。今回の実行環境ではメール送信者ではなく「Guest」になった


    画像

    上の図は、スクリプト全文を読んで項目ごとに分類したものです。priorityは赤(一切触れない)、impactとurgency、caller_idは橙(条件やコンテキスト次第で変わる)、category・contact_typeは緑(常に固定値)です。

    画面から作るときと、メールから作られるときで、入力のルールが違う

    サービスデスクの相談を実機で裏付けるには、フィールド単位でUIとメールの扱いを並べるのが早道です。Incidentの新規フォーム(/incident.do?sys_id=-1)とCreate Incidentスクリプトを見比べると、8項目で次のような違いがありました。


    画像

    表の中でも実務への影響が大きいのはCallerとShort descriptionの行です。画面ではUI Policyが赤字の必須マークを付け、未入力のままSubmitを押すとブラウザが先に進ませません。ところがメール起票はサーバー側でGlideRecordに値を代入してinsert()するだけなので、この必須チェックを一切通りません。


    画像

    実際に空欄のままの新規フォームを開くと、CallerとShort descriptionには赤いアスタリスクが付き、Priorityはグレーの読み取り専用として表示されます。Impact・Urgencyの既定値はどちらも3-Lowです。

    この違いを実機で確かめるため、件名を空にしたメールをsys_emailに直接作成し、標準のCreate Incidentで処理させました。結果はINC0010480としてShort descriptionが空欄のままIncidentが作成され、エラーにはなりませんでした。UIの必須マークはフォームの仕組みであり、サーバー側の挿入では働かないことが実機で確認できます。

    UIとメールは同じData Lookupエンジンに合流する

    表のPriority行が示すとおり、UIでもメールでもスクリプトはpriorityを直接操作しません。両者が最終的にどこで合流するのかを、dl_definition(Data Lookup Definitions)の設定から追いました。

    incidentの「Priority Lookup」という定義には、run_on_form_changeとrun_on_insert、run_on_updateという3つのフラグがすべてtrueで登録されています。run_on_form_changeはUIでImpact・Urgencyを変更した瞬間に効くフラグです。run_on_insert・run_on_updateはサーバー側でレコードを挿入・更新したときに効くフラグです。つまりUIのフォーム操作もメールのGlideRecord挿入も、同じdl_u_priorityという1つのエンジンを別の入口から呼んでいるだけだと分かります。


    画像

    合流点が同じだからこそ、画面起票とメール起票でPriorityの計算結果自体は食い違いません。食い違って見えるのは、合流する前のImpact・Urgencyの決め方が違うからです。画面は人が選び、メールはImportanceヘッダーという狭い条件でしか動かないという、入力側の差がそのまま結果の差になっています。

    管理者は「メールの内容を見て優先度が判断される」と期待している

    問い合わせメールの本文に「至急」「システム停止」と書けば、Incidentのpriorityが自動的に上がる。多くの管理者はこの動きを期待してメール窓口を運用しています。無理もありません。

    しかし実際に判定材料になっているのは本文の文言ではなく、メールソフトが付けるImportanceヘッダーというメタデータです。本文は関係ありません。送信側のメールソフトが「重要度: 高」を設定していなければ、スクリプトはそれを拾いません。この前提を知らないまま運用すると、なぜ緊急のメールが平常優先度で起票されるのか分からなくなります。

    問い合わせ窓口を設計する担当者と、実際にメールを打つ利用者との間には、もう1段のずれもあります。多くのメールソフトでは、重要度マークは送信画面の隅にある小さなボタンで、意識して押さない限り付きません。件名や本文に緊急性を書いても、その1クリックを忘れれば標準優先度のまま起票されます。

    sysevent_in_email_actionはtaskの外側にある独立したルール

    Inbound Email Action(sysevent_in_email_action)は、Incidentのビジネスルールやワークフローの一部ではありません。sys_db_objectで調べると、super_classは「Rule」でした。メール受信という別のイベントをきっかけに、指定したテーブルへレコードを作成・更新するための独立した仕組みです。

    スクリプトの中ではcurrent(対象レコードのGlideRecord)とemail(解析済みメールの情報)という2つの変数が使えます。email.subject・email.body_text・email.importanceのように、メールの構成要素をオブジェクトのプロパティとして読み取り、currentに代入していく作りです。テーブルへの代入を1行ずつ積み上げるだけの、見た目には素朴なスクリプトです。難しい制御構造もありません。条件分岐はif文が2つあるだけです。

    Type・Order・Conditionsが「どのメールで動くか」を決める

    sysevent_in_email_actionのフォームには、TypeやExecution Order、Conditionsなどの項目が並びます。Typeを「New」にすると、このアクションが適用されるのは新規スレッドのメールだけになります。既存レコードへの返信は対象外です。


    画像

    「Create Incident」はConditions欄が空、Required rolesも空でした。件名やロールによる絞り込みを一切せず、新規メールであれば無条件でIncidentを作成する設定です。Execution Orderは100で、複数のInbound Email Actionが同じ条件に一致する場合、この数値が小さいものから順に試されます。数値は自由に変更でき、独自のアクションを標準より先に評価させることもできます。

    Typeには「New」のほかに「Reply」「Forward」という選択肢もあります。「Reply」は既存のタスクへの返信メールを処理するときに使う種別で、対象レコードをウォーターマークや件名から特定してから、そのレコードを更新します。今回検証したpriority・impact・urgencyの扱いは「Create Incident」(Type=New)に限った話です。「Reply」側のInbound Email Actionは別のスクリプトを持っており、この記事の検証範囲には含めていません。

    Action typeという項目もあり、「Record Action」と「Reply Email」の2択です。「Record Action」はレコードを作成・更新する今回のような処理で、「Reply Email」はレコードを操作せずに定型の返信メールだけを送る処理です。「Create Incident」は前者に当たります。

    公式ドキュメントがpriority・urgency・impactをどう説明しているか

    sys_documentation(フィールドの公式説明)を見ると、3つの項目の役割がそれぞれ次のように書かれていました。

    Sequence in which an incident needs to be resolved
    (訳: インシデントを解決すべき順序)
    引用元: /sys_documentation_list.do?sysparm_query=name=incident^element=priority

    The extent to which resolution of an incident can bear delay
    (訳: インシデントの解決を、どれだけ遅らせられるか)
    引用元: /sys_documentation_list.do?sysparm_query=name=incident^element=urgency

    Measure of the business criticality of the affected service
    (訳: 影響を受けたサービスの、事業上の重大性を測る指標)
    引用元: /sys_documentation_list.do?sysparm_query=name=task^element=impact

    3つの説明を並べると、priorityは「結果として決まる順序」、urgencyとimpactは「その順序を決めるための2つの物差し」という役割分担が読み取れます。スクリプトがurgencyとimpactだけを操作し、priorityには触れない作りになっているのは、この役割分担と一致しています。

    実機でメールを1件処理させ、priority・urgency・impact・callerを実測する

    sys_emailに模擬受信メールを1件作り、実際に「Create Incident」を処理させました。宛先・差出人はどちらもexample.comの架空アドレスです。

    PDIは既定でメール受信処理そのものがオフになっている

    sys_emailへstate=readyのレコードを作っただけでは、何分待ってもIncidentが作られませんでした。システムプロパティ(sys_properties)は設定値の置き場を確認すると、原因はglide.email.read.active(メール受信処理の有効化)が既定でfalseだったことです。POP3やIMAPのメールボックスも1件も設定されておらず、受信メールを定期的に処理するジョブ自体が存在しない状態でした。

    Reprocess Emailボタンで手動処理できる

    sys_emailのフォームには「Reprocess Email」というボタンがあります。これを押すと、glide.email.read.activeの設定に関係なく、そのレコード1件だけをInbound Email Actionのエンジンに乗せて処理させられます。今回はこのボタンを使い、実運用のコードパスをそのまま通す形で検証しました。


    画像

    処理が終わると、Targetにできたインシデントへのリンクが入り、Stateが「Processed」に変わります。数秒で終わります。この画面はImportanceヘッダー付きのメールを処理した後のものです。

    通常メールの結果

    Importanceヘッダーを付けないメールを処理すると、callerとimpact、urgencyとpriorityは次のようになりました。


    画像

    Callerは「Guest」でした。差出人アドレスはcustomer-a@example.comでしたが、そのアドレスに一致するユーザーへ紐づくことはありません。impact・urgencyは既定の3-Low、priorityはその組み合わせで決まる5-Planningです。

    Importance: highを付けたメールの結果

    同じ手順で、Importanceヘッダーにhighを指定したメールも処理しました。


    画像

    impact・urgencyがともに1-Highへ上書きされ、priorityは1-Criticalになりました。callerは今回もGuestです。2件の結果を並べると、priorityの項目にスクリプトが一切触れていないことが分かります。impact・urgencyの組み合わせが変わった結果として、priorityも連動して変わっただけです。

    priorityが変わる本当の理由:Priority Data Lookup

    impact・urgencyからpriorityが決まる対応表は、dl_u_priority(Priority Data Lookup)というテーブルにデータとして格納されていました。条件と結果の組み合わせを並べただけのデータレコードで、スクリプトは1行も関わりません。この「条件に一致したら値を返す」という仕組みは、担当者の自動割り当てで使われるData Lookupと同じ設計です。用途は違っても、判定の型は共通しています。

    今回観測した2パターンは、このテーブルの中の次の2行と一致します。

    • impact=3-Low, urgency=3-Low → priority=5-Planning

    • impact=1-High, urgency=1-High → priority=1-Critical

    Inbound Email Actionのスクリプトを直接いじらなくても、dl_u_priority側の対応表を編集すれば、同じimpact・urgencyの組み合わせでもpriorityの出方を変えられます。priorityを調整したいときに疑うべき場所は、メールのスクリプトではなくこちらです。テーブルが違います。

    assigned_toだけは特殊な書式のメールが必要

    スクリプトにはemail.body.assignという一風変わった参照もあります。email.bodyはメール本文をそのまま読むemail.body_textとは別物で、本文中の「名前: 値」という行を自動で解析したオブジェクトです。sys_propertiesのglide.pop3.parse_startにはこの仕組みの説明がありました。

    Text indicating the beginning of the email body section where name:value pairs should be parsed
    (訳: name:value のペアを解析すべき、メール本文セクションの開始を示すテキスト)
    引用元: /sys_properties_list.do?sysparm_query=name=glide.pop3.parse_start

    このPARSE_START〜PARSE_ENDという目印で挟まれた範囲だけが解析対象になります。本文に「assign: yamada」のような行を書いても、この目印で囲んでいなければemail.body.assignはundefinedのままで、assigned_toには何も入りません。今回の検証ではこの書式を使ったメールを作っておらず、assigned_toが設定される場面までは確認していません。

    この結果が実務のメール窓口設計にどう関わるか

    「メールで起票すると優先度が上がらない」という相談を受けたら、まずImportanceヘッダーの有無を疑ってください。本文にどんな言葉が書かれていても、標準のスクリプトはヘッダー以外を見ていません。

    callerが常にGuestになる点も見落とせません。誰からのメールでも同じ結果です。差出人の追跡や返信の宛先管理をメールのfromアドレスに頼っている運用では、caller_idを見ても送信者は分かりません。email.origemailをコメントに残す仕組みはすでにありますが、正式なユーザーとして紐づけたい場合は、送信元アドレスからユーザーを検索してcurrent.caller_idに設定する処理を、標準スクリプトへ追加で書く必要があります。

    では、priorityにも意味を持たせたいという冒頭の相談には、どう応えればよいのでしょうか。次の節で、OOTBのまま運用でカバーするか、設定を追加するかを実機での検証結果に基づいて判定します。

    OOTBのままにするか、追加のInbound Email Actionを1本足すか

    判定です。「メールでも優先度に意味を持たせたい」という要望には、標準のCreate Incidentには触れず、条件付きのInbound Email Actionを1本追加することを推奨します。全メールを一律で底上げする改修や、標準スクリプトを複製して丸ごと置き換える設計はおすすめしません。理由を実機の検証結果から順に説明します。

    標準スクリプトを直接書き換える案は避けるべきです。メジャーアップグレードで標準ロジックが更新されても、書き換えた側は追随せず取り残されます。標準を複製してまるごと差し替える案も同じ弱点を抱えるうえ、対象が全メールに及ぶため、複製側に不具合があったときの被害範囲も最大になります。

    そこで、標準はそのまま残し、特定の条件のメールだけを横から拾う追加のInbound Email Actionを検証しました。設定は次のとおりです。

    • Target table: Incident / Type: New / Action type: Record Action

    • Execution Order: 50(標準Create Incidentの100より小さく、先に評価される)

    • Conditions: Subject contains 緊急(実運用では自社のキーワードに置き換える)

    • スクリプトはCreate Incidentとほぼ同じ内容に、current.impact = 1; current.urgency = 1;を追加しただけ


    画像

    この設計を実機で動かす過程で、見落とすと事故につながる仕様に気づきました。Inbound Email Actionは、条件が一致した最初の1件だけが動くとは限りません。stop_processingという項目をfalseのままにしておくと、Order順に条件へ一致したアクションが次々と実行され続けます。

    実際に確認しました。stop_processingをfalseにしたまま、「緊急」を含む件名のメールを1件処理させたところです。追加したアクション(Order=50)と標準のCreate Incident(Order=100、条件なしのため常に一致)の両方が実行され、同じメール1通からIncidentが2件(INC0010475・INC0010476)作られました。片方はimpact/urgencyが1-High、もう片方は既定の3-Lowのままです。


    画像

    原因は単純でした。stop_processingをtrueに変更して同条件のメールを再度処理すると、作られるIncidentは1件(INC0010477)だけになりました。「緊急」を含まない通常のメールも別途処理しましたが、標準のCreate Incidentだけが動き、追加したアクションの影響は受けませんでした(INC0010478)。追加のInbound Email Actionを作るときは、stop_processingを有効にすることが前提条件だと分かります。

    判定をまとめます。

    • 場面: メールにもimpact/urgencyの手がかりを持たせたい → 判定: 追加設定を推奨 → 理由: 標準に触れず対象メールだけ迂回でき、stop_processing=trueで二重作成も防げることをPDIで確認した

    • 場面: 標準のCreate Incidentを直接書き換える、または丸ごと複製して差し替える → 判定: 非推奨 → 理由: メジャーアップグレードでの更新から外れ、不具合時の影響が全メールに及ぶ

    • 場面: caller_idが常にGuestになる問題への対応 → 判定: 本記事の検証範囲外 → 理由: priorityとは独立した論点で、送信元アドレスからユーザーを解決する別の改修が必要

    キーワード条件を使わず、OOTBのまま運用でカバーする選択肢も残ります。件名にキーワードが乗る保証がない、あるいは受付件数が少なくトリアージで十分回せるなら、無理に自動化せず次の3点だけ手順化しておけば実務は回ります。

    1. 受信箱を定期的にトリアージし、件名・本文を見て手動でImpact・Urgencyを引き上げる担当を決めておく

    2. Importanceヘッダーを送れるメール環境なら、問い合わせ窓口宛のテンプレートに重要度を明示的に付ける手順を案内に含める

    3. caller_idが常にGuestになる前提で、返信先の追跡は差出人アドレス(email.origemailのコメント)を必ず参照するルールにしておく

    実機で気づいたこと

    まず確認しておきたいのは、sys_emailにレコードを作るだけでは何も起こらないことです。何分待っても状態は変わりません。PDIは検証や事故防止のためか、メール受信処理そのものが既定でオフになっています。実際のメール窓口を持つ本番環境とは前提が違う点に、手を動かして初めて気づきました。

    「Reprocess Email」というボタンの存在も、実機を触っていて見つけたものです。最初はスクリプトの中身をコピーして手元で再現するしかないと考えていましたが、このボタンを使えば実際のコードパスをそのまま1件だけ通せます。存在を知っているかどうかで、検証にかかる手間がまったく違いました。地味なボタンですが、価値は大きいと感じました。

    caller_idの挙動も印象的でした。スクリプトの1行目にあるコメントには「opened_byはすでに送信者のユーザーIDに設定されている」と書かれています。ところがcaller_idは別の変数で、gs.getUserID()という、そのときの実行コンテキストのユーザーが入る作りです。コメントを読んだだけでは、この2つの項目の違いに気づけません。opened_byとcaller_idは似た名前の項目ですが、中身は別々に決まっています。今回はcaller_idだけを対象に確認しており、opened_byの実際の値までは追っていません。似た名前の項目ほど、どちらを見ているかを取り違えやすいと感じました。

    注意が要るのは、追加のInbound Email Actionを検証していて1通のメールから2件のIncidentが生まれた点です。stop_processingという項目名を見たときは、正直「止める対象は何だろう」くらいにしか思っていませんでした。実際に動かして初めて、条件が重なる設計は自分で防がない限りServiceNow側では防いでくれないと気づきます。追加のルールを作るたびに、他の一致するアクションが無いかを確認する習慣が要ると実感しました。


    画像

    2件の結果を並べた表です。priorityの行だけ、スクリプトが一度も出てこないことに気づきます。

    用語

    • Inbound Email Action(sysevent_in_email_action) … 受信メールをきっかけにレコードを作成・更新するルール。テーブルはRuleを継承する

    • Priority Data Lookup(dl_u_priority) … impact・urgencyの組み合わせからpriorityを決める対応表。スクリプトではなくデータで持つ

    • Data Lookup Definitions(dl_definition) … run_on_form_change・run_on_insert・run_on_updateの3フラグで、UI変更時とサーバー挿入・更新時のどちらでData Lookupを起動するかを制御するテーブル

    • glide.email.read.active … メール受信処理そのものを有効にするシステムプロパティ。PDIでは既定でfalse

    • Reprocess Email … sys_emailのレコード1件を手動でInbound Email Actionにかけ直すボタン。sys_emailのフォーム上にある

    • Stop processing(sysevent_in_email_action.stop_processing) … trueにすると、そのメールに対する以降のInbound Email Actionの評価を止める設定。falseのまま条件が重なると複数のアクションが同時に実行される

    • email.body / email.body_text … 前者はPARSE_START〜PARSE_END内を解析した値、後者は本文全体の生テキスト

    自分の環境で確認するときのURL

    • /sysevent_in_email_action_list.do?sysparm_query=table=incident^active=true … incident向けのInbound Email Action一覧

    • /dl_u_priority_list.do … impact・urgency・priorityの対応表

    • /dl_definition_list.do?sysparm_query=source_table=incident … incident向けのData Lookup Definitions一覧(run_on_form_change等のフラグを確認できる)

    • /sys_properties_list.do?sysparm_query=name=glide.email.read.active … メール受信処理の有効/無効

    引用した公式説明を自分で開く

    この記事で引用した説明文は、ServiceNowが製品に同梱しているフィールドのドキュメントです。次のURLを自分のインスタンスで開くと、同じ記述がフォームの中に見つかります。

    • priority / urgencyの公式説明(引用元):/sys_documentation_list.do?sysparm_query=name=incident^element=priority^ORname=incident^element=urgency

    • impactの公式説明(引用元):/sys_documentation_list.do?sysparm_query=name=task^element=impact

    • glide.pop3.parse_startの公式説明(引用元):/sys_properties_list.do?sysparm_query=name=glide.pop3.parse_start

    参考リンク

    検証範囲とおことわり

    数値と挙動はZurich PDI(OOTB)で2026-08-15に確認したものです。テストはexample.com宛の模擬メールをsys_emailに直接作成し、「Reprocess Email」ボタン、またはボタンと同じ処理(syseventテーブルへのemail.readイベント挿入)で処理させました。実際のPOP3・IMAP・Exchange経由の受信は検証していません。メール送信は一切行っていません。

    検証のためglide.email.read.activeを一時的にtrueへ変更しましたが、自動処理が働かないことを確認しただけで、Incidentの作成自体は「Reprocess Email」で行いました。確認後は既定値のfalseへ戻しています。POP3・IMAPアカウントの追加や送信系の設定変更は行っていません。email.body.assignによるassigned_to自動設定、返信メールへの対応、他のInbound Email Actionとの優先順位は今回の検証範囲の外です。

    最初に「Reprocess Email」の存在を知らないまま、スクリプト本文をコピーしてScripts - Backgroundで動かす方法も試しました。その結果ではcaller_idがSystem Administratorになり、今回報告した「Guest」とは異なる値でした。これは検証を実行したユーザーの違いによるもので、gs.getUserID()が実行コンテキストに依存するという性質そのものを裏付けています。本文で紹介した数値は、実際のInbound Email Action経由(Reprocess Email/sysevent挿入)で処理した、より実運用に近い結果です。

    推奨設計として紹介した追加のInbound Email Action(記事検証: 件名キーワードでImpact/Urgencyを設定)はPDI上に作成し、動作確認後にActiveをオフへ戻しています。他の記事の検証で同じPDIを使う際に、意図せず動き続けないようにするための後始末です。設定自体(Order=50 / Conditions=Subject contains 緊急 / Stop processing=true)はレコードとして残しており、内容はそのまま再現できます。作成したsys_emailとインシデント(INC0010468〜INC0010480の一部)はデータとして残しています。

    関連記事

     
     
    ServiceNowのPDI(Personal Developer Instance)を実機で観察して、Noteに記事を書いています 実装・運用・教育の現場視点で淡々と記録中です リクエストがあればその記事も書きます 個人の観察日記です

    あなたへのおすすめ