Skip to content

Commit d35be4e

Browse files
authored
Merge pull request #9 from logicwind/dev
update readme file
2 parents 1d41523 + 8f3562f commit d35be4e

File tree

7 files changed

+272
-168
lines changed

7 files changed

+272
-168
lines changed

README.md

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,8 @@ trackSearch,
4848
disableTracking,
4949
enableTracking,
5050
startSession,
51-
trackMediaEvent
51+
trackMediaEvent,
52+
trackCampaign
5253
} from '@logicwind/react-native-matomo-tracker';
5354

5455
```
@@ -285,14 +286,14 @@ trackMediaEvent function use to monitor user interactions with media content, su
285286
| mediaHeight | The resolution height of the media in pixels. Only recommended being set for videos. |
286287
| mediaFullScreen| Should be 0 or 1 and defines whether the media is currently viewed in full screen. Only recommended being set for videos. |
287288
| mediaSE | An optional comma separated list of which positions within a media a user has played. For example if the user has viewed position 5s, 10s, 15s and 35s, then you would need to send 5,10,15,35. We recommend to round to the next 5 seconds and not send a value for each second. Internally, Matomo may round to the next 15 or 30 seconds. For performance optimisation we recommend not sending the same position twice. Meaning if you have sent ma_se=10 there is no need to send later ma_se=10,20 but instead only ma_se=20. |
288-
289+
| dimensions| Dimension contains a key and a value, and where the key is a custom dimension key created on the Matomo dashboard and the value should be a string, you'll need to ensure that the dimensions array is processed correctly. [create custom dimension](https://matomo.org/faq/reporting-tools/create-track-and-manage-custom-dimensions/)
289290

290291

291292
#### Examples
292293

293294
```js
294295

295-
trackMediaEvent({siteId:"siteid",mediaId:"unique id",mediaTitle:"video media play track",playerName:"test 08",mediaType:MediaType.VIDEO,mediaResource:"http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4",mediaStatus:"100",mediaLength:"100",mediaFullScreen:"1",mediaHeight:"720",mediaWidth:"1080",mediaProgress:"100"});
296+
trackMediaEvent({siteId:"siteid",mediaId:"unique id",mediaTitle:"video media play track",playerName:"test 08",mediaType:MediaType.VIDEO,mediaResource:"http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4",mediaStatus:"100",mediaLength:"100",mediaFullScreen:"1",mediaHeight:"720",mediaWidth:"1080",mediaProgress:"100", dimensions:[{key:"dimension1",value: "cf7fad2e-fae4-4c49-9924-ad9a2a7c50de"}]});
296297

