Merge pull request #3580 from omnivore-app/feature/replace-segment-with-posthog

replace segment with posthog
This commit is contained in:
Hongbo Wu
2024-02-26 18:30:26 +08:00
committed by GitHub
32 changed files with 181 additions and 219 deletions

View File

@ -24,6 +24,6 @@ GCS_UPLOAD_BUCKET=
GCS_UPLOAD_SA_KEY_FILE_PATH=
GCS_UPLOAD_PRIVATE_BUCKET=
TWITTER_BEARER_TOKEN=
SEGMENT_WRITE_KEY='test'
POSTHOG_API_KEY='test'
PUBSUB_VERIFICATION_TOKEN='123456'
CONTENT_FETCH_URL=http://localhost:9090/

View File

@ -45,7 +45,6 @@
"@sentry/node": "^5.26.0",
"@sentry/tracing": "^7.9.0",
"addressparser": "^1.0.1",
"analytics-node": "^6.0.0",
"apollo-datasource": "^3.3.1",
"apollo-server-express": "^3.6.3",
"axios": "^0.27.2",
@ -88,6 +87,7 @@
"oauth": "^0.10.0",
"pg": "^8.3.3",
"postgrator": "^4.2.0",
"posthog-node": "^3.6.3",
"private-ip": "^2.3.3",
"prom-client": "^15.1.0",
"rss-parser": "^3.13.0",

View File

