Skip to content

Commit 63994ea

Browse files
author
Ivan Kudinov
committed
CCS-105439 Add bluetooth & nfc methods
1 parent 040cab0 commit 63994ea

File tree

12 files changed

+339
-124
lines changed

12 files changed

+339
-124
lines changed

package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@expressms/smartapp-sdk",
3-
"version": "1.12.0-alpha.5",
3+
"version": "1.12.0-alpha.7",
44
"description": "Smartapp SDK",
55
"main": "build/main/index.js",
66
"typings": "build/main/index.d.ts",

src/index.ts

+11-102
Original file line numberDiff line numberDiff line change
@@ -1,103 +1,12 @@
1-
import Bridge from '@expressms/smartapp-bridge'
2-
import {
3-
cleanCache,
4-
clientStorageClear,
5-
clientStorageGet,
6-
clientStorageRemove,
7-
clientStorageSet,
8-
createDeeplink,
9-
getAppVisibility,
10-
getChats,
11-
getConnectionStatus,
12-
getLayoutType,
13-
getSmartAppList,
14-
getUnreadCounter,
15-
handleDeeplink,
16-
openChatMessage,
17-
openClientSettings,
18-
openGroupChat,
19-
requestLocation,
20-
searchCorporatePhonebook,
21-
searchLocalPhonebook,
22-
sendBotCommand,
23-
subscribeClientEvents,
24-
unsubscribeClientEvents,
25-
} from './lib/client'
26-
import { openFile, uploadFile, uploadFiles } from './lib/client/file'
27-
import {
28-
addContact,
29-
createPersonalChat,
30-
getContact,
31-
openContactCard,
32-
openPersonalChat,
33-
requestSelfProfile,
34-
sendMessage,
35-
} from './lib/contacts'
36-
import { useQuery } from './lib/helpers/helpers'
37-
import { ready } from './lib/logging'
38-
import { onNotification } from './lib/notification'
39-
import {
40-
getCredentials,
41-
runWebCommandsPipeline,
42-
setAllowedNavigationDomains,
43-
setCredentials,
44-
setWebResourceCookies,
45-
} from './lib/proxy'
46-
import {
47-
closeSmartApp,
48-
exitSmartAppToCatalog,
49-
onBackPressed,
50-
onMoveToRoot,
51-
openSmartApp,
52-
routingChanged,
53-
} from './lib/routing'
1+
export * from './lib/client'
2+
export * from './lib/client/file'
3+
export * from './lib/contacts'
4+
export * from './lib/helpers/helpers'
5+
export * from './lib/logging'
6+
export * from './lib/notification'
7+
export * from './lib/routing'
8+
export * from './lib/proxy'
9+
export * from './lib/devices'
5410

55-
export {
56-
Bridge,
57-
ready,
58-
routingChanged,
59-
onBackPressed,
60-
addContact,
61-
getContact,
62-
createPersonalChat,
63-
onNotification,
64-
sendMessage,
65-
openSmartApp,
66-
openFile,
67-
uploadFile,
68-
uploadFiles,
69-
exitSmartAppToCatalog,
70-
useQuery,
71-
openClientSettings,
72-
getChats,
73-
searchCorporatePhonebook,
74-
sendBotCommand,
75-
openGroupChat,
76-
onMoveToRoot,
77-
requestLocation,
78-
openContactCard,
79-
requestSelfProfile,
80-
closeSmartApp,
81-
getAppVisibility,
82-
getConnectionStatus,
83-
subscribeClientEvents,
84-
unsubscribeClientEvents,
85-
createDeeplink,
86-
openChatMessage,
87-
clientStorageGet,
88-
clientStorageSet,
89-
clientStorageRemove,
90-
clientStorageClear,
91-
openPersonalChat,
92-
handleDeeplink,
93-
searchLocalPhonebook,
94-
getUnreadCounter,
95-
getLayoutType,
96-
cleanCache,
97-
getSmartAppList,
98-
setWebResourceCookies,
99-
setAllowedNavigationDomains,
100-
runWebCommandsPipeline,
101-
getCredentials,
102-
setCredentials,
103-
}
11+
import Bridge from '@expressms/smartapp-bridge'
12+
export { Bridge }

src/lib/client/index.ts

-8
Original file line numberDiff line numberDiff line change
@@ -67,13 +67,6 @@ const sendBotCommand = ({
6767
})
6868
}
6969

