Skip to content

Commit

Permalink
fix: contact sales
Browse files Browse the repository at this point in the history
  • Loading branch information
abuaboud committed Jun 18, 2024
1 parent a2633e2 commit 2236f19
Show file tree
Hide file tree
Showing 6 changed files with 187 additions and 159 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,9 @@ import { flagService } from '../../flags/flag.service'
import { pieceMetadataService } from '../../pieces/piece-metadata-service'
import { platformService } from '../../platform/platform.service'
import { userService } from '../../user/user-service'
import { logger } from '@activepieces/server-shared'
import { ActivepiecesError, ApEdition, CreateTrialLicenseKeyRequestBody, ErrorCode, LicenseKeyEntity, PackageType, PlatformRole, UserStatus } from '@activepieces/shared'
import { logger, rejectedPromiseHandler } from '@activepieces/server-shared'
import { ActivepiecesError, ApEdition, CreateTrialLicenseKeyRequestBody, ErrorCode, LicenseKeyEntity, PackageType, PlatformRole, TelemetryEventName, UserStatus } from '@activepieces/shared'
import { telemetry } from '../../helper/telemetry.utils'

const secretManagerLicenseKeysRoute = 'https://secrets.activepieces.com/license-keys'

Expand Down Expand Up @@ -59,6 +60,13 @@ export const licenseKeysService = {
const errorMessage = JSON.stringify(await response.json())
handleUnexpectedSecretsManagerError(errorMessage)
}
rejectedPromiseHandler(telemetry.trackPlatform(request.platformId, {
name: TelemetryEventName.KEY_ACTIVIATED,
payload: {
date: dayjs().toISOString(),
key: request.key,
},
}))
},
async getKey(license: string | undefined): Promise<LicenseKeyEntity | null> {
if (isNil(license)) {
Expand Down
8 changes: 8 additions & 0 deletions packages/server/api/src/app/helper/telemetry.utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { projectService } from '../project/project-service'
import { getEdition } from './secret-helper'
import { logger, system, SystemProp } from '@activepieces/server-shared'
import { ProjectId, TelemetryEvent, User, UserId } from '@activepieces/shared'
import { platformService } from '../platform/platform.service'

const telemetryEnabled = system.getBoolean(SystemProp.TELEMETRY_ENABLED)

Expand All @@ -27,6 +28,13 @@ export const telemetry = {
}
analytics.identify(identify)
},
async trackPlatform(platformId: ProjectId, event: TelemetryEvent): Promise<void> {
if (!telemetryEnabled) {
return
}
const platform = await platformService.getOneOrThrow(platformId)
await this.trackUser(platform.ownerId, event)
},
async trackProject(
projectId: ProjectId,
event: TelemetryEvent,
Expand Down
17 changes: 16 additions & 1 deletion packages/shared/src/lib/common/telemetry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,10 +59,23 @@ type FlowIssueResolved = {
flowId: string
}

type RequestTrialSubmitted = {
name: string;
email: string;
numberOfEmployees: string;
companyName: string;
goal: string;
}

type RequestTrialClicked = {
location: string
}

type KeyActiviated = {
date: string
key: string
}

type UpgradeClicked = {
limitType?: 'team'
}
Expand Down Expand Up @@ -118,6 +131,7 @@ export enum TelemetryEventName {
QUOTA_ALERT = 'quota.alert',
REQUEST_TRIAL_CLICKED = 'request.trial.clicked',
REQUEST_TRIAL_SUBMITTED = 'request.trial.submitted',
KEY_ACTIVIATED = 'key.activated',
FLOW_ISSUE_CLICKED = 'flow.issue.clicked',
FLOW_ISSUE_RESOLVED = 'flow.issue.resolved',
UPGRADE_CLICKED = 'upgrade.clicked',
Expand Down Expand Up @@ -153,7 +167,8 @@ export type TelemetryEvent =
| BaseTelemetryEvent<TelemetryEventName.SIGNED_UP, SignedUp>
| BaseTelemetryEvent<TelemetryEventName.REFERRAL, Referral>
| BaseTelemetryEvent<TelemetryEventName.REQUEST_TRIAL_CLICKED, RequestTrialClicked>
| BaseTelemetryEvent<TelemetryEventName.REQUEST_TRIAL_SUBMITTED, Record<string, string>>
| BaseTelemetryEvent<TelemetryEventName.KEY_ACTIVIATED, KeyActiviated>
| BaseTelemetryEvent<TelemetryEventName.REQUEST_TRIAL_SUBMITTED, RequestTrialSubmitted>
| BaseTelemetryEvent<TelemetryEventName.FLOW_ISSUE_CLICKED, FlowIssueClicked>
| BaseTelemetryEvent<TelemetryEventName.FLOW_ISSUE_RESOLVED, FlowIssueResolved>
| BaseTelemetryEvent<TelemetryEventName.UPGRADE_CLICKED, UpgradeClicked>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,132 +3,132 @@ <h2 class="ap-sticky ap-top-0 ap-z-50 ap-px-10 ap-py-4 ap-border-b ap-border ap-
<form [formGroup]="contactSalesForm" (ngSubmit)="submitForm()" class=" ap-flex ap-flex-col ap-h-screen">


<div class="ap-px-10 ap-text-base ap-flex-auto ap-overflow-y-auto">
<div class="ap-px-10 ap-text-base ap-flex-auto ap-overflow-y-auto">
<div class="ap-flex ap-flex-col ap-mt-6 ap-gap-2">
<div class="ap-flex ap-gap-4 ap-justify-between">
<mat-form-field class="ap-flex-grow" appearance="outline" >
<mat-form-field class="ap-flex-grow" appearance="outline">
<mat-label>Name</mat-label>
<input name="name" cdkFocusInitial matInput [formControl]="contactSalesForm.controls.name"
<input name="name" cdkFocusInitial matInput [formControl]="contactSalesForm.controls.name"
autocomplete="off">
@if(contactSalesForm.controls.name.invalid)
{
<mat-error i18n>
Name is required
</mat-error>
}
@if(contactSalesForm.controls.name.invalid)
{
<mat-error i18n>
Name is required
</mat-error>
}
</mat-form-field>
<mat-form-field class="ap-flex-grow" appearance="outline" >
<mat-form-field class="ap-flex-grow" appearance="outline">
<mat-label>Work email</mat-label>
<input name="text" type="email" cdkFocusInitial matInput [formControl]="contactSalesForm.controls.email"
autocomplete="off" required>
@if(contactSalesForm.controls.email.invalid) {
<mat-error>
@if(contactSalesForm.controls.email.getError('email')) {
<ng-container i18n>Email is invalid </ng-container> }
@if(contactSalesForm.controls.email.getError('required')) {
<ng-container i18n>Email is required </ng-container> }
@if(contactSalesForm.controls.email.getError(ErrorCode.EMAIL_ALREADY_HAS_ACTIVATION_KEY))
{
<ng-container i18n
>Email already has been used.
</ng-container>
}
</mat-error>
}

<input name="text" type="email" cdkFocusInitial matInput
[formControl]="contactSalesForm.controls.email" autocomplete="off" required>
@if(contactSalesForm.controls.email.invalid) {
<mat-error>
@if(contactSalesForm.controls.email.getError('email')) {
<ng-container i18n>Email is invalid </ng-container> }
@if(contactSalesForm.controls.email.getError('required')) {
<ng-container i18n>Email is required </ng-container> }
@if(contactSalesForm.controls.email.getError(ErrorCode.EMAIL_ALREADY_HAS_ACTIVATION_KEY))
{
<ng-container i18n>Email already has been used.
</ng-container>
}
</mat-error>
}

</mat-form-field>
</div>
<div class="ap-flex ap-gap-4 ap-justify-between">
<mat-form-field class="ap-flex-grow" appearance="outline" >
<mat-form-field class="ap-flex-grow" appearance="outline">
<mat-label i18n>Company Name </mat-label>
<input name="text" type="text" matInput i18n-placeholder autocomplete="off" [formControl]="contactSalesForm.controls.companyName">
<input name="text" type="text" matInput i18n-placeholder autocomplete="off"
[formControl]="contactSalesForm.controls.companyName">
@if(contactSalesForm.controls.companyName.invalid)
{
<mat-error i18n>
Company name is required.
</mat-error>
<mat-error i18n>
Company name is required.
</mat-error>
}

</mat-form-field>
<mat-form-field class="ap-flex-grow" appearance="outline" >
<mat-form-field class="ap-flex-grow" appearance="outline">
<mat-label i18n>Number of Employees </mat-label>
<mat-select [formControl]="contactSalesForm.controls.numberOfEmployees">
@for(opt of numberOfEmployeesOptions; track opt)
{
<mat-option [value]="opt">
{{ opt }}
</mat-option>
{
<mat-option [value]="opt">
{{ opt }}
</mat-option>
}


</mat-select>
@if(contactSalesForm.controls.numberOfEmployees.invalid)
{
<mat-error i18n >
Number of employees is required.
</mat-error>
<mat-error i18n>
Number of employees is required.
</mat-error>
}

</mat-form-field>
</div>
<mat-form-field class="ap-w-full">
<mat-label i18n>Goal</mat-label>
<mat-select [formControl]="contactSalesForm.controls.goal">
@for(goal of goals; track goal)
{
<mat-option [value]="goal.telemetryValue">
{{ goal.displayName }}
</mat-option>
{
<mat-option [value]="goal.telemetryValue">
{{ goal.displayName }}
</mat-option>
}


</mat-select>
@if(contactSalesForm.controls.goal.invalid)
{
<mat-error i18n>
Goal is required.
</mat-error>
<mat-error i18n>
Goal is required.
</mat-error>
}
</mat-form-field>

</mat-form-field>
</div>
<div class="ap-mt-3 ap-font-semibold">Try Enterprise to access: </div>
<div class="ap-flex ap-mt-3 ap-flex-wrap ">
@for(featureName of featuresNames; track featureName)
{
<div class="ap-flex ap-gap-3 ap-my-3 ap-basis-[50%]">

<svg-icon class="ap-h-[20px] ap-w-[20px] ap-fill-success" src="assets/img/custom/check.svg" [applyClass]="true"></svg-icon>
{{
featureName
}}


</div>
}
</div>


<div class="ap-text-body ap-font-semibold ap-mt-15 ap-mb-6 ap-text-center ">
Deploy your automations securely with Activepieces
</div>
<div class="ap-flex ap-gap-6 ap-justify-center ap-items-center">
@for(logo of logos; track logo) {
<img class="ap-h-6" [src]="logo" />
}
</div>


<div class="ap-mt-3 ap-font-semibold">Try Enterprise to access: </div>
<div class="ap-flex ap-mt-3 ap-flex-wrap ">
@for(featureName of featuresNames; track featureName)
{
<div class="ap-flex ap-gap-3 ap-my-3 ap-basis-[50%]">

<svg-icon class="ap-h-[20px] ap-w-[20px] ap-fill-success" src="assets/img/custom/check.svg"
[applyClass]="true"></svg-icon>
{{
featureName
}}


</div>
}
</div>


<div class="ap-text-body ap-font-semibold ap-mt-15 ap-mb-6 ap-text-center ">
Deploy your automations securely with Activepieces
</div>
<div class="ap-flex ap-gap-6 ap-justify-center ap-items-center">
@for(logo of logos; track logo) {
<img class="ap-h-6" [src]="logo" />
}
</div>


</div>

<div class=" ap-mt-[80px] ap-flex ap-gap-2 ap-sticky ap-bottom-0 ap-z-50 ap-px-10 ap-py-4 ap-border-t ap-border ap-bg-white">
<div
class=" ap-mt-[80px] ap-flex ap-gap-2 ap-sticky ap-bottom-0 ap-z-50 ap-px-10 ap-py-4 ap-border-t ap-border ap-bg-white">
<ap-button type="submit" btnStyle="flat" btnColor="primary" [loading]="loading$ | async | defaultFalse" i18n>
Submit
</ap-button>
<ap-button type="button" btnStyle="flat" btnColor="basic" (click)="closeSlideout()">Cancel</ap-button>
</div>
</form>

@if(sendRequest$ | async)
{
}
@if(sendRequest$ | async){}
Loading

0 comments on commit 2236f19

Please sign in to comment.