Rename user notification preferences

This commit is contained in:
Ian Philips 2022-09-14 10:26:08 -06:00
parent edbae16c8e
commit 7ba2eab65e
9 changed files with 73 additions and 64 deletions

View File

@ -138,7 +138,7 @@ export const getDestinationsForUser = async (
privateUser: PrivateUser, privateUser: PrivateUser,
reason: notification_reason_types | keyof notification_subscription_types reason: notification_reason_types | keyof notification_subscription_types
) => { ) => {
const notificationSettings = privateUser.notificationSubscriptionTypes const notificationSettings = privateUser.notificationPreferences
let destinations let destinations
let subscriptionType: keyof notification_subscription_types | undefined let subscriptionType: keyof notification_subscription_types | undefined
if (Object.keys(notificationSettings).includes(reason)) { if (Object.keys(notificationSettings).includes(reason)) {
@ -151,9 +151,11 @@ export const getDestinationsForUser = async (
? notificationSettings[subscriptionType] ? notificationSettings[subscriptionType]
: [] : []
} }
// const unsubscribeEndpoint = getFunctionUrl('unsubscribe')
return { return {
sendToEmail: destinations.includes('email'), sendToEmail: destinations.includes('email'),
sendToBrowser: destinations.includes('browser'), sendToBrowser: destinations.includes('browser'),
// unsubscribeUrl: `${unsubscribeEndpoint}?id=${privateUser.id}&type=${subscriptionType}`,
urlToManageThisNotification: `${DOMAIN}/notifications?tab=settings&section=${subscriptionType}`, urlToManageThisNotification: `${DOMAIN}/notifications?tab=settings&section=${subscriptionType}`,
} }
} }

View File

