Skip to content

Commit 79f2e81

Browse files
Merge branch 'master' into ar2rsawseen/master
2 parents 62ce756 + 3d82f1f commit 79f2e81

File tree

7 files changed

+114
-6
lines changed

7 files changed

+114
-6
lines changed

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,12 @@ Fixes:
33
- [languages] Calculated total users percentage correctly
44
- [countly-edge] Add import from Countly Edge Server
55

6+
Features:
7+
- [hooks] Support sending header information for HTTP actions
8+
9+
Enterprise fixes:
10+
- [ab-testing] Mismatching user counts between ab-testing and user profiles
11+
612
## Version 24.05.24
713
Enterprise fixes:
814
- [ldap] Fixed issues that would lead to configuration options not being picked up

plugins/hooks/api/api.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,7 @@ const CheckEffectProperties = function(effect) {
234234
if (effect) {
235235
if (effect.type === "HTTPEffect") {
236236
rules.url = { 'required': true, 'type': 'URL', 'regex': '^(?!.*(?:localhost|127\\.0\\.0\\.1|\\[::1\\])).*(?:https?|ftp):\\/\\/(?:[a-zA-Z0-9-]+(?:\\.[a-zA-Z0-9-]+)+|\\[(?:[a-fA-F0-9]{1,4}:){7}[a-fA-F0-9]{1,4}\\])(?::\\d{1,5})?(?:\\/\\S*)?$' };
237+
rules.headers = { 'required': false, 'type': 'Object' };
237238
}
238239
}
239240
return rules;

plugins/hooks/api/parts/effects/http.js

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,19 +41,23 @@ class HTTPEffect {
4141
async run(options) {
4242
const logs = [];
4343
const {effect, params, rule, effectStep, _originalInput} = options;
44-
const {method, url, requestData} = effect.configuration;
44+
const {method, url, requestData, headers} = effect.configuration;
4545
try {
4646
const parsedURL = utils.parseStringTemplate(url, params);
4747
const parsedRequestData = utils.parseStringTemplate(requestData, params, method);
4848
log.d("[hook http effect ]", parsedURL, parsedRequestData, method);
4949

5050
// todo: assemble params for request;
5151
// const params = {}
52-
52+
const requestHeaders = headers || {};
5353
const methodOption = method && method.toLowerCase() || "get";
5454
switch (methodOption) {
5555
case 'get':
56-
await request.get({uri: parsedURL + "?" + parsedRequestData, timeout: this._timeout}, function(e, r, body) {
56+
await request.get({
57+
uri: parsedURL + "?" + parsedRequestData,
58+
timeout: this._timeout,
59+
headers: requestHeaders
60+
}, function(e, r, body) {
5761
log.d("[http get effect]", e, body);
5862
if (e) {
5963
logs.push(`Error: ${e.message}`);
@@ -91,6 +95,7 @@ class HTTPEffect {
9195
uri: parsedURL,
9296
json: parsedJSON,
9397
timeout: this._timeout,
98+
headers: requestHeaders
9499
},
95100
function(e, r, body) {
96101
log.d("[httpeffects]", e, body, rule);

plugins/hooks/frontend/public/javascripts/countly.views.js

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,7 @@
143143
data: function() {
144144
return {
145145
methodOptions: [{label: 'GET', value: 'get'}, {label: 'POST', value: 'post'}],
146+
headers: []
146147
};
147148
},
148149
props: {
@@ -152,10 +153,40 @@
152153
},
153154
mounted: function() {
154155
this.value.requestData = _.unescape(this.value.requestData);
156+
// Initialize headers from saved configuration
157+
if (this.value.headers) {
158+
this.headers = Object.entries(this.value.headers).map(([key, value]) => ({key, value}));
159+
}
155160
},
156161
methods: {
157162
textChange: function(event) {
158163
this.value.requestData = _.unescape(event.currentTarget.value);
164+
},
165+
addHeader: function() {
166+
this.headers.push({key: '', value: ''});
167+
this.updateHeaders();
168+
},
169+
removeHeader: function(index) {
170+
this.headers.splice(index, 1);
171+
this.updateHeaders();
172+
},
173+
updateHeaders: function() {
174+
// Convert headers array to object format and update value
175+
const headerObj = {};
176+
this.headers.forEach(h => {
177+
if (h.key && h.value) {
178+
headerObj[h.key] = h.value;
179+
}
180+
});
181+
this.value.headers = headerObj;
182+
}
183+
},
184+
watch: {
185+
headers: {
186+
deep: true,
187+
handler: function() {
188+
this.updateHeaders();
189+
}
159190
}
160191
}
161192
});

plugins/hooks/frontend/public/localization/hooks.properties

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ configs.help.hooks-timeWindowForRequestLimit=The time window for the request lim
4646
hooks.InternalEventTrigger = Internal Actions
4747
hooks.trigger-api-endpoint-uri= API Endpoint
4848
hooks.trigger-introduction = Introduction
49-
hooks.trigger-api-endpoint-intro-content = <span>Send a GET request with query string parameter payload as a JSON string to the below URL:</span><br/><span class="url"> {0}</span>
49+
hooks.trigger-api-endpoint-intro-content = <span>Send a GET request with query string parameter "payload" as a JSON string to the below URL:</span><br/><span class="url"> {0}</span>
5050
hooks.APIEndPointTrigger = API Endpoint
5151
hooks.internal-event-selector-title = Internal Actions
5252
hooks.internal-event-selector-placeholder = Please select an internal action
@@ -118,7 +118,7 @@ hooks.remove-action = Remove action
118118
hooks.send-email = Email addresses to send the data to
119119
hooks.http-intro = Query string (for GET) or request body (for POST)
120120
hooks.trigger-via = Trigger Type
121-
hooks.api-trigger-intro = Send a GET request with query string parameter payload as a JSON string
121+
hooks.api-trigger-intro = Send a GET request with query string parameter "payload" as a JSON string
122122
hooks.copy-url = Copy URL
123123
hooks.incoming-data = Data to trigger this hook
124124
hooks.filter-rule = USE FILTERING RULE
@@ -143,4 +143,11 @@ hooks.actions-tips = Select the actions the hook will do upon being triggered. Y
143143
hooks.application-tips = The app(s) for which you want to create a hook.
144144
hooks.trigger-count-tips = Number of times the hook has been triggered.
145145
hooks.trigger-action-tips = Identifies the trigger for the hook, and the actions that show the method through which data will be sent.
146-
hooks.trigger-save-failed = Hook could not be saved.
146+
hooks.trigger-save-failed = Hook could not be saved.
147+
148+
# HTTP Headers related texts
149+
hooks.http-headers = HTTP Headers
150+
hooks.add-http-header = Add HTTP Header
151+
hooks.remove-http-header = Remove Header
152+
hooks.header-key = Header Key
153+
hooks.header-value = Header Value

plugins/hooks/frontend/public/stylesheets/vue-main.scss

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -283,4 +283,22 @@
283283
cursor:pointer;
284284
font-size: 12px;
285285
font-weight: 500;
286+
}
287+
288+
289+
.hooks-http-headers {
290+
&__validation {
291+
display: contents;
292+
}
293+
294+
&__remove-button {
295+
color: #D23F00;
296+
font-size: 16px;
297+
font-weight: 500;
298+
cursor: pointer;
299+
}
300+
301+
&__remove-button:hover {
302+
background-color: transparent;
303+
}
286304
}

plugins/hooks/frontend/public/templates/vue-effects.html

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,5 +95,45 @@
9595
</validation-provider>
9696
</div>
9797

98+
<!-- HTTP Headers Section -->
99+
<div class="cly-vue-drawer-step__section">
100+
<div class="text-medium text-heading">
101+
{{i18n('hooks.http-headers')}}
102+
</div>
103+
<div v-for="(header, index) in headers" :key="index" class="hooks-http-headers bu-mb-2">
104+
<div class="bu-is-flex bu-is-align-items-center">
105+
<validation-provider name="action-http-header-key" rules="required" class="hooks-http-headers__validation">
106+
<el-input
107+
:placeholder="i18n('hooks.header-key')"
108+
class="bu-mr-2"
109+
style="width:40%;"
110+
v-model="header.key">
111+
</el-input>
112+
</validation-provider>
113+
<validation-provider name="action-http-header-value" rules="required" class="hooks-http-headers__validation">
114+
<el-input
115+
:placeholder="i18n('hooks.header-value')"
116+
class="bu-mr-2"
117+
style="width:40%; flex:1"
118+
v-model="header.value">
119+
</el-input>
120+
</validation-provider>
121+
<el-button
122+
@click="removeHeader(index)"
123+
class="hooks-http-headers__remove-button color-red-100"
124+
type="text"
125+
>
126+
<i class="cly-io cly-io-trash"></i>
127+
</el-button>
128+
</div>
129+
</div>
130+
<el-button
131+
@click="addHeader"
132+
class="hooks-http-headers__add-button bg-light-blue-100 color-blue-100 bu-mt-2"
133+
type="text"
134+
>
135+
+ {{i18n('hooks.add-http-header')}}
136+
</el-button>
137+
</div>
98138
</div>
99139
</script>

0 commit comments

Comments
 (0)