@seeka-labs/cli-apps 1.1.4 → 1.1.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -9,7 +9,10 @@ import {
9
9
  } from '@seeka-labs/sdk-apps-server';
10
10
 
11
11
  import { queueNames, triggerBackgroundJob } from '../lib/jobs';
12
+ // START: component:browser
12
13
  import { getSeekaBrowserPlugin } from '../lib/browser'
14
+ // END: component:browser
15
+
13
16
  import { webhookLogger } from '../lib/logging';
14
17
  import { startServices } from '../lib/services';
15
18
  import {
@@ -115,6 +118,7 @@ export async function seekaAppWebhook(req: HttpRequest, context: InvocationConte
115
118
 
116
119
  break;
117
120
  }
121
+ // START: component:browser
118
122
  case SeekaWebhookCallType.BrowserSdkPlugin: {
119
123
  const plugin = await getSeekaBrowserPlugin(installation as SeekaAppInstallState, logger);
120
124
 
@@ -127,6 +131,7 @@ export async function seekaAppWebhook(req: HttpRequest, context: InvocationConte
127
131
  }
128
132
  }
129
133
  }
134
+ // END: component:browser
130
135
  }
131
136
  }
132
137
  catch (err) {
@@ -0,0 +1,14 @@
1
+ # http://editorconfig.org
2
+ root = true
3
+
4
+ [*]
5
+ charset = utf-8
6
+ end_of_line = lf
7
+ indent_size = 2
8
+ indent_style = space
9
+ insert_final_newline = true
10
+ trim_trailing_whitespace = true
11
+
12
+ [*.md]
13
+ max_line_length = 0
14
+ trim_trailing_whitespace = true
@@ -0,0 +1,11 @@
1
+ export default {
2
+ roots: ['<rootDir>/src'],
3
+ testMatch: [
4
+ "**/*.test.ts"
5
+ ],
6
+ transform: {
7
+ "^.+\\.(ts|tsx)$": "ts-jest"
8
+ },
9
+ collectCoverageFrom: ["src/**/*.ts", "!**/node_modules/**"],
10
+ coverageReporters: ["html", "text", "text-summary", "cobertura"],
11
+ }
@@ -0,0 +1,12 @@
1
+ import { SampleAppConvergeSdkPlugin } from "./plugin";
2
+ import type { ISampleAppBrowserSdkPluginConfig } from "../../lib/browser/models";
3
+
4
+ declare global {
5
+ interface Window {
6
+ SampleAppConvergeSdkPlugin: (pluginConfig: ISampleAppBrowserSdkPluginConfig) => SampleAppConvergeSdkPlugin;
7
+ }
8
+ }
9
+
10
+ (window as Window).SampleAppConvergeSdkPlugin = (pluginConfig: ISampleAppBrowserSdkPluginConfig) => {
11
+ return new SampleAppConvergeSdkPlugin(pluginConfig);
12
+ };
@@ -0,0 +1,6 @@
1
+
2
+ describe("SampleTest", () => {
3
+ test("Sample", () => {
4
+ expect(1).toStrictEqual(1);
5
+ });
6
+ });
@@ -0,0 +1,158 @@
1
+
2
+ import {
3
+ ConvergeSdk,
4
+ IConvergePlugin,
5
+ TrackingActivityNames, getActivityName
6
+ } from '@seeka-labs/converge';
7
+
8
+ import type { EnrichSeekaProfileFromSampleAppRequest, ISampleAppBrowserSdkPluginConfig } from '../../../lib/browser/models'
9
+
10
+ import { version, dependencies } from '../../package.json';
11
+
12
+ const checkSdkAndPluginVersion = (expectedVersion: string, sdk: ConvergeSdk, pluginName: string): void => {
13
+ let runtimeVersion = sdk.config.runtime.ver as string;
14
+ runtimeVersion = runtimeVersion.replace('^', '');
15
+ expectedVersion = expectedVersion.replace('^', '');
16
+
17
+ if (expectedVersion !== runtimeVersion) {
18
+ sdk.debug.warn(`The expected SDK version of ${expectedVersion} for the ${pluginName} plugin does not match the current installlation runtime of ${runtimeVersion}`);
19
+ }
20
+ }
21
+
22
+ export class SampleAppConvergeSdkPlugin implements IConvergePlugin<ISampleAppBrowserSdkPluginConfig> {
23
+ constructor(pluginConfig: ISampleAppBrowserSdkPluginConfig) {
24
+ this.type = "seeka-app-example-name";
25
+ // this.name = this.type + "-" + pluginConfig.siteId;
26
+ this.name = this.type;
27
+ this.version = version;
28
+ this.sdk = {} as ConvergeSdk;
29
+ this.config = pluginConfig || {};
30
+ }
31
+ sdk: ConvergeSdk;
32
+
33
+ privacyConfig = {
34
+ // TODO
35
+ requiresIabPurposes: []
36
+ }
37
+
38
+ name: string;
39
+ type: string;
40
+ version: string;
41
+ config: ISampleAppBrowserSdkPluginConfig;
42
+
43
+ async init(_params: any): Promise<void> {
44
+ window.addEventListener('message', async (event) => {
45
+ if (event.origin === 'https://calendly.com') {
46
+ await this.handleSampleAppEvent(event);
47
+ }
48
+ })
49
+
50
+ checkSdkAndPluginVersion(dependencies['@seeka-labs/converge'], this.sdk, this.name)
51
+ }
52
+
53
+ private async handleSampleAppEvent(event: any) {
54
+ const eventType = event.data.event;
55
+ if (!eventType || eventType.indexOf('calendly.') !== 0) return;
56
+
57
+ this.sdk.debug.verbose("SampleApp event received", { eventType, event })
58
+ switch (eventType) {
59
+ case 'calendly.date_and_time_selected':
60
+ break;
61
+ case 'calendly.event_type_viewed':
62
+ break;
63
+ case 'calendly.event_scheduled':
64
+ {
65
+ let activityName: TrackingActivityNames;
66
+ let activityNameCustom: string = '';
67
+
68
+ if (this.config?.eventBookedEventName) {
69
+ activityName = getActivityName(this.config.eventBookedEventName);
70
+ if (activityName === TrackingActivityNames.Custom) {
71
+ activityNameCustom = this.config.eventBookedEventName;
72
+ }
73
+ }
74
+ else {
75
+ activityName = TrackingActivityNames.Custom;
76
+ activityNameCustom = 'SampleAppInviteCreated';
77
+ }
78
+
79
+ const activityId = this.getEventId(event.data.payload)
80
+ const eventId = event.data.payload.event.uri.split('/').splice(-1)[0];
81
+
82
+ switch (activityName) {
83
+ case TrackingActivityNames.Custom: {
84
+ await this.sdk.track.custom(activityNameCustom, {
85
+ activityIdentifier: activityId,
86
+ contentId: eventId
87
+ });
88
+ break;
89
+ }
90
+ default: {
91
+ await this.sdk.track.activity(activityName, {
92
+ activityIdentifier: activityId,
93
+ contentId: eventId
94
+ });
95
+ break;
96
+ }
97
+ }
98
+
99
+ await this.sendAttendeeToApp(event.data.payload);
100
+
101
+ break;
102
+ }
103
+ }
104
+ }
105
+
106
+ private async sendAttendeeToApp(payload: any): Promise<void> {
107
+ try {
108
+ const eventId = payload.event.uri
109
+ const inviteeId = payload.invitee.uri;
110
+
111
+ const beaconUrl = `${this.config.appUrl}/api/profile/enrich`;
112
+
113
+ // if (navigator.sendBeacon && !navigator.sendBeacon(beaconUrl, JSON.stringify(beaconPayload))) {
114
+ // this.sdk.debug.warn('Failed to send attendee to SampleApp app')
115
+ // }
116
+ // else {
117
+ const res = await fetch(beaconUrl, {
118
+ method: 'POST',
119
+ keepalive: true,
120
+ mode: 'cors',
121
+ credentials: 'omit',
122
+ headers: {
123
+ 'Content-Type': 'application/json',
124
+ },
125
+ body: JSON.stringify({
126
+ appId: this.config.appId,
127
+ appInstallId: this.config.appInstallId,
128
+ event: eventId,
129
+ invitee: inviteeId,
130
+ seekaPersonId: this.sdk.identity.personId,
131
+ } as EnrichSeekaProfileFromSampleAppRequest)
132
+ })
133
+ if (!res.ok) {
134
+ this.sdk.debug.error('Failed to send attendee to SampleApp app')
135
+ }
136
+ // }
137
+ }
138
+ catch (err) {
139
+ this.sdk.debug.error('Failed to send attendee to SampleApp app', err)
140
+ }
141
+ }
142
+
143
+ // Should match Seeka developer app for dedupe
144
+ private getEventId(payload: any) {
145
+ const eventId = payload.event.uri.split('/').splice(-1)[0];
146
+ const inviteeId = this.getInviteeId(payload);
147
+
148
+ return `calendly_${eventId}_invite_${inviteeId}_created`
149
+ }
150
+
151
+ private getInviteeId(payload: any) {
152
+ return payload.invitee.uri.split('/').splice(-1)[0];
153
+ }
154
+
155
+ isLoaded(): boolean {
156
+ return true;
157
+ }
158
+ }
@@ -0,0 +1,35 @@
1
+ {
2
+ "compilerOptions": {
3
+ "allowJs": false,
4
+ "target": "ESNext",
5
+ "module": "ESNext",
6
+ "resolveJsonModule": true,
7
+ "moduleResolution": "node",
8
+ "noEmit": true,
9
+ "strict": true,
10
+ "noImplicitAny": false,
11
+ "strictNullChecks": true,
12
+ "strictFunctionTypes": true,
13
+ "noUnusedLocals": false,
14
+ "noUnusedParameters": false,
15
+ "noImplicitReturns": true,
16
+ "noFallthroughCasesInSwitch": true,
17
+ "importHelpers": true,
18
+ "skipLibCheck": true,
19
+ "esModuleInterop": true,
20
+ "allowSyntheticDefaultImports": true,
21
+ "experimentalDecorators": true,
22
+ "sourceMap": true,
23
+ "types": [
24
+ "node",
25
+ "jest"
26
+ ],
27
+ "lib": [
28
+ "ES6",
29
+ "DOM"
30
+ ]
31
+ },
32
+ "include": [
33
+ "src/browser.ts",
34
+ ]
35
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@seeka-labs/cli-apps",
3
- "version": "1.1.4",
3
+ "version": "1.1.6",
4
4
  "description": "Seeka - Apps CLI",
5
5
  "author": "SEEKA <platform@seeka.co>",
6
6
  "license": "MIT",
@@ -26,7 +26,8 @@
26
26
  "build:templates": "node ./scripts/build-templates.js",
27
27
  "watch": "tsc -w",
28
28
  "clean": "yarn rimraf dist",
29
- "dev": "yarn run clean && yarn build && rimraf seeka-app-test1 && node dist/index.js init seeka-app-test1 --template azure-function --email 'dev@seeka.co' --developer Seeka --noDependencies --browser --env 'SEEKA_APP_ID=123' 'SEEKA_APP_SECRET=345' --packageManager yarn",
29
+ "dev": "yarn run clean && yarn build && rimraf seeka-app-test1 && node dist/index.js init seeka-app-test1 --template azure-function --email 'dev@seeka.co' --developer Seeka --noDependencies --browser --npmUsername testy --npmPassword passworddd --env 'SEEKA_APP_ID=123' 'SEEKA_APP_SECRET=345' --packageManager yarn",
30
+ "dev:nobrowser": "yarn run clean && yarn build && rimraf seeka-app-test1 && node dist/index.js init seeka-app-test1 --template azure-function --email 'dev@seeka.co' --developer Seeka --noDependencies --env 'SEEKA_APP_ID=123' 'SEEKA_APP_SECRET=345' --packageManager yarn",
30
31
  "dev:skipSubDir": "yarn run clean && yarn build && rimraf seeka-app-test1 && mkdir seeka-app-test1 && cd seeka-app-test1 && mkdir rootfolder && cd rootfolder && node ../../dist/index.js init seeka-app-test1 --template azure-function --skipSubDir --email 'dev@seeka.co' --developer Seeka --noDependencies --browser --env 'SEEKA_APP_ID=123' 'SEEKA_APP_SECRET=345' --packageManager yarn",
31
32
  "dev:skipSubDir2": "yarn run clean && yarn build && cd seeka-app-test2 && node ../dist/index.js init seeka-app-test1 --template azure-function --skipSubDir --email 'dev@seeka.co' --developer Seeka --noDependencies --browser --env 'SEEKA_APP_ID=123' 'SEEKA_APP_SECRET=345' --packageManager yarn"
32
33
  },
@@ -34,18 +35,19 @@
34
35
  "@jest/globals": "^29.7.0",
35
36
  "@types/cross-spawn": "^6.0.6",
36
37
  "@types/jest": "^29.5.12",
37
- "@types/memory-cache": "^0.2.5",
38
+ "@types/lodash-es": "^4.17.12",
38
39
  "@types/node": "^18.14.0",
39
40
  "camelcase": "^8.0.0",
40
41
  "commander": "^12.0.0",
41
- "cross-env": "^7.0.3",
42
42
  "cross-spawn": "^7.0.3",
43
43
  "esbuild": "^0.20.0",
44
44
  "jest": "^29.7.0",
45
- "nodemon": "^3.0.3",
46
45
  "ts-jest": "^29.1.2",
47
- "ts-node": "^10.9.2",
48
46
  "typescript": "^5.3.3"
49
47
  },
50
- "gitHead": "bd153ede29757d814a114f97953a587b62f0de18"
48
+ "gitHead": "bd153ede29757d814a114f97953a587b62f0de18",
49
+ "dependencies": {
50
+ "lodash-es": "^4.17.21",
51
+ "source-map-support": "^0.5.21"
52
+ }
51
53
  }