70-
const requestLocation = () => {
71-
return bridge?.sendClientEvent({
72-
method: METHODS.REQUEST_LOCATION,
73-
params: {},
74-
})
75-
}
76-
7770
/**
7871
* Get client current connection status. It's based on client's WebSocket connection state.
7972
* @returns Promise that'll be fullfilled with status data on success, otherwise rejected with reason
@@ -243,7 +236,6 @@ export {
243236
searchCorporatePhonebook,
244237
openGroupChat,
245238
sendBotCommand,
246-
requestLocation,
247239
getConnectionStatus,
248240
createDeeplink,
249241
openChatMessage,

src/lib/devices/bluetooth.ts

+194
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,194 @@
1+
import bridge from '@expressms/smartapp-bridge'
2+
import {
3+
BleDeviceCallback,
4+
BluetoothBleDeviceFoundEvent,
5+
BluetoothDiscoverGattServicesResponse,
6+
BluetoothScanBleDevicesResponse,
7+
BluetoothStatusResponse,
8+
ERROR_CODES,
9+
METHODS,
10+
} from '../../types'
11+
12+
const deviceCallbacks: Array<BleDeviceCallback> = []
13+
14+
/**
15+
* Install bridge event listener for founded devices during scan
16+
*/
17+
const installBridgeEventListener = () => {
18+
if (!bridge) return
19+
20+
bridge.onReceive(event => {
21+
if (event.type !== 'ble_device_found') return
22+
23+
const {
24+
payload: { bleDevice },
25+
} = event as BluetoothBleDeviceFoundEvent
26+
27+
deviceCallbacks.map(cb => cb(bleDevice))
28+
})
29+
}
30+
31+
/**
32+
* Add callback to list
33+
*/
34+
const addDeviceCallback = (callback?: BleDeviceCallback) => {
35+
if (callback) deviceCallbacks.push(callback)
36+
}
37+
38+
/**
39+
* Remove callback from list
40+
*/
41+
const removeDeviceCallback = (callback?: BleDeviceCallback) => {
42+
if (!callback) return
43+
44+
const index = deviceCallbacks.findIndex(cb => cb === callback)
45+
if (index !== -1) deviceCallbacks.splice(index, 1)
46+
}
47+
48+
/**
49+
* Enable bluetooth
50+
* @returns Promise that'll be fullfilled on success, otherwise rejected with reason
51+
*/
52+
export const enable = (): Promise<BluetoothStatusResponse> => {
53+
if (!bridge) return Promise.reject(ERROR_CODES.NO_BRIDGE)
54+
55+
return bridge
56+
.sendClientEvent({
57+
method: METHODS.ENABLE_BLUETOOTH,
58+
params: {},
59+
})
60+
.then(event => event as BluetoothStatusResponse)
61+
}
62+
63+
/**
64+
* Scan BLE devices nearby
65+
* @param scanDuration Duration to scan devices in milliseconds
66+
* @param deviceCallback Callback that triggered on device found
67+
* @returns Promise that'll be fullfilled with `payload.bleDevices` on success, otherwise rejected with reason
68+
*/
69+
export const scanBleDevices = ({
70+
scanDuration,
71+
deviceCallback,
72+
}: {
73+
scanDuration: number
74+
deviceCallback?: BleDeviceCallback
75+
}): Promise<BluetoothScanBleDevicesResponse> => {
76+
if (!bridge) return Promise.reject(ERROR_CODES.NO_BRIDGE)
77+
78+
addDeviceCallback(deviceCallback)
79+
80+
return bridge
81+
.sendClientEvent({
82+
method: METHODS.SCAN_BLE_DEVICES,
83+
params: {
84+
scanDuration,
85+
},
86+
})
87+
.then(event => {
88+
removeDeviceCallback(deviceCallback)
89+
return event as BluetoothScanBleDevicesResponse
90+
})
91+
.catch(() => {
92+
removeDeviceCallback(deviceCallback)
93+
return Promise.reject()
94+
})
95+
}
96+
97+
/**
98+
* Connect bluetooth BLE device
99+
* @param bleDeviceAddress Address of the BLE device
100+
* @returns Promise that'll be fullfilled on success, otherwise rejected with reason
101+
*/
102+
export const connectBleDevice = ({
103+
bleDeviceAddress,
104+
}: {
105+
bleDeviceAddress: string
106+
}): Promise<BluetoothStatusResponse> => {
107+
if (!bridge) return Promise.reject(ERROR_CODES.NO_BRIDGE)
108+
109+
return bridge
110+
.sendClientEvent({
111+
method: METHODS.CONNECT_BLE_DEVICE,
112+
params: {
113+
bleDeviceAddress,
114+
},
115+
})
116+
.then(event => event as BluetoothStatusResponse)
117+
}
118+
119+
/**
120+
* Disonnect bluetooth BLE device
121+
* @param bleDeviceAddress Address of the BLE device
122+
* @returns Promise that'll be fullfilled on success, otherwise rejected with reason
123+
*/
124+
export const disconnectBleDevice = ({
125+
bleDeviceAddress,
126+
}: {
127+
bleDeviceAddress: string
128+
}): Promise<BluetoothStatusResponse> => {
129+
if (!bridge) return Promise.reject(ERROR_CODES.NO_BRIDGE)
130+
131+
return bridge
132+
.sendClientEvent({
133+
method: METHODS.DISCONNECT_BLE_DEVICE,
134+
params: {
135+
bleDeviceAddress,
136+
},
137+
})
138+
.then(event => event as BluetoothStatusResponse)
139+
}
140+
141+
/**
142+
* Discover services and characteristics of the BLE device
143+
* @param bleDeviceAddress Address of the BLE device
144+
* @returns Promise that'll be fullfilled with `payload.gattServices` on success, otherwise rejected with reason
145+
*/
146+
export const discoverGattServices = ({
147+
bleDeviceAddress,
148+
}: {
149+
bleDeviceAddress: string
150+
}): Promise<BluetoothDiscoverGattServicesResponse> => {
151+
if (!bridge) return Promise.reject(ERROR_CODES.NO_BRIDGE)
152+
153+
return bridge
154+
.sendClientEvent({
155+
method: METHODS.DISCOVER_BLE_GATT_SERVICES,
156+
params: {
157+
bleDeviceAddress,
158+
},
159+
})
160+
.then(event => event as BluetoothDiscoverGattServicesResponse)
161+
}
162+
163+
/**
164+
* Read BLE GATT characteristic
165+
* @param bleDeviceAddress Address of the BLE device
166+
* @param gattServiceUuid UUID of the GATT service
167+
* @param gattCharacteristicUuid UUID of the GATT characteristic
168+
* @returns Promise that'll be fullfilled with `payload.value` on success, otherwise rejected with reason
169+
*/
170+
export const readBleGattCharacteristic = ({
171+
bleDeviceAddress,
172+
gattServiceUuid,
173+
gattCharacteristicUuid,
174+
}: {
175+
bleDeviceAddress: string,
176+
gattServiceUuid: string,
177+
gattCharacteristicUuid: string,
178+
}): Promise<BluetoothDiscoverGattServicesResponse> => {
179+
if (!bridge) return Promise.reject(ERROR_CODES.NO_BRIDGE)
180+
181+
return bridge
182+
.sendClientEvent({
183+
method: METHODS.READ_BLE_GATT_CHARACTERISTIC,
184+
params: {
185+
bleDeviceAddress,
186+
gattServiceUuid,
187+
gattCharacteristicUuid,
188+
},
189+
})
190+
.then(event => event as BluetoothDiscoverGattServicesResponse)
191+
}
192+
193+
// Init device event listener
194+
installBridgeEventListener()

