Skip to content

Commit 1d41523

Browse files
authored
Merge pull request #8 from logicwind/dev
Added campaign tracking
2 parents 50f6193 + cc6ac70 commit 1d41523

File tree

8 files changed

+169
-31
lines changed

8 files changed

+169
-31
lines changed

README.md

Lines changed: 53 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -295,7 +295,58 @@ trackMediaEvent function use to monitor user interactions with media content, su
295295
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"});
296296

297297
```
298-
298+
299+
300+
### trackCampaign()
301+
302+
Tracking campaigns usually involves recording information about user interactions that can be tied to specific marketing efforts, such as UTM parameters.It requires the parameters `title` and `campaignUrl`
303+
304+
- #### Default Campaign Tracking Values
305+
* Campaign (Required): mtm_campaign
306+
<br>A descriptive name for the campaign, e.g. a blog post title or email campaign name.</br>
307+
308+
* Keyword (Recommended): mtm_keyword
309+
<br>The specific keyword that someone searched for, or category of interest.</br>
310+
311+
- #### Additional Campaign Tracking Values
312+
(Available with Matomo Cloud or Marketing Campaigns Reporting Plugin)
313+
314+
* Source (Recommended): `mtm_source`
315+
<br>The actual source of the traffic, e.g. newsletter, twitter, ebay, etc.</br>
316+
317+
* Medium (Recommended): `mtm_medium`
318+
<br>The type of marketing channel, e.g. email, social, paid, etc.</br>
319+
320+
* Content (Optional): `mtm_content`
321+
<br>This is a specific link or content that somebody clicked. e.g. banner, big-green-button</br>
322+
323+
* ID (Optional): `mtm_cid`
324+
<br>A unique identifier for your specific ad. This parameter is often used with the numeric IDs automatically generated by advertising platforms.</br>
325+
326+
* Group (Requires Matomo 4 or above): `mtm_group`
327+
<br>The audience your campaign is targeting e.g. customers, retargeting, etc</br>
328+
329+
330+
* Placement (Requires Matomo 4 or above): `mtm_placement`
331+
<br>The placement on an advertising network e.g. newsfeed, sidebar, home-banner, etc.</br>
332+
333+
334+
If you already have URLs tagged with Google Analytics parameters these are also supported:
335+
336+
* utm_campaign,
337+
* utm_source,
338+
* utm_medium,
339+
* utm_term,
340+
* utm_content,
341+
* utm_id.
342+
343+
#### Examples
344+
345+
```js
346+
347+
trackCampaign("Home screen","https://example.com/?mtm_campaign=2020_august_promo&mtm_source=google&mtm_medium=email&mtm_keyword=august promo&mtm_content=primary-cta")
348+
349+
```
299350

300351
## Methods
301352

@@ -318,6 +369,7 @@ trackMediaEvent({siteId:"siteid",mediaId:"unique id",mediaTitle:"video media pla
318369
| [enableTracking](#enabletracking) | - |||||
319370
| [setLogger](#setlogger) | - |||||
320371
| [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+
| [trackCampaign](#trackcampaign) | title: String, campaignUrl: String |||||
321373

322374

323375
<!-- ## Contributing

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

Lines changed: 53 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,10 @@ package com.logicwind.reactnativematomotracker
22

33
import android.app.Application
44
import android.content.ContentValues.TAG
5+
import android.content.Context
6+
import android.content.pm.PackageInfo
57
import android.os.Build
68
import android.util.Log
7-
import androidx.core.content.pm.PackageInfoCompat
89
import com.facebook.react.bridge.ReactApplicationContext
910
import com.facebook.react.bridge.ReactContextBaseJavaModule
1011
import com.facebook.react.bridge.ReactMethod
@@ -29,6 +30,8 @@ class ReactNativeMatomoTrackerModule(reactContext: ReactApplicationContext) :
2930
private var tracker: Tracker? = null
3031
private val client = OkHttpClient()
3132
private var authToken: String? = null
33+
private var site_Id: String = ""
34+
private var context:ReactApplicationContext = reactContext
3235

3336
override fun getName(): String {
3437
return NAME
@@ -61,6 +64,7 @@ class ReactNativeMatomoTrackerModule(reactContext: ReactApplicationContext) :
6164
@ReactMethod
6265
fun createTracker(uri:String,siteId:Int,token:String) {
6366
authToken = token;
67+
site_Id = siteId.toString();
6468
setTracker(uri,siteId)
6569
}
6670

@@ -183,6 +187,52 @@ class ReactNativeMatomoTrackerModule(reactContext: ReactApplicationContext) :
183187
}
184188
}
185189

190+
fun getUserAgent(context: ReactApplicationContext): String {
191+
val packageInfo: PackageInfo = context.packageManager.getPackageInfo(context.packageName, 0)
192+
val appName = context.applicationInfo.loadLabel(context.packageManager).toString()
193+
val appVersion = packageInfo.versionName
194+
val userAgent = "Android/${Build.VERSION.RELEASE} (${Build.MODEL}; ${Build.MANUFACTURER}), MatomoTrackerSDK/4.2 $appName/$appVersion"
195+
196+
return userAgent
197+
}
198+
199+
@ReactMethod
200+
fun trackCampaign(title:String, campaignUrl: String) {
201+
202+
if (tracker != null) {
203+
val userAgent = getUserAgent(context)
204+
val baseUrl = tracker?.apiUrl
205+
var query = "idsite=${encode(site_Id)}" +
206+
"&rec=1" +
207+
"&url=${encode(campaignUrl)}" +
208+
"&action_name=${title}" +
209+
"&_id=${encode(tracker?.visitorId.toString())}"
210+
try {
211+
val urlString = "$baseUrl?$query"
212+
val jsonBody = """
213+
{
214+
"auth_token": "$authToken",
215+
}
216+
""".trimIndent()
217+
218+
val requestBody = jsonBody.toRequestBody("application/json; charset=utf-8".toMediaType())
219+
220+
val request = Request.Builder()
221+
.url(urlString)
222+
.header("User-Agent",userAgent)
223+
.post(requestBody)
224+
.build()
225+
226+
client.newCall(request).execute().use { response ->
227+
val responseCode = response.code
228+
println(" responseCode : "+ responseCode)
229+
}
230+
}catch (e:Exception){
231+
Log.e(TAG, "error : ${e.message}")
232+
}
233+
}
234+
}
235+
186236

187237
@ReactMethod
188238
fun trackMedia(
@@ -213,6 +263,7 @@ class ReactNativeMatomoTrackerModule(reactContext: ReactApplicationContext) :
213263
}
214264

215265
val baseUrl = tracker?.apiUrl
266+
val userAgent = getUserAgent(context)
216267
var query = "idsite=${encode(siteId)}" +
217268
"&rec=1" +
218269
"&r=${generateRandomNumber()}" +
@@ -263,6 +314,7 @@ class ReactNativeMatomoTrackerModule(reactContext: ReactApplicationContext) :
263314

264315
val request = Request.Builder()
265316
.url(urlString)
317+
.header("User-Agent",userAgent)
266318
.post(requestBody)
267319
.build()
268320

example/ios/Podfile.lock

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ PODS:
77
- hermes-engine (0.74.1):
88
- hermes-engine/Pre-built (= 0.74.1)
99
- hermes-engine/Pre-built (0.74.1)
10-
- logicwind-react-native-matomo-tracker (0.3.2):
10+
- logicwind-react-native-matomo-tracker (0.3.3):
1111
- DoubleConversion
1212
- glog
1313
- hermes-engine
@@ -1376,7 +1376,7 @@ SPEC CHECKSUMS:
13761376
fmt: 4c2741a687cc09f0634a2e2c72a838b99f1ff120
13771377
glog: c5d68082e772fa1c511173d6b30a9de2c05a69a2
13781378
hermes-engine: 16b8530de1b383cdada1476cf52d1b52f0692cbc
1379-
logicwind-react-native-matomo-tracker: 3875a57609e26fb4af6b2998adc3db7421d5acf6
1379+
logicwind-react-native-matomo-tracker: eefe6c3abc9a2e54ac2c73a74ec75da5b2f20edf
13801380
MatomoTracker: 1f3772a41c27393067d0126071afe6ae1c7f739e
13811381
RCT-Folly: 02617c592a293bd6d418e0a88ff4ee1f88329b47
13821382
RCTDeprecation: efb313d8126259e9294dc4ee0002f44a6f676aba

example/src/App.tsx

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import {
1818
setUserId,
1919
setVisitorId,
2020
startSession,
21+
trackCampaign,
2122
trackDispatch,
2223
trackDownload,
2324
trackEvent,
@@ -27,14 +28,14 @@ import {
2728
trackOutlink,
2829
trackScreen,
2930
trackSearch,
30-
3131
} from '@logicwind/react-native-matomo-tracker';
3232

3333
export default function App() {
3434
const [result] = React.useState<number | undefined>();
3535

3636
React.useEffect(() => {
37-
createTracker("https://your-matomo-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
38+
setLogger()
3839
}, []);
3940

4041
return (
@@ -43,6 +44,15 @@ export default function App() {
4344
<View style={styles.container}>
4445
<Text>Matomo Tracking {result}</Text>
4546

47+
<Pressable
48+
style={styles.button}
49+
onPress={() => {
50+
trackCampaign("Home screen","rntestApp://home?mtm_campaign=2020_august_promo&mtm_source=google&mtm_medium=email&mtm_keyword=2020 august promo&mtm_content=primary-cta")
51+
}}
52+
>
53+
<Text style={styles.buttonText}>Track Campaign</Text>
54+
</Pressable>
55+
4656
<Pressable
4757
style={styles.button}
4858
onPress={() => {

ios/ReactNativeMatomoTracker.mm

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -39,14 +39,9 @@ @interface RCT_EXTERN_MODULE(ReactNativeMatomoTracker, NSObject)
3939

4040
RCT_EXTERN_METHOD(enableTracking)
4141

42-
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)
43-
44-
45-
46-
47-
48-
42+
RCT_EXTERN_METHOD(trackCampaign:(NSString *)title withCampaignUrl:(NSString *)campaignUrl)
4943

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)
5045

5146

5247

ios/ReactNativeMatomoTracker.swift

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ class ReactNativeMatomoTracker: NSObject {
66

77
var matomoTracker: MatomoTracker?
88
var baseURL = "";
9+
var site_id = "";
910
var authToken = "";
1011
var _id = "";
1112
override init() {
@@ -21,8 +22,10 @@ class ReactNativeMatomoTracker: NSObject {
2122
func createTracker(uri:String,siteId:String,token:String) {
2223
authToken = token
2324
let queue = UserDefaultsQueue(UserDefaults.standard, autoSave: true)
25+
2426
baseURL = uri
25-
27+
site_id = siteId
28+
2629
let dispatcher = URLSessionDispatcher(baseURL: URL(string:baseURL)!)
2730
matomoTracker = MatomoTracker(siteId: siteId, queue: queue, dispatcher: dispatcher)
2831
matomoTracker?.userId = _id;
@@ -115,7 +118,29 @@ class ReactNativeMatomoTracker: NSObject {
115118

116119
}
117120

118-
121+
@objc(trackCampaign:withCampaignUrl:)
122+
func trackCampaign(title:String,campaignUrl:String) {
123+
124+
if let campaignUrl = URL(string: campaignUrl) {
125+
if let components = URLComponents(url: campaignUrl, resolvingAgainstBaseURL: false),
126+
let queryItems = components.queryItems {
127+
var campaignParameters = [String: String]()
128+
for queryItem in queryItems {
129+
if let value = queryItem.value {
130+
campaignParameters[queryItem.name] = value
131+
}
132+
}
133+
134+
matomoTracker?.track(view: ["campaign"], url: campaignUrl)
135+
matomoTracker?.dispatch()
136+
}
137+
138+
} else {
139+
print("Invalid URL string")
140+
}
141+
142+
}
143+
119144
@objc(trackMedia:withMediaId:withMediaTitle:withPlayerName:withMediaType:withMediaResource:withMediaStatus:withMediaLength:withMediaProgress:withMediaTTP:withMediaWidth:withMediaHeight:withMediaSE:withMediaFullScreen:)
120145
func trackMediaEvent(
121146
siteId: String,

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@logicwind/react-native-matomo-tracker",
3-
"version": "0.3.3",
3+
"version": "0.3.4",
44
"description": "React-native plugin for matomo analytics",
55
"main": "lib/commonjs/index",
66
"module": "lib/module/index",

src/index.tsx

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -17,67 +17,71 @@ const ReactNativeMatomoTracker = NativeModules.ReactNativeMatomoTracker
1717
}
1818
);
1919

20-
export function createTracker(uri: String, siteId: Number,token:String=""): Promise<number> {
20+
export function createTracker(uri: String, siteId: Number,token:String="") {
2121
return ReactNativeMatomoTracker.createTracker(uri, Platform.OS=="ios"?siteId.toString() :siteId,token);
2222
}
2323

24-
export function trackScreen(screenName: String, title: String): Promise<number> {
24+
export function trackScreen(screenName: String, title: String) {
2525
return ReactNativeMatomoTracker.trackScreen(screenName, title);
2626
}
2727

28-
export function trackEvent(category:String,action:String,name:String="",value:Number=0): Promise<number> {
28+
export function trackEvent(category:String,action:String,name:String="",value:Number=0) {
2929
return ReactNativeMatomoTracker.trackEvent(category,action,name,value);
3030
}
3131

32-
export function trackDispatch(): Promise<number> {
32+
export function trackDispatch(){
3333
return ReactNativeMatomoTracker.trackDispatch();
3434
}
3535

36-
export function trackOutlink(url:String): Promise<number> {
36+
export function trackOutlink(url:String) {
3737
return ReactNativeMatomoTracker.trackOutlink(url);
3838
}
3939

40-
export function trackSearch(keyword:String): Promise<number> {
40+
export function trackSearch(keyword:String) {
4141
return ReactNativeMatomoTracker.trackSearch(keyword);
4242
}
4343

44-
export function trackImpression(contentName:String): Promise<number> {
44+
export function trackImpression(contentName:String){
4545
return ReactNativeMatomoTracker.trackImpression(contentName);
4646
}
4747

48-
export function trackInteraction(contentName:String,contentInteraction:String): Promise<number> {
48+
export function trackInteraction(contentName:String,contentInteraction:String) {
4949
return ReactNativeMatomoTracker.trackInteraction(contentName,contentInteraction);
5050
}
5151

52-
export function trackDownload(category:String,action:String,url:String): Promise<number> {
52+
export function trackDownload(category:String,action:String,url:String){
5353
return ReactNativeMatomoTracker.trackDownload(category,action,url);
5454
}
5555

56-
export function setUserId(id:String): Promise<number> {
56+
export function setUserId(id:String) {
5757
return ReactNativeMatomoTracker.setUserId(id);
5858
}
5959

60-
export function setVisitorId(visitorId:String): Promise<number> {
60+
export function setVisitorId(visitorId:String) {
6161
return ReactNativeMatomoTracker.setVisitorId(visitorId);
6262
}
6363

64-
export function disableTracking(): Promise<number> {
64+
export function disableTracking() {
6565
return ReactNativeMatomoTracker.disableTracking();
6666
}
6767

68-
export function enableTracking(): Promise<number> {
68+
export function enableTracking() {
6969
return ReactNativeMatomoTracker.enableTracking();
7070
}
7171

7272

73-
export function setLogger(): Promise<number> {
73+
export function setLogger(){
7474
return ReactNativeMatomoTracker.setLogger();
7575
}
7676

77-
export function startSession(): Promise<number> {
77+
export function startSession() {
7878
return ReactNativeMatomoTracker.startSession();
7979
}
8080

81+
export function trackCampaign(title:String,campaignUrl:String) {
82+
return ReactNativeMatomoTracker.trackCampaign(title,campaignUrl);
83+
}
84+
8185
export function trackMediaEvent(
8286
{siteId,mediaId,mediaTitle,playerName,mediaType,mediaResource,mediaStatus,mediaLength="",mediaProgress="",mediaTTP="",mediaWidth="",mediaHeight="",mediaSE="",mediaFullScreen=""}:{
8387
siteId: String,

0 commit comments

Comments
 (0)