@24i/bigscreen-sdk 1.0.41 → 1.0.42-alpha.2709
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.
- package/README.md +2 -3
- package/ci/is_ci_job_skippable.sh +153 -0
- package/package.json +1 -1
- package/packages/analytics/src/clients/TealiumAnalytics/TealiumAnalytics.ts +12 -3
- package/packages/analytics/src/clients/TealiumAnalytics/mappers/__mocks__/mediaPayload.ts +14 -14
- package/packages/analytics/src/clients/TealiumAnalytics/mappers/mapSceneView.ts +1 -1
- package/packages/analytics/src/clients/TealiumAnalytics/types.ts +2 -1
- package/packages/analytics/src/clients/TwentyFourIQ/TwentyFourIQClient.ts +11 -22
- package/packages/analytics/src/clients/TwentyFourIQ/constants.ts +1 -0
- package/packages/analytics/src/clients/TwentyFourIQ/mappers/mapBase.ts +4 -3
- package/packages/analytics/src/clients/TwentyFourIQ/types.ts +2 -2
package/README.md
CHANGED
|
@@ -6,9 +6,8 @@ sidebar_label: README
|
|
|
6
6
|
---
|
|
7
7
|
|
|
8
8
|
# SmartApps BIGscreen SDK
|
|
9
|
-
|
|
10
|
-
[](https://coveralls.io/github/24i/smartapps-bigscreen-sdk?branch=development)
|
|
9
|
+
[](https://github.com/24i/smartapps-bigscreen-sdk/actions/workflows/pull-request.yml)
|
|
10
|
+
[](https://sonarcloud.io/summary/new_code?id=24i_smartapps-bigscreen-sdk)
|
|
12
11
|
|
|
13
12
|
* [GitHub](https://github.com/24i/smartapps-bigscreen-sdk)
|
|
14
13
|
* [Confluence](https://24imedia.atlassian.net/wiki/spaces/PRDNGBIGSCR/overview)
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
|
|
3
|
+
: '
|
|
4
|
+
Resolves whether CI job can be skipped or not.
|
|
5
|
+
|
|
6
|
+
It requires to be executed with "source", as the script exports result as a variable
|
|
7
|
+
which needs to be processed outside the script.
|
|
8
|
+
|
|
9
|
+
- EXPORTS:
|
|
10
|
+
Exports numeric variable IS_CI_JOB_SKIPPABLE,
|
|
11
|
+
where 0 represents not skippable build and 1 represent skippable build.
|
|
12
|
+
|
|
13
|
+
- PARAMETERS:
|
|
14
|
+
File paths or glob patterns with paths to files which are not relevant for the CI job.
|
|
15
|
+
Each glob pattern has to be wrapped into double quotes.
|
|
16
|
+
|
|
17
|
+
- USAGE:
|
|
18
|
+
source <path/to/script.sh> "filePathOrGlob1" "filePathOrGlob2" ... "filePathOrGlobN"
|
|
19
|
+
|
|
20
|
+
- EXAMPLE:
|
|
21
|
+
source path/to/script.sh "docs/**/*" ".eslintrc.json"
|
|
22
|
+
if [[ "$IS_CI_JOB_SKIPPABLE" -eq 1 ]]; then
|
|
23
|
+
# job is skippable, do something here
|
|
24
|
+
fi
|
|
25
|
+
'
|
|
26
|
+
|
|
27
|
+
# Includes filenames beginning with a ‘.’ in the results of filename expansion.
|
|
28
|
+
# The filenames ‘.’ and ‘..’ must always be matched explicitly, even if dotglob is set.
|
|
29
|
+
shopt -s dotglob
|
|
30
|
+
|
|
31
|
+
# Patterns which fail to match filenames during filename expansion will not result in an expansion error.
|
|
32
|
+
shopt -u failglob
|
|
33
|
+
|
|
34
|
+
# The pattern ‘**’ used in a filename expansion context will match all files and zero or more directories and subdirectories.
|
|
35
|
+
shopt -s globstar
|
|
36
|
+
|
|
37
|
+
# Bash allows filename patterns which match no files to expand to a null string, rather than themselves.
|
|
38
|
+
shopt -s nullglob
|
|
39
|
+
|
|
40
|
+
function printFormattedArrayItems () {
|
|
41
|
+
FUNCTION_INPUT_ARRAY=("$@")
|
|
42
|
+
for i in "${FUNCTION_INPUT_ARRAY[@]}"; do
|
|
43
|
+
echo " - $i"
|
|
44
|
+
done
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
# Exported numeric variable with the result.
|
|
48
|
+
# 0 represents not skippable build, 1 represent skippable build.
|
|
49
|
+
IS_CI_JOB_SKIPPABLE=0
|
|
50
|
+
|
|
51
|
+
# Printed when build is skippable.
|
|
52
|
+
RESULT_TRUE_STRING="It's possible to skip the CI job!"
|
|
53
|
+
|
|
54
|
+
# Printed when build is not skippable.
|
|
55
|
+
RESULT_FALSE_STRING="It's NOT possible to skip the CI job!"
|
|
56
|
+
|
|
57
|
+
# Variable for providing details about the result.
|
|
58
|
+
RESULT_REASON_STRING="N/A"
|
|
59
|
+
|
|
60
|
+
# The range of commits that were included in the push or pull request.
|
|
61
|
+
# Example "SHA1...SHA2".
|
|
62
|
+
COMMIT_RANGE=""
|
|
63
|
+
|
|
64
|
+
echo ""
|
|
65
|
+
echo "==========================================================================================="
|
|
66
|
+
echo "RESOLVING THE POSSIBILITY TO SKIP THE CI JOB..."
|
|
67
|
+
|
|
68
|
+
# GitHub Actions CI
|
|
69
|
+
if [[ "$GITHUB_EVENT_NAME" == "pull_request" ]]; then
|
|
70
|
+
# This is a Pull Request event
|
|
71
|
+
if [[ -z "$GITHUB_BASE_REF" ]]; then
|
|
72
|
+
RESULT_REASON_STRING="GITHUB_BASE_REF is empty for this CI build."
|
|
73
|
+
elif [[ -z "$GITHUB_HEAD_REF" ]]; then
|
|
74
|
+
RESULT_REASON_STRING="GITHUB_HEAD_REF is empty for this CI build."
|
|
75
|
+
else
|
|
76
|
+
COMMIT_RANGE="origin/${GITHUB_BASE_REF}...origin/${GITHUB_HEAD_REF}"
|
|
77
|
+
echo "set COMMIT_RANGE for PR (GA) to \"${COMMIT_RANGE}\""
|
|
78
|
+
fi
|
|
79
|
+
else
|
|
80
|
+
# This is not Pull Request event (it is for example push)
|
|
81
|
+
if [[ "$GA_EVENT_BEFORE" == "0000000000000000000000000000000000000000" ]]; then
|
|
82
|
+
# variable it is set to zeros for the initial commit of a new branch
|
|
83
|
+
RESULT_REASON_STRING="GA_EVENT_BEFORE is zeros for this CI build."
|
|
84
|
+
elif [[ -z "$GA_EVENT_BEFORE" ]]; then
|
|
85
|
+
RESULT_REASON_STRING="GA_EVENT_BEFORE is empty for this CI build."
|
|
86
|
+
elif [[ -z "$GA_EVENT_AFTER" ]]; then
|
|
87
|
+
RESULT_REASON_STRING="GA_EVENT_AFTER is empty for this CI build."
|
|
88
|
+
else
|
|
89
|
+
COMMIT_RANGE="${GA_EVENT_BEFORE}...${GA_EVENT_AFTER}"
|
|
90
|
+
echo "set COMMIT_RANGE for \"${GITHUB_EVENT_NAME}\" (GA) to \"${COMMIT_RANGE}\""
|
|
91
|
+
fi
|
|
92
|
+
fi
|
|
93
|
+
|
|
94
|
+
if [[ ! -z "$COMMIT_RANGE" ]]; then
|
|
95
|
+
CHANGED_FILES_ARRAY=()
|
|
96
|
+
while IFS= read -r line; do
|
|
97
|
+
CHANGED_FILES_ARRAY+=("${line}")
|
|
98
|
+
done < <(git diff --name-only "$COMMIT_RANGE")
|
|
99
|
+
|
|
100
|
+
IRRELEVANT_FILES_INPUT_ARRAY=($@) # array with all params
|
|
101
|
+
|
|
102
|
+
RESOLVED_RELEVANT_FILES=()
|
|
103
|
+
RESOLVED_IRRELEVANT_FILES=()
|
|
104
|
+
for i in "${CHANGED_FILES_ARRAY[@]}"; do
|
|
105
|
+
if [[ "${IRRELEVANT_FILES_INPUT_ARRAY[*]}" =~ $i ]]; then
|
|
106
|
+
RESOLVED_IRRELEVANT_FILES+=("$i")
|
|
107
|
+
else
|
|
108
|
+
RESOLVED_RELEVANT_FILES+=("$i")
|
|
109
|
+
fi
|
|
110
|
+
done
|
|
111
|
+
|
|
112
|
+
echo ""
|
|
113
|
+
echo "Provided filter for irrelevant files ($#):"
|
|
114
|
+
printFormattedArrayItems "$@"
|
|
115
|
+
|
|
116
|
+
echo ""
|
|
117
|
+
echo "Resolved provided filter for irrelevant files (${#IRRELEVANT_FILES_INPUT_ARRAY[@]}):"
|
|
118
|
+
printFormattedArrayItems "${IRRELEVANT_FILES_INPUT_ARRAY[@]}"
|
|
119
|
+
|
|
120
|
+
echo ""
|
|
121
|
+
echo "Detected changed files from GIT (${#CHANGED_FILES_ARRAY[@]}):"
|
|
122
|
+
printFormattedArrayItems "${CHANGED_FILES_ARRAY[@]}"
|
|
123
|
+
|
|
124
|
+
echo ""
|
|
125
|
+
echo "Changed files resolved as relevant for the CI job (${#RESOLVED_RELEVANT_FILES[@]}):"
|
|
126
|
+
printFormattedArrayItems "${RESOLVED_RELEVANT_FILES[@]}"
|
|
127
|
+
|
|
128
|
+
echo ""
|
|
129
|
+
echo "Changed files resolved as irrelevant for the CI job: (${#RESOLVED_IRRELEVANT_FILES[@]}):"
|
|
130
|
+
printFormattedArrayItems "${RESOLVED_IRRELEVANT_FILES[@]}"
|
|
131
|
+
|
|
132
|
+
if [[ ${#RESOLVED_RELEVANT_FILES[@]} -eq 0 ]]; then
|
|
133
|
+
IS_CI_JOB_SKIPPABLE=1
|
|
134
|
+
RESULT_REASON_STRING="With given filter, all changed files are irrelevant for this CI job."
|
|
135
|
+
else
|
|
136
|
+
RESULT_REASON_STRING="With given filter, there are changes which have to be processed in this CI job."
|
|
137
|
+
fi
|
|
138
|
+
fi
|
|
139
|
+
|
|
140
|
+
echo ""
|
|
141
|
+
echo "The result:"
|
|
142
|
+
if [[ "$IS_CI_JOB_SKIPPABLE" -eq 1 ]]; then
|
|
143
|
+
echo " $RESULT_TRUE_STRING"
|
|
144
|
+
else
|
|
145
|
+
echo " $RESULT_FALSE_STRING"
|
|
146
|
+
fi
|
|
147
|
+
echo ""
|
|
148
|
+
echo "The reason of the result:"
|
|
149
|
+
echo " $RESULT_REASON_STRING"
|
|
150
|
+
echo "==========================================================================================="
|
|
151
|
+
echo ""
|
|
152
|
+
|
|
153
|
+
export IS_CI_JOB_SKIPPABLE
|
package/package.json
CHANGED
|
@@ -103,7 +103,7 @@ export class TealiumAnalytics implements AnalyticsClient {
|
|
|
103
103
|
platform_type: platformType ?? BIGSCREEN_PLATFORM_TYPE,
|
|
104
104
|
app_type: appType ?? BIGSCREEN_APP_TYPE,
|
|
105
105
|
ott_type: BIGSCREEN_OTT_TYPE,
|
|
106
|
-
app_id: `${entity} ${language}
|
|
106
|
+
app_id: `${entity} ${language} : ${this.appVersion}`,
|
|
107
107
|
};
|
|
108
108
|
}
|
|
109
109
|
|
|
@@ -157,9 +157,18 @@ export class TealiumAnalytics implements AnalyticsClient {
|
|
|
157
157
|
}
|
|
158
158
|
const eventBody = {
|
|
159
159
|
...this.constantPayload,
|
|
160
|
-
...mappingFunction(triggerName, payload as Payload),
|
|
160
|
+
...mappingFunction(triggerName, payload as Payload, this.config),
|
|
161
161
|
};
|
|
162
|
-
|
|
162
|
+
const filteredEventBody: TeaResult = Object.entries(eventBody).reduce(
|
|
163
|
+
(acc: any, [key, value]) => {
|
|
164
|
+
if (value != null && value !== '') {
|
|
165
|
+
acc[key] = value;
|
|
166
|
+
}
|
|
167
|
+
return acc;
|
|
168
|
+
},
|
|
169
|
+
{} as TeaResult,
|
|
170
|
+
);
|
|
171
|
+
if (eventBody) await this.sendEvent(filteredEventBody);
|
|
163
172
|
} catch (e) {
|
|
164
173
|
console.warn(`[${this.name}] Error onEvent: `, e);
|
|
165
174
|
}
|
|
@@ -6,15 +6,14 @@ export const MEDIA_PAYLOAD: Payload = {
|
|
|
6
6
|
title: 'Test Video',
|
|
7
7
|
url: 'https://example.com/video',
|
|
8
8
|
contentType: 'video/mp4',
|
|
9
|
-
externalId: '',
|
|
10
9
|
percent: 2,
|
|
11
10
|
provider: 'provider',
|
|
12
11
|
assetId: '12345',
|
|
13
12
|
app_id: 'app_id',
|
|
14
13
|
app_type: 'html5',
|
|
15
|
-
sceneName: '',
|
|
16
|
-
sceneId: '',
|
|
17
|
-
sceneType: '',
|
|
14
|
+
sceneName: 'pageName',
|
|
15
|
+
sceneId: 'categories',
|
|
16
|
+
sceneType: 'vod',
|
|
18
17
|
sessionId: 1,
|
|
19
18
|
sessionNumber: 1,
|
|
20
19
|
userId: '10',
|
|
@@ -25,18 +24,20 @@ export const MEDIA_PAYLOAD: Payload = {
|
|
|
25
24
|
deviceType: 'smarttv',
|
|
26
25
|
searchTerm: '',
|
|
27
26
|
itemId: '',
|
|
27
|
+
pubDate: '2012/02/12',
|
|
28
28
|
message: 'error message',
|
|
29
29
|
section: 'BROWSE',
|
|
30
|
-
subcontentType: '',
|
|
30
|
+
subcontentType: 'section',
|
|
31
|
+
seriesTitle: 'section',
|
|
31
32
|
};
|
|
32
33
|
|
|
33
34
|
export const TEALIUM_PAGEINFO_PAYLOAD = {
|
|
34
|
-
categories: '',
|
|
35
|
+
categories: 'categories',
|
|
35
36
|
content_type: 'video',
|
|
36
|
-
page_name: '',
|
|
37
|
-
page_title: '',
|
|
38
|
-
section: '',
|
|
39
|
-
subcontent_type: '',
|
|
37
|
+
page_name: 'pageName',
|
|
38
|
+
page_title: 'pageName',
|
|
39
|
+
section: 'section',
|
|
40
|
+
subcontent_type: 'section',
|
|
40
41
|
};
|
|
41
42
|
|
|
42
43
|
export const TEALIUM_STATIC_CORE_PAYLOAD = {
|
|
@@ -44,7 +45,7 @@ export const TEALIUM_STATIC_CORE_PAYLOAD = {
|
|
|
44
45
|
tealium_profile: 'main',
|
|
45
46
|
tealium_environment: 'dev',
|
|
46
47
|
tealium_datasource: 'abc',
|
|
47
|
-
app_id: 'auto english:v1.0-test',
|
|
48
|
+
app_id: 'auto english : v1.0-test',
|
|
48
49
|
app_type: 'html5',
|
|
49
50
|
entity: 'auto',
|
|
50
51
|
language: 'english',
|
|
@@ -61,10 +62,9 @@ export const TEALIUM_MEDIA_PAYLOAD = {
|
|
|
61
62
|
byline: 'N/A',
|
|
62
63
|
canonical_url: 'https://example.com/video',
|
|
63
64
|
media_type: 'video/mp4',
|
|
64
|
-
pub_date: '',
|
|
65
|
-
tags: '',
|
|
65
|
+
pub_date: '2012/02/12',
|
|
66
66
|
video_length: 120,
|
|
67
67
|
video_name: 'Test Video',
|
|
68
68
|
video_position: 60,
|
|
69
|
-
video_series_title: '',
|
|
69
|
+
video_series_title: 'section',
|
|
70
70
|
};
|
|
@@ -14,25 +14,18 @@ import { CorePayload, DeviceInfo, EventBody, Payload, SessionInfo } from './type
|
|
|
14
14
|
// eslint-disable-next-line no-magic-numbers
|
|
15
15
|
const SESSION_TIMEOUT = 30 * MINUTE_IN_MS;
|
|
16
16
|
|
|
17
|
-
const
|
|
17
|
+
const TWENTY_FOUR_IQ_SESSION_COUNTER = '24iQ_session_counter';
|
|
18
18
|
|
|
19
19
|
export class TwentyFourIQClient implements AnalyticsClient {
|
|
20
20
|
name = '24iQ';
|
|
21
21
|
|
|
22
|
-
deviceInfo = {
|
|
23
|
-
manufacturer: '',
|
|
24
|
-
platform: '',
|
|
25
|
-
platformVersion: '',
|
|
26
|
-
deviceId: '',
|
|
27
|
-
appVersion: '',
|
|
28
|
-
applicationId: '',
|
|
29
|
-
deviceType: '',
|
|
30
|
-
};
|
|
31
|
-
|
|
32
22
|
constantPayload: CorePayload & SessionInfo & DeviceInfo = {
|
|
33
23
|
sessionNumber: 0,
|
|
34
24
|
sessionId: 0,
|
|
35
|
-
|
|
25
|
+
appVersion: '',
|
|
26
|
+
deviceId: '',
|
|
27
|
+
manufacturer: '',
|
|
28
|
+
platform: '',
|
|
36
29
|
};
|
|
37
30
|
|
|
38
31
|
sessionTimeout = createTimeout();
|
|
@@ -46,24 +39,20 @@ export class TwentyFourIQClient implements AnalyticsClient {
|
|
|
46
39
|
}
|
|
47
40
|
|
|
48
41
|
async init() {
|
|
49
|
-
this.
|
|
50
|
-
this.
|
|
51
|
-
this.
|
|
52
|
-
this.
|
|
42
|
+
this.constantPayload.deviceId = await device.getUuid();
|
|
43
|
+
this.constantPayload.manufacturer = await device.getManufacturerName();
|
|
44
|
+
this.constantPayload.platform = await device.getPlatformName();
|
|
45
|
+
this.constantPayload.appVersion = this.appVersion;
|
|
53
46
|
await this.startSession();
|
|
54
47
|
}
|
|
55
48
|
|
|
56
49
|
async startSession() {
|
|
57
50
|
const sessionNumber = parseInt(
|
|
58
|
-
await Storage.getItem(
|
|
51
|
+
await Storage.getItem(TWENTY_FOUR_IQ_SESSION_COUNTER) ?? '0', 10,
|
|
59
52
|
) + 1;
|
|
60
53
|
this.constantPayload.sessionNumber = sessionNumber;
|
|
61
54
|
this.constantPayload.sessionId = generateSessionId();
|
|
62
|
-
|
|
63
|
-
this.constantPayload.platform = this.deviceInfo.platform;
|
|
64
|
-
this.constantPayload.platformVersion = this.deviceInfo.platformVersion;
|
|
65
|
-
this.constantPayload.appVersion = this.appVersion;
|
|
66
|
-
await Storage.setItem(TWENYFOURIQ_SESSION_COUNTER, sessionNumber.toString());
|
|
55
|
+
await Storage.setItem(TWENTY_FOUR_IQ_SESSION_COUNTER, sessionNumber.toString());
|
|
67
56
|
this.isSessionActive = true;
|
|
68
57
|
this.setSessionTimeout();
|
|
69
58
|
}
|
|
@@ -92,6 +92,7 @@ export const TRIGGER_NAME_TO_24IQ_EVENTS: { [K in AnalyticsTriggers]?: EVENTS[];
|
|
|
92
92
|
[AnalyticsTriggers.SCROLL_75]: [EVENTS.SCROLL],
|
|
93
93
|
[AnalyticsTriggers.SCROLL_90]: [EVENTS.SCROLL],
|
|
94
94
|
[AnalyticsTriggers.APP_CLOSE]: [EVENTS.VIDEO_STOP, EVENTS.PLAYER_CLOSE],
|
|
95
|
+
// VERSION 2 ?
|
|
95
96
|
[AnalyticsTriggers.AD_LOADED]: [EVENTS.AD_LOADED],
|
|
96
97
|
[AnalyticsTriggers.AD_SKIPPED]: [EVENTS.AD_SKIPPED],
|
|
97
98
|
};
|
|
@@ -4,14 +4,15 @@ import { formatDateTime, getTimezoneOffsetString } from '../helper';
|
|
|
4
4
|
|
|
5
5
|
export const mapBase = (payload: Payload): BaseResult => {
|
|
6
6
|
const timestampDate = time.getCurrentTime();
|
|
7
|
-
const
|
|
7
|
+
const formattedTimestamp = getTimezoneOffsetString();
|
|
8
8
|
return {
|
|
9
9
|
session_id: payload.sessionId.toString(),
|
|
10
10
|
timestamp_initiated: formatDateTime(timestampDate),
|
|
11
11
|
device_id: payload.deviceId,
|
|
12
|
-
device_type:
|
|
12
|
+
device_type: 'SmartTV',
|
|
13
13
|
device_platform: payload.platform || '',
|
|
14
|
-
|
|
14
|
+
device_manufacturer: payload.manufacturer || '',
|
|
15
|
+
device_timezone: formattedTimestamp,
|
|
15
16
|
service_id: payload.serviceId || '',
|
|
16
17
|
user_id: payload.userId || '',
|
|
17
18
|
user_profile_id: payload.userProfileId,
|
|
@@ -27,7 +27,6 @@ export interface DeviceInfo {
|
|
|
27
27
|
appVersion: string,
|
|
28
28
|
manufacturer: string,
|
|
29
29
|
platform: string,
|
|
30
|
-
platformVersion: string,
|
|
31
30
|
deviceId: string,
|
|
32
31
|
}
|
|
33
32
|
|
|
@@ -37,7 +36,7 @@ export interface SceneInfo {
|
|
|
37
36
|
sceneType?: string,
|
|
38
37
|
}
|
|
39
38
|
|
|
40
|
-
export type Payload = CorePayload & SceneInfo & SessionInfo & UserInfo & AppInfo;
|
|
39
|
+
export type Payload = CorePayload & SceneInfo & SessionInfo & UserInfo & DeviceInfo & AppInfo;
|
|
41
40
|
|
|
42
41
|
export type EventBody = AnyPayload;
|
|
43
42
|
|
|
@@ -52,6 +51,7 @@ export type BaseResult = {
|
|
|
52
51
|
device_id: string;
|
|
53
52
|
device_type: string;
|
|
54
53
|
device_platform: string;
|
|
54
|
+
device_manufacturer: string;
|
|
55
55
|
device_timezone: string;
|
|
56
56
|
service_id: string;
|
|
57
57
|
user_id?: string;
|