-
Notifications
You must be signed in to change notification settings - Fork 9
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
AUT Feature #404
Open
hardikmashru
wants to merge
106
commits into
main
Choose a base branch
from
AUT_main
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
AUT Feature #404
Changes from 79 commits
Commits
Show all changes
106 commits
Select commit
Hold shift + click to select a range
0266240
Integrate AUT feature (#301)
hani-iterable 287aa89
Add user object to trackanonsession and create user after live/valid …
hardikmashru 8a178d6
Merge branch 'main' into AUT_main
hardikmashru e1a9651
aut changes
hardikmashru cff5e8b
pushed files temporarily
hardikmashru 0f3861e
some updates for AUT fixes
hardikmashru bc57c34
updates
hardikmashru 1cf0763
Criteria bugs fixed
c0c9f17
Criteria bugs fixed
a9ccb27
Criteria bugs fixed
04155d3
Criteria bugs fixed
8b20a65
Merge branch 'main' into AUT_main
hardikmashru bf750bc
event test undo
hardikmashru 2c8c031
Update events.ts
hardikmashru 44999e3
updateuser changes
hardikmashru 72eb4a3
updates
hardikmashru 6ffc682
more fixes and updates
hardikmashru ec08641
Authorization test file fixed
39e1729
Fixed destination email case
594b1cc
Sync events in case of anon user not created and developer tries to c…
4d4a6f3
Handle updateCart flow separately for Anon event and when syncing data
492addb
Fixed all the test file with authorixation and annon user event manager
f123483
Fixed JWT case
9691279
removed logs and did some improvements
hardikmashru b953345
fixed some circular dependencies
hardikmashru 27b4792
keep current identity of anon user if merge fails
hardikmashru 1f35dd1
logic changes for criteria
hardikmashru c2dcfcb
Simple min match works
8525a72
Not check event again when matched criteria
8bc20a3
Fixed event stored in local as it is and remove criteria id when sync
ea4031c
remove criteria id from events if not available in criteria list when…
0abef34
JWT changes added in example
3a905db
Merge branch 'main' into AUT_main
24f8ac0
Authorization changes pushed
e6cfdd7
Authorization test fxed
0f2fcab
Fixed comments
9a02a89
Create new AUT example
e672975
Merge branch 'AUT_main' into AUT_main_logicchanges2
0ece6da
Update setUserId
0bafce5
webpack updated
3dd3ab7
Fixed test files
065e5cf
Merge branch 'AUT_main' into AUT_main_logicchanges2
9b69989
remove criteria from utils
e511b7e
Test file is fixed and criteria matched
38863fd
Remove logs
f1ab176
Revert Users and Commerce changes
78069c8
Fixed import circular dependency
3a4a4bc
Fixed circular dependancy
8caeaae
Update imports
0c4597e
Reverted eventform
6a75ded
Fixed circular dependency
263bd46
more fixes
hardikmashru 909f7b0
Update webpack.config.js
hardikmashru 9a8911d
fixed some suggestions
hardikmashru db1c7ae
Fixed comment
0b1480e
Fixed single item matches code (#410)
hardikmashru 6d50998
Add merge param (#414)
hardikmashru 41ffd79
MOB 8960 (#415)
hardikmashru 06c55d9
Isset purchase update fix (#416)
hardikmashru 7c04dba
Fixed bools needs to be string (#422)
darshan-iterable c403521
MOB-9055: Resolve nested criteria match issue (#423)
darshan-iterable 85a2d22
MOB-9138: Resolves DoesNotEqual criteria match issue (#426)
darshan-iterable 2606561
Merge branch 'main' into AUT_main
hani-iterable 6102cd3
Merge branch 'main' into AUT_main 2606561
hani-iterable 80ceb0e
revert back eslint rule
hani-iterable c8d6dbf
Resolve path related error
hani-iterable 5d60f23
[MOB-9258] fixed nested IsSet matching (#427)
darshan-iterable 55e06f7
MOB-9305: fixed events createdAt timeStamps (#431)
darshan-iterable 9061631
MOB-9168: Written automated unit tests against Combination logic with…
darshan-iterable 7ae6910
MOB-8824: Added limitation to event storage (#430)
darshan-iterable fc1d7ec
Nested custom event check related change (#432)
hani-iterable 4197cb2
MOB 9328 - Verify AUT works with JWT (#437)
hani-iterable 2eda85d
MOB 9149 - Sample app object updates not formatted properly (#438)
hani-iterable 904f602
MOB-9308: supports nested field types (#439)
darshan-iterable 0218166
MOB-9081: Written automated unit tests for different field types and …
darshan-iterable 93e1b0f
fully supports comparison for data in Array data with all comparator …
darshan-iterable 16baf6c
MOB 9328 add JWT in response (#441)
hani-iterable 4013132
updated nested field logic (#445)
darshan-iterable 25fcde1
MOB-9145: support isOneOf and isNotOneOf comparator (#446)
darshan-iterable 8f6e6a7
[MOB-9522]: Fix JWT UserID Support (#452)
mprew97 c9a304a
[MOB-9505] rename merge parameter (#450)
darshan-iterable 1963926
MOB-9307 Add test to validate object created by custom event and user…
darshan-iterable aa2a124
[MOB-9402] update user should not be a separate call (#453)
darshan-iterable 51bd3a2
[MOB-9568] update "criterias" to "criteriaSets" (#456)
darshan-iterable 5b7ffa0
[MOB-9578] implements identity resolution (#458)
darshan-iterable 604ea66
MOB-9650 Added support for nested criteria match a.b.c (#457)
darshan-iterable c720d4f
[MOB-9652] support for nested JSON array (#459)
darshan-iterable 275b460
[MOB-9639] Added handler for notifying customer app of a newly create…
darshan-iterable 1d28695
[MOB-9640] Keep AUT off until concent to track is granted (#462)
darshan-iterable 66dc2a0
[MOB-9899]: Add Auth Checks Before API Calls (#463)
mprew97 fdf8dd7
[MOB-9955]: Allow IdentityResolution Overrides and Move onAnonUserCre…
mprew97 1cf59ee
fix replay issue with JWT (#465)
mprew97 b3f50c4
[MOB-9954]: fix userMergeScenario test (#466)
mprew97 061b42c
[MOB-9954]: Fix Circular Dependency and Clean Up Auth Checks on API C…
mprew97 9c41772
rename (#470)
mprew97 1387a2d
[MOB-9703] Added support for fetching new JWT prior to calling merge …
darshan-iterable fd7d971
[MOB-9970] anonymous criteria should match for nested values (#472)
darshan-iterable 7699b03
[MOB-10064] single primitive array bug fix (#473)
darshan-iterable 2f3792e
[MOB-10086]: Minor AUT Code Cleanup/Renaming (#474)
mprew97 baa3f7c
[MOB-10091]: AUT Pre-Bash Updates (#475)
mprew97 f95cc67
Merge branch 'main' of github.com:Iterable/iterable-web-sdk into AUT_…
mprew97 0c0fd2d
remove md file (#477)
mprew97 c293ab4
add method to clear anon data (#480)
mprew97 ebd61bf
add new messsage to rejection (#479)
mprew97 4ceae33
[MOB-10123]: Clear Anon Data When Replay is False (#478)
mprew97 4b1829a
update release version (#481)
mprew97 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,138 @@ | ||
# Anonymous User Event Tracking Iterable's Web SDK | ||
The Anonymous User Tracking Module is a pivotal component within our WEB SDK that seamlessly captures user events while maintaining anonymity for non-logged-in users. This module is designed to diligently gather and store events triggered by users who have not yet signed in. Once specific criteria are met or when the user decides to engage further, the module securely synchronizes all accumulated anonymous events with our servers. | ||
|
||
By adopting a privacy-first approach, the module allows us to gain valuable insights into user interactions without compromising their personal information. As users transition from anonymous to logged-in status, the module smoothly transitions as well, associating future events with the user's unique identity while ensuring the continuity of event tracking. | ||
|
||
Key Features: | ||
|
||
- Anonymous Event Tracking: Captures a diverse range of user events even before they log in, ensuring a comprehensive understanding of user behavior. | ||
Privacy Protection: Safeguards user anonymity by collecting and storing events without requiring personal information. | ||
- Event Synchronization: Upon meeting predefined conditions, securely transmits all anonymous events to the server, enabling data-driven decision-making. | ||
- Seamless User Transition: Effortlessly shifts from tracking anonymous events to associating events with specific users as they log in. | ||
- Enhanced Insights: Provides a holistic view of user engagement patterns, contributing to a more informed product optimization strategy. | ||
Implementing the Anonymous | ||
|
||
# Installation | ||
|
||
To install this SDK through NPM: | ||
|
||
``` | ||
$ npm install @iterable/web-sdk | ||
``` | ||
|
||
with yarn: | ||
|
||
``` | ||
$ yarn add @iterable/web-sdk | ||
``` | ||
|
||
or with a CDN: | ||
|
||
```js | ||
<script src="https://unpkg.com/@iterable/web-sdk/index.js"></script> | ||
``` | ||
|
||
# Methods | ||
- [`getAnonCriteria`] | ||
- [`trackAnonEvent`] | ||
- [`trackAnonPurchaseEvent`] | ||
- [`trackAnonUpdateCart`] | ||
- [`createUser`] | ||
- [`syncEvents`] | ||
- [`checkCriteriaCompletion`] | ||
|
||
# Usage | ||
|
||
1. `trackAnonEvent` | ||
The 'trackAnonEvent' function within the Iterable-Web SDK empowers seamless tracking of diverse web events. Developers can enrich event data with specific metadata using the 'dataFields' attribute. This function intelligently distinguishes between logged-in and non-logged-in users, securely storing event data on the server post-login, while locally preserving data for anonymous users, ensuring comprehensive event monitoring in both scenarios. | ||
|
||
```ts | ||
const eventDetails = { | ||
...conditionalParams, | ||
createNewFields: true, | ||
createdAt: (Date.now() / 1000) | 0, | ||
dataFields: { website: { domain: 'omni.com' }, eventType: 'track' }, | ||
}; | ||
|
||
await anonymousUserEventManager.trackAnonEvent(eventDetails); | ||
``` | ||
|
||
2. `trackAnonPurchaseEvent` | ||
The 'trackAnonPurchaseEvent' function in the Iterable-Web SDK enables precise tracking of purchase-related web events. Developers can seamlessly include specific details about purchased items. With an innate understanding of user authentication status, the function securely stores event data on the server post-login, while also providing localized storage for non-logged-in users, guaranteeing comprehensive event monitoring in both usage scenarios. | ||
|
||
```ts | ||
const eventDetails = { | ||
...conditionalParams, | ||
items: [{ name: purchaseItem, id: 'fdsafds', price: 100, quantity: 2 }], | ||
total: 200 | ||
} | ||
|
||
await anonymousUserEventManager.trackAnonPurchaseEvent(eventDetails); | ||
``` | ||
|
||
3. `trackAnonUpdateCart` | ||
The 'trackAnonUpdateCart' function in the Iterable-Web SDK empowers effortless tracking of web events related to cart updates. Developers can accurately outline details for multiple items within the cart. It seamlessly handles data, securely transmitting events to the server upon user login, while also providing local storage for event details in the absence of user login, ensuring comprehensive event tracking in all scenarios. | ||
|
||
```ts | ||
const eventDetails = { | ||
...conditionalParams, | ||
items: [{ name: cartItem, id: 'fdsafds', price: 100, quantity: 2 }] | ||
} | ||
|
||
await anonymousUserEventManager.trackAnonUpdateCart(eventDetails); | ||
``` | ||
|
||
4. `createUser` | ||
The 'createUser' function in the Iterable-Web SDK facilitates user creation by assigning a unique user UUID. This function also supports the seamless updating of user details on the server, providing a comprehensive solution for managing user data within your application. | ||
|
||
```ts | ||
await anonymousUserEventManager.createUser(uuid, process.env.API_KEY); | ||
``` | ||
|
||
5. `getAnonCriteria` | ||
The 'getAnonCriteria' function within the Iterable-Web SDK retrieves criteria from the server for matching purposes. It efficiently fetches and returns an array of criteria, providing developers with essential tools to enhance their application's functionality through data-driven decision-making. | ||
|
||
```ts | ||
const criteriaList = await anonymousUserEventManager.getAnonCriteria(); | ||
``` | ||
|
||
6. `checkCriteriaCompletion` | ||
The 'checkCriteriaCompletion' function in the Iterable-Web SDK performs a local assessment of stored events to determine if they fulfill specific criteria. If any of the stored events satisfy the criteria, the function returns 'true', offering developers a reliable method to validate the completion status of predefined conditions based on accumulated event data. | ||
|
||
```ts | ||
const isCriteriaCompleted = await anonymousUserEventManager.checkCriteriaCompletion(); | ||
``` | ||
|
||
7. `syncEvents` | ||
The 'syncEvents' function within the Iterable-Web SDK facilitates the seamless synchronization of locally stored events to the server while sequentially maintaining their order. This function efficiently transfers all accumulated events, clearing the local storage in the process, ensuring data consistency and integrity between the client and server-side environments. | ||
|
||
```ts | ||
await anonymousUserEventManager.syncEvents(); | ||
``` | ||
|
||
# Example | ||
|
||
```ts | ||
const eventDetails = { | ||
...conditionalParams, | ||
createNewFields: true, | ||
createdAt: (Date.now() / 1000) | 0, | ||
userId: loggedInUser, | ||
dataFields: { website: { domain: 'omni.com' }, eventType: 'track' }, | ||
deviceInfo: { | ||
appPackageName: 'my-website' | ||
} | ||
}; | ||
|
||
await anonymousUserEventManager.trackAnonEvent(eventDetails); | ||
const isCriteriaCompleted = await anonymousUserEventManager.checkCriteriaCompletion(); | ||
|
||
if (isCriteriaCompleted) { | ||
const userId = uuidv4(); | ||
const App = await initialize(process.env.API_KEY); | ||
await App.setUserID(userId); | ||
await anonymousUserEventManager.createUser(userId, process.env.API_KEY); | ||
setLoggedInUser({ type: 'user_update', data: userId }); | ||
await anonymousUserEventManager.syncEvents(); | ||
} | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,150 @@ | ||
/* eslint-disable @typescript-eslint/no-unused-vars */ | ||
import { ChangeEvent, FC, FormEvent, useState } from 'react'; | ||
import styled from 'styled-components'; | ||
|
||
import { TextField as _TextField } from './TextField'; | ||
import { Button as _Button } from './Button'; | ||
|
||
import { useUser } from '../context/Users'; | ||
|
||
const TextField = styled(_TextField)``; | ||
|
||
const Button = styled(_Button)` | ||
margin-left: 0.4em; | ||
max-width: 425px; | ||
`; | ||
|
||
const Form = styled.form` | ||
display: flex; | ||
flex-flow: row; | ||
align-items: center; | ||
justify-content: flex-end; | ||
height: 100%; | ||
|
||
${TextField} { | ||
align-self: stretch; | ||
margin-top: 5px; | ||
} | ||
`; | ||
|
||
const StyledDiv = styled.div` | ||
display: flex; | ||
flex-direction: column; | ||
align-items: flex-start; | ||
`; | ||
|
||
const Error = styled.div` | ||
color: red; | ||
`; | ||
|
||
interface Props { | ||
setEmail: (email: string) => Promise<void>; | ||
setUserId: (userId: string, merge?: boolean) => Promise<void>; | ||
logout: () => void; | ||
} | ||
|
||
export const LoginFormWithoutJWT: FC<Props> = ({ | ||
setEmail, | ||
setUserId, | ||
logout | ||
}) => { | ||
const [useEmail, setUseEmail] = useState<boolean>(true); | ||
const [user, updateUser] = useState<string>(process.env.LOGIN_EMAIL || ''); | ||
|
||
const [error, setError] = useState<string>(''); | ||
|
||
const [isEditingUser, setEditingUser] = useState<boolean>(false); | ||
|
||
const { loggedInUser, setLoggedInUser } = useUser(); | ||
|
||
const handleSubmit = (e: FormEvent<HTMLFormElement>) => { | ||
e.preventDefault(); | ||
|
||
const setUser = useEmail ? setEmail : setUserId; | ||
|
||
setUser(user, true) | ||
.then(() => { | ||
setEditingUser(false); | ||
setLoggedInUser({ type: 'user_update', data: user }); | ||
}) | ||
.catch(() => setError('Something went wrong!')); | ||
}; | ||
|
||
const handleLogout = () => { | ||
logout(); | ||
setLoggedInUser({ type: 'user_update', data: '' }); | ||
}; | ||
|
||
const handleEditUser = () => { | ||
updateUser(loggedInUser); | ||
setEditingUser(true); | ||
}; | ||
|
||
const handleCancelEditUser = () => { | ||
updateUser(''); | ||
setEditingUser(false); | ||
}; | ||
|
||
const handleRadioChange = (e: ChangeEvent<HTMLInputElement>) => { | ||
setUseEmail(e.target.value === 'email'); | ||
}; | ||
|
||
const first5 = loggedInUser.substring(0, 5); | ||
const last9 = loggedInUser.substring(loggedInUser.length - 9); | ||
|
||
return ( | ||
<> | ||
{loggedInUser && !isEditingUser ? ( | ||
<> | ||
<Button onClick={handleEditUser}> | ||
Logged in as {`${first5}...${last9}`} (change) | ||
</Button> | ||
<Button onClick={handleLogout}>Logout</Button> | ||
</> | ||
) : ( | ||
<StyledDiv> | ||
<Form> | ||
<div> | ||
<input | ||
type="radio" | ||
id="userId" | ||
name="userId" | ||
value="userId" | ||
checked={!useEmail} | ||
onChange={handleRadioChange} | ||
/> | ||
<label>UserId</label> | ||
</div> | ||
<div> | ||
<input | ||
type="radio" | ||
id="email" | ||
name="email" | ||
value="email" | ||
checked={useEmail} | ||
onChange={handleRadioChange} | ||
/> | ||
<label>Email</label> | ||
</div> | ||
</Form> | ||
<Form onSubmit={handleSubmit} data-qa-login-form> | ||
<TextField | ||
onChange={(e) => updateUser(e.target.value)} | ||
value={user} | ||
placeholder="e.g. [email protected]" | ||
required | ||
data-qa-login-input | ||
/> | ||
<Button type="submit">{isEditingUser ? 'Change' : 'Login'}</Button> | ||
{isEditingUser && ( | ||
<Button onClick={handleCancelEditUser}>Cancel</Button> | ||
)} | ||
</Form> | ||
{error && <Error>{error}</Error>} | ||
</StyledDiv> | ||
)} | ||
</> | ||
); | ||
}; | ||
|
||
export default LoginFormWithoutJWT; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@bradumbaugh do we want to keep/update this readme?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@mprew97 no, let's please pull the readme from the SDK.