Skip to content

MailGuardianReddit/devvit-journey-insights

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Devvit Journey Insights

A standalone Devvit app that other developers can install to inspect Journey telemetry in chart form.

What this scaffold includes

  • Ingestion API endpoint for Journey events with per-project key auth.
  • Dashboard charts for funnel, retention cohorts, drop-off heatmap, latency trends, segments, and raw event explorer.
  • Project registration and API key rotation endpoints.
  • Redis-backed event persistence with bounded reads/writes and degraded in-memory fallback.
  • Starter TypeScript + Vite + Hono + React structure.

Local setup

  1. Install dependencies.
npm install
  1. Configure app secrets/settings through Devvit settings.

Example snippet from devvit.json:

{
  "settings": {
    "global": {
      "journey_insights_admin_key": {
        "type": "string",
        "label": "Journey Insights Admin Key",
        "isSecret": true
      }
    }
  }
}

Set the real secret value with CLI (do not put real values in devvit.json):

npx devvit settings set journey_insights_admin_key "replace-with-strong-admin-key"
npx devvit settings list

Optional local fallback for development only:

$env:JOURNEY_INSIGHTS_ADMIN_KEY = "replace-with-strong-admin-key"
  1. Login to Devvit and run playtest.
npm run login
npm run dev

API

POST /api/projects/register

Create a project and one API key.

Headers:

  • content-type: application/json
  • authorization: Bearer <admin-key> when journey_insights_admin_key is configured.

Body:

{
  "projectId": "proj_my_game"
}

Response includes projectId and apiKey.

POST /api/projects/rotate-key

Rotate key for an existing project.

Headers:

  • content-type: application/json
  • authorization: Bearer <admin-key> when journey_insights_admin_key is configured.

Body:

{
  "projectId": "proj_my_game"
}

POST /api/ingest

Headers:

  • content-type: application/json
  • authorization: Bearer <project-api-key>
  • x-project-id: <project-id>

Body:

{
  "events": [
    {
      "appId": "example-app",
      "projectId": "example-project",
      "journeyId": "journey-123",
      "eventType": "Journey.Start",
      "at": 1760000000000,
      "segment": "desktop"
    }
  ]
}

GET /api/snapshot

Headers:

  • authorization: Bearer <project-api-key>
  • x-project-id: <project-id> or ?projectId= query.

Returns dashboard-ready chart data for the selected project.

Multi-app model

This app is designed so each external app pushes telemetry to this app's ingestion endpoint. That gives team-wide cross-app analytics without needing direct read access across native Devvit Journey streams.

Using Devvit Journeys Journey ID With This App

Yes, the Devvit Journeys pattern works here, but you need one adapter step: thread x-devvit-journey-id from your client request into a server route, then forward it to this app's POST /api/ingest payload as journeyId.

Client example (your app):

import { telemetry } from '@devvit/analytics/client/reddit';

export async function submitScore(score: number): Promise<void> {
  const journeyId = telemetry.getActiveJourneyId();

  await fetch('/api/score', {
    method: 'POST',
    headers: {
      'content-type': 'application/json',
      ...(journeyId ? { 'x-devvit-journey-id': journeyId } : {}),
    },
    body: JSON.stringify({ score }),
  });
}

Server adapter example (your app backend):

app.post('/api/score', async (req, res) => {
  const journeyIdHeader = req.header('x-devvit-journey-id');
  const journeyId = typeof journeyIdHeader === 'string' ? journeyIdHeader : '';
  const score = Number(req.body?.score ?? 0);

  await fetch(`${process.env.JOURNEY_INSIGHTS_URL}/api/ingest`, {
    method: 'POST',
    headers: {
      'content-type': 'application/json',
      authorization: `Bearer ${process.env.JOURNEY_INSIGHTS_PROJECT_KEY}`,
      'x-project-id': process.env.JOURNEY_INSIGHTS_PROJECT_ID ?? '',
    },
    body: JSON.stringify({
      events: [
        {
          appId: 'your-app-id',
          projectId: process.env.JOURNEY_INSIGHTS_PROJECT_ID,
          journeyId: journeyId || `fallback-${Date.now()}`,
          eventType: 'Journey.End',
          at: Date.now(),
          complete: true,
          win: true,
          score,
          action: 'submit_score',
          actionDetails: 'score submitted from gameplay flow',
        },
      ],
    }),
  });

  res.json({ ok: true });
});

Notes:

  • This app does not provide /api/score; your backend route is the adapter.
  • Keep eventType aligned with actual user commitment points.
  • Do not send PII in action or actionDetails.

Plug-and-play setup for other developers

  1. Open Journey Insights dashboard.
  2. Enter Project ID and click "Create Project + Key" (or paste existing ID/key).
  3. Paste the generated ID/key into your app's telemetry sender.
  4. Open the same dashboard, keep those credentials filled in, and charts load automatically.

Next implementation steps

  • Add per-project quotas and request metering.
  • Add role-based admin auth integration.
  • Add CSV export and schema versioning.

About

No description, website, or topics provided.

Resources

Stars

2 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors