ノンアクティブなコンタクトの情報を更新する方法

samatsu 6/15/2016 1165 N/A xDB Programming

公開サイト(ライブサイト)を訪問中ではない(セッションがない)ノンアクティブなコンタクト、つまりCDサーバーのクラスターでロックが取得されていないコンタクトの情報を更新するサンプルプログラムをご紹介したいと思います。ちなみに、セッション中のコンタクト自身の情報をリクエスト処理中に更新する方法については、こちらを参照してください。

動作確認環境

  • Sitecore 8.0 Update 6

今回紹介するサンプルプログラムでは、特定されたコンタクト(Identified contact)の識別子をメソッドで受け取ってそのコンタクトをロードし、同じくメソッドに引数で渡された newFirstName でコンタクトの IContactPersonalInfoファセットのFirstNameをアップデートします。 

1.コンタクトを更新するサンプルプログラム

サンプルプログラムは次の通りです。 ContactManager を作成して、引数で指定された識別子をもとに、コンタクトを読み込んでいます。ロックの取得に成功したら、単純にコンタクトを更新し、変更を xDB(MongoDB)に書き込んでコンタクトに対して取得したロックをリリースしています。

対象のコンタクトが他のクラスターでロックをすでに取得されていた場合は何もしていません。

private void UpdateContact(string identifier, string newFirstName)
{
    Sitecore.Diagnostics.Assert.ArgumentNotNullOrEmpty(identifier, "identifier");
    ContactManager manager = Sitecore.Configuration.Factory.CreateObject("tracking/contactManager", true) as Sitecore.Analytics.Tracking.ContactManager;
    if (manager == null)
    {
        Sitecore.Diagnostics.Log.Warn("cannot create ContactManager", this);
    }
    // コンタクトを検索
    Contact c = manager.LoadContactReadOnly(identifier);
    if (c == null)
    {
        Sitecore.Diagnostics.Log.Warn("cannot find contact {0}", identifier);
        return;
    }
    LockAttemptResult<Contact> result = manager.TryLoadContact(c.ContactId, 1);
    if (result.Status == LockAttemptStatus.Success)
    {
        // コンタクトのロックを取得できた場合
        var personalInfo = result.Object.GetFacet<IContactPersonalInfo>("Personal");
        personalInfo.FirstName = newFirstName;
        manager.FlushContactToXdb(result.Object);
        manager.SaveAndReleaseContact(result.Object);
    }
    else if (result.Status == LockAttemptStatus.AlreadyLocked && result.LockedBy.Type == LeaseOwnerType.WebCluster)
    {
        // CDサーバーのクラスタにコンタクトが訪問中のため、CDサーバー側でロックが取得されている
        // アクティブなコンタクトは、ロックが解放するまで待機するか、CDサーバー側
        // で更新するコードを実行する。
        // CDサーバーにWeb API,Webサービス,HTTPハンドラ(ashx)などを実装し、
        // コンタクトを更新するリクエストをCM側から送る。
        // 以下リクエストを行うためのURLを準備する例
        string clusterName = result.LockedBy.Identifier; // クラスタ名(Analytics.ClusterName)
        string url = string.Format("https://{0}/contact/api/contact/update?id={1}", clusterName, c.ContactId);
        // 必要なパラメーターを設定してリクエストを送信する
    }
}

プログラムを実行すると、 tracking.contact にドキュメントが追加されて、しばらくするとプロセッシングサーバーにより追加されたデータが処理されアナリティクスインデックスも適切に更新されます。

エクスペリエンスプロファイルで検索を行うと、検索結果の一覧に表示されるコンタクト名前が変わるので適切にインデックスのデータがアップデートされていることを確認できます。

2.アクティブユーザーを更新する方法

ライブサイトを訪問中のアクティブなコンタクト(つまりロックがCDサーバーのクラスター側で取得されているコンタクト)は、ロックを取得しているクラスターでしか更新できません。そのため、コンタクトを更新したい場合は、ロックが解放されるまで待ってからリトライするか、紹介したサンプルコード内のコメントになるように、ロックを取得しているCDサーバーのクラスターに何らかの方法でリクエストを送信し、CDサーバー側でコンタクト情報をロードして更新してあげる必要があります。

逆の言い方をすれば、上記対応をするだけでアクティブなコンタクトの情報も更新することができます。

時間があったら、コンタクトをバルク更新するサンプルもご紹介します。