feat(usernames): follow-up email and setting for email opt-out

This commit is contained in:
Sabe Jones
2018-11-08 10:00:25 -06:00
parent 7fbc68511b
commit 5d6b6ed29a
4 changed files with 114 additions and 0 deletions

View File

@@ -0,0 +1,110 @@
const MIGRATION_NAME = '20181108_username_email.js';
const AUTHOR_NAME = 'Sabe'; // in case script author needs to know when their ...
const AUTHOR_UUID = '7f14ed62-5408-4e1b-be83-ada62d504931'; // ... own data is done
/*
* Send emails to eligible users announcing upcoming username changes
*/
import monk from 'monk';
import nconf from 'nconf';
import { sendTxn } from '../../website/server/libs/email';
const CONNECTION_STRING = nconf.get('MIGRATION_CONNECT_STRING');
const BASE_URL = nconf.get('BASE_URL');
let dbUsers = monk(CONNECTION_STRING).get('users', { castIds: false });
function processUsers (lastId) {
// specify a query to limit the affected users (empty for all users):
let query = {
migration: {$ne: MIGRATION_NAME},
'flags.verifiedUsername': {$ne: true},
'auth.timestamps.loggedin': {$gt: new Date('2018-10-25')},
};
if (lastId) {
query._id = {
$gt: lastId,
};
}
dbUsers.find(query, {
sort: {_id: 1},
limit: 100,
fields: [
'_id',
'auth',
'preferences',
'profile',
], // specify fields we are interested in to limit retrieved data (empty if we're not reading data):
})
.then(updateUsers)
.catch((err) => {
console.log(err);
return exiting(1, `ERROR! ${ err}`);
});
}
let progressCount = 1000;
let count = 0;
function updateUsers (users) {
if (!users || users.length === 0) {
console.warn('All appropriate users found and modified.');
displayData();
return;
}
let userPromises = users.map(updateUser);
let lastUser = users[users.length - 1];
return Promise.all(userPromises)
.then(() => delay(7000))
.then(() => {
processUsers(lastUser._id);
});
}
function updateUser (user) {
count++;
dbUsers.update({_id: user._id}, {$set: {migration: MIGRATION_NAME}});
sendTxn(
user,
'username-change-followup',
[{name: 'UNSUB_EMAIL_TYPE_URL', content: '/user/settings/notifications?unsubFrom=majorUpdates'},
{name: 'LOGIN_NAME', content: user.auth.local.username},
{name: 'BASE_URL', content: BASE_URL}]
);
if (count % progressCount === 0) console.warn(`${count} ${user._id}`);
if (user._id === AUTHOR_UUID) console.warn(`${AUTHOR_NAME} processed`);
}
function displayData () {
console.warn(`\n${count} users processed\n`);
return exiting(0);
}
function delay (t, v) {
return new Promise(function batchPause (resolve) {
setTimeout(resolve.bind(null, v), t);
});
}
function exiting (code, msg) {
code = code || 0; // 0 = success
if (code && !msg) {
msg = 'ERROR!';
}
if (msg) {
if (code) {
console.error(msg);
} else {
console.log(msg);
}
}
process.exit(code);
}
module.exports = processUsers;

View File

@@ -59,6 +59,7 @@ export default {
'importantAnnouncements',
'weeklyRecaps',
'onboarding',
'majorUpdates',
]),
// list of email-only notifications
onlyEmailsIds: Object.freeze([

View File

@@ -125,6 +125,7 @@
"importantAnnouncements": "Reminders to check in to complete tasks and receive prizes",
"weeklyRecaps": "Summaries of your account activity in the past week (Note: this is currently disabled due to performance issues, but we hope to have this back up and sending e-mails again soon!)",
"onboarding": "Guidance with setting up your Habitica account",
"majorUpdates": "Important announcements",
"questStarted": "Your Quest has Begun",
"invitedQuest": "Invited to Quest",
"kickedGroup": "Kicked from group",

View File

@@ -481,6 +481,7 @@ let schema = new Schema({
importantAnnouncements: {$type: Boolean, default: true},
weeklyRecaps: {$type: Boolean, default: true},
onboarding: {$type: Boolean, default: true},
majorUpdates: {$type: Boolean, default: true},
},
pushNotifications: {
unsubscribeFromAll: {$type: Boolean, default: false},
@@ -492,6 +493,7 @@ let schema = new Schema({
invitedGuild: {$type: Boolean, default: true},
questStarted: {$type: Boolean, default: true},
invitedQuest: {$type: Boolean, default: true},
majorUpdates: {$type: Boolean, default: true},
},
suppressModals: {
levelUp: {$type: Boolean, default: false},