Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add opt-in telemetry #24

Merged
merged 3 commits into from
Jan 3, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion idkit/esbuild/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ export default /** @type {import('esbuild').BuildOptions} */ ({
logLevel: 'info',
define: {
global: 'globalThis',
worldIdJSVersion: JSON.stringify(packageJson.version),
IDKitVersion: JSON.stringify(packageJson.version),
},
entryPoints: [require.resolve('../src/index.ts')],
globalName: 'IDKit',
Expand Down
1 change: 1 addition & 0 deletions idkit/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@
"framer-motion": "^7.6.7",
"js-sha3": "^0.8.0",
"phone": "^3.1.30",
"posthog-js-lite": "2.0.0-alpha5",
"qr-code-styling-new": "^1.6.1",
"react-countdown": "^2.3.4",
"react-country-flag": "^3.0.2",
Expand Down
5 changes: 3 additions & 2 deletions idkit/src/components/IDKitWidget/States/EnterPhoneState.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import PhoneInput from '@/components/PhoneInput'
import WorldIDIcon from '@/components/WorldIDIcon'
import { XMarkIcon } from '@heroicons/react/20/solid'
import { isRequestCodeError, requestCode } from '@/services/phone'
import { getTelemetryId, telemetryPhoneTyped } from '@/lib/telemetry'

const getParams = ({
processing,
Expand All @@ -30,8 +31,8 @@ const getParams = ({
try {
setProcessing(true)
setErrorState(null)
// FIXME: ph_distinct_id
await requestCode(phoneNumber, stringifiedActionId, '')
await requestCode(phoneNumber, stringifiedActionId, getTelemetryId())
telemetryPhoneTyped()
setProcessing(false)
setStage(IDKITStage.ENTER_CODE)
} catch (error) {
Expand Down
9 changes: 7 additions & 2 deletions idkit/src/components/IDKitWidget/States/VerifyCodeState.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { useMemo, useRef } from 'react'
import useIDKitStore from '@/store/idkit'
import { DEFAULT_COPY } from '@/types/config'
import type { IDKitStore } from '@/store/idkit'
import { getTelemetryId } from '@/lib/telemetry'
import WorldIDIcon from '@/components/WorldIDIcon'
import ResendButton from '@/components/ResendButton'
import SMSCodeInput from '@/components/SMSCodeInput'
Expand Down Expand Up @@ -34,8 +35,12 @@ const getParams = ({
try {
setErrorState(null)
setProcessing(true)
// FIXME: Add ph_distinct_id
const { nullifier_hash, ...proof_payload } = await verifyCode(phoneNumber, code, stringifiedActionId, '')
const { nullifier_hash, ...proof_payload } = await verifyCode(
phoneNumber,
code,
stringifiedActionId,
getTelemetryId()
)
onSuccess({ signal_type: SignalType.Phone, nullifier_hash, proof_payload })
} catch (error) {
setProcessing(false)
Expand Down
52 changes: 52 additions & 0 deletions idkit/src/lib/telemetry.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import PostHog from 'posthog-js-lite'

// Set at build time
declare const IDKitVersion: string

function factoryPostHogFetchError(error: unknown) {
return { name: 'telemetry-error', error }
}

if (typeof window !== 'undefined') {
window.onunhandledrejection = function (event) {
return event.reason.name !== 'telemetry-error'
}
}

async function posthogFetch(input: RequestInfo, init?: RequestInit): Promise<Response> {
try {
return await fetch(input, init)
} catch (error) {
throw factoryPostHogFetchError(error)
}
}

const posthog = new PostHog(
'phc_QttqgDbMQDYHX1EMH7FnT6ECBVzdp0kGUq92aQaVQ6I', // cspell:disable-line
{ persistence: 'memory' }
)

posthog.fetch = posthogFetch

// Attributes sent on all events
const SUPER_PROPS = { version: IDKitVersion, package: 'idkit-js' }

export const getTelemetryId = (): string => {
return posthog.getDistinctId()
}

export const initTelemetry = (enableTelemetry?: boolean): void => {
if (enableTelemetry) {
posthog.capture('idkit loaded', SUPER_PROPS)
} else {
posthog.optOut()
}
}

export const telemetryModalOpened = (): void => {
posthog.capture('idkit opened', SUPER_PROPS)
}

export const telemetryPhoneTyped = (): void => {
posthog.capture('idkit phone typed', SUPER_PROPS)
}
13 changes: 7 additions & 6 deletions idkit/src/store/idkit.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import create from 'zustand'
import { IDKITStage } from '@/types'
import { worldIDHash } from '@/lib/hashing'
import { telemetryModalOpened } from '@/lib/telemetry'
import type { CallbackFn, ErrorState, ISuccessResult } from '@/types'
import type { Config, ConfigSource, StringOrAdvanced } from '@/types/config'

Expand All @@ -23,7 +24,6 @@ export type IDKitStore = {
setOpen: (open: boolean) => void
setStage: (stage: IDKITStage) => void
onOpenChange: (open: boolean) => void
setActionId: (actionId: StringOrAdvanced) => void
onSuccess: (result: ISuccessResult) => void
setProcessing: (processing: boolean) => void
setPhoneNumber: (phoneNumber: string) => void
Expand All @@ -49,10 +49,6 @@ const useIDKitStore = create<IDKitStore>()((set, get) => ({
setOpen: open => set({ open }),
setCode: code => set({ code }),
setStage: stage => set({ stage }),
setActionId: actionId => {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not used anywhere, removing for maintainability

const stringifiedActionId = typeof actionId === 'string' ? actionId : worldIDHash(actionId).digest
set({ actionId, stringifiedActionId })
},
setErrorState: errorState => set({ errorState }),
setPhoneNumber: phoneNumber => set({ phoneNumber }),
setProcessing: (processing: boolean) => set({ processing }),
Expand All @@ -65,8 +61,10 @@ const useIDKitStore = create<IDKitStore>()((set, get) => ({
})
},
setOptions: ({ onSuccess, signal, actionId, autoClose, copy }: Config, source: ConfigSource) => {
const stringifiedActionId = typeof actionId === 'string' ? actionId : worldIDHash(actionId).digest
set(store => ({
actionId,
stringifiedActionId,
signal,
autoClose,
copy: { ...store.copy, ...copy },
Expand All @@ -81,7 +79,10 @@ const useIDKitStore = create<IDKitStore>()((set, get) => ({
if (get().autoClose) setTimeout(() => set({ open: false }), 1000)
},
onOpenChange: open => {
if (open) return set({ open })
if (open) {
telemetryModalOpened()
return set({ open })
}
set({ open, phoneNumber: '', code: '', processing: false, stage: IDKITStage.ENTER_PHONE })
},
}))
Expand Down
3 changes: 3 additions & 0 deletions idkit/src/vanilla.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import type { Config } from './types/config'
import type { Root } from 'react-dom/client'
import { ConfigSource } from './types/config'
import { createRoot } from 'react-dom/client'
import { initTelemetry } from './lib/telemetry'
import IDKitWidget from './components/IDKitWidget'

let root: Root
Expand All @@ -25,6 +26,8 @@ export const init = (config: Config): void => {
root = createRoot(node)
root.render(<IDKitWidget {...config} />)

initTelemetry(config.enableTelemetry)

isInitialized = true
}
} catch (error) {
Expand Down
5 changes: 5 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -9987,6 +9987,11 @@ postcss@^8.3.5, postcss@^8.4.12, postcss@^8.4.18, postcss@^8.4.19, postcss@^8.4.
picocolors "^1.0.0"
source-map-js "^1.0.2"

[email protected]:
version "2.0.0-alpha5"
resolved "https://registry.yarnpkg.com/posthog-js-lite/-/posthog-js-lite-2.0.0-alpha5.tgz#60cff1b756ba2723ebb0222ca132fd0de8036210"
integrity sha512-tlkBdypJuvK/s00n4EiQjwYVfuuZv6vt8BF3g1ooIQa2Gz9Vz80p8q3qsPLZ0V5ErGRy6i3Q4fWC9TDzR7GNRQ==

prelude-ls@^1.2.1:
version "1.2.1"
resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396"
Expand Down