From 3aeceec3a959f3651a4d0e220b1844270025e42d Mon Sep 17 00:00:00 2001 From: Aashil Date: Wed, 23 Sep 2026 16:53:59 +0545 Subject: [PATCH] chore: add temporary read-only diagnostic for active-conversation cap Co-Authored-By: Claude Sonnet 5 --- .github/workflows/diagnose-active-cap.yml | 35 +++++++++++++++ scripts/diagnose-active-cap.mjs | 52 +++++++++++++++++++++++ 2 files changed, 87 insertions(+) create mode 100644 .github/workflows/diagnose-active-cap.yml create mode 100644 scripts/diagnose-active-cap.mjs diff --git a/.github/workflows/diagnose-active-cap.yml b/.github/workflows/diagnose-active-cap.yml new file mode 100644 index 0000000..701e43c --- /dev/null +++ b/.github/workflows/diagnose-active-cap.yml @@ -0,0 +1,35 @@ +name: Diagnose active-conversation cap (temporary, read-only) + +on: + workflow_dispatch: + inputs: + account_key: + description: "Crisp account key from config/inbox-to-repo.json (e.g. USER_REGISTRATION)" + required: true + type: string + session_id: + description: "Crisp session_id to locate in the sorted list" + required: true + type: string + +jobs: + diagnose: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 + with: + node-version: "20" + - run: node scripts/diagnose-active-cap.mjs + env: + ACCOUNT_KEY: ${{ inputs.account_key }} + TARGET_SESSION_ID: ${{ inputs.session_id }} + CRISP_USER_REGISTRATION_IDENTIFIER: ${{ secrets.CRISP_USER_REGISTRATION_IDENTIFIER }} + CRISP_USER_REGISTRATION_KEY: ${{ secrets.CRISP_USER_REGISTRATION_KEY }} + CRISP_USER_REGISTRATION_WEBSITE_ID: ${{ vars.CRISP_USER_REGISTRATION_WEBSITE_ID }} + CRISP_EVEREST_FORMS_IDENTIFIER: ${{ secrets.CRISP_EVEREST_FORMS_IDENTIFIER }} + CRISP_EVEREST_FORMS_KEY: ${{ secrets.CRISP_EVEREST_FORMS_KEY }} + CRISP_EVEREST_FORMS_WEBSITE_ID: ${{ vars.CRISP_EVEREST_FORMS_WEBSITE_ID }} + CRISP_THEMEGRILL_IDENTIFIER: ${{ secrets.CRISP_THEMEGRILL_IDENTIFIER }} + CRISP_THEMEGRILL_KEY: ${{ secrets.CRISP_THEMEGRILL_KEY }} + CRISP_THEMEGRILL_WEBSITE_ID: ${{ vars.CRISP_THEMEGRILL_WEBSITE_ID }} diff --git a/scripts/diagnose-active-cap.mjs b/scripts/diagnose-active-cap.mjs new file mode 100644 index 0000000..7e591b0 --- /dev/null +++ b/scripts/diagnose-active-cap.mjs @@ -0,0 +1,52 @@ +#!/usr/bin/env node +// One-off, read-only diagnostic: how many unresolved conversations does this +// account actually have, and where does TARGET_SESSION_ID rank in the same +// order_date_updated=1 sort that fetchActiveConversations uses? Answers +// whether the 10-page/200-item cap is actually why a given session gets +// missed, instead of guessing from code alone. +import { credsForAccount, crispGet } from "./crisp-client.mjs"; + +const { ACCOUNT_KEY, TARGET_SESSION_ID } = process.env; +if (!ACCOUNT_KEY || !TARGET_SESSION_ID) { + console.error("Missing required env vars: ACCOUNT_KEY, TARGET_SESSION_ID"); + process.exit(1); +} + +async function main() { + const creds = credsForAccount(ACCOUNT_KEY); + const conversations = []; + let rank = -1; + let hitRateLimit = false; + + for (let page = 1; page <= 50; page++) { + const params = new URLSearchParams({ filter_not_resolved: "true", order_date_updated: "1" }); + let data; + try { + ({ data } = await crispGet(creds, `/website/${creds.websiteId}/conversations/${page}?${params}`)); + } catch (err) { + console.error(`Page ${page} request failed: ${err.message}`); + hitRateLimit = true; + break; + } + if (!data || data.length === 0) break; + conversations.push(...data); + const idx = data.findIndex((c) => c.session_id === TARGET_SESSION_ID); + if (idx !== -1 && rank === -1) rank = conversations.length - data.length + idx + 1; + console.log(`Page ${page}: ${data.length} conversations (running total ${conversations.length})`); + if (data.length < 20) break; + } + + console.log(`\n=== Result for ${ACCOUNT_KEY} ===`); + console.log(`Total unresolved conversations fetched: ${conversations.length}${hitRateLimit ? " (stopped early -- rate limited)" : ""}`); + console.log(`Current 10-page/200-item cap covers ranks 1-200.`); + if (rank === -1) { + console.log(`${TARGET_SESSION_ID}: NOT FOUND within ${conversations.length} fetched (either resolved right now, or beyond page 50).`); + } else { + console.log(`${TARGET_SESSION_ID}: rank ${rank} by most-recently-updated -- ${rank <= 200 ? "WITHIN" : "OUTSIDE"} the current 200-item cap.`); + } +} + +main().catch((err) => { + console.error(err); + process.exit(1); +});