Unomi use of UpdatePoperties event to enrich profil - apache-unomi

We are tring to enrich a profil using UpdateProperties event.
Something wrong, it didn't work.
Step of our process :
Search of the profil :
Use of the prive API /profiles/search
So we find a profil and get the profilId "60de10fe-e6ff-11ec-8fea-0242ac120002" for next step.
Enrich profil :
Use of the API public /context.json to post the json
{
"sessionId": null,
"profileId": "60de10fe-e6ff-11ec-8fea-0242ac120002",
"events": [
{
"itemType": "event",
"scope": "myScope",
"eventType": "updateProperties",
"properties": {
"update": {
"properties.age": "24"
},
"add": {
"properties.kids" : "1"
}
}
}
]
}
Response :
{
"profileId": "60de10fe-e6ff-11ec-8fea-0242ac120002",
"sessionId": null,
"profileProperties": null,
"sessionProperties": null,
"profileSegments": null,
"profileScores": null,
"filteringResults": null,
"processedEvents": 1,
"personalizations": null,
"trackedConditions": [
{
"parameterValues": {
"operator": "and",
"subConditions": [
{
"parameterValues": {
"formId": "zoneLeadFormEvent"
},
"type": "formEventCondition"
}
]
},
"type": "booleanCondition"
},
{
"parameterValues": {
"formId": "testFormTracking",
"pagePath": "/tracker/"
},
"type": "formEventCondition"
},
{
"parameterValues": {
"formId": "searchForm"
},
"type": "formEventCondition"
},
{
"parameterValues": {
"formId": "advancedSearchForm"
},
"type": "formEventCondition"
}
],
"anonymousBrowsing": false,
"consents": {}
}
Validation of the profile changes
Get /cxs/profiles/60de10fe-e6ff-11ec-8fea-0242ac120002
So, the properties are not updated.
We use a rules the merge the profil on a custom identifier :
{
"metadata": {
"id": "update_with_custom_identifier",
"name": "UpdateWithCustomIdentifier",
"description": "Copy my properties to profile properties on update"
},
"condition": {
"parameterValues": {
"subConditions": [
{
"parameterValues": {
},
"type": "updatePropertiesEventCondition"
}
],
"operator": "and"
},
"type": "booleanCondition"
},
"actions": [
{
"parameterValues": {
"mergeProfilePropertyValue": "eventProperty::target.properties.myIdentifier",
"mergeProfilePropertyName": "mergeCustomIdentifier"
},
"type": "mergeProfilesOnPropertyAction"
},
{
"parameterValues": {
},
"type": "allEventToProfilePropertiesAction"
}
]
}
What's the good method ?
Thanks in advance

Related

Google-Chat-API: Open dialog from posted message

I use bot to post cards with version 2 (сards_v2 property).
Cards are rendered as normal, but I want to add a Button to open Dialog. This does not work.
How can I achieve this?
I post to POST /v1/chat/channels/:channel_id/messages?
body:
{
"cards_v2": [{
"card": {
"header": {
"title": "Rolodex",
"subtitle": "Manage your contacts!",
"imageType": "CIRCLE",
"imageUrl": "https://www.gstatic.com/images/branding/product/2x/contacts_48dp.png"
},
"sections": [{
"widgets": [{
"buttonList": {
"buttons": [{
"text": "Add Contact",
"onClick": {
"action": {
"function": "openDialog",
"interaction": "OPEN_DIALOG"
}
}
}]
}
}]
}]
}
}]
}
Then I click on Button, and receive event:
{
"type": "CARD_CLICKED",
"eventTime": "2022-08-31T16:16:36.147391Z",
"message": {
"name": "spaces/:space_id/messages/YTyNVBNW-H4.YTyNVBNW-H4",
"sender": { ... },
"createTime": "2022-08-31T16:16:31.639439Z",
"thread": { ... },
"space": { ... },
"cardsV2": [{
"card": {
"header": {
"title": "Rolodex",
"subtitle": "Manage your contacts!",
"imageType": "CIRCLE",
"imageUrl": "https://www.gstatic.com/images/branding/product/2x/contacts_48dp.png"
},
"sections": [{
"widgets": [{
"buttonList": {
"buttons": [{
"text": "Add Contact",
"onClick": {
"action": {
"function": "openDialog"
}
}
}]
}
}]
}]
}
}],
"retentionSettings": {
"state": "PERMANENT"
}
},
"user": { ... },
"space": { ... },
"action": {
"actionMethodName": "openDialog"
},
"common": {
"hostApp": "CHAT",
"invokedFunction": "openDialog"
}
}
First: Event skips DialogEventType is REQUEST_DIALOG.
Second: When I respond with dialog response, but no dialog appears.
{
"actionResponse": {
"type": "DIALOG",
"dialogAction": {
"dialog": {
"body": {
"sections": [{
"header": "Add new contact",
"widgets": [{
"textInput": {
"name": "contactName",
"label": "Name",
"type": "SINGLE_LINE"
}
}, {
"buttonList": {
"buttons": [{
"text": "Next",
"onClick": {
"action": {
"function": "openSequentialDialog"
}
}
}]
}
}]
}]
}
}
}
}
}
I see only error:

