diff --git a/common/user.ts b/common/user.ts
index 90ee2070..8f8e6d0d 100644
--- a/common/user.ts
+++ b/common/user.ts
@@ -29,6 +29,7 @@ export type PrivateUser = {
email?: string
unsubscribedFromResolutionEmails?: boolean
unsubscribedFromCommentEmails?: boolean
+ unsubscribedFromAnswerEmails?: boolean
initialDeviceToken?: string
initialIpAddress?: string
}
diff --git a/functions/src/create-answer.ts b/functions/src/create-answer.ts
index d18a5a2a..5e711e03 100644
--- a/functions/src/create-answer.ts
+++ b/functions/src/create-answer.ts
@@ -5,7 +5,8 @@ import { Contract } from '../../common/contract'
import { User } from '../../common/user'
import { getNewMultiBetInfo } from '../../common/new-bet'
import { Answer } from '../../common/answer'
-import { getValues } from './utils'
+import { getContract, getValues } from './utils'
+import { sendNewAnswerEmail } from './emails'
export const createAnswer = functions.runWith({ minInstances: 1 }).https.onCall(
async (
@@ -28,7 +29,7 @@ export const createAnswer = functions.runWith({ minInstances: 1 }).https.onCall(
return { status: 'error', message: 'Invalid text' }
// Run as transaction to prevent race conditions.
- return await firestore.runTransaction(async (transaction) => {
+ const result = await firestore.runTransaction(async (transaction) => {
const userDoc = firestore.doc(`users/${userId}`)
const userSnap = await transaction.get(userDoc)
if (!userSnap.exists)
@@ -103,8 +104,15 @@ export const createAnswer = functions.runWith({ minInstances: 1 }).https.onCall(
})
transaction.update(userDoc, { balance: newBalance })
- return { status: 'success', answerId, betId: newBetDoc.id }
+ return { status: 'success', answerId, betId: newBetDoc.id, answer }
})
+
+ const { answer } = result
+ const contract = await getContract(contractId)
+
+ if (answer && contract) await sendNewAnswerEmail(answer, contract)
+
+ return result
}
)
diff --git a/functions/src/email-templates/market-answer.html b/functions/src/email-templates/market-answer.html
new file mode 100644
index 00000000..225436ad
--- /dev/null
+++ b/functions/src/email-templates/market-answer.html
@@ -0,0 +1,499 @@
+
+
+
+
+
+ Market answer
+
+
+
+
+
+
+
+ |
+
+
+
+
+
+
+
+
+
+ |
+
+
+
+
+
+
+
+
+ {{name}}
+
+ |
+
+
+
+
+ {{answer}}
+
+ |
+
+
+
+
+ |
+
+
+ |
+
+
+ |
+
+
+
+
+ |
+ |
+
+
+
+
diff --git a/functions/src/email-templates/market-comment.html b/functions/src/email-templates/market-comment.html
index aa629646..8a472941 100644
--- a/functions/src/email-templates/market-comment.html
+++ b/functions/src/email-templates/market-comment.html
@@ -333,11 +333,12 @@
Arial, sans-serif;
box-sizing: border-box;
font-size: 16px;
- white-space: pre-line;
margin: 0;
"
>
- {{comment}}
+ {{comment}}
diff --git a/functions/src/emails.ts b/functions/src/emails.ts
index da6b3c4b..456a92fe 100644
--- a/functions/src/emails.ts
+++ b/functions/src/emails.ts
@@ -1,4 +1,5 @@
import _ = require('lodash')
+import { Answer } from '../../common/answer'
import { getProbability } from '../../common/calculate'
import { Comment } from '../../common/comment'
import { Contract } from '../../common/contract'
@@ -149,14 +150,11 @@ export const sendNewCommentEmail = async (
const privateUser = await getPrivateUser(userId)
if (
!privateUser ||
- privateUser.unsubscribedFromCommentEmails ||
- !privateUser.email
+ !privateUser.email ||
+ privateUser.unsubscribedFromCommentEmails
)
return
- const user = await getUser(userId)
- if (!user) return
-
const { question, creatorUsername, slug } = contract
const marketUrl = `https://manifold.markets/${creatorUsername}/${slug}`
@@ -184,3 +182,43 @@ export const sendNewCommentEmail = async (
{ from }
)
}
+
+export const sendNewAnswerEmail = async (
+ answer: Answer,
+ contract: Contract
+) => {
+ // Send to just the creator for now.
+ const { creatorId: userId } = contract
+ const privateUser = await getPrivateUser(userId)
+ if (
+ !privateUser ||
+ !privateUser.email ||
+ privateUser.unsubscribedFromAnswerEmails
+ )
+ return
+
+ const { question, creatorUsername, slug } = contract
+ const { name, avatarUrl, text } = answer
+
+ const marketUrl = `https://manifold.markets/${creatorUsername}/${slug}`
+ const unsubscribeUrl = `https://us-central1-${
+ isProd ? 'mantic-markets' : 'dev-mantic-markets'
+ }.cloudfunctions.net/unsubscribe?id=${userId}&type=market-answer`
+
+ const subject = `New answer on ${question}`
+ const from = `${name} `
+
+ await sendTemplateEmail(
+ privateUser.email,
+ subject,
+ 'market-answer',
+ {
+ name,
+ avatarUrl: avatarUrl ?? '',
+ answer: text,
+ marketUrl,
+ unsubscribeUrl,
+ },
+ { from }
+ )
+}
diff --git a/functions/src/unsubscribe.ts b/functions/src/unsubscribe.ts
index 97201ed8..25b11771 100644
--- a/functions/src/unsubscribe.ts
+++ b/functions/src/unsubscribe.ts
@@ -16,8 +16,15 @@ export const unsubscribe = functions
const { name } = user
const update: Partial = {
- unsubscribedFromResolutionEmails: type === 'market-resolve',
- unsubscribedFromCommentEmails: type === 'market-comment',
+ ...(type === 'market-resolve' && {
+ unsubscribedFromResolutionEmails: true,
+ }),
+ ...(type === 'market-comment' && {
+ unsubscribedFromCommentEmails: true,
+ }),
+ ...(type === 'market-answer' && {
+ unsubscribedFromAnswerEmails: true,
+ }),
}
await firestore.collection('private-users').doc(id).update(update)
@@ -30,6 +37,10 @@ export const unsubscribe = functions
res.send(
`${name}, you have been unsubscribed from market comment emails on Manifold Markets.`
)
+ else if (type === 'market-answer')
+ res.send(
+ `${name}, you have been unsubscribed from market answer emails on Manifold Markets.`
+ )
else res.send(`${name}, you have been unsubscribed.`)
} else {
res.send('This user is not currently subscribed or does not exist.')