Skip to content

Commit 4179093

Browse files
authored
feat: Added optional handler for CONFIGURATION/INITIALIZE event (#183)
* feat: Added optional handler for CONFIGURATION/INITIALIZE event
1 parent 2801efc commit 4179093

File tree

6 files changed

+224
-8
lines changed

6 files changed

+224
-8
lines changed

docs/classes/_smart_app_d_.smartapp.md

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ Name | Type | Description |
5757
* [handleLambdaCallback](_smart_app_d_.smartapp.md#handlelambdacallback)
5858
* [handleMockCallback](_smart_app_d_.smartapp.md#handlemockcallback)
5959
* [handleOAuthCallback](_smart_app_d_.smartapp.md#handleoauthcallback)
60+
* [initialized](_smart_app_d_.smartapp.md#initialized)
6061
* [installed](_smart_app_d_.smartapp.md#installed)
6162
* [keyApiHost](_smart_app_d_.smartapp.md#keyapihost)
6263
* [oauthHandler](_smart_app_d_.smartapp.md#oauthhandler)
@@ -505,6 +506,31 @@ Name | Type |
505506

506507
___
507508

509+
### initialized
510+
511+
**initialized**(`callback`: function): *[SmartApp](_smart_app_d_.smartapp.md)*
512+
513+
Defines a handler to be called the first time a SmartApp is installed. If not specified then the
514+
`updated()` handler will be called on the initial installation as well as updates.
515+
516+
**Parameters:**
517+
518+
**callback**: *function*
519+
520+
▸ (`context`: [SmartAppContext](../interfaces/_util_smart_app_context_d_.smartappcontext.md), `initialization`: [Initialization](_util_initialization_d_.initialization.md), `configData`: [ConfigurationData](../modules/_lifecycle_events_d_.md#configurationdata)): *[HandlerResponse](../modules/_smart_app_d_.md#handlerresponse)*
521+
522+
**Parameters:**
523+
524+
Name | Type |
525+
------ | ------ |
526+
`context` | [SmartAppContext](../interfaces/_util_smart_app_context_d_.smartappcontext.md) |
527+
`initialization` | [Initialization](_util_initialization_d_.initialization.md) |
528+
`configData` | [ConfigurationData](../modules/_lifecycle_events_d_.md#configurationdata) |
529+
530+
**Returns:** *[SmartApp](_smart_app_d_.smartapp.md)*
531+
532+
___
533+
508534
### installed
509535

510536
**installed**(`callback`: function): *[SmartApp](_smart_app_d_.smartapp.md)*

lib/smart-app.d.ts

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import DeviceCommandsEvent = AppEvent.DeviceCommandsEvent;
1818
import SecurityArmStateEvent = AppEvent.SecurityArmStateEvent;
1919
import ExecuteData = AppEvent.ExecuteData;
2020
import UninstallData = AppEvent.UninstallData;
21+
import {Initialization} from './util/initialization'
2122

2223
/**
2324
* Configuration options for SmartApps. These can either be passed into the constructor
@@ -383,6 +384,16 @@ export class SmartApp {
383384
*/
384385
handleOAuthCallback(request: WebHookRequest): Promise<ContextRecord>
385386

387+
/**
388+
* Defines a handler to be called the first time a SmartApp is installed. If not specified then the
389+
* `updated()` handler will be called on the initial installation as well as updates.
390+
*/
391+
initialized(callback: (
392+
context: SmartAppContext,
393+
initialization: Initialization,
394+
configData: AppEvent.ConfigurationData) =>
395+
HandlerResponse): SmartApp
396+
386397
/**
387398
* Defines a handler to be called the first time a SmartApp is installed. If not specified then the
388399
* `updated()` handler will be called on the initial installation as well as updates.
@@ -418,7 +429,7 @@ export class SmartApp {
418429
* explicitly required by this app. For example `['r:devices:*', and 'x:devices:*']
419430
* to be able to read and control all devices in the location. You do not have to
420431
* provide this list for devices selected by the user in configuration settings.
421-
*
432+
*
422433
* If permissions are specified, [[appId]] is also required.
423434
*/
424435
permissions(value: string | string[]): SmartApp

lib/smart-app.js

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ const Authorizer = require('./util/authorizer')
88
const responders = require('./util/responders')
99
const SmartAppContext = require('./util/smart-app-context')
1010
const Page = require('./pages/page')
11+
const Initialization = require('./util/initialization')
1112
const Log = require('./util/log')
1213
const ConfigurationError = require('./util/configuration-error')
1314

@@ -39,6 +40,7 @@ class SmartApp {
3940
})
4041
this._log.warn(msg)
4142
})
43+
this._initializedHandler = null
4244
this._installedHandler = ((ctx, installData) => {
4345
this._updatedHandler(ctx, installData)
4446
})
@@ -169,6 +171,15 @@ class SmartApp {
169171
return this
170172
}
171173

174+
// /////////////////////////////
175+
// Configuration/Initialize //
176+
// /////////////////////////////
177+
178+
initialized(callback) {
179+
this._initializedHandler = callback
180+
return this
181+
}
182+
172183
/// //////////////////////
173184
// Configuration/Page //
174185
/// //////////////////////
@@ -491,15 +502,21 @@ class SmartApp {
491502
switch (configurationData.phase) {
492503
case 'INITIALIZE': {
493504
this._log.event(evt, configurationData.phase)
505+
const initialize = {
506+
id: this._id,
507+
firstPageId: this._firstPageId,
508+
permissions: this._permissions,
509+
disableCustomDisplayName: this._disableCustomDisplayName,
510+
disableRemoveApp: this._disableRemoveApp
511+
}
512+
513+
if (this._initializedHandler) {
514+
await this._initializedHandler(context, new Initialization(initialize), configurationData)
515+
}
516+
494517
responder.respond({
495518
statusCode: 200, configurationData: {
496-
initialize: {
497-
id: this._id,
498-
firstPageId: this._firstPageId,
499-
permissions: this._permissions,
500-
disableCustomDisplayName: this._disableCustomDisplayName,
501-
disableRemoveApp: this._disableRemoveApp
502-
}
519+
initialize
503520
}
504521
})
505522
break

lib/util/initialization.d.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
export class Initialization {
2+
firstPageId(value: string)
3+
permissions(value: string | string[])
4+
disableCustomDisplayName(value?: boolean)
5+
disableRemoveApp(value?: boolean)
6+
}

lib/util/initialization.js

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
'use strict'
2+
3+
module.exports = class Initialization {
4+
constructor(params) {
5+
this._params = params
6+
}
7+
8+
firstPageId(value) {
9+
this._params.firstPageId = value
10+
return this
11+
}
12+
13+
permissions(value) {
14+
this._params.permissions = value
15+
return this
16+
}
17+
18+
disableCustomDisplayName(value = true) {
19+
this._params.disableCustomDisplayName = value
20+
return this
21+
}
22+
23+
disableRemoveApp(value = true) {
24+
this._params.disableRemoveApp = value
25+
return this
26+
}
27+
}
Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
const SmartApp = require('../../lib/smart-app')
2+
3+
describe('smartapp-initialize-spec', () => {
4+
test('default handler', async () => {
5+
const app = new SmartApp()
6+
.appId('xxx')
7+
.firstPageId('page1')
8+
.permissions(['r:devices:*'])
9+
.disableCustomDisplayName(true)
10+
.disableRemoveApp(true)
11+
12+
// Initialize configuration callback
13+
const resp = await app.handleMockCallback({
14+
lifecycle: 'CONFIGURATION',
15+
executionId: 'e6903fe6-f88f-da69-4c12-e2802606ccbc',
16+
locale: 'en',
17+
version: '0.1.0',
18+
client: {
19+
os: 'ios',
20+
version: '0.0.0',
21+
language: 'en-US'
22+
},
23+
configurationData: {
24+
installedAppId: '7d7fa36d-0ad9-4893-985c-6b75858e38e4',
25+
phase: 'INITIALIZE',
26+
pageId: '',
27+
previousPageId: '',
28+
config: {}
29+
},
30+
settings: {}
31+
})
32+
33+
const expectedInitResponse = {initialize: {
34+
id: 'xxx',
35+
firstPageId: 'page1',
36+
permissions: ['r:devices:*'],
37+
disableCustomDisplayName: true,
38+
disableRemoveApp: true
39+
}}
40+
41+
expect(resp.configurationData).toStrictEqual(expectedInitResponse)
42+
})
43+
44+
test('custom handler page', async () => {
45+
const app = new SmartApp()
46+
.appId('xxx')
47+
.permissions(['r:devices:*'])
48+
.initialized((ctx, initialization) => {
49+
initialization.firstPageId('page2A')
50+
})
51+
52+
// Initialize configuration callback
53+
const resp = await app.handleMockCallback({
54+
lifecycle: 'CONFIGURATION',
55+
executionId: 'e6903fe6-f88f-da69-4c12-e2802606ccbc',
56+
locale: 'en',
57+
version: '0.1.0',
58+
client: {
59+
os: 'ios',
60+
version: '0.0.0',
61+
language: 'en-US'
62+
},
63+
configurationData: {
64+
installedAppId: '7d7fa36d-0ad9-4893-985c-6b75858e38e4',
65+
phase: 'INITIALIZE',
66+
pageId: '',
67+
previousPageId: '',
68+
config: {}
69+
},
70+
settings: {}
71+
})
72+
73+
const expectedInitResponse = {initialize: {
74+
id: 'xxx',
75+
firstPageId: 'page2A',
76+
permissions: ['r:devices:*'],
77+
disableCustomDisplayName: false,
78+
disableRemoveApp: false
79+
}}
80+
81+
expect(resp.configurationData).toStrictEqual(expectedInitResponse)
82+
})
83+
84+
test('custom handler all', async () => {
85+
const app = new SmartApp()
86+
.appId('xxx')
87+
.firstPageId('page1')
88+
.permissions(['r:devices:*'])
89+
.disableCustomDisplayName(true)
90+
.disableRemoveApp(true)
91+
.initialized((ctx, initialization) => {
92+
initialization.firstPageId('page2')
93+
.disableCustomDisplayName(false)
94+
.disableRemoveApp(false)
95+
.permissions(['r:devices:*', 'x:devices:*'])
96+
})
97+
98+
// Initialize configuration callback
99+
const resp = await app.handleMockCallback({
100+
lifecycle: 'CONFIGURATION',
101+
executionId: 'e6903fe6-f88f-da69-4c12-e2802606ccbc',
102+
locale: 'en',
103+
version: '0.1.0',
104+
client: {
105+
os: 'ios',
106+
version: '0.0.0',
107+
language: 'en-US'
108+
},
109+
configurationData: {
110+
installedAppId: '7d7fa36d-0ad9-4893-985c-6b75858e38e4',
111+
phase: 'INITIALIZE',
112+
pageId: '',
113+
previousPageId: '',
114+
config: {}
115+
},
116+
settings: {}
117+
})
118+
119+
const expectedInitResponse = {initialize: {
120+
id: 'xxx',
121+
firstPageId: 'page2',
122+
permissions: ['r:devices:*', 'x:devices:*'],
123+
disableCustomDisplayName: false,
124+
disableRemoveApp: false
125+
}}
126+
127+
expect(resp.configurationData).toStrictEqual(expectedInitResponse)
128+
})
129+
})

0 commit comments

Comments
 (0)