297298
```
298299

@@ -368,7 +369,7 @@ trackCampaign("Home screen","https://example.com/?mtm_campaign=2020_august_promo
368369
| [disableTracking](#disabletracking) | - |||||
369370
| [enableTracking](#enabletracking) | - |||||
370371
| [setLogger](#setlogger) | - |||||
371-
| [trackMediaEvent](#trackmediaevent) | siteId: String, mediaId: String, mediaTitle: String, playerName: String, mediaType: String, mediaResource: String, mediaStatus: String,mediaLength?:String, mediaProgress?:String, mediaTTP?: String, mediaWidth?: String, mediaHeight?: String, mediaSE?: String, mediaFullScreen?:String |||||
372+
| [trackMediaEvent](#trackmediaevent) | siteId: String, mediaId: String, mediaTitle: String, playerName: String, mediaType: String, mediaResource: String, mediaStatus: String,mediaLength?:String, mediaProgress?:String, mediaTTP?: String, mediaWidth?: String, mediaHeight?: String, mediaSE?: String, mediaFullScreen?:String, dimensions : [object] |||||
372373
| [trackCampaign](#trackcampaign) | title: String, campaignUrl: String |||||
373374

374375

@@ -398,6 +399,14 @@ Click on “Create new token”
398399

399400
</details>
400401

402+
<details>
403+
<summary>How do I fix the tracking not work after successfully inetgration</summary>
404+
<br> if you have install matomo successfully but it will not track the event on matomo dashbaord then you have to check your project's bundle name in Matomo's bot detector list to validate if the starting characters match in their list or not. if it is match with your bundle name then you need to chnage your bundle name in ios.
405+
</br>
406+
<br>Here's the bot list of Matomo's bot detector: <a href="https://github.com/matomo-org/device-detector?tab=readme-ov-file#what-device-detector-is-able-to-detect">click here</a></br>
407+
408+
</details>
409+
401410
## License
402411

403412
This project is licensed under the MIT License - see the [LICENSE.md](LICENSE) file for details

android/src/main/java/com/logicwind/reactnativematomotracker/ReactNativeMatomoTrackerModule.kt

Lines changed: 114 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package com.logicwind.reactnativematomotracker
22

3+
import android.annotation.SuppressLint
34
import android.app.Application
45
import android.content.ContentValues.TAG
56
import android.content.Context
@@ -9,10 +10,12 @@ import android.util.Log
910
import com.facebook.react.bridge.ReactApplicationContext
1011
import com.facebook.react.bridge.ReactContextBaseJavaModule
1112
import com.facebook.react.bridge.ReactMethod
13+
import com.facebook.react.bridge.ReadableArray
1214
import okhttp3.MediaType.Companion.toMediaType
1315
import okhttp3.OkHttpClient
1416
import okhttp3.Request
1517
import okhttp3.RequestBody.Companion.toRequestBody
18+
import org.json.JSONObject
1619
import org.matomo.sdk.Matomo
1720
import org.matomo.sdk.Tracker
1821
import org.matomo.sdk.TrackerBuilder
@@ -41,14 +44,10 @@ class ReactNativeMatomoTrackerModule(reactContext: ReactApplicationContext) :
4144
fun setTracker(uri:String,siteId: Int) {
4245
if (tracker == null) {
4346
try {
44-
4547
tracker = TrackerBuilder.createDefault(uri, siteId)
4648
.build(mMatomoTracker)
47-
4849
Log.e(TAG, "initialized successfully! ${tracker}")
4950

50-
51-
5251
} catch (e: Exception) {
5352
Log.e(TAG, "An error occurred: ${e.message}")
5453
}
@@ -64,8 +63,20 @@ class ReactNativeMatomoTrackerModule(reactContext: ReactApplicationContext) :
6463
@ReactMethod
6564
fun createTracker(uri:String,siteId:Int,token:String) {
6665
authToken = token;
67-
site_Id = siteId.toString();
68-
setTracker(uri,siteId)
66+
67+
if (uri.isEmpty() && siteId <= 0) {
68+
Log.e("createTracker", "baseURL and siteId is empty or undefined");
69+
}
70+
else if(uri.isEmpty()){
71+
Log.e("createTracker", "baseURL is empty or undefined");
72+
}
73+
else if(siteId <= 0){
74+
Log.e("createTracker", "siteId is empty or undefined");
75+
}
76+
else{
77+
site_Id = siteId.toString();
78+
setTracker(uri,siteId)
79+
}
6980
}
7081

7182
@ReactMethod
@@ -196,6 +207,7 @@ class ReactNativeMatomoTrackerModule(reactContext: ReactApplicationContext) :
196207
return userAgent
197208
}
198209

210+
@SuppressLint("SuspiciousIndentation")
199211
@ReactMethod
200212
fun trackCampaign(title:String, campaignUrl: String) {
201213

@@ -210,10 +222,10 @@ class ReactNativeMatomoTrackerModule(reactContext: ReactApplicationContext) :
210222
try {
211223
val urlString = "$baseUrl?$query"
212224
val jsonBody = """
213-
{
214-
"auth_token": "$authToken",
215-
}
216-
""".trimIndent()
225+
{
226+
"auth_token": "$authToken"
227+
}
228+
""".trimIndent()
217229

218230
val requestBody = jsonBody.toRequestBody("application/json; charset=utf-8".toMediaType())
219231

@@ -249,81 +261,116 @@ class ReactNativeMatomoTrackerModule(reactContext: ReactApplicationContext) :
249261
mediaWidth: String,
250262
mediaHeight: String,
251263
mediaSE: String,
252-
mediaFullScreen:String
253-
264+
mediaFullScreen:String,
265+
dimensions: ReadableArray
254266
) {
255267

256-
if(mediaStatus=="0") {
257-
TrackHelper.track().event(mediaType, "play").name(mediaTitle).with(tracker)
258-
trackDispatch()
259-
}
260-
if(mediaStatus==mediaLength && mediaStatus==mediaProgress) {
261-
TrackHelper.track().event(mediaType, "stop").name(mediaTitle).with(tracker)
262-
trackDispatch()
263-
}
268+
if(siteId.isNotEmpty() && tracker!=null){
269+
if(mediaStatus=="0") {
270+
TrackHelper.track().event(mediaType, "play").name(mediaTitle).with(tracker)
271+
trackDispatch()
272+
}
273+
if(mediaStatus==mediaLength && mediaStatus==mediaProgress) {
274+
TrackHelper.track().event(mediaType, "stop").name(mediaTitle).with(tracker)
275+
trackDispatch()
276+
}
264277

265-
val baseUrl = tracker?.apiUrl
266-
val userAgent = getUserAgent(context)
267-
var query = "idsite=${encode(siteId)}" +
268-
"&rec=1" +
269-
"&r=${generateRandomNumber()}" +
270-
"&ma_id=${encode(mediaId)}" +
271-
"&ma_ti=${encode(mediaTitle)}" +
272-
"&ma_pn=${encode(playerName)}" +
273-
"&ma_mt=${encode(mediaType)}" +
274-
"&ma_re=${encode(mediaResource)}"+
275-
"&ma_st=${encode(mediaStatus)}"+
276-
"&_id=${encode(tracker?.visitorId.toString())}"
277-
278-
if(mediaLength.isNotEmpty()){
279-
query=query+ "&ma_le=${encode(mediaLength)}";
280-
}
278+
fun convertJsonString(jsonString: String): JSONObject? {
279+
return try {
280+
JSONObject(jsonString)
281+
} catch (e: Exception) {
282+
e.printStackTrace()
283+
null
284+
}
285+
}
281286

282-
if(mediaProgress.isNotEmpty()){
283-
query=query+ "&ma_ps=${encode(mediaProgress)}";
284-
}
285287

286-
if(mediaWidth.isNotEmpty()){
287-
query=query+ "&ma_w=${encode(mediaWidth)}";
288-
}
288+
val baseUrl = tracker?.apiUrl
289+
val userAgent = getUserAgent(context)
290+
var query = "idsite=${encode(siteId)}" +
291+
"&rec=1" +
292+
"&r=${generateRandomNumber()}" +
293+
"&ma_id=${encode(mediaId)}" +
294+
"&ma_ti=${encode(mediaTitle)}" +
295+
"&ma_pn=${encode(playerName)}" +
296+
"&ma_mt=${encode(mediaType)}" +
297+
"&ma_re=${encode(mediaResource)}"+
298+
"&ma_st=${encode(mediaStatus)}"+
299+
"&_id=${encode(tracker?.visitorId.toString())}"
289300

290-
if(mediaHeight.isNotEmpty()){
291-
query=query+ "&ma_h=${encode(mediaHeight)}";
292-
}
301+
if (dimensions.size() > 0) {
302+
for (i in 0 until dimensions.size()) {
303+
val dimension = dimensions.getMap(i)
304+
val key = dimension?.getString("key")
305+
val value = dimension?.getString("value")
306+
307+
if (key != null && value != null) {
308+
try {
309+
val jsonObject = JSONObject(value)
310+
val jsonValueString = jsonObject.toString()
311+
TrackHelper.track().screen("/media").dimension(i+1,value).with(tracker)
312+
trackDispatch()
313+
} catch (e: Exception) {
314+
TrackHelper.track().screen("/media").dimension(i+1,value).with(tracker)
315+
trackDispatch()
316+
}
317+
}
318+
}
319+
}
293320

294-
if(mediaFullScreen.isNotEmpty()){
295-
query=query+ "&ma_fs=${encode(mediaFullScreen)}";
296-
}
321+
if(mediaLength.isNotEmpty()){
322+
query=query+ "&ma_le=${encode(mediaLength)}";
323+
}
297324

298-
if(mediaSE.isNotEmpty()){
299-
query=query+ "&ma_se=${encode(mediaSE)}";
300-
}
325+
if(mediaProgress.isNotEmpty()){
326+
query=query+ "&ma_ps=${encode(mediaProgress)}";
327+
}
301328

302-
if(mediaTTP.isNotEmpty()){
303-
query=query+ "&ma_ttp=${encode(mediaTTP)}";
304-
}
305-
try {
306-
val urlString = "$baseUrl?$query"
307-
val jsonBody = """
329+
if(mediaWidth.isNotEmpty()){
330+
query=query+ "&ma_w=${encode(mediaWidth)}";
331+
}
332+
333+
if(mediaHeight.isNotEmpty()){
334+
query=query+ "&ma_h=${encode(mediaHeight)}";
335+
}
336+
337+
if(mediaFullScreen.isNotEmpty()){
338+
query=query+ "&ma_fs=${encode(mediaFullScreen)}";
339+
}
340+
341+
if(mediaSE.isNotEmpty()){
342+
query=query+ "&ma_se=${encode(mediaSE)}";
343+
}
344+
345+
if(mediaTTP.isNotEmpty()){
346+
query=query+ "&ma_ttp=${encode(mediaTTP)}";
347+
}
348+
try {
349+
val urlString = "$baseUrl?$query"
350+
val jsonBody = """
308351
{
309352
"auth_token": "$authToken",
310353
}
311354
""".trimIndent()
312355

313-
val requestBody = jsonBody.toRequestBody("application/json; charset=utf-8".toMediaType())
356+
val requestBody = jsonBody.toRequestBody("application/json; charset=utf-8".toMediaType())
314357

315-
val request = Request.Builder()
316-
.url(urlString)
317-
.header("User-Agent",userAgent)
318-
.post(requestBody)
319-
.build()
358+
val request = Request.Builder()
359+
.url(urlString)
360+
.header("User-Agent",userAgent)
361+
.post(requestBody)
362+
.build()
320363

321-
client.newCall(request).execute().use { response ->
322-
val responseCode = response.code
364+
client.newCall(request).execute().use { response ->
365+
val responseCode = response.code
366+
println("responseCode : $responseCode")
367+
}
368+
}catch (e:Exception){
369+
Log.e(TAG, "error : ${e.message}")
323370
}
324-
}catch (e:Exception){
325-
Log.e(TAG, "error : ${e.message}")
326371
}
372+
373+
327374
}
328375

329376
private fun generateRandomNumber(): Long {

example/src/App.tsx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ export default function App() {
3434
const [result] = React.useState<number | undefined>();
3535

3636
React.useEffect(() => {
37-
createTracker("https://your-domain-url/matomo.php", 1) //Replace 1 with your matomo site id
37+
createTracker("https://your-domain-url/matomo.php", 1) //Replace 1 with your matomo site id
3838
setLogger()
3939
}, []);
4040

@@ -185,7 +185,9 @@ export default function App() {
185185
<Pressable
186186
style={styles.button}
187187
onPress={() => {
188-
trackMediaEvent({ siteId: "siteId", mediaId: Date.now.toString(), mediaTitle: "video media play track", playerName: "test 08", mediaType: MediaType.VIDEO, mediaResource: "http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4", mediaStatus: "100", mediaLength: "100", mediaFullScreen: "1", mediaHeight: "720", mediaWidth: "1080", mediaProgress: "100" });
188+
trackMediaEvent({ siteId: "siteId", mediaId: Date.now.toString(), mediaTitle: "video media play track", playerName: "test 08", mediaType: MediaType.VIDEO, mediaResource: "http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4", mediaStatus: "100", mediaLength: "100", mediaFullScreen: "1", mediaHeight: "720", mediaWidth: "1080", mediaProgress: "100",
189+
dimensions:[{key:"dimension1",value: "cf7fad2e-fae4-4c49-9924-ad9a2a7c50de"}]
190+
});
189191
}}
190192
>
191193
<Text style={styles.buttonText}>Video Play Stop</Text>

ios/ReactNativeMatomoTracker.mm

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ @interface RCT_EXTERN_MODULE(ReactNativeMatomoTracker, NSObject)
4141

4242
RCT_EXTERN_METHOD(trackCampaign:(NSString *)title withCampaignUrl:(NSString *)campaignUrl)
4343

44-
RCT_EXTERN_METHOD(trackMedia:(NSString *)siteId withMediaId:(NSString *)mediaId withMediaTitle:(NSString *)mediaTitle withPlayerName:(NSString *)playerName withMediaType:(NSString *)mediaType withMediaResource:(NSString *)mediaResource withMediaStatus:(NSString *)mediaStatus withMediaLength:(NSString *)mediaLength withMediaProgress:(NSString *)mediaProgress withMediaTTP:(NSString *)mediaTTP withMediaWidth:(NSString *)mediaWidth withMediaHeight:(NSString *)mediaHeight withMediaSE:(NSString *)mediaSE withMediaFullScreen:(NSString *)mediaFullScreen)
44+
RCT_EXTERN_METHOD(trackMedia:(NSString *)siteId withMediaId:(NSString *)mediaId withMediaTitle:(NSString *)mediaTitle withPlayerName:(NSString *)playerName withMediaType:(NSString *)mediaType withMediaResource:(NSString *)mediaResource withMediaStatus:(NSString *)mediaStatus withMediaLength:(NSString *)mediaLength withMediaProgress:(NSString *)mediaProgress withMediaTTP:(NSString *)mediaTTP withMediaWidth:(NSString *)mediaWidth withMediaHeight:(NSString *)mediaHeight withMediaSE:(NSString *)mediaSE withMediaFullScreen:(NSString *)mediaFullScreen withDimensions:(NSArray<NSDictionary *> *)dimensions)
4545

4646

4747

0 commit comments

Comments
 (0)