airbridge-react-native-sdk-restricted 4.2.0 → 4.3.0

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.
Files changed (59) hide show
  1. package/.github/workflows/documentation.yml +7 -0
  2. package/airbridge_sdk.json +2 -2
  3. package/android/src/main/java/co/ab180/airbridge/reactnative/AirbridgeReactNative.kt +10 -18
  4. package/android/src/main/java/co/ab180/airbridge/reactnative/common/AirbridgeJSON.kt +4 -3
  5. package/android/src/main/java/co/ab180/airbridge/reactnative/module/PlacementInteractor.kt +16 -0
  6. package/build/document/assets/icons.js +1 -1
  7. package/build/document/assets/icons.svg +1 -1
  8. package/build/document/assets/main.js +1 -1
  9. package/build/document/assets/navigation.js +1 -1
  10. package/build/document/assets/search.js +1 -1
  11. package/build/document/assets/style.css +66 -21
  12. package/build/document/classes/Airbridge.html +9 -2
  13. package/build/document/classes/AirbridgeTrackingLinkOption.html +25 -0
  14. package/build/document/index.html +3 -3
  15. package/build/document/modules.html +3 -1
  16. package/build/document/types/AirbridgeTrackingLink.html +3 -0
  17. package/build/source/Airbridge.d.ts +12 -0
  18. package/build/source/Airbridge.js +12 -0
  19. package/build/source/Airbridge.js.map +1 -1
  20. package/build/source/constant/AirbridgeTrackingLinkOption.d.ts +27 -0
  21. package/build/source/constant/AirbridgeTrackingLinkOption.js +102 -0
  22. package/build/source/constant/AirbridgeTrackingLinkOption.js.map +1 -0
  23. package/build/source/module/Placement.d.ts +3 -0
  24. package/build/source/module/Placement.js +28 -0
  25. package/build/source/module/Placement.js.map +1 -1
  26. package/build/source/module.d.ts +2 -0
  27. package/build/source/module.js +2 -0
  28. package/build/source/module.js.map +1 -1
  29. package/build/source/type/AirbridgeTrackingLink.d.ts +8 -0
  30. package/build/source/type/AirbridgeTrackingLink.js +2 -0
  31. package/build/source/type/AirbridgeTrackingLink.js.map +1 -0
  32. package/changelog.md +14 -0
  33. package/ios/AirbridgeReactNative/AirbridgeReactNative.m +0 -6
  34. package/ios/AirbridgeReactNative/AirbridgeReactNative.swift +12 -32
  35. package/ios/AirbridgeReactNative/Common/AirbridgeJSON.swift +26 -0
  36. package/ios/AirbridgeReactNative/Module/AirbridgeModuleExtern.m +5 -0
  37. package/ios/AirbridgeReactNative/Module/PlacementInteractor.swift +22 -0
  38. package/package.json +1 -1
  39. package/qa/airbridge.json +2 -1
  40. package/qa/airbridge_qa.json +1 -1
  41. package/qa/android/app/src/main/java/co/ab180/airbridge/qa/application/ConfigurationLoader.kt +19 -23
  42. package/qa/android/app/src/main/java/co/ab180/airbridge/qa/application/module/IdentifiersInteractor.kt +27 -0
  43. package/qa/ios/AirbridgeQA/AirbridgeJSONSwizzler.swift +68 -0
  44. package/qa/ios/AirbridgeQA/AppDelegate.mm +3 -31
  45. package/qa/ios/AirbridgeQA/IdentifiersInteractor.m +2 -0
  46. package/qa/ios/AirbridgeQA/IdentifiersInteractor.swift +24 -0
  47. package/qa/ios/AirbridgeQA.xcodeproj/project.pbxproj +5 -1
  48. package/qa/ios/Podfile.lock +61 -61
  49. package/qa/package-lock.json +2254 -9009
  50. package/qa/source/navigations/Stack.js +7 -0
  51. package/qa/source/pages/Home.js +5 -0
  52. package/qa/source/pages/Identifiers.js +15 -1
  53. package/qa/source/pages/TrackingLink.js +162 -0
  54. package/readme.md +1 -1
  55. package/source/Airbridge.ts +21 -1
  56. package/source/constant/AirbridgeTrackingLinkOption.ts +122 -0
  57. package/source/module/Placement.ts +54 -2
  58. package/source/module.ts +2 -0
  59. package/source/type/AirbridgeTrackingLink.ts +10 -0