GA4 data api - (not set) in custom dimensions

We are currently using GA4 data API and faced the issue when custom dimensions returns value "(not set)".
We were using the following article to set custom dimension for the session count, but we still receiving "(not set)" values.
Example of request:
{
"dateRanges": [
{
"startDate": "2021-09-01",
"endDate": "2021-09-05"
}
],
"offset": 0,
"limit": 100,
"dimensionFilter": {
"filter": {
"fieldName": "eventName",
"stringFilter": {
"matchType": 1,
"value": "screen_view",
"caseSensitive": true
}
}
},
"dimensions": [
{
"name": "customUser:applicationID"
},
{
"name": "customEvent:ga_session_number"
},
{
"name": "dateHour"
},
{
"name": "platform"
},
{
"name": "sessionSource"
},
{
"name": "sessionMedium"
},
{
"name": "sessionCampaignName"
},
{
"name": "deviceCategory"
}
],
"metrics": [
{
"name": "userEngagementDuration"
}
]
}
Does anybody have any idea why it may happen?

Logic App with azure monitor and conditions

I create a workflow with logicAPP. The goal is to notify a team when patch is missing for VM. I use azure monitor in the logic app to set the query. I decided to put after the Azure Monitor , a condition to know if the query table is empty or have data. if the table is empty, the logix is true , so it does'nt send notification, and when its false , it sends notification.
When I run , I got a logic errors. Normally , the table has not data but after condition , the function empty([my_table]) returns false and sends me notification with the result ("The query yielded no data")
what is the problem ??
Thanks
Based on the above shared requirement we have created the logic app & tested it our local environment , it is working fine.
Below is the complete logic code :
{
"definition": {
"$schema": "https://schema.management.azure.com/providers/Microsoft.Logic/schemas/2016-06-01/workflowdefinition.json#",
"actions": {
"Condition_2": {
"actions": {
"Terminate_2": {
"inputs": {
"runStatus": "Cancelled"
},
"runAfter": {},
"type": "Terminate"
}
},
"else": {
"actions": {
"Send_an_email_(V2)_2": {
"inputs": {
"body": {
"Body": "<p>#{base64ToString(body('Run_query_and_visualize_results')?['body'])}</p>",
"Subject": "list of vm from update management ",
"To": "<UserEmailId>"
},
"host": {
"connection": {
"name": "#parameters('$connections')['office365']['connectionId']"
}
},
"method": "post",
"path": "/v2/Mail"
},
"runAfter": {},
"type": "ApiConnection"
}
}
},
"expression": {
"and": [
{
"equals": [
"#length(body('Run_query_and_visualize_results')?['body'])",
0
]
}
]
},
"runAfter": {
"Run_query_and_visualize_results": [
"Succeeded"
]
},
"type": "If"
},
"Run_query_and_visualize_results": {
"inputs": {
"body": "Update\n| where Classification == 'Security Updates' or Classification == 'Critical Updates'\n| where UpdateState == 'Needed'\n| summarize by Computer,ResourceGroup,Classification,UpdateState\n|sort by Computer",
"host": {
"connection": {
"name": "#parameters('$connections')['azuremonitorlogs']['connectionId']"
}
},
"method": "post",
"path": "/visualizeQuery",
"queries": {
"resourcegroups": "<Resource_group_Name",
"resourcename": "<log analytics workspacename",
"resourcetype": "Log Analytics Workspace",
"subscriptions": "<subcription_id>",
"timerange": "Last 12 hours",
"visType": "Html Table"
}
},
"runAfter": {},
"type": "ApiConnection"
}
},
"contentVersion": "1.0.0.0",
"outputs": {},
"parameters": {
"$connections": {
"defaultValue": {},
"type": "Object"
}
},
"triggers": {
"Recurrence": {
"evaluatedRecurrence": {
"frequency": "Hour",
"interval": 3
},
"recurrence": {
"frequency": "Hour",
"interval": 3
},
"type": "Recurrence"
}
}
},
"parameters": {
"$connections": {
"value": {
"azuremonitorlogs": {
"connectionId": "/subscriptions/<subcription-id>/resourceGroups/<resource-group>/providers/Microsoft.Web/connections/azuremonitorlogs",
"connectionName": "azuremonitorlogs",
"id": "/subscriptions/<subcription-id>/providers/Microsoft.Web/locations/northcentralus/managedApis/azuremonitorlogs"
},
"office365": {
"connectionId": "/subscriptions/<subcription-id>/resourceGroups/<resource-group>/providers/Microsoft.Web/connections/office365",
"connectionName": "office365",
"id": "/subscriptions/<subcription-id>/providers/Microsoft.Web/locations/northcentralus/managedApis/office365"
}
}
}
}
}
please find the reference output of the above logic sample run :