@ -65,9 +65,7 @@ export type PrivateUser = {
initialDeviceToken?: string initialDeviceToken?: string
initialIpAddress?: string initialIpAddress?: string
apiKey?: string apiKey?: string
/** @deprecated - use notificationSubscriptionTypes */ notificationPreferences: notification_subscription_types
notificationPreferences?: notification_subscribe_types
notificationSubscriptionTypes: notification_subscription_types
twitchInfo?: { twitchInfo?: {
twitchName: string twitchName: string
controlToken: string controlToken: string
@ -142,9 +140,6 @@ export const getDefaultNotificationSettings = (
privateUser?: PrivateUser, privateUser?: PrivateUser,
noEmails?: boolean noEmails?: boolean
) => { ) => {
const prevPref = privateUser?.notificationPreferences ?? 'all'
const wantsLess = prevPref === 'less'
const wantsAll = prevPref === 'all'
const { const {
unsubscribedFromCommentEmails, unsubscribedFromCommentEmails,
unsubscribedFromAnswerEmails, unsubscribedFromAnswerEmails,
@ -161,111 +156,96 @@ export const getDefaultNotificationSettings = (
return { return {
// Watched Markets // Watched Markets
all_comments_on_watched_markets: constructPref( all_comments_on_watched_markets: constructPref(
wantsAll, true,
!unsubscribedFromCommentEmails !unsubscribedFromCommentEmails
), ),
all_answers_on_watched_markets: constructPref( all_answers_on_watched_markets: constructPref(
wantsAll, true,
!unsubscribedFromAnswerEmails !unsubscribedFromAnswerEmails
), ),
// Comments // Comments
tips_on_your_comments: constructPref( tips_on_your_comments: constructPref(true, !unsubscribedFromCommentEmails),
wantsAll || wantsLess, comments_by_followed_users_on_watched_markets: constructPref(true, false),
!unsubscribedFromCommentEmails
),
comments_by_followed_users_on_watched_markets: constructPref(
wantsAll,
false
),
all_replies_to_my_comments_on_watched_markets: constructPref( all_replies_to_my_comments_on_watched_markets: constructPref(
wantsAll || wantsLess, true,
!unsubscribedFromCommentEmails !unsubscribedFromCommentEmails
), ),
all_replies_to_my_answers_on_watched_markets: constructPref( all_replies_to_my_answers_on_watched_markets: constructPref(
wantsAll || wantsLess, true,
!unsubscribedFromCommentEmails !unsubscribedFromCommentEmails
), ),
all_comments_on_contracts_with_shares_in_on_watched_markets: constructPref( all_comments_on_contracts_with_shares_in_on_watched_markets: constructPref(
wantsAll, true,
!unsubscribedFromCommentEmails !unsubscribedFromCommentEmails
), ),
// Answers // Answers
answers_by_followed_users_on_watched_markets: constructPref( answers_by_followed_users_on_watched_markets: constructPref(
wantsAll || wantsLess, true,
!unsubscribedFromAnswerEmails !unsubscribedFromAnswerEmails
), ),
answers_by_market_creator_on_watched_markets: constructPref( answers_by_market_creator_on_watched_markets: constructPref(
wantsAll || wantsLess, true,
!unsubscribedFromAnswerEmails !unsubscribedFromAnswerEmails
), ),
all_answers_on_contracts_with_shares_in_on_watched_markets: constructPref( all_answers_on_contracts_with_shares_in_on_watched_markets: constructPref(
wantsAll, true,
!unsubscribedFromAnswerEmails !unsubscribedFromAnswerEmails
), ),
// On users' markets // On users' markets
your_contract_closed: constructPref( your_contract_closed: constructPref(
wantsAll || wantsLess, true,
!unsubscribedFromResolutionEmails !unsubscribedFromResolutionEmails
), // High priority ), // High priority
all_comments_on_my_markets: constructPref( all_comments_on_my_markets: constructPref(
wantsAll || wantsLess, true,
!unsubscribedFromCommentEmails !unsubscribedFromCommentEmails
), ),
all_answers_on_my_markets: constructPref( all_answers_on_my_markets: constructPref(
wantsAll || wantsLess, true,
!unsubscribedFromAnswerEmails !unsubscribedFromAnswerEmails
), ),
subsidized_your_market: constructPref(wantsAll || wantsLess, true), subsidized_your_market: constructPref(true, true),
// Market updates // Market updates
resolutions_on_watched_markets: constructPref( resolutions_on_watched_markets: constructPref(
wantsAll || wantsLess, true,
!unsubscribedFromResolutionEmails !unsubscribedFromResolutionEmails
), ),
market_updates_on_watched_markets: constructPref( market_updates_on_watched_markets: constructPref(true, false),
wantsAll || wantsLess,
false
),
market_updates_on_watched_markets_with_shares_in: constructPref( market_updates_on_watched_markets_with_shares_in: constructPref(
wantsAll || wantsLess, true,
false false
), ),
resolutions_on_watched_markets_with_shares_in: constructPref( resolutions_on_watched_markets_with_shares_in: constructPref(
wantsAll || wantsLess, true,
!unsubscribedFromResolutionEmails !unsubscribedFromResolutionEmails
), ),
//Balance Changes //Balance Changes
loan_income: constructPref(wantsAll || wantsLess, false), loan_income: constructPref(true, false),
betting_streaks: constructPref(wantsAll || wantsLess, false), betting_streaks: constructPref(true, false),
referral_bonuses: constructPref(wantsAll || wantsLess, true), referral_bonuses: constructPref(true, true),
unique_bettors_on_your_contract: constructPref( unique_bettors_on_your_contract: constructPref(true, false),
wantsAll || wantsLess,
false
),
tipped_comments_on_watched_markets: constructPref( tipped_comments_on_watched_markets: constructPref(
wantsAll || wantsLess, true,
!unsubscribedFromCommentEmails !unsubscribedFromCommentEmails
), ),
tips_on_your_markets: constructPref(wantsAll || wantsLess, true), tips_on_your_markets: constructPref(true, true),
limit_order_fills: constructPref(wantsAll || wantsLess, false), limit_order_fills: constructPref(true, false),
// General // General
tagged_user: constructPref(wantsAll || wantsLess, true), tagged_user: constructPref(true, true),
on_new_follow: constructPref(wantsAll || wantsLess, true), on_new_follow: constructPref(true, true),
contract_from_followed_user: constructPref(wantsAll || wantsLess, true), contract_from_followed_user: constructPref(true, true),
trending_markets: constructPref( trending_markets: constructPref(
false, false,
!unsubscribedFromWeeklyTrendingEmails !unsubscribedFromWeeklyTrendingEmails
), ),
profit_loss_updates: constructPref(false, true), profit_loss_updates: constructPref(false, true),
probability_updates_on_watched_markets: constructPref( probability_updates_on_watched_markets: constructPref(true, false),
wantsAll || wantsLess,
false
),
thank_you_for_purchases: constructPref( thank_you_for_purchases: constructPref(
false, false,
!unsubscribedFromGenericEmails !unsubscribedFromGenericEmails

View File

@ -77,7 +77,7 @@ service cloud.firestore {
allow read: if userId == request.auth.uid || isAdmin(); allow read: if userId == request.auth.uid || isAdmin();
allow update: if (userId == request.auth.uid || isAdmin()) allow update: if (userId == request.auth.uid || isAdmin())
&& request.resource.data.diff(resource.data).affectedKeys() && request.resource.data.diff(resource.data).affectedKeys()
.hasOnly(['apiKey', 'unsubscribedFromResolutionEmails', 'unsubscribedFromCommentEmails', 'unsubscribedFromAnswerEmails', 'notificationPreferences', 'unsubscribedFromWeeklyTrendingEmails', 'notificationSubscriptionTypes', 'twitchInfo']); .hasOnly(['apiKey', 'unsubscribedFromResolutionEmails', 'unsubscribedFromCommentEmails', 'unsubscribedFromAnswerEmails', 'unsubscribedFromWeeklyTrendingEmails', 'notificationPreferences', 'twitchInfo']);
} }
match /private-users/{userId}/views/{viewId} { match /private-users/{userId}/views/{viewId} {

View File

@ -83,7 +83,7 @@ export const createuser = newEndpoint(opts, async (req, auth) => {
email, email,
initialIpAddress: req.ip, initialIpAddress: req.ip,
initialDeviceToken: deviceToken, initialDeviceToken: deviceToken,
notificationSubscriptionTypes: getDefaultNotificationSettings(auth.uid), notificationPreferences: getDefaultNotificationSettings(auth.uid),
} }
await firestore.collection('private-users').doc(auth.uid).create(privateUser) await firestore.collection('private-users').doc(auth.uid).create(privateUser)

View File

@ -214,7 +214,7 @@ export const sendOneWeekBonusEmail = async (
if ( if (
!privateUser || !privateUser ||
!privateUser.email || !privateUser.email ||
!privateUser.notificationSubscriptionTypes.onboarding_flow.includes('email') !privateUser.notificationPreferences.onboarding_flow.includes('email')
) )
return return
@ -247,7 +247,7 @@ export const sendCreatorGuideEmail = async (
if ( if (
!privateUser || !privateUser ||
!privateUser.email || !privateUser.email ||
!privateUser.notificationSubscriptionTypes.onboarding_flow.includes('email') !privateUser.notificationPreferences.onboarding_flow.includes('email')
) )
return return
@ -279,7 +279,7 @@ export const sendThankYouEmail = async (
if ( if (
!privateUser || !privateUser ||
!privateUser.email || !privateUser.email ||
!privateUser.notificationSubscriptionTypes.thank_you_for_purchases.includes( !privateUser.notificationPreferences.thank_you_for_purchases.includes(
'email' 'email'
) )
) )
@ -460,9 +460,7 @@ export const sendInterestingMarketsEmail = async (
if ( if (
!privateUser || !privateUser ||
!privateUser.email || !privateUser.email ||
!privateUser.notificationSubscriptionTypes.trending_markets.includes( !privateUser.notificationPreferences.trending_markets.includes('email')
'email'
)
) )
return return

View File

@ -17,7 +17,7 @@ async function main() {
.collection('private-users') .collection('private-users')
.doc(privateUser.id) .doc(privateUser.id)
.update({ .update({
notificationSubscriptionTypes: getDefaultNotificationSettings( notificationPreferences: getDefaultNotificationSettings(
privateUser.id, privateUser.id,
privateUser, privateUser,
disableEmails disableEmails

View File

@ -21,7 +21,7 @@ async function main() {
id: user.id, id: user.id,
email, email,
username, username,
notificationSubscriptionTypes: getDefaultNotificationSettings(user.id), notificationPreferences: getDefaultNotificationSettings(user.id),
} }
if (user.totalDeposits === undefined) { if (user.totalDeposits === undefined) {

View File

@ -0,0 +1,29 @@
import * as admin from 'firebase-admin'
import { initAdmin } from './script-init'
import { getPrivateUser } from 'functions/src/utils'
import { filterDefined } from 'common/lib/util/array'
import { FieldValue } from 'firebase-admin/firestore'
initAdmin()
const firestore = admin.firestore()
async function main() {
// const privateUsers = await getAllPrivateUsers()
const privateUsers = filterDefined([
await getPrivateUser('6hHpzvRG0pMq8PNJs7RZj2qlZGn2'),
])
await Promise.all(
privateUsers.map((privateUser) => {
if (!privateUser.id) return Promise.resolve()
return firestore.collection('private-users').doc(privateUser.id).update({
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
notificationPreferences: privateUser.notificationSubscriptionTypes,
notificationSubscriptionTypes: FieldValue.delete(),
})
})
)
}
if (require.main === module) main().then(() => process.exit())

View File

@ -183,8 +183,8 @@ export function NotificationSettings(props: {
toast toast
.promise( .promise(
updatePrivateUser(privateUser.id, { updatePrivateUser(privateUser.id, {
notificationSubscriptionTypes: { notificationPreferences: {
...privateUser.notificationSubscriptionTypes, ...privateUser.notificationPreferences,
[subscriptionTypeKey]: destinations.includes(setting) [subscriptionTypeKey]: destinations.includes(setting)
? destinations.filter((d) => d !== setting) ? destinations.filter((d) => d !== setting)
: uniq([...destinations, setting]), : uniq([...destinations, setting]),
@ -240,7 +240,7 @@ export function NotificationSettings(props: {
const getUsersSavedPreference = ( const getUsersSavedPreference = (
key: keyof notification_subscription_types key: keyof notification_subscription_types
) => { ) => {
return privateUser.notificationSubscriptionTypes[key] ?? [] return privateUser.notificationPreferences[key] ?? []
} }
const Section = memo(function Section(props: { const Section = memo(function Section(props: {