@@ -15,6 +15,7 @@ import { RequestPermissionsPage } from '../pages/RequestPermissions'
15
15
  import BrowsePage from '../pages/Browse'
16
16
  import AppInfoPage from '../pages/AppInfo'
17
17
  import SkadPage from '../pages/Skad'
18
+ import TrackingLinkPage from '../pages/TrackingLink'
18
19
 
19
20
  const Stack = createStackNavigator()
20
21
 
@@ -110,6 +111,12 @@ const StackNavigation = () => {
110
111
  headerLeft: () => createNavigateBackButton(navigation),
111
112
  headerRight: () => createNavigateHomeButton(navigation)
112
113
  })} />
114
+ <Stack.Screen name='createTrackingLink'
115
+ component={TrackingLinkPage}
116
+ options={({ navigation }) => ({
117
+ headerLeft: () => createNavigateBackButton(navigation),
118
+ headerRight: () => createNavigateHomeButton(navigation)
119
+ })} />
113
120
  </Stack.Navigator>
114
121
  )
115
122
  }
@@ -105,6 +105,11 @@ export default function HomePage({ navigation }) {
105
105
  title={'Tracking Links Within Apps'}
106
106
  accessibilityLabel={'trackingLinksWithinApps'}
107
107
  onPress={() => navigation.navigate('trackingLinksWithinApps')} />
108
+ <CustomButton
109
+ buttonColor={Colors.blue}
110
+ title={'Create Tracking Link'}
111
+ accessibilityLabel={'Create Tracking Link'}
112
+ onPress={() => navigation.navigate('createTrackingLink')} />
108
113
  <CustomButton
109
114
  buttonColor={Colors.teal}
110
115
  title={'Browse'}
@@ -27,11 +27,13 @@ export default class IdentifiersPage extends Component {
27
27
  gaid: 'N/A',
28
28
  fcmToken: storage.get('fcmToken') ?? 'N/A',
29
29
  apnsToken: storage.get('apnsToken') ?? 'N/A',
30
+ airbridgeJSON: '-'
30
31
  };
31
32
 
32
33
  this.confirmRef = React.createRef()
33
34
 
34
35
  this.fetchIdentifiers()
36
+ this.fetchAirbridgeJSON()
35
37
 
36
38
  if (Platform.OS === 'ios') {
37
39
  fcmService.requestPermission()
@@ -40,7 +42,7 @@ export default class IdentifiersPage extends Component {
40
42
 
41
43
  fetchIdentifiers = async () => {
42
44
  const response = await NativeModules.IdentifiersInteractor.identifiers()
43
- console.log('response : ' + response)
45
+ console.log('fetchIdentifiers response : ' + response)
44
46
  const jsonData = JSON.parse(response)
45
47
  const data = jsonData['data']
46
48
  this.setState({
@@ -51,6 +53,14 @@ export default class IdentifiersPage extends Component {
51
53
  })
52
54
  }
53
55
 
56
+ fetchAirbridgeJSON = async () => {
57
+ const response = await NativeModules.IdentifiersInteractor.airbridgeJSON()
58
+ console.log('fetchAirbridgeJSON response : ' + response)
59
+ this.setState({
60
+ airbridgeJSON: response
61
+ })
62
+ }
63
+
54
64
  reloadToken = async () => {
55
65
  this.setState({
56
66
  fcmToken: 'Reloading..',
@@ -101,6 +111,10 @@ export default class IdentifiersPage extends Component {
101
111
  title={'PushToken'}
102
112
  text={this.state.apnsToken}
103
113
  accessibilityLabel={'airbridgePushToken'} />
114
+ <VerticalPreference
115
+ title={'airbridgeJSON'}
116
+ text={this.state.airbridgeJSON}
117
+ accessibilityLabel={'airbridgeJSON'} />
104
118
 
105
119
  <ConfirmDialog
106
120
  ref={this.confirmRef}
@@ -0,0 +1,162 @@
1
+ import React, { Component } from 'react'
2
+ import { View } from 'react-native'
3
+
4
+ import { Styles } from '../common/Styles'
5
+ import { Colors } from '../common/Colors'
6
+ import CustomButton from '../component/CustomButton'
7
+ import CustomTextInput from '../component/CustomTextInput'
8
+
9
+ import { Airbridge, AirbridgeTrackingLinkOption } from 'airbridge-react-native-sdk-restricted';
10
+
11
+ import VerticalPreference from '../component/VerticalPreference';
12
+
13
+ export default class TrackingLinkPage extends Component {
14
+
15
+ constructor(props) {
16
+ super(props);
17
+
18
+ this.state = {
19
+ channel: '',
20
+ option: '',
21
+ shortURL: '',
22
+ qrcodeURL: ''
23
+ }
24
+ }
25
+
26
+ request = () => {
27
+ var outputChannel = this.state.channel.trim()
28
+ var flatOption = this.state.option.trim()
29
+ outputChannel = outputChannel.length == 0 ? null : outputChannel
30
+ flatOption = flatOption.length == 0 ? '{}' : flatOption
31
+
32
+ console.log(`outputChannel: ${outputChannel}`)
33
+ console.log(`flatOption: ${flatOption}`)
34
+
35
+ if (outputChannel == null || flatOption == null) {
36
+ return
37
+ }
38
+
39
+ var outputOption = null
40
+ try {
41
+ outputOption = JSON.parse(flatOption)
42
+ } catch (error) {
43
+ console.log(`TrackingLinkPage request error : ${error}`)
44
+ return
45
+ }
46
+
47
+ if (outputOption == null) {
48
+ return
49
+ }
50
+
51
+ Airbridge.createTrackingLink(
52
+ outputChannel,
53
+ outputOption,
54
+ (airbridgeTrackingLink) => {
55
+ console.log(`airbridgeTrackingLink. shortURL: ${airbridgeTrackingLink.shortURL}`)
56
+ this.setState({
57
+ shortURL: airbridgeTrackingLink.shortURL,
58
+ qrcodeURL: airbridgeTrackingLink.qrcodeURL,
59
+ })
60
+ }
61
+ )
62
+ }
63
+
64
+ clear = () => {
65
+ this.setState({
66
+ shortURL: '',
67
+ qrcodeURL: '',
68
+ })
69
+ }
70
+
71
+ request_tmp1 = () => {
72
+ this.request_template(
73
+ 'test',
74
+ {
75
+ [AirbridgeTrackingLinkOption.CAMPAIGN]: 'test_campaign',
76
+ [AirbridgeTrackingLinkOption.AD_GROUP]: 'request_1_group',
77
+ }
78
+ )
79
+ }
80
+
81
+ request_tmp2 = () => {
82
+ this.request_template(
83
+ 'test',
84
+ {
85
+ [AirbridgeTrackingLinkOption.CAMPAIGN]: 'test_campaign',
86
+ [AirbridgeTrackingLinkOption.AD_GROUP]: 'request_2_group',
87
+ }
88
+ )
89
+ }
90
+
91
+ request_template = (channel, option) => {
92
+ Airbridge.createTrackingLink(
93
+ channel,
94
+ option,
95
+ (airbridgeTrackingLink) => {
96
+ console.log(`airbridgeTrackingLink. shortURL: ${airbridgeTrackingLink.shortURL}`)
97
+ this.setState({
98
+ shortURL: airbridgeTrackingLink.shortURL,
99
+ qrcodeURL: airbridgeTrackingLink.qrcodeURL
100
+ })
101
+ }
102
+ )
103
+ }
104
+
105
+ render() {
106
+ return (
107
+ <View style={Styles.container}>
108
+ <CustomTextInput
109
+ title={'channel'}
110
+ placeholder={'channel'}
111
+ accessibilityLabel='channel'
112
+ onChangeText={newText => this.setState({ channel: newText })}
113
+ value={this.state.value} />
114
+ <View style={{ margin: 4 }} />
115
+ <CustomTextInput
116
+ title={'option'}
117
+ placeholder={'option'}
118
+ accessibilityLabel='option'
119
+ onChangeText={newText => this.setState({ option: newText })}
120
+ value={this.state.value} />
121
+ <View style={{ margin: 8 }} />
122
+ <CustomButton
123
+ buttonColor={Colors.blue}
124
+ title={'REQUEST'}
125
+ titleColor='white'
126
+ accessibilityLabel={'REQUEST'}
127
+ onPress={() => this.request()} />
128
+ <CustomButton
129
+ buttonColor={Colors.blue}
130
+ title={'clear'}
131
+ titleColor='white'
132
+ accessibilityLabel={'clear'}
133
+ onPress={() => this.clear()} />
134
+
135
+ <View style={{ margin: 16 }} />
136
+ <VerticalPreference
137
+ title={'shortUrl'}
138
+ text={this.state.shortURL}
139
+ accessibilityLabel={'shortUrl'} />
140
+ <VerticalPreference
141
+ title={'qrUrl'}
142
+ text={this.state.qrcodeURL}
143
+ accessibilityLabel={'qrUrl'} />
144
+
145
+ <View style={{ margin: 16 }} />
146
+ <CustomButton
147
+ buttonColor={Colors.blue}
148
+ title={'request-tmp1'}
149
+ titleColor='white'
150
+ accessibilityLabel={'request-tmp1'}
151
+ onPress={() => this.request_tmp1()} />
152
+ <CustomButton
153
+ buttonColor={Colors.blue}
154
+ title={'request-tmp2'}
155
+ titleColor='white'
156
+ accessibilityLabel={'request-tmp2'}
157
+ onPress={() => this.request_tmp2()} />
158
+
159
+ </View>
160
+ )
161
+ }
162
+ }
package/readme.md CHANGED
@@ -6,6 +6,6 @@ Airbridge SDK for React Native
6
6
 
7
7
  - https://help.airbridge.io/
8
8
 
9
- ### Reference
9
+ ## Reference
10
10
 
11
11
  - https://reference.airbridge.io/airbridge-react-native-sdk/latest/
@@ -7,6 +7,8 @@ import { createRegisterModule } from './module/Register'
7
7
  import { createSwitchModule } from './module/Switch'
8
8
  import { createWebInterfaceModule } from './module/WebInterface'
9
9
 
10
+ import { AirbridgeTrackingLink } from './type/AirbridgeTrackingLink'
11
+
10
12
  export const createDependency = () => {}
11
13
 
12
14
  createDependency.Airbridge = () => ({
@@ -337,4 +339,22 @@ export class Airbridge {
337
339
  static handleWebInterfaceCommand(command: string): void {
338
340
  this.#dependency.webInterfaceModule.handleWebInterfaceCommand(command)
339
341
  }
340
- }
342
+
343
+ /**
344
+ * Creates a tracking-link using airbridge-server that move user
345
+ * to specific page of app and track click-event.
346
+ *
347
+ * @param channel The channel of tracking-link.
348
+ * @param option The option to create tracking-link.
349
+ * @param onSuccess Created tracking-link is delivered if succeed.
350
+ * @param onFailure Error is delivered if failed.
351
+ */
352
+ static createTrackingLink(
353
+ channel: string,
354
+ option: Record<string, any>,
355
+ onSuccess: (airbridgeTrackingLink: AirbridgeTrackingLink) => void,
356
+ onFailure?: (error: Error) => void
357
+ ): void {
358
+ this.#dependency.placementModule.createTrackingLink(channel, option, onSuccess, onFailure)
359
+ }
360
+ }
@@ -0,0 +1,122 @@
1
+ /**
2
+ * Contains key of tracking-link option.
3
+ */
4
+ export class AirbridgeTrackingLinkOption {
5
+ /// A campaign parameter. (String)
6
+ static get CAMPAIGN() {
7
+ return 'campaign'
8
+ }
9
+
10
+ /// A campaign parameter. (String)
11
+ static get AD_GROUP() {
12
+ return 'ad_group'
13
+ }
14
+
15
+ /// A campaign parameter. (String)
16
+ static get AD_CREATIVE() {
17
+ return 'ad_creative'
18
+ }
19
+
20
+ /// A campaign parameter. (String)
21
+ static get CONTENT() {
22
+ return 'content'
23
+ }
24
+
25
+ /// A campaign parameter. (String)
26
+ static get TERM() {
27
+ return 'term'
28
+ }
29
+
30
+ /// A campaign parameter. (String)
31
+ static get SUB_ID() {
32
+ return 'sub_id'
33
+ }
34
+
35
+ /// A campaign parameter. (String)
36
+ static get SUB_ID_1() {
37
+ return 'sub_id_1'
38
+ }
39
+
40
+ /// A campaign parameter. (String)
41
+ static get SUB_ID_2() {
42
+ return 'sub_id_2'
43
+ }
44
+
45
+ /// A campaign parameter. (String)
46
+ static get SUB_ID_3() {
47
+ return 'sub_id_3'
48
+ }
49
+
50
+ /// A url of deeplink open the app. (Custom Scheme URL String)
51
+ static get DEEPLINK_URL() {
52
+ return 'deeplink_url'
53
+ }
54
+
55
+ /// A option enable stop-over-feature of deeplink. (Boolean)
56
+ static get DEEPLINK_STOPOVER() {
57
+ return 'deeplink_stopover'
58
+ }
59
+
60
+ /// A url of fallback for ios if app is not installed. ("store" | Web URL String)
61
+ static get FALLBACK_IOS() {
62
+ return 'fallback_ios'
63
+ }
64
+
65
+ /// A url of fallback for android if app is not installed. ("store" | Web URL String)
66
+ static get FALLBACK_ANDROID() {
67
+ return 'fallback_android'
68
+ }
69
+
70
+ /// A url of fallback for desktop if app is not installed. (Web URL String)
71
+ static get FALLBACK_DESKTOP() {
72
+ return 'fallback_desktop'
73
+ }
74
+
75
+ /// A custom id of store for ios used when user move to store. (String)
76
+ static get FALLBACK_IOS_STORE_PPID() {
77
+ return 'fallback_ios_store_ppid'
78
+ }
79
+
80
+ /// A custom id of store for android used when user move to store. (String)
81
+ static get FALLBACK_ANDROID_STORE_LISTING() {
82
+ return 'fallback_android_store_listing'
83
+ }
84
+
85
+ /// A title of link-preview. (String)
86
+ static get OGTAG_TITLE() {
87
+ return 'ogtag_title'
88
+ }
89
+
90
+ /// A description of link-preview. (String)
91
+ static get OGTAG_DESCRIPTION() {
92
+ return 'ogtag_description'
93
+ }
94
+
95
+ /// A image-url of link-preview. (Web URL String)
96
+ static get OGTAG_IMAGE_URL() {
97
+ return 'ogtag_image_url'
98
+ }
99
+
100
+ /// A customization of link-preview. ("desktop")
101
+ /// - Note: Airbridge crawl og-tag from response of FALLBACK_DESKTOP.
102
+ static get OGTAG_WEBSITE_CRAWL() {
103
+ return 'ogtag_website_crawl'
104
+ }
105
+
106
+ /// A custom-short-id of tracking-link. (String)
107
+ /// - Warning: Must be used with CUSTOM_DOMAIN option.
108
+ /// - Note: Refer example. <https://app.example.com/invite>
109
+ static get CUSTOM_SHORT_ID() {
110
+ return 'custom_short_id'
111
+ }
112
+
113
+ /// A option enable re-engagement-feature of attribution. ("off" | "on_true" | "on_false")
114
+ /// - Note: "off" uses touchpoint from install and deeplink event.
115
+ /// - Note: "on_true" uses touchpoint from deeplink event only.
116
+ /// Can be used by re-engagement campaign.
117
+ /// - Note: "on_false" uses touchpoint from install event only.
118
+ /// Can be used by UA(user-acquisition) campaign.
119
+ static get IS_REENGAGEMENT() {
120
+ return 'is_reengagement'
121
+ }
122
+ }
@@ -4,7 +4,9 @@ import { createInteractor } from '../architecture/Interactor'
4
4
  import { check } from '../utility/check'
5
5
  import { log } from '../utility/log'
6
6
 
7
- export const createDependency = () => {}
7
+ import { AirbridgeTrackingLink } from '../type/AirbridgeTrackingLink'
8
+
9
+ export const createDependency = () => { }
8
10
 
9
11
  type PlacementInteractor = {
10
12
  click(
@@ -13,12 +15,20 @@ type PlacementInteractor = {
13
15
  onSuccess: () => void,
14
16
  onFailure: (message: string) => void,
15
17
  ): Promise<boolean>
18
+
16
19
  impression(
17
20
  promiseID: string,
18
21
  trackingLink: string,
19
22
  onSuccess: () => void,
20
23
  onFailure: (message: string) => void,
21
24
  ): Promise<boolean>
25
+
26
+ createTrackingLink(
27
+ channel: string,
28
+ option: Record<string, any>,
29
+ onSuccess: (airbridgeTrackingLink: Record<string, string>) => void,
30
+ onFailure: (message: string) => void,
31
+ ): void
22
32
  }
23
33
 
24
34
  createDependency.PlacementModule = () => ({
@@ -28,7 +38,7 @@ createDependency.PlacementModule = () => ({
28
38
 
29
39
  export type PlacementModule = ReturnType<typeof createPlacementModule>
30
40
 
31
- export const createPlacementModule= () => {
41
+ export const createPlacementModule = () => {
32
42
  // create dependency
33
43
  const { emitter, interactor } = createDependency.PlacementModule()
34
44
 
@@ -126,9 +136,51 @@ export const createPlacementModule= () => {
126
136
  })
127
137
  }
128
138
 
139
+ const createTrackingLink = (
140
+ channel: string,
141
+ option: Record<string, any>,
142
+ onSuccess: (airbridgeTrackingLink: AirbridgeTrackingLink) => void,
143
+ onFailure?: (error: Error) => void
144
+ ): void => {
145
+ if (!check.string(channel)) {
146
+ log.unmatchedType('channel', 'string')
147
+ return
148
+ }
149
+ if (!(check.undefined(option) || check.object(option))) {
150
+ log.unmatchedType('option', 'object')
151
+ return
152
+ }
153
+ if (!check.function(onSuccess)) {
154
+ log.unmatchedType('onSuccess', 'function?')
155
+ return
156
+ }
157
+ if (!(check.function(onFailure) || check.undefined(onFailure))) {
158
+ log.unmatchedType('onFailure', 'function?')
159
+ return
160
+ }
161
+
162
+ interactor.createTrackingLink(
163
+ channel,
164
+ option,
165
+ (airbridgeTrackingLink: Record<string, string>) => {
166
+ if (
167
+ check.string(airbridgeTrackingLink['qrcodeURL']) &&
168
+ check.string(airbridgeTrackingLink['shortURL'])
169
+ ) {
170
+ onSuccess?.({
171
+ qrcodeURL: airbridgeTrackingLink['qrcodeURL'],
172
+ shortURL: airbridgeTrackingLink['shortURL']
173
+ })
174
+ }
175
+ },
176
+ (message: string) => { onFailure?.(Error(message)) }
177
+ )
178
+ }
179
+
129
180
  // create object
130
181
  return {
131
182
  click,
132
183
  impression,
184
+ createTrackingLink
133
185
  }
134
186
  }
package/source/module.ts CHANGED
@@ -1,3 +1,5 @@
1
1
  export { Airbridge } from './Airbridge'
2
+ export * from './type/AirbridgeTrackingLink'
2
3
  export * from './constant/AirbridgeAttribute'
3
4
  export * from './constant/AirbridgeCategory'
5
+ export * from './constant/AirbridgeTrackingLinkOption'
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Holds variable types of tracking-link that move user
3
+ * to specific page of app and track click-event.
4
+ */
5
+ export type AirbridgeTrackingLink = {
6
+ /// A tracking-link url contains short mapping-id of option
7
+ shortURL: string
8
+ /// A qrcode image-url of tracking-link
9
+ qrcodeURL: string
10
+ }