{
  "cells": [
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "5XNYlDkDLpqU"
      },
      "outputs": [],
      "source": [
        "# Copyright 2025 Google LLC\n",
        "#\n",
        "# Licensed under the Apache License, Version 2.0 (the \"License\");\n",
        "# you may not use this file except in compliance with the License.\n",
        "# You may obtain a copy of the License at\n",
        "#\n",
        "#     https://www.apache.org/licenses/LICENSE-2.0\n",
        "#\n",
        "# Unless required by applicable law or agreed to in writing, software\n",
        "# distributed under the License is distributed on an \"AS IS\" BASIS,\n",
        "# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n",
        "# See the License for the specific language governing permissions and\n",
        "# limitations under the License."
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "5tR528hOD4Dx"
      },
      "source": [
        "# Recording Real-Time User Events in Vertex AI Search Datastores\n",
        "\n",
        "<table align=\"left\">\n",
        "  <td style=\"text-align: center\">\n",
        "    <a href=\"https://art-analytics.appspot.com/r.html?uaid=G-FHXEFWTT4E&utm_source=aRT-vais-building-blocks&utm_medium=aRT-clicks&utm_campaign=vais-building-blocks&destination=vais-building-blocks&url=https%3A%2F%2Fcolab.research.google.com%2Fgithub%2FGoogleCloudPlatform%2Fapplied-ai-engineering-samples%2Fblob%2Fmain%2Fsearch%2Fvais-building-blocks%2Frecord_user_events.ipynb\">\n",
        "      <img width=\"32px\" src=\"https://www.gstatic.com/pantheon/images/bigquery/welcome_page/colab-logo.svg\" alt=\"Google Colaboratory logo\"><br> Open in Colab\n",
        "    </a>\n",
        "  </td>\n",
        "  <td style=\"text-align: center\">\n",
        "    <a href=\"https://art-analytics.appspot.com/r.html?uaid=G-FHXEFWTT4E&utm_source=aRT-vais-building-blocks&utm_medium=aRT-clicks&utm_campaign=vais-building-blocks&destination=vais-building-blocks&url=https%3A%2F%2Fconsole.cloud.google.com%2Fvertex-ai%2Fcolab%2Fimport%2Fhttps%3A%252F%252Fraw.githubusercontent.com%252FGoogleCloudPlatform%252Fapplied-ai-engineering-samples%252Fmain%252Fsearch%252Fvais-building-blocks%252Frecord_user_events.ipynb\">\n",
        "      <img width=\"32px\" src=\"https://lh3.googleusercontent.com/JmcxdQi-qOpctIvWKgPtrzZdJJK-J3sWE1RsfjZNwshCFgE_9fULcNpuXYTilIR2hjwN\" alt=\"Google Cloud Colab Enterprise logo\"><br> Open in Colab Enterprise\n",
        "    </a>\n",
        "  </td>\n",
        "  <td style=\"text-align: center\">\n",
        "    <a href=\"https://art-analytics.appspot.com/r.html?uaid=G-FHXEFWTT4E&utm_source=aRT-vais-building-blocks&utm_medium=aRT-clicks&utm_campaign=vais-building-blocks&destination=vais-building-blocks&url=https%3A%2F%2Fconsole.cloud.google.com%2Fvertex-ai%2Fworkbench%2Fdeploy-notebook%3Fdownload_url%3Dhttps%3A%2F%2Fraw.githubusercontent.com%2FGoogleCloudPlatform%2Fapplied-ai-engineering-samples%2Fmain%2Fsearch%2Fvais-building-blocks%2Frecord_user_events.ipynb\">\n",
        "      <img src=\"https://www.gstatic.com/images/branding/gcpiconscolors/vertexai/v1/32px.svg\" alt=\"Vertex AI logo\"><br> Open in Vertex AI Workbench\n",
        "    </a>\n",
        "  </td>\n",
        "  <td style=\"text-align: center\">\n",
        "    <a href=\"https://github.com/GoogleCloudPlatform/applied-ai-engineering-samples/blob/main/search/vais-building-blocks/record_user_events.ipynb\">\n",
        "      <img width=\"32px\" src=\"https://upload.wikimedia.org/wikipedia/commons/9/91/Octicons-mark-github.svg\" alt=\"GitHub logo\"><br> View on GitHub\n",
        "    </a>\n",
        "  </td>\n",
        "</table>\n",
        "\n",
        "<div style=\"clear: both;\"></div>\n",
        "\n",
        "<b>Share to:</b>\n",
        "\n",
        "<a href=\"https://www.linkedin.com/sharing/share-offsite/?url=https%3A//github.com/GoogleCloudPlatform/generative-ai/blob/main/search/vais-building-blocks/record_user_events.ipynb\" target=\"_blank\">\n",
        "  <img width=\"20px\" src=\"https://upload.wikimedia.org/wikipedia/commons/8/81/LinkedIn_icon.svg\" alt=\"LinkedIn logo\">\n",
        "</a>\n",
        "\n",
        "<a href=\"https://bsky.app/intent/compose?text=https%3A//github.com/GoogleCloudPlatform/generative-ai/blob/main/search/vais-building-blocks/record_user_events.ipynb\" target=\"_blank\">\n",
        "  <img width=\"20px\" src=\"https://upload.wikimedia.org/wikipedia/commons/7/7a/Bluesky_Logo.svg\" alt=\"Bluesky logo\">\n",
        "</a>\n",
        "\n",
        "<a href=\"https://twitter.com/intent/tweet?url=https%3A//github.com/GoogleCloudPlatform/generative-ai/blob/main/search/vais-building-blocks/record_user_events.ipynb\" target=\"_blank\">\n",
        "  <img width=\"20px\" src=\"https://upload.wikimedia.org/wikipedia/commons/5/53/X_logo_2023_original.svg\" alt=\"X logo\">\n",
        "</a>\n",
        "\n",
        "<a href=\"https://reddit.com/submit?url=https%3A//github.com/GoogleCloudPlatform/generative-ai/blob/main/search/vais-building-blocks/record_user_events.ipynb\" target=\"_blank\">\n",
        "  <img width=\"20px\" src=\"https://redditinc.com/hubfs/Reddit%20Inc/Brand/Reddit_Logo.png\" alt=\"Reddit logo\">\n",
        "</a>\n",
        "\n",
        "<a href=\"https://www.facebook.com/sharer/sharer.php?u=https%3A//github.com/GoogleCloudPlatform/generative-ai/blob/main/search/vais-building-blocks/record_user_events.ipynb\" target=\"_blank\">\n",
        "  <img width=\"20px\" src=\"https://upload.wikimedia.org/wikipedia/commons/5/51/Facebook_f_logo_%282019%29.svg\" alt=\"Facebook logo\">\n",
        "</a>"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "pkd93iDpEBWx"
      },
      "source": [
        "| | |\n",
        "|----------|-------------|\n",
        "| Author(s)   | Hossein Mansour|\n",
        "| Reviewers(s) | \tAbhishek Bhagwat|\n",
        "| Last updated | 2025-01-07: The first draft |"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "yAnTektvEQjb"
      },
      "source": [
        "# Overview\n",
        "\n",
        "\n",
        "In this notebook, we demonstrate how to [record real-time](https://cloud.google.com/generative-ai-app-builder/docs/record-user-events) user events for Vertex AI Search (VAIS) Website Datastores. While there are subtle differences, a very similar approach can be applied to recording real-time user events for other types of VAIS datastores such as unstructured datastores containing PDFs.\n",
        "\n",
        "\n",
        "User events are reported by customers as their users interact with their search and recommendation apps in different ways. [Event types](https://cloud.google.com/generative-ai-app-builder/docs/user-events#types) supported by the broader family of VAIS apps include search, view homepage, view category, view item, add to card, purchased, media play, and media complete. User events are the primary way VAIS recommendations apps learn from user behavior. They can also lead to significant improvements in search apps hence are highly encouraged.\n",
        "\n",
        "\n",
        "In the context of Website search, VAIS considers both the relevancy of the page to the query as well as the likelihood of a click learned from user behavior on the public web to come up with the final ranking of the results. Reranking based on user behavior is most helpful for ambiguous head queries where many results are relevant to the query and the tie breaker is the user preference captured via click events.\n",
        "\n",
        "\n",
        "While VAIS is designed to provide a great experience out-of-the-box, there is a possibility to further enhance the user experience by reporting historical and real time user events by the customer as additional signals. This enables the search app to learn from user interaction with the search results which leads to increasingly better ranking over time. This is particularly helpful when user behavior on a customer's domain significantly deviates from user behavior on the web. It is also important for authenticated search where the target pages are not publically available.\n",
        "\n",
        "![user_events.png](https://storage.googleapis.com/github-repo/generative-ai/search/vais-building-blocks/record_user_events/user_events.png)\n",
        "\n",
        "\n",
        "User events can influence the ranking of the results in three tires:\n",
        "- **Popularity** where pages with more clicks get prioritized\n",
        "- **Relevancy** where the relevance of pages to a certain query is judged by the likelihood of a click learned from the past interaction of ALL users with the app\n",
        "- **Personalization** where the preference of a certain user is captured via their own past interactions with the app\n",
        "Depending on the quality and quantity of user events one or more of these tiers can get unlocked. Enabling these tiers does not require any explicit opt-in or config change by the customer.\n",
        "\n",
        "\n",
        "In addition to better ranking, user events enable VAIS to report on more advanced search metrics such as CTR in the [analytics tab](https://cloud.google.com/generative-ai-app-builder/docs/view-analytics).\n",
        "\n",
        "\n",
        "The focus of this notebook is on recording real-time user events, however VAIS allows for [importing historical user events](https://cloud.google.com/generative-ai-app-builder/docs/import-user-events) as well.\n",
        "\n",
        "\n",
        "Additionally in this notebook we'll focus on explicit reporting of user events via `userEvents.write` method but there is an alternative way of leveraging [JavaPixel](https://cloud.google.com/generative-ai-app-builder/docs/record-user-events#record-with-javascript-pixel) to achieve the same goal which is the recommended approach if the customer can control the page source.\n",
        "\n",
        "\n",
        "To run this notebook you need an existing advanced website search datastore.\n",
        "\n",
        "\n",
        "We will perform the following steps:\n",
        "\n",
        "\n",
        "- Define helper functions to issue search, and report search and view-item events\n",
        "- Define a function to generate and report synthetic user events\n",
        "- Issue a sample search and report corresponding events\n",
        "- Cleanup\n",
        "\n",
        "\n",
        "REST API is used throughout this notebook. Please consult the [official documentation](https://cloud.google.com/generative-ai-app-builder/docs/apis) for alternative ways to achieve the same goal, namely Client libraries and RPC.\n",
        "\n",
        "\n",
        "\n",
        "\n",
        "# Vertex AI Search\n",
        "Vertex AI Search (VAIS) is a fully-managed platform, powered by large language models, that lets you build AI-enabled search and recommendation experiences for your public or private websites or mobile applications\n",
        "\n",
        "\n",
        "VAIS can handle a diverse set of data sources including structured, unstructured, and website data, as well as data from third-party applications such as Jira, Salesforce, and Confluence.\n",
        "\n",
        "\n",
        "VAIS also has built-in integration with LLMs which enables you to provide answers to complex questions, grounded in your data\n",
        "\n",
        "\n",
        "# Using this Notebook\n",
        "If you're running outside of Colab, depending on your environment you may need to install pip packages that are included in the Colab environment by default but are not part of the Python Standard Library. Outside of Colab you'll also notice comments in code cells that look like #@something, these trigger special Colab functionality but don't change the behavior of the notebook.\n",
        "\n",
        "\n",
        "This tutorial uses the following Google Cloud services and resources:\n",
        "\n",
        "\n",
        "- Service Usage API\n",
        "- Discovery Engine API\n",
        "\n",
        "\n",
        "This notebook has been tested in the following environment:\n",
        "\n",
        "\n",
        "- Python version = 3.10.12\n",
        "- google.cloud.storage = 2.8.0\n",
        "- google.auth = 2.27.0\n",
        "\n",
        "\n",
        "# Getting Started\n",
        "\n",
        "\n",
        "The following steps are necessary to run this notebook, no matter what notebook environment you're using.\n",
        "\n",
        "\n",
        "If you're entirely new to Google Cloud, [get started here](https://cloud.google.com/docs/get-started)\n",
        "\n",
        "\n",
        "## Google Cloud Project Setup\n",
        "\n",
        "\n",
        "1. [Select or create a Google Cloud project](https://console.cloud.google.com/cloud-resource-manager). When you first create an account, you get a $300 free credit towards your compute/storage costs\n",
        "2. [Make sure that billing is enabled for your project](https://cloud.google.com/billing/docs/how-to/modify-project)\n",
        "3. [Enable the Service Usage API](https://console.cloud.google.com/apis/library/serviceusage.googleapis.com)\n",
        "4. [Enable the Discovery Engine API for your project](https://console.cloud.google.com/marketplace/product/google/discoveryengine.googleapis.com)\n",
        "\n",
        "\n",
        "## Google Cloud Permissions\n",
        "\n",
        "\n",
        "Ideally you should have [Owner role](https://cloud.google.com/iam/docs/understanding-roles) for your project to run this notebook. If that is not an option, you need at least the following [roles](https://cloud.google.com/iam/docs/granting-changing-revoking-access)\n",
        "- **`roles/serviceusage.serviceUsageAdmin`** to enable APIs\n",
        "- **`roles/iam.serviceAccountAdmin`** to modify service agent permissions\n",
        "- **`roles/discoveryengine.admin`** to modify discoveryengine assets\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "49x_J4vWOuNg"
      },
      "source": [
        "#Setup Environment"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "kMYYfGpyOl5G"
      },
      "source": [
        "## Authentication\n",
        "\n",
        " If you're using Colab, run the code in the next cell. Follow the pop-ups and authenticate with an account that has access to your Google Cloud [project](https://cloud.google.com/resource-manager/docs/creating-managing-projects#identifying_projects).\n",
        "\n",
        "If you're running this notebook somewhere besides Colab, make sure your environment has the right Google Cloud access. If that's a new concept to you, consider looking into [Application Default Credentials for your local environment](https://cloud.google.com/docs/authentication/provide-credentials-adc#local-dev) and [initializing the Google Cloud CLI](https://cloud.google.com/docs/authentication/gcloud). In many cases, running `gcloud auth application-default login` in a shell on the machine running the notebook kernel is sufficient.\n",
        "\n",
        "More authentication options are discussed [here](https://cloud.google.com/docs/authentication)."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 1,
      "metadata": {
        "id": "DZjtfEDG7Sr3"
      },
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "Authenticated\n"
          ]
        }
      ],
      "source": [
        "# Colab authentication.\n",
        "import sys\n",
        "\n",
        "if \"google.colab\" in sys.modules:\n",
        "    from google.colab import auth\n",
        "\n",
        "    auth.authenticate_user()\n",
        "    print(\"Authenticated\")"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 2,
      "metadata": {
        "id": "kT3Eda7_mlTP"
      },
      "outputs": [],
      "source": [
        "from google.auth import default\n",
        "from google.auth.transport.requests import AuthorizedSession\n",
        "\n",
        "creds, _ = default()\n",
        "authed_session = AuthorizedSession(creds)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "otijhCIjOzk-"
      },
      "source": [
        "## Import Libraries"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 3,
      "metadata": {
        "id": "DlIp4zv3cdA7"
      },
      "outputs": [],
      "source": [
        "import time"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "N51y_mPgPHsj"
      },
      "source": [
        "## Configure environment\n",
        "\n",
        "The Location of a Datastore is set at the time of creation and it should be called appropriately to query the Datastore. Given that our sample website datastore is `global`, we use that within this notebook.\n",
        "\n",
        "You can find more information regarding the `Location` of datastores and associated limitations [here](https://cloud.google.com/generative-ai-app-builder/docs/locations#specify_a_multi-region_for_your_data_store).\n",
        "\n",
        "`VAIS_BRANCH` is the branch of VAIS to use. Given that this feature is available in GA, we use V1 here."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 11,
      "metadata": {
        "id": "hKLBf1GqROW7"
      },
      "outputs": [],
      "source": [
        "PROJECT_ID = \"\"  # @param {type: 'string'}\n",
        "DATASTORE_ID = \"\"  # @param {type: 'string'}\n",
        "LOCATION = \"global\"  # @param [\"global\", \"us\", \"eu\"]\n",
        "VAIS_BRANCH = \"v1\"  # @param {type: 'string'}"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "Akk3C5vK8oG6"
      },
      "source": [
        "# Step 1. Define Helper functions\n",
        "\n",
        "In this section we define helper functions to issue a sample search request to a datastore, report a search event, report a view-item event, and pull all of these together to simulate the flow of a user doing search and clicking on a result.\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "C2hXlewDINDg"
      },
      "source": [
        "## Helper functions to issue basic search on a Datastore"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "v-XHQIOooshe"
      },
      "outputs": [],
      "source": [
        "def search(\n",
        "    project_id: str, location: str, datastore_id: str, searchQuery: str, pageSize: int\n",
        "):\n",
        "    \"\"\"Searches a datastore using the provided query.\"\"\"\n",
        "    response = authed_session.post(\n",
        "        f\"https://discoveryengine.googleapis.com/{VAIS_BRANCH}/projects/{project_id}/locations/{location}/collections/default_collection/dataStores/{datastore_id}/servingConfigs/default_search:search\",\n",
        "        headers={\n",
        "            \"Content-Type\": \"application/json\",\n",
        "        },\n",
        "        json={\"query\": searchQuery, \"pageSize\": pageSize},\n",
        "    )\n",
        "    return response"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "eAigF6KHkMZ2"
      },
      "source": [
        "## Helper functions to report search and view-item events"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "IO1AxLZckXYK"
      },
      "outputs": [],
      "source": [
        "def search_event(\n",
        "    project_id: str,\n",
        "    location: str,\n",
        "    datastore_id: str,\n",
        "    user_pseudo_id: str,\n",
        "    search_query: str,\n",
        "    impressions: list,\n",
        "    attribution_token: str,\n",
        "):\n",
        "    \"\"\"Report search events.\"\"\"\n",
        "    response = authed_session.post(\n",
        "        f\"https://discoveryengine.googleapis.com/{VAIS_BRANCH}/projects/{project_id}/locations/{location}/collections/default_collection/dataStores/{datastore_id}/userEvents:write\",\n",
        "        headers={\n",
        "            \"Content-Type\": \"application/json\",\n",
        "        },\n",
        "        json={\n",
        "            \"eventType\": \"search\",\n",
        "            \"userPseudoId\": user_pseudo_id,\n",
        "            \"searchInfo\": {\n",
        "                \"searchQuery\": search_query,\n",
        "            },\n",
        "            \"documents\": impressions,\n",
        "            \"attributionToken\": attribution_token,\n",
        "        },\n",
        "    )\n",
        "    return response\n",
        "\n",
        "\n",
        "def view_event(\n",
        "    project_id: str,\n",
        "    location: str,\n",
        "    datastore_id: str,\n",
        "    user_pseudo_id: str,\n",
        "    viewed_uri: str,\n",
        "    attribution_token: str,\n",
        "):\n",
        "    \"\"\"Report view-item events.\"\"\"\n",
        "    response = authed_session.post(\n",
        "        f\"https://discoveryengine.googleapis.com/{VAIS_BRANCH}/projects/{project_id}/locations/{location}/collections/default_collection/dataStores/{datastore_id}/userEvents:write\",\n",
        "        headers={\n",
        "            \"Content-Type\": \"application/json\",\n",
        "        },\n",
        "        json={\n",
        "            \"attributionToken\": attribution_token,\n",
        "            \"eventType\": \"view-item\",\n",
        "            \"userPseudoId\": user_pseudo_id,\n",
        "            \"documents\": [{\"uri\": viewed_uri}],\n",
        "        },\n",
        "    )\n",
        "    return response"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "DYArgsiAiVfs"
      },
      "source": [
        "# Step 2. Define a function to generate and report synthetic user events\n",
        "\n",
        "In this function we issue a search, report a search event which includes the corresponding attribution token and impressions (i.e. list of results shown to the end user), and finally report a view-item event which shows which link did the user click on.\n",
        "\n",
        "For the purpose of this notebook, we extract the list of impressions from the search response, however some customers may apply their own post-processiong logic in which case the final ranking of the results may differ from the one in VAIS response. For those cases the explicit list of impressions should be provided in the following format:\n",
        "```\n",
        "impressions = [\n",
        "    {\n",
        "        'uri': 'https://example.com/page-1'\n",
        "    },\n",
        "    {\n",
        "        'uri': 'https://example.com/page-2'\n",
        "    },\n",
        "    {\n",
        "        'uri': 'https://example.com/page-3[link text](https://)'\n",
        "    },\n",
        "]\n",
        "```\n",
        "\n",
        "Note that the only change needed to apply the same approach to reporting user events for other types of datastores is to [identify documents](https://cloud.google.com/generative-ai-app-builder/docs/reference/rest/v1/projects.locations.dataStores.userEvents#documentinfo) with other fields such as document id.\n",
        "\n",
        "\n",
        "On a broader note, a similar approach can be applied to reporting user events for recommendation apps. See the full anatomy of a user event in [reference documentation](https://cloud.google.com/generative-ai-app-builder/docs/reference/rest/v1/projects.locations.dataStores.userEvents). Noteworthy is the attributes field which can be used to improve recommendation by providing additional user info such as their age, gender, location, etc."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "_0uAQTKD78_k"
      },
      "outputs": [],
      "source": [
        "def generate_synthetic_events(\n",
        "    project_id: str,\n",
        "    location: str,\n",
        "    datastore_id: str,\n",
        "    user_pseudo_id: str,\n",
        "    search_query: str,\n",
        "    page_size: int,\n",
        "    viewed_uri: str,\n",
        "):\n",
        "    \"\"\"Issue a search hand report the corresponding events.\"\"\"\n",
        "\n",
        "    search_resp = search(project_id, location, datastore_id, search_query, page_size)\n",
        "    print(\"Search response:\")\n",
        "    print(search_resp.json())\n",
        "    attribution_token = search_resp.json()[\"attributionToken\"]\n",
        "\n",
        "    impressions = [\n",
        "        {\"uri\": result[\"document\"][\"derivedStructData\"][\"link\"]}\n",
        "        for result in search_resp.json()[\"results\"]\n",
        "    ]\n",
        "    print(\"Impression list:\")\n",
        "    print(impressions)\n",
        "    time.sleep(1)\n",
        "\n",
        "    search_event_resp = search_event(\n",
        "        project_id,\n",
        "        location,\n",
        "        datastore_id,\n",
        "        user_pseudo_id,\n",
        "        search_query,\n",
        "        impressions,\n",
        "        attribution_token,\n",
        "    )\n",
        "    print(\"Sent search event:\")\n",
        "    print(search_event_resp.json())\n",
        "    time.sleep(2)\n",
        "\n",
        "    view_event_resp = view_event(\n",
        "        project_id,\n",
        "        location,\n",
        "        datastore_id,\n",
        "        user_pseudo_id,\n",
        "        viewed_uri,\n",
        "        attribution_token,\n",
        "    )\n",
        "    print(\"Sent view event:\")\n",
        "    print(view_event_resp.json())"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "HtpTWTZIVsFD"
      },
      "source": [
        "# Step 3. Issue a sample search and report corresponding events\n",
        "\n",
        "In this example we have a VAIS website datastore for VAIS documentation. An end user with user_pseudo_id of Alice searches for the term `filter results`. The top five results are presented and Alice clicks on one of the results, a page describing how to filter generic search results in this instance.\n",
        "\n",
        "Please modify these parameters as it relates to you target datastore."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "p0fO9uNgVzKl"
      },
      "outputs": [],
      "source": [
        "generate_synthetic_events(\n",
        "    project_id=PROJECT_ID,\n",
        "    location=LOCATION,\n",
        "    datastore_id=DATASTORE_ID,\n",
        "    user_pseudo_id=\"Alice\",\n",
        "    search_query=\"filter results\",\n",
        "    page_size=5,\n",
        "    viewed_uri=\"https://cloud.google.com/generative-ai-app-builder/docs/filter-search-metadata\",\n",
        ")"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "N4A-_l_jLY5W"
      },
      "source": [
        "# Cleanup\n",
        "\n",
        "Cleanup resources created in this notebook, specifically purging the events recorded in the notebook.\n",
        "\n",
        "Purge events can optionally have filters to only purge a subset of events. We purge events reported for \"Alice\" userPseudoId.\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "WgMKwi7hLZjA"
      },
      "outputs": [],
      "source": [
        "def purge_event(project_id: str, location: str, datastore_id: str, purge_filter: str):\n",
        "    \"\"\"Purge events matching a filter.\"\"\"\n",
        "    response = authed_session.post(\n",
        "        f\"https://discoveryengine.googleapis.com/{VAIS_BRANCH}/projects/{project_id}/locations/{location}/collections/default_collection/dataStores/{datastore_id}/userEvents:purge\",\n",
        "        headers={\n",
        "            \"Content-Type\": \"application/json\",\n",
        "        },\n",
        "        json={\"filter\": purge_filter},\n",
        "    )\n",
        "    return response\n",
        "\n",
        "\n",
        "resp = purge_event(\n",
        "    project_id=PROJECT_ID,\n",
        "    location=LOCATION,\n",
        "    datastore_id=DATASTORE_ID,\n",
        "    purge_filter='eventTime>\"2024-12-23T18:25:43.511Z\" userPseudoId=\"Alice\"',\n",
        ")\n",
        "print(resp.json())"
      ]
    }
  ],
  "metadata": {
    "colab": {
      "name": "record_user_events.ipynb",
      "toc_visible": true
    },
    "kernelspec": {
      "display_name": "Python 3",
      "name": "python3"
    }
  },
  "nbformat": 4,
  "nbformat_minor": 0
}
