zixflow-reactnative 1.0.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 (284) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +451 -0
  3. package/android/build.gradle +155 -0
  4. package/android/cio-core.gradle +12 -0
  5. package/android/consumer-rules.pro +3 -0
  6. package/android/gradle.properties +5 -0
  7. package/android/src/main/AndroidManifest.xml +19 -0
  8. package/android/src/main/java/io/customer/reactnative/sdk/CustomerIOReactNativePackage.kt +85 -0
  9. package/android/src/main/java/io/customer/reactnative/sdk/NativeCustomerIOModule.kt +201 -0
  10. package/android/src/main/java/io/customer/reactnative/sdk/constant/Keys.kt +20 -0
  11. package/android/src/main/java/io/customer/reactnative/sdk/extension/MapExtensions.kt +92 -0
  12. package/android/src/main/java/io/customer/reactnative/sdk/extension/ReactExtensions.kt +11 -0
  13. package/android/src/main/java/io/customer/reactnative/sdk/extension/StringExtensions.kt +3 -0
  14. package/android/src/main/java/io/customer/reactnative/sdk/extension/ViewExtensions.kt +34 -0
  15. package/android/src/main/java/io/customer/reactnative/sdk/location/NativeLocationModule.kt +66 -0
  16. package/android/src/main/java/io/customer/reactnative/sdk/logging/NativeCustomerIOLoggingModule.kt +90 -0
  17. package/android/src/main/java/io/customer/reactnative/sdk/messaginginapp/InlineInAppMessageViewManager.kt +56 -0
  18. package/android/src/main/java/io/customer/reactnative/sdk/messaginginapp/NativeMessagingInAppModule.kt +215 -0
  19. package/android/src/main/java/io/customer/reactnative/sdk/messaginginapp/NotificationInboxExtensions.kt +23 -0
  20. package/android/src/main/java/io/customer/reactnative/sdk/messaginginapp/ReactInAppEventListener.kt +77 -0
  21. package/android/src/main/java/io/customer/reactnative/sdk/messaginginapp/ReactInAppPlatformDelegate.kt +37 -0
  22. package/android/src/main/java/io/customer/reactnative/sdk/messaginginapp/ReactInlineInAppMessageView.kt +44 -0
  23. package/android/src/main/java/io/customer/reactnative/sdk/messaginginapp/ReactNotificationInboxChangeListener.kt +47 -0
  24. package/android/src/main/java/io/customer/reactnative/sdk/messagingpush/NativeMessagingPushModule.kt +283 -0
  25. package/android/src/main/java/io/customer/reactnative/sdk/messagingpush/PermissionStatus.kt +9 -0
  26. package/android/src/main/java/io/customer/reactnative/sdk/messagingpush/PushMessagingExtensions.kt +58 -0
  27. package/android/src/main/java/io/customer/reactnative/sdk/util/Preconditions.kt +35 -0
  28. package/android/src/main/res/values/customer_io_config.xml +13 -0
  29. package/customerio-reactnative.podspec +60 -0
  30. package/ios/CustomerioReactnative.xcodeproj/project.pbxproj +285 -0
  31. package/ios/CustomerioReactnative.xcodeproj/project.xcworkspace/contents.xcworkspacedata +4 -0
  32. package/ios/CustomerioReactnative.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +8 -0
  33. package/ios/wrappers/CustomerioReactnative-Bridging-Header.h +2 -0
  34. package/ios/wrappers/NativeCustomerIO.mm +100 -0
  35. package/ios/wrappers/NativeCustomerIO.swift +162 -0
  36. package/ios/wrappers/inapp/InboxMessage+Conversion.swift +22 -0
  37. package/ios/wrappers/inapp/NativeMessagingInApp.mm +122 -0
  38. package/ios/wrappers/inapp/NativeMessagingInApp.swift +214 -0
  39. package/ios/wrappers/inapp/ReactInAppEventListener.swift +74 -0
  40. package/ios/wrappers/inapp/inline/InlineInAppMessageStateEvent.swift +23 -0
  41. package/ios/wrappers/inapp/inline/RCTInlineMessageNative.h +18 -0
  42. package/ios/wrappers/inapp/inline/RCTInlineMessageNative.mm +168 -0
  43. package/ios/wrappers/inapp/inline/ReactInlineMessageView.h +42 -0
  44. package/ios/wrappers/inapp/inline/ReactInlineMessageView.swift +124 -0
  45. package/ios/wrappers/location/NativeLocation.mm +52 -0
  46. package/ios/wrappers/location/NativeLocation.swift +37 -0
  47. package/ios/wrappers/logging/NativeCustomerIOLogging.mm +81 -0
  48. package/ios/wrappers/logging/NativeCustomerIOLogging.swift +62 -0
  49. package/ios/wrappers/push/NativeMessagingPush.mm +87 -0
  50. package/ios/wrappers/push/NativeMessagingPush.swift +119 -0
  51. package/ios/wrappers/utils/CioConfigUtils.swift +63 -0
  52. package/ios/wrappers/utils/CioConstants.swift +25 -0
  53. package/ios/wrappers/utils/Preconditions.swift +20 -0
  54. package/ios/wrappers/utils/RCTCustomerIOUtils.h +19 -0
  55. package/lib/commonjs/cio-params.js +2 -0
  56. package/lib/commonjs/cio-params.js.map +1 -0
  57. package/lib/commonjs/components/InlineInAppMessageView.js +146 -0
  58. package/lib/commonjs/components/InlineInAppMessageView.js.map +1 -0
  59. package/lib/commonjs/components/index.js +14 -0
  60. package/lib/commonjs/components/index.js.map +1 -0
  61. package/lib/commonjs/customerio-cdp.js +163 -0
  62. package/lib/commonjs/customerio-cdp.js.map +1 -0
  63. package/lib/commonjs/customerio-inapp.js +107 -0
  64. package/lib/commonjs/customerio-inapp.js.map +1 -0
  65. package/lib/commonjs/customerio-location.js +53 -0
  66. package/lib/commonjs/customerio-location.js.map +1 -0
  67. package/lib/commonjs/customerio-push.js +115 -0
  68. package/lib/commonjs/customerio-push.js.map +1 -0
  69. package/lib/commonjs/index.js +17 -0
  70. package/lib/commonjs/index.js.map +1 -0
  71. package/lib/commonjs/native-logger-listener.js +84 -0
  72. package/lib/commonjs/native-logger-listener.js.map +1 -0
  73. package/lib/commonjs/notification-inbox.js +132 -0
  74. package/lib/commonjs/notification-inbox.js.map +1 -0
  75. package/lib/commonjs/package.json +1 -0
  76. package/lib/commonjs/postInstall.js +13 -0
  77. package/lib/commonjs/postInstall.js.map +1 -0
  78. package/lib/commonjs/specs/components/InlineMessageNativeComponent.ts +59 -0
  79. package/lib/commonjs/specs/modules/NativeCustomerIO.js +40 -0
  80. package/lib/commonjs/specs/modules/NativeCustomerIO.js.map +1 -0
  81. package/lib/commonjs/specs/modules/NativeCustomerIOLocation.js +15 -0
  82. package/lib/commonjs/specs/modules/NativeCustomerIOLocation.js.map +1 -0
  83. package/lib/commonjs/specs/modules/NativeCustomerIOLogging.js +19 -0
  84. package/lib/commonjs/specs/modules/NativeCustomerIOLogging.js.map +1 -0
  85. package/lib/commonjs/specs/modules/NativeCustomerIOMessagingInApp.js +16 -0
  86. package/lib/commonjs/specs/modules/NativeCustomerIOMessagingInApp.js.map +1 -0
  87. package/lib/commonjs/specs/modules/NativeCustomerIOMessagingPush.js +15 -0
  88. package/lib/commonjs/specs/modules/NativeCustomerIOMessagingPush.js.map +1 -0
  89. package/lib/commonjs/types/data-pipelines.js +123 -0
  90. package/lib/commonjs/types/data-pipelines.js.map +1 -0
  91. package/lib/commonjs/types/in-app.js +43 -0
  92. package/lib/commonjs/types/in-app.js.map +1 -0
  93. package/lib/commonjs/types/index.js +39 -0
  94. package/lib/commonjs/types/index.js.map +1 -0
  95. package/lib/commonjs/types/internal.js +2 -0
  96. package/lib/commonjs/types/internal.js.map +1 -0
  97. package/lib/commonjs/types/push.js +49 -0
  98. package/lib/commonjs/types/push.js.map +1 -0
  99. package/lib/commonjs/utils/native-bridge.js +31 -0
  100. package/lib/commonjs/utils/native-bridge.js.map +1 -0
  101. package/lib/commonjs/utils/param-validation.js +136 -0
  102. package/lib/commonjs/utils/param-validation.js.map +1 -0
  103. package/lib/commonjs/zixflow.js +71 -0
  104. package/lib/commonjs/zixflow.js.map +1 -0
  105. package/lib/module/cio-params.js +2 -0
  106. package/lib/module/cio-params.js.map +1 -0
  107. package/lib/module/components/InlineInAppMessageView.js +141 -0
  108. package/lib/module/components/InlineInAppMessageView.js.map +1 -0
  109. package/lib/module/components/index.js +6 -0
  110. package/lib/module/components/index.js.map +1 -0
  111. package/lib/module/customerio-cdp.js +157 -0
  112. package/lib/module/customerio-cdp.js.map +1 -0
  113. package/lib/module/customerio-inapp.js +92 -0
  114. package/lib/module/customerio-inapp.js.map +1 -0
  115. package/lib/module/customerio-location.js +48 -0
  116. package/lib/module/customerio-location.js.map +1 -0
  117. package/lib/module/customerio-push.js +111 -0
  118. package/lib/module/customerio-push.js.map +1 -0
  119. package/lib/module/index.js +12 -0
  120. package/lib/module/index.js.map +1 -0
  121. package/lib/module/native-logger-listener.js +79 -0
  122. package/lib/module/native-logger-listener.js.map +1 -0
  123. package/lib/module/notification-inbox.js +127 -0
  124. package/lib/module/notification-inbox.js.map +1 -0
  125. package/lib/module/package.json +1 -0
  126. package/lib/module/postInstall.js +13 -0
  127. package/lib/module/postInstall.js.map +1 -0
  128. package/lib/module/specs/components/InlineMessageNativeComponent.ts +59 -0
  129. package/lib/module/specs/modules/NativeCustomerIO.js +41 -0
  130. package/lib/module/specs/modules/NativeCustomerIO.js.map +1 -0
  131. package/lib/module/specs/modules/NativeCustomerIOLocation.js +13 -0
  132. package/lib/module/specs/modules/NativeCustomerIOLocation.js.map +1 -0
  133. package/lib/module/specs/modules/NativeCustomerIOLogging.js +18 -0
  134. package/lib/module/specs/modules/NativeCustomerIOLogging.js.map +1 -0
  135. package/lib/module/specs/modules/NativeCustomerIOMessagingInApp.js +15 -0
  136. package/lib/module/specs/modules/NativeCustomerIOMessagingInApp.js.map +1 -0
  137. package/lib/module/specs/modules/NativeCustomerIOMessagingPush.js +13 -0
  138. package/lib/module/specs/modules/NativeCustomerIOMessagingPush.js.map +1 -0
  139. package/lib/module/types/data-pipelines.js +126 -0
  140. package/lib/module/types/data-pipelines.js.map +1 -0
  141. package/lib/module/types/in-app.js +42 -0
  142. package/lib/module/types/in-app.js.map +1 -0
  143. package/lib/module/types/index.js +6 -0
  144. package/lib/module/types/index.js.map +1 -0
  145. package/lib/module/types/internal.js +2 -0
  146. package/lib/module/types/internal.js.map +1 -0
  147. package/lib/module/types/push.js +47 -0
  148. package/lib/module/types/push.js.map +1 -0
  149. package/lib/module/utils/native-bridge.js +25 -0
  150. package/lib/module/utils/native-bridge.js.map +1 -0
  151. package/lib/module/utils/param-validation.js +132 -0
  152. package/lib/module/utils/param-validation.js.map +1 -0
  153. package/lib/module/zixflow.js +23 -0
  154. package/lib/module/zixflow.js.map +1 -0
  155. package/lib/typescript/commonjs/cio-params.d.ts +5 -0
  156. package/lib/typescript/commonjs/cio-params.d.ts.map +1 -0
  157. package/lib/typescript/commonjs/components/InlineInAppMessageView.d.ts +41 -0
  158. package/lib/typescript/commonjs/components/InlineInAppMessageView.d.ts.map +1 -0
  159. package/lib/typescript/commonjs/components/index.d.ts +3 -0
  160. package/lib/typescript/commonjs/components/index.d.ts.map +1 -0
  161. package/lib/typescript/commonjs/customerio-cdp.d.ts +40 -0
  162. package/lib/typescript/commonjs/customerio-cdp.d.ts.map +1 -0
  163. package/lib/typescript/commonjs/customerio-inapp.d.ts +48 -0
  164. package/lib/typescript/commonjs/customerio-inapp.d.ts.map +1 -0
  165. package/lib/typescript/commonjs/customerio-location.d.ts +31 -0
  166. package/lib/typescript/commonjs/customerio-location.d.ts.map +1 -0
  167. package/lib/typescript/commonjs/customerio-push.d.ts +56 -0
  168. package/lib/typescript/commonjs/customerio-push.d.ts.map +1 -0
  169. package/lib/typescript/commonjs/index.d.ts +8 -0
  170. package/lib/typescript/commonjs/index.d.ts.map +1 -0
  171. package/lib/typescript/commonjs/native-logger-listener.d.ts +8 -0
  172. package/lib/typescript/commonjs/native-logger-listener.d.ts.map +1 -0
  173. package/lib/typescript/commonjs/notification-inbox.d.ts +57 -0
  174. package/lib/typescript/commonjs/notification-inbox.d.ts.map +1 -0
  175. package/lib/typescript/commonjs/package.json +1 -0
  176. package/lib/typescript/commonjs/postInstall.d.ts +2 -0
  177. package/lib/typescript/commonjs/postInstall.d.ts.map +1 -0
  178. package/lib/typescript/commonjs/specs/components/InlineMessageNativeComponent.d.ts +40 -0
  179. package/lib/typescript/commonjs/specs/components/InlineMessageNativeComponent.d.ts.map +1 -0
  180. package/lib/typescript/commonjs/specs/modules/NativeCustomerIO.d.ts +46 -0
  181. package/lib/typescript/commonjs/specs/modules/NativeCustomerIO.d.ts.map +1 -0
  182. package/lib/typescript/commonjs/specs/modules/NativeCustomerIOLocation.d.ts +14 -0
  183. package/lib/typescript/commonjs/specs/modules/NativeCustomerIOLocation.d.ts.map +1 -0
  184. package/lib/typescript/commonjs/specs/modules/NativeCustomerIOLogging.d.ts +18 -0
  185. package/lib/typescript/commonjs/specs/modules/NativeCustomerIOLogging.d.ts.map +1 -0
  186. package/lib/typescript/commonjs/specs/modules/NativeCustomerIOMessagingInApp.d.ts +23 -0
  187. package/lib/typescript/commonjs/specs/modules/NativeCustomerIOMessagingInApp.d.ts.map +1 -0
  188. package/lib/typescript/commonjs/specs/modules/NativeCustomerIOMessagingPush.d.ts +20 -0
  189. package/lib/typescript/commonjs/specs/modules/NativeCustomerIOMessagingPush.d.ts.map +1 -0
  190. package/lib/typescript/commonjs/types/data-pipelines.d.ts +143 -0
  191. package/lib/typescript/commonjs/types/data-pipelines.d.ts.map +1 -0
  192. package/lib/typescript/commonjs/types/in-app.d.ts +67 -0
  193. package/lib/typescript/commonjs/types/in-app.d.ts.map +1 -0
  194. package/lib/typescript/commonjs/types/index.d.ts +4 -0
  195. package/lib/typescript/commonjs/types/index.d.ts.map +1 -0
  196. package/lib/typescript/commonjs/types/internal.d.ts +20 -0
  197. package/lib/typescript/commonjs/types/internal.d.ts.map +1 -0
  198. package/lib/typescript/commonjs/types/push.d.ts +49 -0
  199. package/lib/typescript/commonjs/types/push.d.ts.map +1 -0
  200. package/lib/typescript/commonjs/utils/native-bridge.d.ts +9 -0
  201. package/lib/typescript/commonjs/utils/native-bridge.d.ts.map +1 -0
  202. package/lib/typescript/commonjs/utils/param-validation.d.ts +44 -0
  203. package/lib/typescript/commonjs/utils/param-validation.d.ts.map +1 -0
  204. package/lib/typescript/commonjs/zixflow.d.ts +14 -0
  205. package/lib/typescript/commonjs/zixflow.d.ts.map +1 -0
  206. package/lib/typescript/module/cio-params.d.ts +5 -0
  207. package/lib/typescript/module/cio-params.d.ts.map +1 -0
  208. package/lib/typescript/module/components/InlineInAppMessageView.d.ts +41 -0
  209. package/lib/typescript/module/components/InlineInAppMessageView.d.ts.map +1 -0
  210. package/lib/typescript/module/components/index.d.ts +3 -0
  211. package/lib/typescript/module/components/index.d.ts.map +1 -0
  212. package/lib/typescript/module/customerio-cdp.d.ts +40 -0
  213. package/lib/typescript/module/customerio-cdp.d.ts.map +1 -0
  214. package/lib/typescript/module/customerio-inapp.d.ts +48 -0
  215. package/lib/typescript/module/customerio-inapp.d.ts.map +1 -0
  216. package/lib/typescript/module/customerio-location.d.ts +31 -0
  217. package/lib/typescript/module/customerio-location.d.ts.map +1 -0
  218. package/lib/typescript/module/customerio-push.d.ts +56 -0
  219. package/lib/typescript/module/customerio-push.d.ts.map +1 -0
  220. package/lib/typescript/module/index.d.ts +8 -0
  221. package/lib/typescript/module/index.d.ts.map +1 -0
  222. package/lib/typescript/module/native-logger-listener.d.ts +8 -0
  223. package/lib/typescript/module/native-logger-listener.d.ts.map +1 -0
  224. package/lib/typescript/module/notification-inbox.d.ts +57 -0
  225. package/lib/typescript/module/notification-inbox.d.ts.map +1 -0
  226. package/lib/typescript/module/package.json +1 -0
  227. package/lib/typescript/module/postInstall.d.ts +2 -0
  228. package/lib/typescript/module/postInstall.d.ts.map +1 -0
  229. package/lib/typescript/module/specs/components/InlineMessageNativeComponent.d.ts +40 -0
  230. package/lib/typescript/module/specs/components/InlineMessageNativeComponent.d.ts.map +1 -0
  231. package/lib/typescript/module/specs/modules/NativeCustomerIO.d.ts +46 -0
  232. package/lib/typescript/module/specs/modules/NativeCustomerIO.d.ts.map +1 -0
  233. package/lib/typescript/module/specs/modules/NativeCustomerIOLocation.d.ts +14 -0
  234. package/lib/typescript/module/specs/modules/NativeCustomerIOLocation.d.ts.map +1 -0
  235. package/lib/typescript/module/specs/modules/NativeCustomerIOLogging.d.ts +18 -0
  236. package/lib/typescript/module/specs/modules/NativeCustomerIOLogging.d.ts.map +1 -0
  237. package/lib/typescript/module/specs/modules/NativeCustomerIOMessagingInApp.d.ts +23 -0
  238. package/lib/typescript/module/specs/modules/NativeCustomerIOMessagingInApp.d.ts.map +1 -0
  239. package/lib/typescript/module/specs/modules/NativeCustomerIOMessagingPush.d.ts +20 -0
  240. package/lib/typescript/module/specs/modules/NativeCustomerIOMessagingPush.d.ts.map +1 -0
  241. package/lib/typescript/module/types/data-pipelines.d.ts +143 -0
  242. package/lib/typescript/module/types/data-pipelines.d.ts.map +1 -0
  243. package/lib/typescript/module/types/in-app.d.ts +67 -0
  244. package/lib/typescript/module/types/in-app.d.ts.map +1 -0
  245. package/lib/typescript/module/types/index.d.ts +4 -0
  246. package/lib/typescript/module/types/index.d.ts.map +1 -0
  247. package/lib/typescript/module/types/internal.d.ts +20 -0
  248. package/lib/typescript/module/types/internal.d.ts.map +1 -0
  249. package/lib/typescript/module/types/push.d.ts +49 -0
  250. package/lib/typescript/module/types/push.d.ts.map +1 -0
  251. package/lib/typescript/module/utils/native-bridge.d.ts +9 -0
  252. package/lib/typescript/module/utils/native-bridge.d.ts.map +1 -0
  253. package/lib/typescript/module/utils/param-validation.d.ts +44 -0
  254. package/lib/typescript/module/utils/param-validation.d.ts.map +1 -0
  255. package/lib/typescript/module/zixflow.d.ts +14 -0
  256. package/lib/typescript/module/zixflow.d.ts.map +1 -0
  257. package/package.json +165 -0
  258. package/src/cio-params.ts +4 -0
  259. package/src/components/InlineInAppMessageView.tsx +187 -0
  260. package/src/components/index.ts +3 -0
  261. package/src/customerio-cdp.ts +190 -0
  262. package/src/customerio-inapp.ts +127 -0
  263. package/src/customerio-location.ts +56 -0
  264. package/src/customerio-push.ts +127 -0
  265. package/src/index.ts +9 -0
  266. package/src/native-logger-listener.ts +84 -0
  267. package/src/notification-inbox.ts +154 -0
  268. package/src/postInstall.js +10 -0
  269. package/src/specs/components/InlineMessageNativeComponent.ts +59 -0
  270. package/src/specs/modules/NativeCustomerIO.ts +55 -0
  271. package/src/specs/modules/NativeCustomerIOLocation.ts +15 -0
  272. package/src/specs/modules/NativeCustomerIOLogging.ts +24 -0
  273. package/src/specs/modules/NativeCustomerIOMessagingInApp.ts +30 -0
  274. package/src/specs/modules/NativeCustomerIOMessagingPush.ts +27 -0
  275. package/src/types/data-pipelines.ts +150 -0
  276. package/src/types/in-app.ts +69 -0
  277. package/src/types/index.ts +3 -0
  278. package/src/types/internal.ts +20 -0
  279. package/src/types/push.ts +50 -0
  280. package/src/utils/native-bridge.ts +30 -0
  281. package/src/utils/param-validation.ts +178 -0
  282. package/src/zixflow.ts +24 -0
  283. package/zixflow-reactnative-richpush.podspec +42 -0
  284. package/zixflow-reactnative.podspec +66 -0