src/lib/devices/gps.ts

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import bridge from '@expressms/smartapp-bridge'
2+
import { METHODS } from '../../types'
3+
4+
/**
5+
* Request GPS position
6+
* @returns Promise that'll be fullfilled with `payload.*` on success, otherwise rejected with reason
7+
*/
8+
export const requestLocation = () => {
9+
return bridge?.sendClientEvent({
10+
method: METHODS.REQUEST_LOCATION,
11+
params: {},
12+
})
13+
}

src/lib/devices/index.ts

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
import * as Bluetooth from './bluetooth'
2+
import * as GPS from './gps'
3+
import { requestLocation } from './gps'
4+
import * as NFC from './nfc'
5+
6+
export { Bluetooth, NFC, GPS, requestLocation }

src/lib/devices/nfc.ts

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import bridge from '@expressms/smartapp-bridge'
2+
import {
3+
ERROR_CODES,
4+
METHODS,
5+
NfcReadTagResponse,
6+
} from '../../types'
7+
8+
/**
9+
* Enable bluetooth
10+
* @returns Promise that'll be fullfilled with `payload.nfcTag` on success, otherwise rejected with reason
11+
*/
12+
export const readTag = (): Promise<NfcReadTagResponse> => {
13+
if (!bridge) return Promise.reject(ERROR_CODES.NO_BRIDGE)
14+
15+
return bridge
16+
.sendClientEvent({
17+
method: METHODS.ENABLE_BLUETOOTH,
18+
params: {},
19+
})
20+
.then(event => event as NfcReadTagResponse)
21+
}

src/lib/notification/index.ts

+1-5
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import bridge from "@expressms/smartapp-bridge"
22
import { METHODS } from "../../types"
33

4-
const onNotification = async (handleNotification: Function) => {
4+
export const onNotification = async (handleNotification: Function) => {
55
const response = await bridge?.sendClientEvent({
66
method: METHODS.NOTIFICATION,
77
params: {},
@@ -14,7 +14,3 @@ const onNotification = async (handleNotification: Function) => {
1414
}
1515
})
1616
}
17-
18-
export {
19-
onNotification,
20-
}

0 commit comments

Comments
 (0)