2022-09-14 23:17:32 +00:00
|
|
|
import { filterDefined } from './util/array'
|
|
|
|
import { notification_reason_types } from './notification'
|
|
|
|
import { getFunctionUrl } from './api'
|
|
|
|
import { DOMAIN } from './envs/constants'
|
|
|
|
import { PrivateUser } from './user'
|
|
|
|
|
|
|
|
export type notification_destination_types = 'email' | 'browser'
|
|
|
|
export type notification_preference = keyof notification_preferences
|
|
|
|
export type notification_preferences = {
|
|
|
|
// Watched Markets
|
|
|
|
all_comments_on_watched_markets: notification_destination_types[]
|
|
|
|
all_answers_on_watched_markets: notification_destination_types[]
|
|
|
|
|
|
|
|
// Comments
|
|
|
|
tipped_comments_on_watched_markets: notification_destination_types[]
|
|
|
|
comments_by_followed_users_on_watched_markets: notification_destination_types[]
|
|
|
|
all_replies_to_my_comments_on_watched_markets: notification_destination_types[]
|
|
|
|
all_replies_to_my_answers_on_watched_markets: notification_destination_types[]
|
|
|
|
all_comments_on_contracts_with_shares_in_on_watched_markets: notification_destination_types[]
|
|
|
|
|
|
|
|
// Answers
|
|
|
|
answers_by_followed_users_on_watched_markets: notification_destination_types[]
|
|
|
|
answers_by_market_creator_on_watched_markets: notification_destination_types[]
|
|
|
|
all_answers_on_contracts_with_shares_in_on_watched_markets: notification_destination_types[]
|
|
|
|
|
|
|
|
// On users' markets
|
|
|
|
your_contract_closed: notification_destination_types[]
|
|
|
|
all_comments_on_my_markets: notification_destination_types[]
|
|
|
|
all_answers_on_my_markets: notification_destination_types[]
|
|
|
|
subsidized_your_market: notification_destination_types[]
|
|
|
|
|
|
|
|
// Market updates
|
|
|
|
resolutions_on_watched_markets: notification_destination_types[]
|
|
|
|
resolutions_on_watched_markets_with_shares_in: notification_destination_types[]
|
|
|
|
market_updates_on_watched_markets: notification_destination_types[]
|
|
|
|
market_updates_on_watched_markets_with_shares_in: notification_destination_types[]
|
|
|
|
probability_updates_on_watched_markets: notification_destination_types[]
|
|
|
|
|
|
|
|
// Balance Changes
|
|
|
|
loan_income: notification_destination_types[]
|
|
|
|
betting_streaks: notification_destination_types[]
|
|
|
|
referral_bonuses: notification_destination_types[]
|
|
|
|
unique_bettors_on_your_contract: notification_destination_types[]
|
|
|
|
tips_on_your_comments: notification_destination_types[]
|
|
|
|
tips_on_your_markets: notification_destination_types[]
|
|
|
|
limit_order_fills: notification_destination_types[]
|
|
|
|
|
|
|
|
// General
|
|
|
|
tagged_user: notification_destination_types[]
|
|
|
|
on_new_follow: notification_destination_types[]
|
|
|
|
contract_from_followed_user: notification_destination_types[]
|
|
|
|
trending_markets: notification_destination_types[]
|
|
|
|
profit_loss_updates: notification_destination_types[]
|
|
|
|
onboarding_flow: notification_destination_types[]
|
|
|
|
thank_you_for_purchases: notification_destination_types[]
|
2022-10-03 13:41:39 +00:00
|
|
|
|
|
|
|
opt_out_all: notification_destination_types[]
|
|
|
|
// When adding a new notification preference, use add-new-notification-preference.ts to existing users
|
2022-09-14 23:17:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
export const getDefaultNotificationPreferences = (
|
|
|
|
userId: string,
|
|
|
|
privateUser?: PrivateUser,
|
|
|
|
noEmails?: boolean
|
|
|
|
) => {
|
|
|
|
const constructPref = (browserIf: boolean, emailIf: boolean) => {
|
|
|
|
const browser = browserIf ? 'browser' : undefined
|
|
|
|
const email = noEmails ? undefined : emailIf ? 'email' : undefined
|
|
|
|
return filterDefined([browser, email]) as notification_destination_types[]
|
|
|
|
}
|
2022-10-03 13:41:39 +00:00
|
|
|
const defaults: notification_preferences = {
|
2022-09-14 23:17:32 +00:00
|
|
|
// Watched Markets
|
2022-09-16 13:43:27 +00:00
|
|
|
all_comments_on_watched_markets: constructPref(true, false),
|
|
|
|
all_answers_on_watched_markets: constructPref(true, false),
|
2022-09-14 23:17:32 +00:00
|
|
|
|
|
|
|
// Comments
|
2022-09-16 13:43:27 +00:00
|
|
|
tips_on_your_comments: constructPref(true, true),
|
|
|
|
comments_by_followed_users_on_watched_markets: constructPref(true, true),
|
|
|
|
all_replies_to_my_comments_on_watched_markets: constructPref(true, true),
|
|
|
|
all_replies_to_my_answers_on_watched_markets: constructPref(true, true),
|
2022-09-14 23:17:32 +00:00
|
|
|
all_comments_on_contracts_with_shares_in_on_watched_markets: constructPref(
|
|
|
|
true,
|
2022-09-16 13:43:27 +00:00
|
|
|
false
|
2022-09-14 23:17:32 +00:00
|
|
|
),
|
|
|
|
|
|
|
|
// Answers
|
2022-09-16 13:43:27 +00:00
|
|
|
answers_by_followed_users_on_watched_markets: constructPref(true, true),
|
|
|
|
answers_by_market_creator_on_watched_markets: constructPref(true, true),
|
2022-09-14 23:17:32 +00:00
|
|
|
all_answers_on_contracts_with_shares_in_on_watched_markets: constructPref(
|
|
|
|
true,
|
2022-09-16 13:43:27 +00:00
|
|
|
true
|
2022-09-14 23:17:32 +00:00
|
|
|
),
|
|
|
|
|
|
|
|
// On users' markets
|
2022-09-16 13:43:27 +00:00
|
|
|
your_contract_closed: constructPref(true, true), // High priority
|
|
|
|
all_comments_on_my_markets: constructPref(true, true),
|
|
|
|
all_answers_on_my_markets: constructPref(true, true),
|
2022-09-14 23:17:32 +00:00
|
|
|
subsidized_your_market: constructPref(true, true),
|
|
|
|
|
|
|
|
// Market updates
|
2022-09-16 13:43:27 +00:00
|
|
|
resolutions_on_watched_markets: constructPref(true, false),
|
2022-09-14 23:17:32 +00:00
|
|
|
market_updates_on_watched_markets: constructPref(true, false),
|
|
|
|
market_updates_on_watched_markets_with_shares_in: constructPref(
|
|
|
|
true,
|
|
|
|
false
|
|
|
|
),
|
2022-09-16 13:43:27 +00:00
|
|
|
resolutions_on_watched_markets_with_shares_in: constructPref(true, true),
|
2022-09-14 23:17:32 +00:00
|
|
|
|
|
|
|
//Balance Changes
|
|
|
|
loan_income: constructPref(true, false),
|
|
|
|
betting_streaks: constructPref(true, false),
|
|
|
|
referral_bonuses: constructPref(true, true),
|
2022-10-03 20:12:55 +00:00
|
|
|
unique_bettors_on_your_contract: constructPref(true, true),
|
2022-09-16 13:43:27 +00:00
|
|
|
tipped_comments_on_watched_markets: constructPref(true, true),
|
2022-09-14 23:17:32 +00:00
|
|
|
tips_on_your_markets: constructPref(true, true),
|
|
|
|
limit_order_fills: constructPref(true, false),
|
|
|
|
|
|
|
|
// General
|
|
|
|
tagged_user: constructPref(true, true),
|
|
|
|
on_new_follow: constructPref(true, true),
|
|
|
|
contract_from_followed_user: constructPref(true, true),
|
2022-09-16 13:43:27 +00:00
|
|
|
trending_markets: constructPref(false, true),
|
2022-09-14 23:17:32 +00:00
|
|
|
profit_loss_updates: constructPref(false, true),
|
|
|
|
probability_updates_on_watched_markets: constructPref(true, false),
|
2022-09-16 13:43:27 +00:00
|
|
|
thank_you_for_purchases: constructPref(false, false),
|
|
|
|
onboarding_flow: constructPref(false, false),
|
2022-10-03 13:41:39 +00:00
|
|
|
|
|
|
|
opt_out_all: [],
|
|
|
|
}
|
|
|
|
return defaults
|
2022-09-14 23:17:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Adding a new key:value here is optional, you can just use a key of notification_subscription_types
|
|
|
|
// You might want to add a key:value here if there will be multiple notification reasons that map to the same
|
|
|
|
// subscription type, i.e. 'comment_on_contract_you_follow' and 'comment_on_contract_with_users_answer' both map to
|
|
|
|
// 'all_comments_on_watched_markets' subscription type
|
|
|
|
// TODO: perhaps better would be to map notification_subscription_types to arrays of notification_reason_types
|
|
|
|
const notificationReasonToSubscriptionType: Partial<
|
|
|
|
Record<notification_reason_types, notification_preference>
|
|
|
|
> = {
|
|
|
|
you_referred_user: 'referral_bonuses',
|
|
|
|
user_joined_to_bet_on_your_market: 'referral_bonuses',
|
|
|
|
tip_received: 'tips_on_your_comments',
|
|
|
|
bet_fill: 'limit_order_fills',
|
|
|
|
user_joined_from_your_group_invite: 'referral_bonuses',
|
|
|
|
challenge_accepted: 'limit_order_fills',
|
|
|
|
betting_streak_incremented: 'betting_streaks',
|
|
|
|
liked_and_tipped_your_contract: 'tips_on_your_markets',
|
|
|
|
comment_on_your_contract: 'all_comments_on_my_markets',
|
|
|
|
answer_on_your_contract: 'all_answers_on_my_markets',
|
|
|
|
comment_on_contract_you_follow: 'all_comments_on_watched_markets',
|
|
|
|
answer_on_contract_you_follow: 'all_answers_on_watched_markets',
|
|
|
|
update_on_contract_you_follow: 'market_updates_on_watched_markets',
|
|
|
|
resolution_on_contract_you_follow: 'resolutions_on_watched_markets',
|
|
|
|
comment_on_contract_with_users_shares_in:
|
|
|
|
'all_comments_on_contracts_with_shares_in_on_watched_markets',
|
|
|
|
answer_on_contract_with_users_shares_in:
|
|
|
|
'all_answers_on_contracts_with_shares_in_on_watched_markets',
|
|
|
|
update_on_contract_with_users_shares_in:
|
|
|
|
'market_updates_on_watched_markets_with_shares_in',
|
|
|
|
resolution_on_contract_with_users_shares_in:
|
|
|
|
'resolutions_on_watched_markets_with_shares_in',
|
|
|
|
comment_on_contract_with_users_answer: 'all_comments_on_watched_markets',
|
|
|
|
update_on_contract_with_users_answer: 'market_updates_on_watched_markets',
|
|
|
|
resolution_on_contract_with_users_answer: 'resolutions_on_watched_markets',
|
|
|
|
answer_on_contract_with_users_answer: 'all_answers_on_watched_markets',
|
|
|
|
comment_on_contract_with_users_comment: 'all_comments_on_watched_markets',
|
|
|
|
answer_on_contract_with_users_comment: 'all_answers_on_watched_markets',
|
|
|
|
update_on_contract_with_users_comment: 'market_updates_on_watched_markets',
|
|
|
|
resolution_on_contract_with_users_comment: 'resolutions_on_watched_markets',
|
|
|
|
reply_to_users_answer: 'all_replies_to_my_answers_on_watched_markets',
|
|
|
|
reply_to_users_comment: 'all_replies_to_my_comments_on_watched_markets',
|
|
|
|
}
|
|
|
|
|
|
|
|
export const getNotificationDestinationsForUser = (
|
|
|
|
privateUser: PrivateUser,
|
2022-09-15 21:25:19 +00:00
|
|
|
// TODO: accept reasons array from most to least important and work backwards
|
2022-09-14 23:17:32 +00:00
|
|
|
reason: notification_reason_types | notification_preference
|
|
|
|
) => {
|
|
|
|
const notificationSettings = privateUser.notificationPreferences
|
|
|
|
const unsubscribeEndpoint = getFunctionUrl('unsubscribe')
|
2022-10-10 13:41:41 +00:00
|
|
|
try {
|
|
|
|
let destinations
|
|
|
|
let subscriptionType: notification_preference | undefined
|
|
|
|
if (Object.keys(notificationSettings).includes(reason)) {
|
|
|
|
subscriptionType = reason as notification_preference
|
|
|
|
destinations = notificationSettings[subscriptionType]
|
|
|
|
} else {
|
|
|
|
const key = reason as notification_reason_types
|
|
|
|
subscriptionType = notificationReasonToSubscriptionType[key]
|
|
|
|
destinations = subscriptionType
|
|
|
|
? notificationSettings[subscriptionType]
|
|
|
|
: []
|
|
|
|
}
|
|
|
|
const optOutOfAllSettings = notificationSettings['opt_out_all']
|
|
|
|
// Your market closure notifications are high priority, opt-out doesn't affect their delivery
|
|
|
|
const optedOutOfEmail =
|
|
|
|
optOutOfAllSettings.includes('email') &&
|
|
|
|
subscriptionType !== 'your_contract_closed'
|
|
|
|
const optedOutOfBrowser =
|
|
|
|
optOutOfAllSettings.includes('browser') &&
|
|
|
|
subscriptionType !== 'your_contract_closed'
|
|
|
|
return {
|
|
|
|
sendToEmail: destinations.includes('email') && !optedOutOfEmail,
|
|
|
|
sendToBrowser: destinations.includes('browser') && !optedOutOfBrowser,
|
|
|
|
unsubscribeUrl: `${unsubscribeEndpoint}?id=${privateUser.id}&type=${subscriptionType}`,
|
|
|
|
urlToManageThisNotification: `${DOMAIN}/notifications?tab=settings§ion=${subscriptionType}`,
|
|
|
|
}
|
|
|
|
} catch (e) {
|
|
|
|
// Fail safely
|
|
|
|
console.log(
|
|
|
|
`couldn't get notification destinations for type ${reason} for user ${privateUser.id}`
|
|
|
|
)
|
|
|
|
return {
|
|
|
|
sendToEmail: false,
|
|
|
|
sendToBrowser: false,
|
|
|
|
unsubscribeUrl: '',
|
|
|
|
urlToManageThisNotification: '',
|
|
|
|
}
|
2022-09-14 23:17:32 +00:00
|
|
|
}
|
|
|
|
}
|