@@ -0,0 +1,283 @@
1
+ package io.customer.reactnative.sdk.messagingpush
2
+
3
+ import android.Manifest
4
+ import android.app.Activity
5
+ import android.content.Intent
6
+ import android.content.pm.PackageManager
7
+ import android.os.Build
8
+ import androidx.core.content.ContextCompat
9
+ import com.facebook.react.bridge.ActivityEventListener
10
+ import com.facebook.react.bridge.Promise
11
+ import com.facebook.react.bridge.ReactApplicationContext
12
+ import com.facebook.react.bridge.ReactContext
13
+ import com.facebook.react.bridge.ReadableMap
14
+ import com.facebook.react.modules.core.PermissionAwareActivity
15
+ import com.facebook.react.modules.core.PermissionListener
16
+ import io.customer.messagingpush.CustomerIOFirebaseMessagingService
17
+ import io.customer.messagingpush.MessagingPushModuleConfig
18
+ import io.customer.messagingpush.ModuleMessagingPushFCM
19
+ import io.customer.messagingpush.config.PushClickBehavior
20
+ import io.customer.messagingpush.di.pushModuleConfig
21
+ import io.customer.messagingpush.di.pushTrackingUtil
22
+ import io.customer.reactnative.sdk.NativeCustomerIOMessagingPushSpec
23
+ import io.customer.reactnative.sdk.constant.Keys
24
+ import io.customer.reactnative.sdk.extension.getTypedValue
25
+ import io.customer.reactnative.sdk.extension.takeIfNotBlank
26
+ import io.customer.reactnative.sdk.util.unsupportedOnAndroid
27
+ import io.customer.sdk.CustomerIO
28
+ import io.customer.sdk.CustomerIOBuilder
29
+ import io.customer.sdk.core.di.SDKComponent
30
+ import io.customer.sdk.core.util.Logger
31
+ import java.util.UUID
32
+
33
+ /**
34
+ * React Native module implementation for Customer.io Push Messaging Native SDK using
35
+ * TurboModules with new architecture.
36
+ */
37
+ class NativeMessagingPushModule(
38
+ private val reactContext: ReactApplicationContext,
39
+ ) : NativeCustomerIOMessagingPushSpec(reactContext), PermissionListener, ActivityEventListener {
40
+ private val logger: Logger
41
+ get() = SDKComponent.logger
42
+
43
+ /**
44
+ * Temporarily holds reference for notification request as the request is dependent on Android
45
+ * lifecycle and cannot be completed instantly.
46
+ */
47
+ private var notificationRequestPromise: Promise? = null
48
+
49
+ override fun initialize() {
50
+ super.initialize()
51
+ reactContext.addActivityEventListener(this)
52
+ }
53
+
54
+ override fun invalidate() {
55
+ reactContext.removeActivityEventListener(this)
56
+ super.invalidate()
57
+ }
58
+
59
+ override fun getPushPermissionStatus(promise: Promise?) {
60
+ val result = checkPushPermissionStatus(reactContext).toReactNativeResult
61
+ promise?.resolve(result)
62
+ }
63
+
64
+ /**
65
+ * To request push notification permissions using native apis. Push notifications doesn't
66
+ * require permissions for Android versions older than 13, so the results are returned instantly.
67
+ * For newer versions, the permission is requested and the promise is resolved after the request
68
+ * has been completed.
69
+ *
70
+ * @param options configurations options for push notifications, required for iOS only,
71
+ * unused on Android.
72
+ * @param promise to resolve and return the results.
73
+ */
74
+ override fun showPromptForPushNotifications(options: ReadableMap?, promise: Promise?) {
75
+ // Skip requesting permissions when already granted
76
+ if (checkPushPermissionStatus(reactContext) == PermissionStatus.Granted) {
77
+ promise?.resolve(PermissionStatus.Granted.toReactNativeResult)
78
+ return
79
+ }
80
+
81
+ try {
82
+ val activity = reactContext.currentActivity
83
+ val permissionAwareActivity = activity as? PermissionAwareActivity
84
+ if (permissionAwareActivity == null) {
85
+ promise?.reject(
86
+ "E_ACTIVITY_DOES_NOT_EXIST",
87
+ "Permission cannot be requested because activity doesn't exist. Please make sure to request permission from UI components only"
88
+ )
89
+ return
90
+ }
91
+
92
+ notificationRequestPromise = promise
93
+ permissionAwareActivity.requestPermissions(
94
+ arrayOf(POST_NOTIFICATIONS_PERMISSION_NAME),
95
+ POST_NOTIFICATIONS_PERMISSION_REQUEST,
96
+ this,
97
+ )
98
+ } catch (ex: Throwable) {
99
+ promise?.reject(ex)
100
+ notificationRequestPromise = null
101
+ }
102
+ }
103
+
104
+ /**
105
+ * Handles push notification received. This is helpful in processing push notifications
106
+ * received outside the CIO SDK.
107
+ *
108
+ * @param message push payload received from FCM.
109
+ * @param handleNotificationTrigger indicating if the local notification should be triggered.
110
+ */
111
+ override fun onMessageReceived(
112
+ message: ReadableMap?,
113
+ handleNotificationTrigger: Boolean,
114
+ promise: Promise?,
115
+ ) {
116
+ try {
117
+ if (message == null) {
118
+ promise?.reject(IllegalArgumentException("Remote message cannot be null"))
119
+ return
120
+ }
121
+
122
+ // Generate destination string, see docs on receiver method for more details
123
+ val destination =
124
+ message.getString("to")?.takeIfNotBlank() ?: UUID.randomUUID().toString()
125
+ val isNotificationHandled = CustomerIOFirebaseMessagingService.onMessageReceived(
126
+ context = reactContext,
127
+ remoteMessage = message.toFCMRemoteMessage(destination = destination),
128
+ handleNotificationTrigger = handleNotificationTrigger,
129
+ )
130
+ promise?.resolve(isNotificationHandled)
131
+ } catch (ex: Throwable) {
132
+ logger.error("Unable to handle push notification, reason: ${ex.message}")
133
+ promise?.reject(ex)
134
+ }
135
+ }
136
+
137
+ override fun trackNotificationResponseReceived(payload: ReadableMap?) {
138
+ unsupportedOnAndroid(methodName = "trackNotificationResponseReceived")
139
+ }
140
+
141
+ override fun trackNotificationReceived(payload: ReadableMap?) {
142
+ unsupportedOnAndroid(methodName = "trackNotificationReceived")
143
+ }
144
+
145
+ /**
146
+ * Get the registered device token for the app.
147
+ * @returns Promise with device token as a string, or error if no token is
148
+ * registered or the method fails to fetch token.
149
+ */
150
+ override fun getRegisteredDeviceToken(promise: Promise?) {
151
+ try {
152
+ // Get the device token from SDK
153
+ val deviceToken: String? = CustomerIO.instance().registeredDeviceToken
154
+
155
+ if (deviceToken != null) {
156
+ promise?.resolve(deviceToken)
157
+ } else {
158
+ promise?.reject("device_token_not_found", "The device token is not available.")
159
+ }
160
+ } catch (e: Exception) {
161
+ promise?.reject(
162
+ "error_getting_device_token",
163
+ "Error fetching registered device token.",
164
+ e
165
+ )
166
+ }
167
+ }
168
+
169
+ /**
170
+ * Checks current permission of push notification permission
171
+ */
172
+ private fun checkPushPermissionStatus(reactContext: ReactContext): PermissionStatus {
173
+ // Skip requesting permissions for older versions where not required
174
+ return if (Build.VERSION.SDK_INT < BUILD_VERSION_CODE_TIRAMISU || ContextCompat.checkSelfPermission(
175
+ reactContext, POST_NOTIFICATIONS_PERMISSION_NAME,
176
+ ) == PackageManager.PERMISSION_GRANTED
177
+ ) PermissionStatus.Granted
178
+ else PermissionStatus.Denied
179
+ }
180
+
181
+ /**
182
+ * Resolves and clears promise with the provided permission status
183
+ */
184
+ private fun resolvePermissionPromise(status: PermissionStatus) {
185
+ notificationRequestPromise?.resolve(status.toReactNativeResult)
186
+ notificationRequestPromise = null
187
+ }
188
+
189
+ override fun onRequestPermissionsResult(
190
+ requestCode: Int,
191
+ permissions: Array<String>,
192
+ grantResults: IntArray,
193
+ ): Boolean = when (requestCode) {
194
+ POST_NOTIFICATIONS_PERMISSION_REQUEST -> {
195
+ // If request is cancelled, the result arrays are empty.
196
+ if (grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
197
+ resolvePermissionPromise(PermissionStatus.Granted)
198
+ } else {
199
+ resolvePermissionPromise(PermissionStatus.Denied)
200
+ }
201
+ true // as this permission listener can be removed now
202
+ }
203
+
204
+ else -> false // desired permission not yet granted, so we will keep the listener
205
+ }
206
+
207
+ override fun onActivityResult(
208
+ activity: Activity,
209
+ requestCode: Int,
210
+ resultCode: Int,
211
+ data: Intent?
212
+ ) {
213
+ // Nothing required here
214
+ }
215
+
216
+ /**
217
+ * If the app is in background and simple push is received, then FCM notification doesn't
218
+ * start new intent apparently because of `singleTask` launchMode being used by React Native
219
+ * apps. Due to this, onCreate activity callback is not triggered and the push notification
220
+ * is not tracked.
221
+ *
222
+ * But onNewIntent is called when the app is launched from background and the intent is
223
+ * received, which helps us tracking the simple push notifications opened metrics.
224
+ */
225
+ override fun onNewIntent(intent: Intent) {
226
+ val intentArguments = intent.extras ?: return
227
+ kotlin.runCatching {
228
+ if (pushModuleConfig.autoTrackPushEvents) {
229
+ SDKComponent.pushTrackingUtil.parseLaunchedActivityForTracking(intentArguments)
230
+ }
231
+ }.onFailure { ex ->
232
+ logger.error("Unable to parse push notification intent, reason: ${ex.message}")
233
+ }
234
+ }
235
+
236
+ companion object {
237
+ const val NAME = "NativeCustomerIOMessagingPush"
238
+
239
+ /**
240
+ * Copying value os [Manifest.permission.POST_NOTIFICATIONS] as constant so we don't have to
241
+ * force newer compile sdk versions
242
+ */
243
+ private const val POST_NOTIFICATIONS_PERMISSION_NAME =
244
+ "android.permission.POST_NOTIFICATIONS"
245
+ private const val BUILD_VERSION_CODE_TIRAMISU = 33
246
+ private const val POST_NOTIFICATIONS_PERMISSION_REQUEST = 24676
247
+
248
+ private val pushModuleConfig: MessagingPushModuleConfig
249
+ get() = SDKComponent.pushModuleConfig
250
+
251
+ /**
252
+ * Adds push messaging module to native Android SDK based on the configuration provided by
253
+ * customer app.
254
+ *
255
+ * @param builder instance of CustomerIOBuilder to add push messaging module.
256
+ * @param config configuration provided by customer app for push messaging module.
257
+ */
258
+ internal fun addNativeModuleFromConfig(
259
+ builder: CustomerIOBuilder,
260
+ config: Map<String, Any>
261
+ ) {
262
+ val androidConfig =
263
+ config.getTypedValue<Map<String, Any>>(key = "android") ?: emptyMap()
264
+ // Prefer `android` object for push configurations as it's more specific to Android
265
+ // For common push configurations, use `config` object instead of `android`
266
+
267
+ // Default push click behavior is to prevent restart of activity in React Native apps
268
+ val pushClickBehavior =
269
+ androidConfig.getTypedValue<String>(Keys.Config.PUSH_CLICK_BEHAVIOR)
270
+ ?.takeIfNotBlank()
271
+ ?.let { value ->
272
+ runCatching { enumValueOf<PushClickBehavior>(value) }.getOrNull()
273
+ } ?: PushClickBehavior.ACTIVITY_PREVENT_RESTART
274
+
275
+ val module = ModuleMessagingPushFCM(
276
+ moduleConfig = MessagingPushModuleConfig.Builder().apply {
277
+ setPushClickBehavior(pushClickBehavior = pushClickBehavior)
278
+ }.build(),
279
+ )
280
+ builder.addCustomerIOModule(module)
281
+ }
282
+ }
283
+ }
@@ -0,0 +1,9 @@
1
+ package io.customer.reactnative.sdk.messagingpush
2
+
3
+ /**
4
+ * Enum class for wrapping status of Android app permissions.
5
+ */
6
+ enum class PermissionStatus {
7
+ Granted,
8
+ Denied,
9
+ }
@@ -0,0 +1,58 @@
1
+ package io.customer.reactnative.sdk.messagingpush
2
+
3
+ import com.facebook.react.bridge.ReadableMap
4
+ import com.google.firebase.messaging.RemoteMessage
5
+ import io.customer.reactnative.sdk.extension.toMap
6
+
7
+ /**
8
+ * Safely transforms any value to string
9
+ */
10
+ private fun Any.toStringOrNull(): String? = try {
11
+ toString()
12
+ } catch (ex: Exception) {
13
+ // We don't need to print any error here as this is expected for some values and doesn't
14
+ // break anything
15
+ null
16
+ }
17
+
18
+ /**
19
+ * Extension function to build FCM [RemoteMessage] using RN map. This should be independent from
20
+ * the sender source and should be able to build a valid [RemoteMessage] for our native SDK.
21
+ *
22
+ * @param destination receiver of the message. It is mainly required for sending upstream messages,
23
+ * since we are using RemoteMessage only for broadcasting messages locally, we can use any non-empty
24
+ * string for it.
25
+ */
26
+ internal fun ReadableMap.toFCMRemoteMessage(destination: String): RemoteMessage {
27
+ val messageParams = buildMap {
28
+ putAll(getMap("notification").toMap())
29
+ // Adding `data` after `notification` so `data` params take more value as we mainly use
30
+ // `data` in rich push
31
+ putAll(getMap("data").toMap())
32
+ }
33
+ return with(RemoteMessage.Builder(destination)) {
34
+ messageParams.let { params ->
35
+ val paramsIterator = params.iterator()
36
+ while (paramsIterator.hasNext()) {
37
+ val (key, value) = paramsIterator.next()
38
+ // Some values in notification object can be another object and may not support
39
+ // mapping to string values, transforming these values in a try-catch so the code
40
+ // doesn't break due to one bad value
41
+ value.toStringOrNull()?.let { v -> addData(key, v) }
42
+ }
43
+ }
44
+ getString("messageId")?.let { id -> setMessageId(id) }
45
+ getString("messageType")?.let { type -> setMessageType(type) }
46
+ getString("collapseKey")?.let { key -> setCollapseKey(key) }
47
+ if (hasKey("ttl")) {
48
+ ttl = getInt("ttl")
49
+ }
50
+ build()
51
+ }
52
+ }
53
+
54
+ /**
55
+ * Maps native class to react native supported type so the result can be passed on to JS/TS classes.
56
+ */
57
+ internal val PermissionStatus.toReactNativeResult: Any
58
+ get() = this.name.uppercase()
@@ -0,0 +1,35 @@
1
+ package io.customer.reactnative.sdk.util
2
+
3
+ import io.customer.reactnative.sdk.BuildConfig
4
+ import io.customer.sdk.core.di.SDKComponent
5
+
6
+ /**
7
+ * Asserts that a value is non-null in debug builds.
8
+ * Returns the value (even if null) in release builds to avoid crashing.
9
+ */
10
+ inline fun <T : Any> assertNotNull(
11
+ value: T?,
12
+ lazyMessage: () -> String = { "Required value was null." }
13
+ ): T? {
14
+ return if (BuildConfig.DEBUG) {
15
+ requireNotNull(value, lazyMessage)
16
+ } else {
17
+ value
18
+ }
19
+ }
20
+
21
+ /**
22
+ * Throws a runtime exception in debug builds and logs a warning in release builds if a method
23
+ * that is only supported on iOS is called from Android.
24
+ *
25
+ * Use this to guard any platform-specific methods that are not expected to run on Android.
26
+ */
27
+ fun unsupportedOnAndroid(methodName: String) {
28
+ val message = "'$methodName' is unsupported on Android and should not be called."
29
+
30
+ if (BuildConfig.DEBUG) {
31
+ error(message)
32
+ } else {
33
+ SDKComponent.logger.error(message)
34
+ }
35
+ }
@@ -0,0 +1,13 @@
1
+ <?xml version="1.0" encoding="utf-8"?>
2
+ <resources>
3
+ <!--
4
+ SDK source to be used in user-agent string
5
+ -->
6
+ <string name="customer_io_react_native_sdk_client_source">ReactNative</string>
7
+ <!--
8
+ SDK version to be used in user-agent string
9
+ This will be updated by update-version script with React Native package version
10
+ whenever new version of React Native package is released
11
+ -->
12
+ <string name="customer_io_react_native_sdk_client_version">6.4.2</string>
13
+ </resources>
@@ -0,0 +1,60 @@
1
+ require "json"
2
+
3
+ package = JSON.parse(File.read(File.join(__dir__, "package.json")))
4
+
5
+ # Used by customers to install native iOS dependencies inside their host iOS app.
6
+ Pod::Spec.new do |s|
7
+ s.name = "customerio-reactnative"
8
+ s.version = package["version"]
9
+ s.summary = package["description"]
10
+ s.homepage = package["homepage"]
11
+ s.license = package["license"]
12
+ s.authors = package["author"]
13
+
14
+ s.platforms = { :ios => min_ios_version_supported }
15
+ s.source = { :git => "https://github.com/customerio/customerio-ios.git", :tag => "#{s.version}" }
16
+
17
+ s.source_files = "ios/wrappers/**/*.{h,m,mm,swift}"
18
+
19
+ # Use install_modules_dependencies helper to install the dependencies if React Native version >=0.71.0.
20
+ # See https://github.com/facebook/react-native/blob/febf6b7f33fdb4904669f99d795eba4c0f95d7bf/scripts/cocoapods/new_architecture.rb#L79.
21
+ if respond_to?(:install_modules_dependencies, true)
22
+ install_modules_dependencies(s)
23
+ else
24
+ s.dependency "React-Core"
25
+ end
26
+
27
+ # Syntax of native iOS pods allows for automatically upgrading to the latest major version of the iOS SDK.
28
+ # Reference: https://guides.cocoapods.org/syntax/podfile.html#pod
29
+ s.dependency "CustomerIO/DataPipelines", package["cioNativeiOSSdkVersion"]
30
+ s.dependency "CustomerIO/MessagingInApp", package["cioNativeiOSSdkVersion"]
31
+
32
+ # If we do not specify a default_subspec, then *all* dependencies inside of *all* the subspecs will be downloaded by cocoapods.
33
+ # We want customers to opt into push dependencies especially because the FCM subpsec downloads Firebase dependencies. APN customers should not install Firebase dependencies at all.
34
+ s.default_subspec = "nopush"
35
+
36
+ s.subspec "nopush" do |ss|
37
+ # This is the default subspec designed to not install any push dependencies. Customer should choose APN or FCM.
38
+ # The SDK at runtime currently requires the MessagingPush module so we do include it here.
39
+ ss.dependency "CustomerIO/MessagingPush", package["cioNativeiOSSdkVersion"]
40
+ end
41
+
42
+ # Note: Subspecs inherit all dependencies specified the parent spec (this file).
43
+ s.subspec "apn" do |ss|
44
+ ss.dependency "CustomerIO/MessagingPushAPN", package["cioNativeiOSSdkVersion"]
45
+ end
46
+
47
+ s.subspec "fcm" do |ss|
48
+ ss.dependency "CustomerIO/MessagingPushFCM", package["cioNativeiOSSdkVersion"]
49
+ # Customer.io Firebase Wrapper - provides Firebase integration
50
+ ss.dependency "CioFirebaseWrapper", package["cioiOSFirebaseWrapperSdkVersion"]
51
+ end
52
+
53
+ # Location module is optional - customers must opt in by adding this subspec.
54
+ s.subspec "location" do |ss|
55
+ ss.dependency "CustomerIO/Location", package["cioNativeiOSSdkVersion"]
56
+ ss.pod_target_xcconfig = {
57
+ 'OTHER_SWIFT_FLAGS' => '$(inherited) -DCIO_LOCATION_ENABLED'
58
+ }
59
+ end
60
+ end