Fire DTM rule after certain seconds - analytics

This is one of the scenarios suggested by our clients which includes firing DTM rule after certain time.
Scenario - As per the requirement, once the website is loaded, and the user does not perform any activity, a page load rule must be fired after 5 seconds. In case a user performs a click or any other action before 5 second, then that particular tracking rule must be fired.
Any suggestion on how should i go for this one.

This is meant to be a PoC, a starting point. You will need to expand on this based on what you define.
As mentioned in my comments on your question, you need to define what "website is loaded" actually means to you (in a way that can actually be coded), and also define what constitutes a user action (also in a way that can actually be coded).
As a Proof of Concept (PoC), I will define "website is loaded" as the window.load event, and "click or any other action" as "clicks on any link".
Also, you weren't entirely clear on what you want to actually trigger. Near as I can tell, you want to trigger the same thing no matter what, and have stated no difference otherwise. So I'm going to make this PoC simplified accordingly, by calling a single Direct Call rule exposing a message signifying which scenario happened.
Part 1 - Timeout
A Page Load Rule is created and set to trigger on the window.load event. When that happens, a setTimeout is called, which will call a function after 5 seconds have passed. When the function iscalled, it checks if a Data Element called "fiveSecondRule" exists. If it does not exist, then it sets it to a value "timeout" to signify it was set from this code. Then a Direct Call rule named "fiveSecondRule" (defined below) is called.
Instructions
First, go to Rules > Page Load Rules, and click Create New Rule. Give your rule a Name of "Five Second Rule - Timeout".
Under Conditions, set the Trigger rule at dropdown to "Onload".
In the Javascript / Third Party Tags section, click Add New Script to open up a script overlay. Name it "config". For Type, select "Non-Sequential Javascript", and select/check the Execute Globally option.
Add the following code to the code box:
window.setTimeout(
function() {
if (!_satellite.getVar('fiveSecondRule')) {
_satellite.setVar('fiveSecondRule','timeout');
_satellite.track('fiveSecondRule');
}
}
,5000
);
Click Save Code and then Save Rule to save the rule.
Expanding the PoC
This is what you will need to alter if your definition of "website is loaded" is something other than window.load event. For example you may instead define it is DOM Ready, in which case you can simply change Trigger rule at to "DOM Ready". However, if your definition is more complex (e.g. waiting for some callback from your site's framework), then you will need to instead put this into a Direct Call rule and explicitly call it yourself.
Note: There is an Event Based Rule of "time passed" Event Type, that you can set to trigger after 5 seconds. As an alternative to the PoC you can do this instead, and add a rule condition similar to described in Part 2 below (instead of code above). The DTM documentation does not detail when the timer actually starts or how it actually keeps track of time for this event.
I haven't really spent much time trying to reverse engineer the core DTM library, but from 5 second eyeballing of it, near as I can tell it "registers" events of this type sometime during "Top of Page" code execution (where DTM Header script is placed), and it uses a cookie/localstorage and a timeInterval to constantly poll it.
So if this all fits your definition of the 5 second rule, it's a little bit less coding to make a 5 second Event Based Rule instead. But I chose the Page Load Rule and setTimeout method above to provide you more flexibility as a baseline, should your definition be more complex.
Part 2 - User Actions
An Event Based Rule is setup to trigger whenever the user clicks on a link. When the rule triggers, the condition code checks if the Data Element named "fiveSecondRule" is set. If not, then a value of "linkClick" is set to signify a link was clicked. Then the Direct Call rule named "fiveSecondRule" is called.
Instructions
Go to Rules > Event Based Rules and click Create New Rule. Give your rule a Name of "Five Second Rule - Link Clicks".
Under Conditions > Event > Event Type, select "click" (should be the default option).
Then For Tag > Element Tag or Selector, add "a" (no quotes).
Note: It's beyond the scope of this post to get into, but depending on what other code is implemented on your site/page, you may need to change some of the other settings in this section.
Next, under Rule Conditions > Criteria, select "Data> Custom" and click Add Criteria. In the Custom code box, add the following code:
if (!_satellite.getVar('fiveSecondRule')) {
_satellite.setVar('fiveSecondRule','linkClick');
_satellite.track('fiveSecondRule');
}
return true;
Click Save Rule to save the rule.
Expanding the PoC
As mentioned, this just covers clicking on links. It sounds like your definition of "action" includes more than that. Once you define what constitutes a user action, create more Event Based Rules accordingly.
Part 3 - Trigger
A Direct Call Rule is setup to act as the "trigger". All rules from Part 1 and Part 2 will ultimately call this rule, and this is where you place the code you want to execute whenever a user performs an action before 5 seconds, or when the 5 seconds pass.
Instructions
Go to Rules > Direct Call Rules and click Create New Rule. Give your rule a Name of "Five Second Rule - Trigger". Under Conditions > String, add "fiveSecondRule" (no quotes).
From here, you can trigger whatever tools you have implemented, or add whatever 3rd party tags you want to trigger. You can use %fiveSecondRule% syntax in the tool fields and it will have a value signifying how it was invoked (e.g. "linkClick" or "timeout", shown above). For javascript syntax (in js code boxes) you can use _satellite.getVar('fiveSecondRule') to get the value.
Expanding the PoC
I suppose it's within the realm of possibilities you may want to trigger separate Direct Call Rules depending on whether it triggers before or after 5 seconds are up. But that really depends on what you are ultimately looking to trigger, which you haven't clarified.
But if so, then rename this Direct Call Rule to "Five Second Rule - Before" and for the Condition, change it to "beforeFiveSecondRule" (no quotes). Also, go back and change the _satellite.track() call argument to this, for all rules you made from Part 2.
Then, create another Direct Call Rule named "Five Second Rule - After", and for the Condition, put "afterFiveSecondRule" (no quotes). Also, go back and change the _satellite.track() argument in Part 1 to this.

Related

Salesforce LWC Database.setSavepoint

Javascript admitted newbie and hacker here, so I suspect this question is very ignorant and a learning experience.
I'm essentially converting an old Apex/Visualforce page to LWC. The Apex code employs Database.setSavepoint() and Database.rollback() and I have no idea how something similar would be accomplished in LWC, or even if it needs to be.
Google provides nothing, and I know it's not done through #wire and #AuraEnabled.
The main pain point of migrating VF apex controllers ("regular ones", oldschool, which were working with massive hidden html field for "viewstate" and weren't using #remoteaction to be a bit more mobile-friendly) to Aura/LWC server-side controllers is the static keyword next to the method definition. You don't have "viewstate" of whole controller passed to the method magically, you need to explicitly pass the params the method needs. From LWC/Aura or (re)query them. It's bit like everything was marked transient if you know what this keyword does.
savepoint and rollback have to happen in one transaction anyway (1 interation, 1 button click). User triggered something and it either succeeds or fails. You can't save the game ;) and 3 interactions later go "gotcha, rollback". The state was written to database, the ship has sailed. And savepoints can't be serialised (you can't grab the variable, pass it to VF/Aura/LWC client-side and later back to the server). If you're passing something back - it means the transaction is almost over and they wouldn't be needed anyway.
So there are no technical problems with it. The question is what is your business logic doing with the rollbacks. Is it some funky "validate before save"? Some way to try firing all validation rules, triggers etc and see what explodes"?
LWC shouldn't care and you should be able to pass the result of this operation back nicely. It's a good question whether you still need this functionality but it's biz question, not technical.

Elicit Slot from within HelpIntent in Alexa

I have implemented a multi-turn dialog for Alexa. The Help-Intent provides different Help-Texts depending on the state of the dialog. After the User has triggered the HelpIntent and was presented the Help-Text, I want to elicit a specific slot with the ElicitSlotDirective
Now this seems to be not supported, since you can only elicit slots of the current intent, and the HelpIntent does not have slots.
https://github.com/alexa/alexa-skills-kit-sdk-for-nodejs/issues/162
My question now is: How can I return to my multi-turn dialog and elicit a specific slot after the user triggered the HelpIntent?
You can now use intent chaining to elicit a slot from a different Intent. For example:
.addDirective({
type: 'Dialog.ElicitSlot',
slotToElicit: 'drink',
updatedIntent: {
name: 'OrderIntent',
confirmationStatus: 'NONE'
}
})
See this blog post.
The documentation states that:
Implementing the built-in intents is recommended, but optional.
I recommend that you define your own HelpIntent with overlapping utterances to the AMAZON.HelpIntent, but with your needed Slot types.
In this case, your service receives an IntentRequest for MyHelpIntent, even though these phrases overlap with the built-in AMAZON.HelpIntent.
The documentation also states, that this practice is not recommended, because the built-in intent may have a better coverage of sample utterances. It states that it is better practice to extend the built-in Intents. But (stupid enough from Amazon), the HelpIntent does not support Slots. So the only way would be a custom Help Intent.
I don't see a way to use Dialog Directives with the built-in Intents.
Here's a convoluted workaround that might work (there's no straight forward way right now, Nov 2018):
On every loop of the multi-turn dialog save your dialog based intent in the session attributes (the whole intent object, you can use the intent.name as key)
On every triggered intent (even HelpIntent) save the intent name in a lastIntent session attribute (to keep track of the previous intent name)
User triggers help and you're now in the HelpIntent. After you provide your help message append a question in the end that will cause the user to say something that will trigger your dialog based intent again
Do the following steps when you are in the dialog based intent and only if the lastIntent was HelpIntent (the one in the previous step):
Load the most recent intent data from the session attributes and, in it, delete the slot value and resolutions of the slot you want to elicitate (alternatively if you want to start from scratch you can delete the remaining slot values too, up to you)
Replace the current intent with the modified intent of the previous step
Emit a DialogDelegate with the current intent (your model needs to flag the slot you want to elicitate with elicitationRequired set to true)

REST optimistic-locking and multiple PUTs

Far as I understand, PUT request is not supposed to return any content.
Consider the client wants to run this pseudo code:
x = resource.get({id: 1});
x.field1 = "some update";
resource.put(x);
x.field2 = "another update";
resource.put(x);
(Imagine I have an input control and a button "Save", this allows me to change a part of object "x" shown in an input control, then on button click PUT changes to server, then continue editing and maybe "save" another change to "x")
Following different proposals on how to implement optimistic locking in REST APIs, the above code MUST fail, because version mark (however implemented) for "x" as returned by get() will become stale after put().
Then how do you people usually make it work?
Or do you just re-GET objects after every PUT?
You can use "conditional" actions with HTTP, for example the If-Match header described here:
https://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.24
In short: You deliver an ETag with the GET request, and supply this ETag back to the server in the If-Match header. The server will respond with a failure if the resource you are trying to PUT has another ETag. You can also use simple timestamps with the If-Unmodified-Since header.
Of course you will have to make your server code understand conditional requests.
For multiple steps, the PUT can indeed return the new representation, it can therefore include the new ETag or timestamp too. Even if the server does not return the new representation for a PUT, you could still use the timestamp from the response with an If-Unmodified-Since conditional PUT.
Here is probably what I was looking for: https://www.rfc-editor.org/rfc/rfc7231#section-4.3.4
They implicitly say that we CAN return ETag from PUT. Though only in the case server applied the changes as they were given, without any corrections.
However this raises yet another question. In real world app PUT caller will run asynchronously in JS gui, like in my example in the question. So, Save button might be pressed several times with or without entering any changes. If we don't use optimistic locking, then supposed PUT idempotency makes it safe to send another PUT query with each button click, as long as the last one wins (but actually if there were changes then it's not guaranteed, so the question remains).
But with optimistic locking, when first PUT succeeds, it returns updatred ETag, ok? And if there is another PUT request running, still with outdated tag version, that latter request will get 412 and the user will see a message "someone else changed the resource" - but actually it was our former changes.
What do you usually do to prevent that? Disable the Save button until its request is fully completed? What if it times out? Or do you think it's acceptable to see concurrent-change error message if it was a timeout, because the stability is already compromised anyway?

What callback to use in CakePHP to catch all changes to model?

I want to add a new functionality to my application: executing a action every time a specific column is changed inside of a specific modal. This column is changed in many places in the application via several methods (save(), saveAll(), updateAll(), saveField()).
My first approach was to use the beforeSave/afterSave callbacks to handle this for every change on Modal level. However, I noticed that these callbacks aren't being done with updateAll() and saveField().
Is there a easy way to track all changes made to a specific column for a specific modal, regardless of the method being used in modal?
You can create your own callback and use it with save all, as described here

How to create Clearcase trigger for only one user?

I would like to make a trigger that only executes for a single user(myself). The reason, is so that I don't "break the build".
Longer explanation: I'm trying to sandbox a Clearcase trigger to automatically apply an attribute to an element when it is checked in, and I don't want to accidentally create a trigger that applies to all developers and potentially ruin everybody's day with the prototype(what works on the first try?).
I see the -nus/ers option which seems to exclude users in the list. I suppose I could comma separate a list of all users, excepting myself. Is this what I'm looking for?
The best sources of information about triggers are listed here, and then EV (Environment Variables) are mentioned in mktrype man page.
Check for isntance:
CLEARCASE_USER
The user who issued the command that caused the trigger to fire; derived from the UNIX or Linux real user ID or the Windows user ID.
If the user id somehow doesn't work, you could consider other environment variables:
CLEARCASE_SNAPSHOT_PN
Your script can control if the user id is yours, and if not, abort.
The path to the root of the snapshot view directory in which the operation that caused the trigger to fire took place.
If your script detect that the path isn't the exact one expected (ie your snapshot view from which your triggered your script), said trigger script would abort.

Resources