Pass an already existing Model to next in Loopback

There is Project model
{
"name": "Project",
"plural": "Projects",
"base": "PersistedModel",
"idInjection": true,
"options": {
"validateUpsert": true
},
"properties": {
"title": {
"type": "string",
"required": true
},
"description": {
"type": "string"
},
"code": {
"type": "string"
},
"startDate": {
"type": "date",
"required": true
},
"endDate": {
"type": "date"
},
"value": {
"type": "number"
},
"infoEN": {
"type": "string"
},
"infoRU": {
"type": "string"
},
"infoAM": {
"type": "string"
},
"externalLinks": {
"type": [
"string"
]
}
},
"validations": [],
"relations": {
"industry": {
"type": "belongsTo",
"model": "Industry",
"foreignKey": "",
"options": {
"nestRemoting": true
}
},
"service": {
"type": "belongsTo",
"model": "Service",
"foreignKey": "",
"options": {
"nestRemoting": true
}
},
"tags": {
"type": "hasAndBelongsToMany",
"model": "Tag",
"foreignKey": "",
"options": {
"nestRemoting": true
}
}
},
"acls": [],
"methods": {}
}
And it hasAndBelongsToMany tags
here is Tag model
{
"name": "Tag",
"plural": "Tags",
"base": "PersistedModel",
"idInjection": true,
"options": {
"validateUpsert": true
},
"properties": {
"name": {
"type": "string",
"required": true
}
},
"validations": [],
"relations": {},
"acls": [],
"methods": {}
}
Now when the relation is created loopback api gives this api endpoint.
POST /Projects/{id}/tags
This creates a new tag into the tags collection and adds it to the project.
But what about adding an already existing tag to the project?
So I figured maybe I add before save hook to the Tag
Here I'll check if the tag exists and then pass the existing one for the relation.
Something like this.
tag.js
'use strict';
module.exports = function(Tag) {
Tag.observe('before save', function(ctx, next) {
console.log(ctx.instance);
Tag.find({name: ctx.instance.name})
next();
});
// Tag.validatesUniquenessOf('name', {message: 'name is not unique'});
};
#HaykSafaryan it just demo to show you how to use tag inside project
var app = require('../../server/server');
module.exports = function(project) {
var tag=app.models.tags
//afterremote it just demo. you can use any method
project.afterRemote('create', function(ctx, next) {
tag.find({name: ctx.instance.name},function(err,result)){
if(err) throw err;
next()
}
});
};
this is just example code to show you how to use update,create ,find ,upsertwithwhere etc. tag for validation you have to setup condition over here it will not take validation which you defined in tags models

How to insert mant-to-many object

I have two structures very similar to pests-owners, this is my structure:
{
"name": "Contratti",
"fields": {
"rischicontratti": {
"collection": "RischiContratti",
"via": "Contratti"
},
"intervento": {
"collection": "Interventi",
"via": "Contratto"
},
"Numero": {
"type": "string"
},
"Impresa": {
"object": "Imprese"
},
"Oggetto": {
"type": "string"
}
},
{
"name": "RischiContratti",
"fields": {
"Contratti": {
"object": "Contratti"
},
"Rischio": {
"object": "Rischi"
}
}
},
{
"name": "Rischi",
"fields": {
"rischicontratti": {
"collection": "RischiContratti",
"via": "Rischio"
},
"rischi_interventi": {
"collection": "rischi_interventi",
"via": "Rischio"
},
"Rischio": {
"type": "string"
}
}
When I'm inserting a Contratto I want to also insert all related Rischi. Is there a way to post all in one call? Or do I have to post first the Contratto and then loop each Rischi?