@ -52,8 +52,8 @@ export const generateApiKeyResolver = authorized<
expiresAt: exp,
})
analytics.track({
userId: uid,
analytics.capture({
distinctId: uid,
event: 'api_key_generated',
properties: {
name,
@ -92,8 +92,8 @@ export const revokeApiKeyResolver = authorized<
const deletedApiKey = await apiRepo.remove(apiKey)
analytics.track({
userId: uid,
analytics.capture({
distinctId: uid,
event: 'api_key_revoked',
properties: {
id,

View File

@ -152,8 +152,8 @@ export const createArticleResolver = authorized<
},
{ log, uid, pubsub }
) => {
analytics.track({
userId: uid,
analytics.capture({
distinctId: uid,
event: 'link_saved',
properties: {
url,
@ -491,7 +491,7 @@ export const getArticleResolver = authorized<
// source: 'resolver',
// resolver: 'setShareArticleResolver',
// articleId: article.id,
// userId: uid,
// distinctId: uid,
// },
// })
@ -535,8 +535,8 @@ export const setBookmarkArticleResolver = authorized<
// delete the item and its metadata
const deletedLibraryItem = await softDeleteLibraryItem(articleID, uid, pubsub)
analytics.track({
userId: uid,
analytics.capture({
distinctId: uid,
event: 'link_removed',
properties: {
id: articleID,
@ -833,8 +833,8 @@ export const bulkActionResolver = authorized<
{ uid, log }
) => {
try {
analytics.track({
userId: uid,
analytics.capture({
distinctId: uid,
event: 'BulkAction',
properties: {
env: env.server.apiEnv,
@ -891,8 +891,8 @@ export const setFavoriteArticleResolver = authorized<
MutationSetFavoriteArticleArgs
>(async (_, { id }, { uid, log }) => {
try {
analytics.track({
userId: uid,
analytics.capture({
distinctId: uid,
event: 'setFavoriteArticle',
properties: {
env: env.server.apiEnv,
@ -928,8 +928,8 @@ export const moveToFolderResolver = authorized<
MoveToFolderError,
MutationMoveToFolderArgs
>(async (_, { id, folder }, { authTrx, log, pubsub, uid }) => {
analytics.track({
userId: uid,
analytics.capture({
distinctId: uid,
event: 'move_to_folder',
properties: {
id,
@ -1002,8 +1002,8 @@ export const fetchContentResolver = authorized<
FetchContentError,
MutationFetchContentArgs
>(async (_, { id }, { authTrx, uid, log, pubsub }) => {
analytics.track({
userId: uid,
analytics.capture({
distinctId: uid,
event: 'fetch_content',
properties: {
id,
@ -1052,8 +1052,8 @@ export const emptyTrashResolver = authorized<
EmptyTrashSuccess,
EmptyTrashError
>(async (_, __, { uid }) => {
analytics.track({
userId: uid,
analytics.capture({
distinctId: uid,
event: 'empty_trash',
})

View File

@ -18,13 +18,12 @@ import {
findLibraryItemByUrl,
} from '../../services/library_item'
import { analytics } from '../../utils/analytics'
import { authorized } from '../../utils/gql-utils'
import {
cleanUrl,
isParsingTimeout,
libraryItemToArticleSavingRequest,
} from '../../utils/helpers'
import { authorized } from '../../utils/gql-utils'
import { isErrorWithCode } from '../user'
export const createArticleSavingRequestResolver = authorized<
@ -32,8 +31,8 @@ export const createArticleSavingRequestResolver = authorized<
CreateArticleSavingRequestError,
MutationCreateArticleSavingRequestArgs
>(async (_, { input: { url } }, { uid, pubsub, log }) => {
analytics.track({
userId: uid,
analytics.capture({
distinctId: uid,
event: 'link_saved',
properties: {
url: url,

View File

@ -244,8 +244,8 @@ export const moveFilterResolver = authorized<
}
}
analytics.track({
userId: uid,
analytics.capture({
distinctId: uid,
event: 'filter_moved',
properties: {
filterId,

View File

@ -59,8 +59,8 @@ export const createHighlightResolver = authorized<
pubsub
)
analytics.track({
userId: uid,
analytics.capture({
distinctId: uid,
event: 'highlight_created',
properties: {
libraryItemId: input.articleId,
@ -143,8 +143,8 @@ export const mergeHighlightResolver = authorized<
pubsub
)
analytics.track({
userId: uid,
analytics.capture({
distinctId: uid,
event: 'highlight_created',
properties: {
libraryItemId: input.articleId,

View File

@ -47,8 +47,8 @@ export const uploadImportFileResolver = authorized<
}
}
analytics.track({
userId: uid,
analytics.capture({
distinctId: uid,
event: 'upload_import_file',
properties: {
type,

View File

@ -117,8 +117,8 @@ export const setIntegrationResolver = authorized<
integration.taskName = null
}
analytics.track({
userId: uid,
analytics.capture({
distinctId: uid,
event: 'integration_set',
properties: {
id: integrationToSave.id,
@ -182,8 +182,8 @@ export const deleteIntegrationResolver = authorized<
const deletedIntegration = await removeIntegration(integration, uid)
deletedIntegration.id = id
analytics.track({
userId: uid,
analytics.capture({
distinctId: uid,
event: 'integration_delete',
properties: {
integrationId: deletedIntegration.id,
@ -238,8 +238,8 @@ export const importFromIntegrationResolver = authorized<
// update task name in integration
await updateIntegration(integration.id, { taskName }, uid)
analytics.track({
userId: uid,
analytics.capture({
distinctId: uid,
event: 'integration_import',
properties: {
integrationId,

View File

@ -61,12 +61,12 @@ export const labelsResolver = authorized<LabelsSuccess, LabelsError>(
})
})
analytics.track({
userId: uid,
analytics.capture({
distinctId: uid,
event: 'labels',
properties: {
env: env.server.apiEnv,
$set: {
$set_once: {
email: user.email,
username: user.profile.username,
},
@ -95,8 +95,8 @@ export const createLabelResolver = authorized<
return tx.withRepository(labelRepository).createLabel(input, uid)
})
analytics.track({
userId: uid,
analytics.capture({
distinctId: uid,
event: 'label_created',
properties: {
...input,
@ -128,8 +128,8 @@ export const deleteLabelResolver = authorized<
}
}
analytics.track({
userId: uid,
analytics.capture({
distinctId: uid,
event: 'label_deleted',
properties: {
labelId,
@ -207,8 +207,8 @@ export const setLabelsResolver = authorized<
// save labels in the library item
await saveLabelsInLibraryItem(labelsSet, pageId, uid, labelSource, pubsub)
analytics.track({
userId: uid,
analytics.capture({
distinctId: uid,
event: 'labels_set',
properties: {
pageId,
@ -282,8 +282,8 @@ export const setLabelsForHighlightResolver = authorized<
// save labels in the highlight
await saveLabelsInHighlight(labelsSet, input.highlightId, uid, pubsub)
analytics.track({
userId: uid,
analytics.capture({
distinctId: uid,
event: 'labels_set_for_highlight',
properties: {
highlightId,
@ -374,8 +374,8 @@ export const moveLabelResolver = authorized<
}
}
analytics.track({
userId: uid,
analytics.capture({
distinctId: uid,
event: 'label_moved',
properties: {
labelId,

View File

@ -65,8 +65,8 @@ export const setLinkArchivedResolver = authorized<
event = 'link_unarchived'
}
analytics.track({
userId: uid,
analytics.capture({
distinctId: uid,
event,
properties: {
env: env.server.apiEnv,

View File

@ -40,10 +40,10 @@ export const createNewsletterEmailResolver = authorized<
CreateNewsletterEmailSuccessPartial,
CreateNewsletterEmailError,
MutationCreateNewsletterEmailArgs
>(async (_parent, { input }, { claims, log }) => {
>(async (_parent, { input }, { uid, log }) => {
log.info('createNewsletterEmailResolver')
analytics.track({
userId: claims.uid,
analytics.capture({
distinctId: uid,
event: 'newsletter_email_address_created',
properties: {
env: env.server.apiEnv,
@ -52,7 +52,7 @@ export const createNewsletterEmailResolver = authorized<
try {
const newsletterEmail = await createNewsletterEmail(
claims.uid,
uid,
undefined,
input?.folder || DEFAULT_NEWSLETTER_FOLDER,
input?.name || undefined,
@ -103,8 +103,8 @@ export const deleteNewsletterEmailResolver = authorized<
DeleteNewsletterEmailError,
MutationDeleteNewsletterEmailArgs
>(async (_parent, args, { uid, log }) => {
analytics.track({
userId: uid,
analytics.capture({
distinctId: uid,
event: 'newsletter_email_address_deleted',
properties: {
env: env.server.apiEnv,
@ -158,8 +158,8 @@ export const updateNewsletterEmailResolver = authorized<
UpdateNewsletterEmailError,
MutationUpdateNewsletterEmailArgs
>(async (_parent, { input }, { uid, log }) => {
analytics.track({
userId: uid,
analytics.capture({
distinctId: uid,
event: 'newsletter_email_updated',
properties: {
env: env.server.apiEnv,

View File

@ -40,8 +40,8 @@ import {
import { findLibraryItemById } from '../../services/library_item'
import { analytics } from '../../utils/analytics'
import { enqueueRecommendation } from '../../utils/createTask'
import { userDataToUser } from '../../utils/helpers'
import { authorized } from '../../utils/gql-utils'
import { userDataToUser } from '../../utils/helpers'
export const createGroupResolver = authorized<
CreateGroupSuccess,
@ -67,8 +67,8 @@ export const createGroupResolver = authorized<
onlyAdminCanSeeMembers: input.onlyAdminCanSeeMembers,
})
analytics.track({
userId: uid,
analytics.capture({
distinctId: uid,
event: 'group_created',
properties: {
group_id: group.id,
@ -213,8 +213,8 @@ export const joinGroupResolver = authorized<
const group = await joinGroup(user, inviteCode)
analytics.track({
userId: uid,
analytics.capture({
distinctId: uid,
event: 'group_joined',
properties: {
group_id: group.id,
@ -319,8 +319,8 @@ export const leaveGroupResolver = authorized<
const success = await leaveGroup(user, groupId)
analytics.track({
userId: uid,
analytics.capture({
distinctId: uid,
event: 'group_left',
properties: {
group_id: groupId,

View File

@ -37,7 +37,7 @@ const validScheduleTime = (str: string): Date | undefined => {
// }
// }
// analytics.track({
// analytics.capture({
// userId: uid,
// event: 'reminder_created',
// properties: {
@ -123,7 +123,7 @@ const validScheduleTime = (str: string): Date | undefined => {
// >(async (_, { linkId: pageId }, { models, claims: { uid }, log }) => {
// log.info('reminderResolver')
// analytics.track({
// analytics.capture({
// userId: uid,
// event: 'reminder',
// properties: {
@ -191,7 +191,7 @@ const validScheduleTime = (str: string): Date | undefined => {
// }
// }
// analytics.track({
// analytics.capture({
// userId: uid,
// event: 'reminder_updated',
// properties: {
@ -265,7 +265,7 @@ const validScheduleTime = (str: string): Date | undefined => {
// >(async (_, { id }, { models, claims: { uid }, log, authTrx }) => {
// log.info('deleteReminderResolver')
// analytics.track({
// analytics.capture({
// userId: uid,
// event: 'reminder_deleted',
// properties: {

View File

@ -1,5 +1,5 @@
/* eslint-disable @typescript-eslint/no-floating-promises */
import { WithDataSourcesContext } from '../types'
import { env } from '../../env'
import {
MutationReportItemArgs,
ReportItemResult,
@ -11,7 +11,7 @@ import {
saveContentDisplayReport,
} from '../../services/reports'
import { analytics } from '../../utils/analytics'
import { env } from '../../env'
import { WithDataSourcesContext } from '../types'
const SUCCESS_MESSAGE = `Your report has been submitted. Thank you.`
const FAILURE_MESSAGE =
@ -42,8 +42,8 @@ export const reportItemResolver: ResolverFn<
const { sharedBy, reportTypes } = args.input
if (sharedBy && isAbuseReport(reportTypes)) {
analytics.track({
userId: sharedBy,
analytics.capture({
distinctId: sharedBy,
event: 'report_created',
properties: {
type: 'abuse',
@ -70,8 +70,8 @@ export const reportItemResolver: ResolverFn<
}
}
analytics.track({
userId: uid,
analytics.capture({
distinctId: uid,
event: 'report_created',
properties: {
type: 'content',

View File

@ -19,8 +19,8 @@ export const savePageResolver = authorized<
SaveError,
MutationSavePageArgs
>(async (_, { input }, { uid }) => {
analytics.track({
userId: uid,
analytics.capture({
distinctId: uid,
event: 'link_saved',
properties: {
url: input.url,
@ -43,8 +43,8 @@ export const saveUrlResolver = authorized<
SaveError,
MutationSaveUrlArgs
>(async (_, { input }, { uid }) => {
analytics.track({
userId: uid,
analytics.capture({
distinctId: uid,
event: 'link_saved',
properties: {
url: input.url,
@ -67,8 +67,8 @@ export const saveFileResolver = authorized<
SaveError,
MutationSaveFileArgs
>(async (_, { input }, { uid }) => {
analytics.track({
userId: uid,
analytics.capture({
distinctId: uid,
event: 'link_saved',
properties: {
url: input.url,

View File

@ -153,8 +153,8 @@ export const unsubscribeResolver = authorized<
await unsubscribe(subscription)
analytics.track({
userId: uid,
analytics.capture({
distinctId: uid,
event: 'unsubscribed',
properties: {
name,
@ -183,8 +183,8 @@ export const subscribeResolver = authorized<
MutationSubscribeArgs
>(async (_, { input }, { uid, log }) => {
try {
analytics.track({
userId: uid,
analytics.capture({
distinctId: uid,
event: 'subscribed',
properties: {
...input,
@ -323,8 +323,8 @@ export const updateSubscriptionResolver = authorized<
MutationUpdateSubscriptionArgs
>(async (_, { input }, { uid, log }) => {
try {
analytics.track({
userId: uid,
analytics.capture({
distinctId: uid,
event: 'update_subscription',
properties: {
...input,
@ -401,8 +401,8 @@ export const scanFeedsResolver = authorized<
ScanFeedsError,
QueryScanFeedsArgs
>(async (_, { input: { opml, url } }, { log, uid }) => {
analytics.track({
userId: uid,
analytics.capture({
distinctId: uid,
event: 'scan_feeds',
properties: {
opml,

View File

@ -12,8 +12,8 @@ export const uploadFileRequestResolver = authorized<
UploadFileRequestError,
MutationUploadFileRequestArgs
>(async (_, { input }, { uid }) => {
analytics.track({
userId: uid,
analytics.capture({
distinctId: uid,
event: 'file_upload_request',
properties: {
url: input.url,

View File

@ -60,8 +60,8 @@ export const setDeviceTokenResolver = authorized<
}
}
analytics.track({
userId: uid,
analytics.capture({
distinctId: uid,
event: 'device_token_deleted',
properties: {
id: deviceToken.id,
@ -77,8 +77,8 @@ export const setDeviceTokenResolver = authorized<
// create token
const deviceToken = await createDeviceToken(uid, token)
analytics.track({
userId: uid,
analytics.capture({
distinctId: uid,
event: 'device_token_created',
properties: {
id: deviceToken.id,

View File

@ -85,8 +85,8 @@ export const deleteWebhookResolver = authorized<
try {
const webhook = await deleteWebhook(id, uid)
analytics.track({
userId: uid,
analytics.capture({
distinctId: uid,
event: 'webhook_delete',
properties: {
webhookId: id,
@ -144,8 +144,8 @@ export const setWebhookResolver = authorized<
})
)
analytics.track({
userId: uid,
analytics.capture({
distinctId: uid,
event: 'webhook_set',
properties: {
webhookId: webhook.id,

View File

@ -3,9 +3,11 @@
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
import * as jwt from 'jsonwebtoken'
import jwksClient from 'jwks-rsa'
import { StatusType } from '../../entity/user'
import { env, homePageURL } from '../../env'
import { LoginErrorCode } from '../../generated/graphql'
import { userRepository } from '../../repository/user'
import { analytics } from '../../utils/analytics'
import { logger } from '../../utils/logger'
import { createSsoToken, ssoRedirectURL } from '../../utils/sso'
import { DecodeTokenResult } from './auth_types'
@ -14,8 +16,6 @@ import {
createWebAuthToken,
suggestedUsername,
} from './jwt_helpers'
import { analytics } from '../../utils/analytics'
import { StatusType } from '../../entity/user'
const appleBaseURL = 'https://appleid.apple.com'
const audienceName = 'app.omnivore.app'
@ -147,8 +147,8 @@ export async function handleAppleWebAuth(
? ssoRedirectURL(ssoToken)
: `${baseURL()}/home`
analytics.track({
userId: user.id,
analytics.capture({
distinctId: user.id,
event: 'login',
properties: {
method: 'apple',

View File

@ -11,6 +11,7 @@ import axios from 'axios'
import cors from 'cors'
import type { Request, Response } from 'express'
import express from 'express'
import rateLimit from 'express-rate-limit'
import * as jwt from 'jsonwebtoken'
import url from 'url'
import { promisify } from 'util'
@ -46,7 +47,6 @@ import {
} from './google_auth'
import { createWebAuthToken } from './jwt_helpers'
import { createMobileAccountCreationResponse } from './mobile/account_creation'
import rateLimit from 'express-rate-limit'
export interface SignupRequest {
email: string
@ -328,8 +328,8 @@ export function authRouter() {
)
}
analytics.track({
userId: user.id,
analytics.capture({
distinctId: user.id,
event: 'login',
properties: {
method: 'google',
@ -463,8 +463,8 @@ export function authRouter() {
)
}
analytics.track({
userId: user.id,
analytics.capture({
distinctId: user.id,
event: 'login',
properties: {
method: 'email',
@ -576,8 +576,8 @@ export function authRouter() {
}
}
analytics.track({
userId: user.id,
analytics.capture({
distinctId: user.id,
event: 'login',
properties: {
method: 'email_verification',
@ -708,8 +708,8 @@ export function authRouter() {
)
}
analytics.track({
userId: user.id,
analytics.capture({
distinctId: user.id,
event: 'login',
properties: {
method: 'password_reset',

View File

@ -49,8 +49,8 @@ export function emailAttachmentRouter() {
const user = newsletterEmail.user
analytics.track({
userId: user.id,
analytics.capture({
distinctId: user.id,
event: 'email_attachment_upload',
properties: {
env: env.server.apiEnv,
@ -116,8 +116,8 @@ export function emailAttachmentRouter() {
const user = newsletterEmail.user
analytics.track({
userId: user.id,
analytics.capture({
distinctId: user.id,
event: 'email_attachment_create_article',
properties: {
env: env.server.apiEnv,

View File

@ -99,8 +99,8 @@ export function emailsServiceRouter() {
return
}
analytics.track({
userId: user.id,
analytics.capture({
distinctId: user.id,
event: 'non_newsletter_email_received',
properties: {
env: env.server.apiEnv,
@ -168,8 +168,8 @@ export function emailsServiceRouter() {
user.id
)
analytics.track({
userId: user.id,
analytics.capture({
distinctId: user.id,
event: 'received_email_saved',
properties: {
env: env.server.apiEnv,

View File

@ -9,12 +9,15 @@ import { json, urlencoded } from 'body-parser'
import cookieParser from 'cookie-parser'
import express, { Express } from 'express'
import * as httpContext from 'express-http-context2'
import promBundle from 'express-prom-bundle'
import rateLimit from 'express-rate-limit'
import { createServer, Server } from 'http'
import * as prom from 'prom-client'
import { config, loggers } from 'winston'
import { makeApolloServer } from './apollo'
import { appDataSource } from './data_source'
import { env } from './env'
import { redisDataSource } from './redis_data_source'
import { articleRouter } from './routers/article_router'
import { authRouter } from './routers/auth/auth_router'
import { mobileAuthRouter } from './routers/auth/mobile/mobile_auth_router'
@ -37,6 +40,7 @@ import { webhooksServiceRouter } from './routers/svc/webhooks'
import { textToSpeechRouter } from './routers/text_to_speech'
import { userRouter } from './routers/user_router'
import { sentryConfig } from './sentry'
import { analytics } from './utils/analytics'
import {
getClaimsByToken,
getTokenByRequest,
@ -44,10 +48,6 @@ import {
} from './utils/auth'
import { corsConfig } from './utils/corsConfig'
import { buildLogger, buildLoggerTransport } from './utils/logger'
import { redisDataSource } from './redis_data_source'
import * as prom from 'prom-client'
import promBundle from 'express-prom-bundle'
import { createPrometheusExporterPlugin } from '@bmatei/apollo-prometheus-exporter'
const PORT = process.env.PORT || 4000
@ -213,6 +213,10 @@ const main = async (): Promise<void> => {
listener.timeout = 640 * 1000 // match headersTimeout
const gracefulShutdown = async (signal: string) => {
console.log('[posthog]: flushing events')
await analytics.shutdownAsync()
console.log('[posthog]: events flushed')
console.log(`[api]: Received ${signal}, closing server...`)
await apollo.stop()

View File

@ -48,8 +48,8 @@ export const createUser = async (input: {
user: existingUser,
})
analytics.track({
userId: existingUser.id,
analytics.capture({
distinctId: existingUser.id,
event: 'create_user',
properties: {
env: env.server.apiEnv,
@ -131,8 +131,8 @@ export const createUser = async (input: {
profile.username
)
analytics.track({
userId: user.id,
analytics.capture({
distinctId: user.id,
event: 'create_user',
properties: {
env: env.server.apiEnv,

View File

@ -28,8 +28,8 @@ export const saveNewsletter = async (
newsletterEmail: NewsletterEmail,
existingSubscription?: Subscription
): Promise<boolean> => {
analytics.track({
userId: newsletterEmail.user.id,
analytics.capture({
distinctId: newsletterEmail.user.id,
event: 'newsletter_email_received',
properties: {
url: data.url,

View File

@ -47,8 +47,8 @@ export const createDeviceToken = async (
userId: string,
token: string
): Promise<UserDeviceToken> => {
analytics.track({
userId: userId,
analytics.capture({
distinctId: userId,
event: 'device_token_created',
properties: {
env: env.server.apiEnv,
@ -70,8 +70,8 @@ export const deleteDeviceToken = async (
id: string,
userId: string
): Promise<boolean> => {
analytics.track({
userId: userId,
analytics.capture({
distinctId: userId,
event: 'device_token_deleted',
properties: {
env: env.server.apiEnv,

View File

@ -40,8 +40,8 @@ export interface BackendEnv {
secret: string
}
}
segment: {
writeKey: string
posthog: {
apiKey: string
}
intercom: {
token: string
@ -136,7 +136,7 @@ const nullableEnvVars = [
'GAUTH_ANDROID_CLIENT_ID',
'GAUTH_CLIENT_ID',
'GAUTH_SECRET',
'SEGMENT_WRITE_KEY',
'POSTHOG_API_KEY',
'TWITTER_BEARER_TOKEN',
'GCS_UPLOAD_PRIVATE_BUCKET',
'SENDER_MESSAGE',
@ -226,8 +226,8 @@ export function getEnv(): BackendEnv {
secret: parse('GAUTH_SECRET'),
},
}
const segment = {
writeKey: parse('SEGMENT_WRITE_KEY'),
const posthog = {
apiKey: parse('POSTHOG_API_KEY'),
}
const intercom = {
token: parse('INTERCOM_TOKEN'),
@ -317,7 +317,7 @@ export function getEnv(): BackendEnv {
client,
server,
google,
segment,
posthog,
intercom,
sentry,
jaeger,

View File

@ -1,4 +1,4 @@
import Analytics = require('analytics-node')
import { PostHog } from 'posthog-node'
import { env } from '../env'
export const analytics = new Analytics(env.segment.writeKey || 'test')
export const analytics = new PostHog(env.posthog.apiKey || 'test')

View File

@ -22,8 +22,8 @@ export const sendPushNotification = async (
type: PushNotificationType
): Promise<string | undefined> => {
try {
analytics.track({
userId,
analytics.capture({
distinctId: userId,
event: 'notification_sent',
properties: {
type,
@ -49,8 +49,8 @@ export const sendMulticastPushNotifications = async (
type: PushNotificationType
): Promise<BatchResponse | undefined> => {
try {
analytics.track({
userId,
analytics.capture({
distinctId: userId,
event: 'notification_sent',
properties: {
type,

View File

@ -5542,14 +5542,6 @@
dependencies:
any-observable "^0.3.0"
"@segment/loosely-validate-event@^2.0.0":
version "2.0.0"
resolved "https://registry.yarnpkg.com/@segment/loosely-validate-event/-/loosely-validate-event-2.0.0.tgz#87dfc979e5b4e7b82c5f1d8b722dfd5d77644681"
integrity sha512-ZMCSfztDBqwotkl848ODgVcAmN4OItEWDCkshcKz0/W6gGSQayuuCtWV/MlodFivAZD793d6UgANd6wCXUfrIw==
dependencies:
component-type "^1.2.1"
join-component "^1.1.0"
"@selderee/plugin-htmlparser2@^0.6.0":
version "0.6.0"
resolved "https://registry.yarnpkg.com/@selderee/plugin-htmlparser2/-/plugin-htmlparser2-0.6.0.tgz#27e994afd1c2cb647ceb5406a185a5574188069d"
@ -9033,20 +9025,6 @@ ajv@^8.11.0:
require-from-string "^2.0.2"
uri-js "^4.2.2"
analytics-node@^6.0.0:
version "6.2.0"
resolved "https://registry.yarnpkg.com/analytics-node/-/analytics-node-6.2.0.tgz#8ae2ebc73d85e5b2aac8d366b974ad36996f629d"
integrity sha512-NLU4tCHlWt0tzEaFQL7NIoWhq2KmQSmz0JvyS2lYn6fc4fEjTMSabhJUx8H1r5995FX8fE3rZ15uIHU6u+ovlQ==
dependencies:
"@segment/loosely-validate-event" "^2.0.0"
axios "^0.27.2"
axios-retry "3.2.0"
lodash.isstring "^4.0.1"
md5 "^2.2.1"
ms "^2.0.0"
remove-trailing-slash "^0.1.0"
uuid "^8.3.2"
ansi-align@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/ansi-align/-/ansi-align-3.0.0.tgz#b536b371cf687caaef236c18d3e21fe3797467cb"
@ -9961,13 +9939,6 @@ axe-core@^4.6.2:
resolved "https://registry.yarnpkg.com/axe-core/-/axe-core-4.8.2.tgz#2f6f3cde40935825cf4465e3c1c9e77b240ff6ae"
integrity sha512-/dlp0fxyM3R8YW7MFzaHWXrf4zzbr0vaYb23VBFCl83R7nWNPg/yaQw2Dc8jzCMmDVLhSdzH8MjrsuIUuvX+6g==
axios-retry@3.2.0:
version "3.2.0"
resolved "https://registry.yarnpkg.com/axios-retry/-/axios-retry-3.2.0.tgz#eb48e72f90b177fde62329b2896aa8476cfb90ba"
integrity sha512-RK2cLMgIsAQBDhlIsJR5dOhODPigvel18XUv1dDXW+4k1FzebyfRk+C+orot6WPZOYFKSfhLwHPwVmTVOODQ5w==
dependencies:
is-retry-allowed "^1.1.0"
axios@^0.24.0:
version "0.24.0"
resolved "https://registry.yarnpkg.com/axios/-/axios-0.24.0.tgz#804e6fa1e4b9c5288501dd9dff56a7a0940d20d6"
@ -10017,6 +9988,15 @@ axios@^1.4.0:
form-data "^4.0.0"
proxy-from-env "^1.1.0"
axios@^1.6.2:
version "1.6.7"
resolved "https://registry.yarnpkg.com/axios/-/axios-1.6.7.tgz#7b48c2e27c96f9c68a2f8f31e2ab19f59b06b0a7"
integrity sha512-/hDJGff6/c7u0hDkvkGxR/oy6CbCs8ziCsC7SqmhjfozqiJGc8Z11wrv9z9lYfY4K8l+H9TpjcMDX0xOZmx+RA==
dependencies:
follow-redirects "^1.15.4"
form-data "^4.0.0"
proxy-from-env "^1.1.0"
axobject-query@^2.2.0:
version "2.2.0"
resolved "https://registry.yarnpkg.com/axobject-query/-/axobject-query-2.2.0.tgz#943d47e10c0b704aa42275e20edf3722648989be"
@ -11308,11 +11288,6 @@ chardet@^0.7.0:
resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.7.0.tgz#90094849f0937f2eedc2425d0d28a9e5f0cbad9e"
integrity sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==
charenc@0.0.2:
version "0.0.2"
resolved "https://registry.yarnpkg.com/charenc/-/charenc-0.0.2.tgz#c0a1d2f3a7092e03774bfa83f14c0fc5790a8667"
integrity sha1-wKHS86cJLgN3S/qD8UwPxXkKhmc=
check-error@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/check-error/-/check-error-1.0.2.tgz#574d312edd88bb5dd8912e9286dd6c0aed4aac82"
@ -11923,11 +11898,6 @@ component-emitter@^1.2.1, component-emitter@^1.3.0:
resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.3.0.tgz#16e4070fba8ae29b679f2215853ee181ab2eabc0"
integrity sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==
component-type@^1.2.1:
version "1.2.1"
resolved "https://registry.yarnpkg.com/component-type/-/component-type-1.2.1.tgz#8a47901700238e4fc32269771230226f24b415a9"
integrity sha1-ikeQFwAjjk/DIml3EjAibyS0Fak=
compressible@^2.0.12, compressible@~2.0.16:
version "2.0.18"
resolved "https://registry.yarnpkg.com/compressible/-/compressible-2.0.18.tgz#af53cca6b070d4c3c0750fbd77286a6d7cc46fba"
@ -12511,11 +12481,6 @@ cross-undici-fetch@^0.1.19:
undici "^4.9.3"
web-streams-polyfill "^3.2.0"
crypt@0.0.2:
version "0.0.2"
resolved "https://registry.yarnpkg.com/crypt/-/crypt-0.0.2.tgz#88d7ff7ec0dfb86f713dc87bbb42d044d3e6c41b"
integrity sha1-iNf/fsDfuG9xPch7u0LQRNPmxBs=
crypto-browserify@^3.11.0:
version "3.12.0"
resolved "https://registry.yarnpkg.com/crypto-browserify/-/crypto-browserify-3.12.0.tgz#396cf9f3137f03e4b8e532c58f698254e00f80ec"
@ -15432,6 +15397,11 @@ follow-redirects@^1.0.0, follow-redirects@^1.14.4, follow-redirects@^1.14.8, fol
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.4.tgz#cdc7d308bf6493126b17ea2191ea0ccf3e535adf"
integrity sha512-Cr4D/5wlrb0z9dgERpUL3LrmPKVDsETIJhaCMeDfuFYcqa5bldGV6wBsAN6X/vxlXQtFBMrXdXxdL8CbDTGniw==
follow-redirects@^1.15.4:
version "1.15.5"
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.5.tgz#54d4d6d062c0fa7d9d17feb008461550e3ba8020"
integrity sha512-vSFWUON1B+yAw1VN4xMfxgn5fTUiaOzAJCKBwIIgT/+7CuGy9+r+5gITvP62j3RmaD5Ph65UaERdOSRGUzZtgw==
for-each@^0.3.3:
version "0.3.3"
resolved "https://registry.yarnpkg.com/for-each/-/for-each-0.3.3.tgz#69b447e88a0a5d32c3e7084f3f1710034b21376e"
@ -17852,7 +17822,7 @@ is-boolean-object@^1.1.0:
call-bind "^1.0.2"
has-tostringtag "^1.0.0"
is-buffer@^1.0.2, is-buffer@^1.1.5, is-buffer@~1.1.6:
is-buffer@^1.0.2, is-buffer@^1.1.5:
version "1.1.6"
resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be"
integrity sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==
@ -18263,11 +18233,6 @@ is-relative@^1.0.0:
dependencies:
is-unc-path "^1.0.0"
is-retry-allowed@^1.1.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/is-retry-allowed/-/is-retry-allowed-1.2.0.tgz#d778488bd0a4666a3be8a1482b9f2baafedea8b4"
integrity sha512-RUbUeKwvm3XG2VYamhJL1xFktgjvPzL0Hq8C+6yrWIswDy3BIXGqCxhxkc30N9jqK311gVU137K8Ei55/zVJRg==
is-set@^2.0.1, is-set@^2.0.2:
version "2.0.2"
resolved "https://registry.yarnpkg.com/is-set/-/is-set-2.0.2.tgz#90755fa4c2562dc1c5d4024760d6119b94ca18ec"
@ -19158,11 +19123,6 @@ jest@^27.4.5:
import-local "^3.0.2"
jest-cli "^27.5.1"
join-component@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/join-component/-/join-component-1.1.0.tgz#b8417b750661a392bee2c2537c68b2a9d4977cd5"
integrity sha1-uEF7dQZho5K+4sJTfGiyqdSXfNU=
jose@^2.0.5:
version "2.0.6"
resolved "https://registry.yarnpkg.com/jose/-/jose-2.0.6.tgz#894ba19169af339d3911be933f913dd02fc57c7c"
@ -20877,15 +20837,6 @@ md5.js@^1.3.4:
inherits "^2.0.1"
safe-buffer "^5.1.2"
md5@^2.2.1:
version "2.3.0"
resolved "https://registry.yarnpkg.com/md5/-/md5-2.3.0.tgz#c3da9a6aae3a30b46b7b0c349b87b110dc3bda4f"
integrity sha512-T1GITYmFaKuO91vxyoQMFETst+O71VUPEU3ze5GNzDm0OWdP8v1ziTaAEPUr/3kLsY3Sftgz242A1SetQiDL7g==
dependencies:
charenc "0.0.2"
crypt "0.0.2"
is-buffer "~1.1.6"
mdast-squeeze-paragraphs@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/mdast-squeeze-paragraphs/-/mdast-squeeze-paragraphs-4.0.0.tgz#7c4c114679c3bee27ef10b58e2e015be79f1ef97"
@ -24531,6 +24482,14 @@ posthog-js@^1.78.2:
dependencies:
fflate "^0.4.1"
posthog-node@^3.6.3:
version "3.6.3"
resolved "https://registry.yarnpkg.com/posthog-node/-/posthog-node-3.6.3.tgz#4d3a2a4385e01c4d9e91d01dbde104e60285853d"
integrity sha512-JB+ei0LkwE+rKHyW5z79Nd1jUaGxU6TvkfjFqY9vQaHxU5aU8dRl0UUaEmZdZbHwjp3WmXCBQQRNyimwbNQfCw==
dependencies:
axios "^1.6.2"
rusha "^0.8.14"
prebuild-install@^7.1.1:
version "7.1.1"
resolved "https://registry.yarnpkg.com/prebuild-install/-/prebuild-install-7.1.1.tgz#de97d5b34a70a0c81334fd24641f2a1702352e45"
@ -26533,11 +26492,6 @@ remove-trailing-separator@^1.0.1:
resolved "https://registry.yarnpkg.com/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz#c24bce2a283adad5bc3f58e0d48249b92379d8ef"
integrity sha1-wkvOKig62tW8P1jg1IJJuSN52O8=
remove-trailing-slash@^0.1.0:
version "0.1.1"
resolved "https://registry.yarnpkg.com/remove-trailing-slash/-/remove-trailing-slash-0.1.1.tgz#be2285a59f39c74d1bce4f825950061915e3780d"
integrity sha512-o4S4Qh6L2jpnCy83ysZDau+VORNvnFw07CKSAymkd6ICNVEPisMyzlc00KlvvicsxKck94SEwhDnMNdICzO+tA==
remove-trailing-spaces@^1.0.6:
version "1.0.7"
resolved "https://registry.yarnpkg.com/remove-trailing-spaces/-/remove-trailing-spaces-1.0.7.tgz#491f04e11d98880714d12429b0d0938cbe030ae6"
@ -26858,6 +26812,11 @@ run-queue@^1.0.0, run-queue@^1.0.3:
dependencies:
aproba "^1.1.1"
rusha@^0.8.14:
version "0.8.14"
resolved "https://registry.yarnpkg.com/rusha/-/rusha-0.8.14.tgz#a977d0de9428406138b7bb90d3de5dcd024e2f68"
integrity sha512-cLgakCUf6PedEu15t8kbsjnwIFFR2D4RfL+W3iWFJ4iac7z4B0ZI8fxy4R3J956kAI68HclCFGL8MPoUVC3qVA==
rxjs@^6.3.3, rxjs@^6.4.0, rxjs@^6.6.0, rxjs@^6.6.3:
version "6.6.7"
resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.6.7.tgz#90ac018acabf491bf65044235d5863c4dab804c9"