2022-08-16 16:43:51 +00:00
|
|
|
import * as dayjs from 'dayjs'
|
|
|
|
|
2022-07-10 22:03:15 +00:00
|
|
|
import { DOMAIN } from '../../common/envs/constants'
|
2022-05-15 17:39:42 +00:00
|
|
|
import { Answer } from '../../common/answer'
|
|
|
|
import { Bet } from '../../common/bet'
|
|
|
|
import { getProbability } from '../../common/calculate'
|
|
|
|
import { Comment } from '../../common/comment'
|
2022-06-06 05:50:27 +00:00
|
|
|
import { Contract } from '../../common/contract'
|
2022-05-15 17:39:42 +00:00
|
|
|
import { DPM_CREATOR_FEE } from '../../common/fees'
|
|
|
|
import { PrivateUser, User } from '../../common/user'
|
2022-07-02 19:37:59 +00:00
|
|
|
import {
|
|
|
|
formatLargeNumber,
|
|
|
|
formatMoney,
|
|
|
|
formatPercent,
|
|
|
|
} from '../../common/util/format'
|
2022-05-19 17:42:03 +00:00
|
|
|
import { getValueFromBucket } from '../../common/calculate-dpm'
|
2022-07-02 19:37:59 +00:00
|
|
|
import { formatNumericProbability } from '../../common/pseudo-numeric'
|
2022-05-19 17:42:03 +00:00
|
|
|
|
2022-08-16 16:43:51 +00:00
|
|
|
import { sendTemplateEmail, sendTextEmail } from './send-email'
|
2022-03-09 02:43:30 +00:00
|
|
|
import { getPrivateUser, getUser } from './utils'
|
2022-07-10 22:03:15 +00:00
|
|
|
import { getFunctionUrl } from '../../common/api'
|
2022-08-06 20:39:52 +00:00
|
|
|
import { richTextToString } from '../../common/util/parse'
|
2022-08-19 17:43:57 +00:00
|
|
|
import { buildCardUrl, getOpenGraphProps } from '../../common/contract-details'
|
2022-07-10 22:03:15 +00:00
|
|
|
|
|
|
|
const UNSUBSCRIBE_ENDPOINT = getFunctionUrl('unsubscribe')
|
2022-01-02 00:08:52 +00:00
|
|
|
|
|
|
|
export const sendMarketResolutionEmail = async (
|
|
|
|
userId: string,
|
2022-02-24 07:04:24 +00:00
|
|
|
investment: number,
|
2022-01-02 00:08:52 +00:00
|
|
|
payout: number,
|
|
|
|
creator: User,
|
2022-05-10 13:49:14 +00:00
|
|
|
creatorPayout: number,
|
2022-01-02 00:08:52 +00:00
|
|
|
contract: Contract,
|
2022-02-20 07:26:26 +00:00
|
|
|
resolution: string,
|
|
|
|
resolutionProbability?: number,
|
|
|
|
resolutions?: { [outcome: string]: number }
|
2022-01-02 00:08:52 +00:00
|
|
|
) => {
|
2022-01-19 03:36:46 +00:00
|
|
|
const privateUser = await getPrivateUser(userId)
|
|
|
|
if (
|
|
|
|
!privateUser ||
|
|
|
|
privateUser.unsubscribedFromResolutionEmails ||
|
|
|
|
!privateUser.email
|
|
|
|
)
|
|
|
|
return
|
|
|
|
|
2022-01-02 00:08:52 +00:00
|
|
|
const user = await getUser(userId)
|
|
|
|
if (!user) return
|
|
|
|
|
2022-03-15 22:27:51 +00:00
|
|
|
const outcome = toDisplayResolution(
|
|
|
|
contract,
|
|
|
|
resolution,
|
|
|
|
resolutionProbability,
|
|
|
|
resolutions
|
|
|
|
)
|
2022-01-02 00:08:52 +00:00
|
|
|
|
2022-01-10 22:07:44 +00:00
|
|
|
const subject = `Resolved ${outcome}: ${contract.question}`
|
2022-01-02 00:08:52 +00:00
|
|
|
|
2022-05-10 13:49:14 +00:00
|
|
|
const creatorPayoutText =
|
|
|
|
userId === creator.id
|
|
|
|
? ` (plus ${formatMoney(creatorPayout)} in commissions)`
|
|
|
|
: ''
|
|
|
|
|
2022-07-10 22:03:15 +00:00
|
|
|
const emailType = 'market-resolved'
|
|
|
|
const unsubscribeUrl = `${UNSUBSCRIBE_ENDPOINT}?id=${userId}&type=${emailType}`
|
|
|
|
|
2022-01-10 22:07:44 +00:00
|
|
|
const templateData: market_resolved_template = {
|
2022-01-19 18:43:12 +00:00
|
|
|
userId: user.id,
|
2022-01-10 22:07:44 +00:00
|
|
|
name: user.name,
|
|
|
|
creatorName: creator.name,
|
|
|
|
question: contract.question,
|
|
|
|
outcome,
|
2022-04-28 02:18:52 +00:00
|
|
|
investment: `${Math.floor(investment)}`,
|
2022-05-10 13:49:14 +00:00
|
|
|
payout: `${Math.floor(payout)}${creatorPayoutText}`,
|
2022-03-09 02:43:30 +00:00
|
|
|
url: `https://${DOMAIN}/${creator.username}/${contract.slug}`,
|
2022-07-10 22:03:15 +00:00
|
|
|
unsubscribeUrl,
|
2022-01-10 22:07:44 +00:00
|
|
|
}
|
2022-01-02 00:08:52 +00:00
|
|
|
|
2022-01-10 22:07:44 +00:00
|
|
|
// Modify template here:
|
|
|
|
// https://app.mailgun.com/app/sending/domains/mg.manifold.markets/templates/edit/market-resolved/initial
|
2022-01-02 00:08:52 +00:00
|
|
|
|
2022-08-16 05:13:38 +00:00
|
|
|
return await sendTemplateEmail(
|
2022-01-19 03:36:46 +00:00
|
|
|
privateUser.email,
|
|
|
|
subject,
|
|
|
|
'market-resolved',
|
|
|
|
templateData
|
|
|
|
)
|
2022-01-02 00:08:52 +00:00
|
|
|
}
|
2022-02-08 11:26:33 +00:00
|
|
|
|
2022-03-15 22:27:51 +00:00
|
|
|
type market_resolved_template = {
|
|
|
|
userId: string
|
|
|
|
name: string
|
|
|
|
creatorName: string
|
|
|
|
question: string
|
|
|
|
outcome: string
|
|
|
|
investment: string
|
|
|
|
payout: string
|
|
|
|
url: string
|
2022-07-10 22:03:15 +00:00
|
|
|
unsubscribeUrl: string
|
2022-03-15 22:27:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
const toDisplayResolution = (
|
|
|
|
contract: Contract,
|
|
|
|
resolution: string,
|
|
|
|
resolutionProbability?: number,
|
|
|
|
resolutions?: { [outcome: string]: number }
|
|
|
|
) => {
|
|
|
|
if (contract.outcomeType === 'BINARY') {
|
|
|
|
const prob = resolutionProbability ?? getProbability(contract)
|
|
|
|
|
|
|
|
const display = {
|
|
|
|
YES: 'YES',
|
|
|
|
NO: 'NO',
|
|
|
|
CANCEL: 'N/A',
|
|
|
|
MKT: formatPercent(prob ?? 0),
|
|
|
|
}[resolution]
|
|
|
|
|
|
|
|
return display || resolution
|
|
|
|
}
|
|
|
|
|
2022-07-02 19:37:59 +00:00
|
|
|
if (contract.outcomeType === 'PSEUDO_NUMERIC') {
|
|
|
|
const { resolutionValue } = contract
|
|
|
|
|
|
|
|
return resolutionValue
|
|
|
|
? formatLargeNumber(resolutionValue)
|
|
|
|
: formatNumericProbability(
|
|
|
|
resolutionProbability ?? getProbability(contract),
|
|
|
|
contract
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
2022-03-15 22:27:51 +00:00
|
|
|
if (resolution === 'MKT' && resolutions) return 'MULTI'
|
2022-03-19 02:11:47 +00:00
|
|
|
if (resolution === 'CANCEL') return 'N/A'
|
2022-03-15 22:27:51 +00:00
|
|
|
|
2022-05-19 17:42:03 +00:00
|
|
|
if (contract.outcomeType === 'NUMERIC' && contract.mechanism === 'dpm-2')
|
|
|
|
return (
|
|
|
|
contract.resolutionValue?.toString() ??
|
|
|
|
getValueFromBucket(resolution, contract).toString()
|
|
|
|
)
|
|
|
|
|
2022-06-01 03:40:08 +00:00
|
|
|
const answer = contract.answers.find((a) => a.id === resolution)
|
2022-04-18 23:02:40 +00:00
|
|
|
if (answer) return answer.text
|
2022-03-15 22:27:51 +00:00
|
|
|
return `#${resolution}`
|
|
|
|
}
|
|
|
|
|
2022-02-08 11:26:33 +00:00
|
|
|
export const sendWelcomeEmail = async (
|
|
|
|
user: User,
|
|
|
|
privateUser: PrivateUser
|
|
|
|
) => {
|
2022-05-11 15:51:58 +00:00
|
|
|
if (!privateUser || !privateUser.email) return
|
|
|
|
|
|
|
|
const { name, id: userId } = user
|
|
|
|
const firstName = name.split(' ')[0]
|
2022-02-08 11:26:33 +00:00
|
|
|
|
2022-05-11 15:51:58 +00:00
|
|
|
const emailType = 'generic'
|
2022-07-10 22:03:15 +00:00
|
|
|
const unsubscribeLink = `${UNSUBSCRIBE_ENDPOINT}?id=${userId}&type=${emailType}`
|
2022-05-11 15:51:58 +00:00
|
|
|
|
2022-08-16 05:13:38 +00:00
|
|
|
return await sendTemplateEmail(
|
2022-05-11 15:51:58 +00:00
|
|
|
privateUser.email,
|
2022-02-08 11:26:33 +00:00
|
|
|
'Welcome to Manifold Markets!',
|
2022-05-11 15:51:58 +00:00
|
|
|
'welcome',
|
|
|
|
{
|
|
|
|
name: firstName,
|
|
|
|
unsubscribeLink,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
from: 'David from Manifold <david@manifold.markets>',
|
|
|
|
}
|
|
|
|
)
|
|
|
|
}
|
2022-02-08 11:26:33 +00:00
|
|
|
|
2022-08-16 16:43:51 +00:00
|
|
|
export const sendPersonalFollowupEmail = async (
|
|
|
|
user: User,
|
|
|
|
privateUser: PrivateUser
|
|
|
|
) => {
|
|
|
|
if (!privateUser || !privateUser.email) return
|
|
|
|
|
|
|
|
const { name } = user
|
|
|
|
const firstName = name.split(' ')[0]
|
|
|
|
|
|
|
|
const emailBody = `Hi ${firstName},
|
|
|
|
|
|
|
|
Thanks for signing up! I'm one of the cofounders of Manifold Markets, and was wondering how you've found your exprience on the platform so far?
|
|
|
|
|
|
|
|
If you haven't already, I encourage you to try creating your own prediction market (https://manifold.markets/create) and joining our Discord chat (https://discord.com/invite/eHQBNBqXuh).
|
|
|
|
|
|
|
|
Feel free to reply to this email with any questions or concerns you have.
|
|
|
|
|
|
|
|
Cheers,
|
|
|
|
|
|
|
|
James
|
|
|
|
Cofounder of Manifold Markets
|
|
|
|
https://manifold.markets
|
|
|
|
`
|
|
|
|
|
|
|
|
const sendTime = dayjs().add(4, 'hours').toString()
|
|
|
|
|
|
|
|
await sendTextEmail(
|
|
|
|
privateUser.email,
|
|
|
|
'How are you finding Manifold?',
|
|
|
|
emailBody,
|
|
|
|
{
|
|
|
|
from: 'James from Manifold <james@manifold.markets>',
|
|
|
|
'o:deliverytime': sendTime,
|
|
|
|
}
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
2022-05-11 15:51:58 +00:00
|
|
|
export const sendOneWeekBonusEmail = async (
|
|
|
|
user: User,
|
|
|
|
privateUser: PrivateUser
|
|
|
|
) => {
|
|
|
|
if (
|
|
|
|
!privateUser ||
|
|
|
|
!privateUser.email ||
|
|
|
|
privateUser.unsubscribedFromGenericEmails
|
|
|
|
)
|
|
|
|
return
|
2022-02-22 22:35:53 +00:00
|
|
|
|
2022-05-11 15:51:58 +00:00
|
|
|
const { name, id: userId } = user
|
|
|
|
const firstName = name.split(' ')[0]
|
2022-02-22 22:35:53 +00:00
|
|
|
|
2022-05-11 15:51:58 +00:00
|
|
|
const emailType = 'generic'
|
2022-07-10 22:03:15 +00:00
|
|
|
const unsubscribeLink = `${UNSUBSCRIBE_ENDPOINT}?id=${userId}&type=${emailType}`
|
2022-02-08 11:26:33 +00:00
|
|
|
|
2022-08-16 05:13:38 +00:00
|
|
|
return await sendTemplateEmail(
|
2022-05-11 15:51:58 +00:00
|
|
|
privateUser.email,
|
2022-08-04 18:03:02 +00:00
|
|
|
'Manifold Markets one week anniversary gift',
|
2022-05-11 15:51:58 +00:00
|
|
|
'one-week',
|
|
|
|
{
|
|
|
|
name: firstName,
|
|
|
|
unsubscribeLink,
|
2022-08-04 18:03:02 +00:00
|
|
|
manalink: 'https://manifold.markets/link/lj4JbBvE',
|
2022-05-11 15:51:58 +00:00
|
|
|
},
|
|
|
|
{
|
|
|
|
from: 'David from Manifold <david@manifold.markets>',
|
|
|
|
}
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
2022-08-17 22:36:52 +00:00
|
|
|
export const sendCreatorGuideEmail = async (
|
|
|
|
user: User,
|
|
|
|
privateUser: PrivateUser
|
|
|
|
) => {
|
|
|
|
if (
|
|
|
|
!privateUser ||
|
|
|
|
!privateUser.email ||
|
|
|
|
privateUser.unsubscribedFromGenericEmails
|
|
|
|
)
|
|
|
|
return
|
|
|
|
|
|
|
|
const { name, id: userId } = user
|
|
|
|
const firstName = name.split(' ')[0]
|
|
|
|
|
|
|
|
const emailType = 'generic'
|
|
|
|
const unsubscribeLink = `${UNSUBSCRIBE_ENDPOINT}?id=${userId}&type=${emailType}`
|
|
|
|
|
|
|
|
return await sendTemplateEmail(
|
|
|
|
privateUser.email,
|
|
|
|
'Market creation guide',
|
|
|
|
'creating-market',
|
|
|
|
{
|
|
|
|
name: firstName,
|
|
|
|
unsubscribeLink,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
from: 'David from Manifold <david@manifold.markets>',
|
|
|
|
}
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
2022-05-11 15:51:58 +00:00
|
|
|
export const sendThankYouEmail = async (
|
|
|
|
user: User,
|
|
|
|
privateUser: PrivateUser
|
|
|
|
) => {
|
|
|
|
if (
|
|
|
|
!privateUser ||
|
|
|
|
!privateUser.email ||
|
|
|
|
privateUser.unsubscribedFromGenericEmails
|
|
|
|
)
|
|
|
|
return
|
|
|
|
|
|
|
|
const { name, id: userId } = user
|
|
|
|
const firstName = name.split(' ')[0]
|
|
|
|
|
|
|
|
const emailType = 'generic'
|
2022-07-10 22:03:15 +00:00
|
|
|
const unsubscribeLink = `${UNSUBSCRIBE_ENDPOINT}?id=${userId}&type=${emailType}`
|
2022-05-11 15:51:58 +00:00
|
|
|
|
2022-08-16 05:13:38 +00:00
|
|
|
return await sendTemplateEmail(
|
2022-05-11 15:51:58 +00:00
|
|
|
privateUser.email,
|
|
|
|
'Thanks for your Manifold purchase',
|
|
|
|
'thank-you',
|
|
|
|
{
|
|
|
|
name: firstName,
|
|
|
|
unsubscribeLink,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
from: 'David from Manifold <david@manifold.markets>',
|
|
|
|
}
|
2022-02-08 11:26:33 +00:00
|
|
|
)
|
|
|
|
}
|
2022-02-17 18:18:02 +00:00
|
|
|
|
|
|
|
export const sendMarketCloseEmail = async (
|
|
|
|
user: User,
|
|
|
|
privateUser: PrivateUser,
|
|
|
|
contract: Contract
|
|
|
|
) => {
|
|
|
|
if (
|
|
|
|
!privateUser ||
|
|
|
|
privateUser.unsubscribedFromResolutionEmails ||
|
|
|
|
!privateUser.email
|
|
|
|
)
|
|
|
|
return
|
|
|
|
|
|
|
|
const { username, name, id: userId } = user
|
|
|
|
const firstName = name.split(' ')[0]
|
|
|
|
|
2022-05-10 15:23:32 +00:00
|
|
|
const { question, slug, volume, mechanism, collectedFees } = contract
|
|
|
|
|
2022-03-09 02:43:30 +00:00
|
|
|
const url = `https://${DOMAIN}/${username}/${slug}`
|
2022-07-10 22:03:15 +00:00
|
|
|
const emailType = 'market-resolve'
|
|
|
|
const unsubscribeUrl = `${UNSUBSCRIBE_ENDPOINT}?id=${userId}&type=${emailType}`
|
2022-02-17 18:18:02 +00:00
|
|
|
|
2022-08-16 05:13:38 +00:00
|
|
|
return await sendTemplateEmail(
|
2022-02-17 18:18:02 +00:00
|
|
|
privateUser.email,
|
|
|
|
'Your market has closed',
|
|
|
|
'market-close',
|
|
|
|
{
|
|
|
|
question,
|
|
|
|
url,
|
2022-07-10 22:03:15 +00:00
|
|
|
unsubscribeUrl,
|
2022-02-17 18:18:02 +00:00
|
|
|
userId,
|
2022-05-10 15:23:32 +00:00
|
|
|
name: firstName,
|
|
|
|
volume: formatMoney(volume),
|
|
|
|
creatorFee:
|
|
|
|
mechanism === 'dpm-2'
|
|
|
|
? `${DPM_CREATOR_FEE * 100}% of the profits`
|
|
|
|
: formatMoney(collectedFees.creatorFee),
|
2022-02-17 18:18:02 +00:00
|
|
|
}
|
|
|
|
)
|
|
|
|
}
|
2022-02-23 01:35:25 +00:00
|
|
|
|
|
|
|
export const sendNewCommentEmail = async (
|
|
|
|
userId: string,
|
|
|
|
commentCreator: User,
|
2022-02-24 00:52:19 +00:00
|
|
|
contract: Contract,
|
2022-02-23 01:35:25 +00:00
|
|
|
comment: Comment,
|
2022-04-21 17:09:06 +00:00
|
|
|
bet?: Bet,
|
2022-05-18 13:25:38 +00:00
|
|
|
answerText?: string,
|
|
|
|
answerId?: string
|
2022-02-23 01:35:25 +00:00
|
|
|
) => {
|
|
|
|
const privateUser = await getPrivateUser(userId)
|
|
|
|
if (
|
|
|
|
!privateUser ||
|
2022-02-23 06:05:04 +00:00
|
|
|
!privateUser.email ||
|
|
|
|
privateUser.unsubscribedFromCommentEmails
|
2022-02-23 01:35:25 +00:00
|
|
|
)
|
|
|
|
return
|
|
|
|
|
|
|
|
const { question, creatorUsername, slug } = contract
|
2022-05-25 22:47:08 +00:00
|
|
|
const marketUrl = `https://${DOMAIN}/${creatorUsername}/${slug}#${comment.id}`
|
2022-07-10 20:46:00 +00:00
|
|
|
const emailType = 'market-comment'
|
2022-07-10 22:03:15 +00:00
|
|
|
const unsubscribeUrl = `${UNSUBSCRIBE_ENDPOINT}?id=${userId}&type=${emailType}`
|
2022-02-23 01:35:25 +00:00
|
|
|
|
|
|
|
const { name: commentorName, avatarUrl: commentorAvatarUrl } = commentCreator
|
2022-08-06 20:39:52 +00:00
|
|
|
const { content } = comment
|
|
|
|
const text = richTextToString(content)
|
2022-02-23 01:35:25 +00:00
|
|
|
|
2022-04-21 17:09:06 +00:00
|
|
|
let betDescription = ''
|
|
|
|
if (bet) {
|
|
|
|
const { amount, sale } = bet
|
2022-04-28 02:18:52 +00:00
|
|
|
betDescription = `${sale || amount < 0 ? 'sold' : 'bought'} ${formatMoney(
|
2022-04-28 03:34:50 +00:00
|
|
|
Math.abs(amount)
|
2022-04-28 02:18:52 +00:00
|
|
|
)}`
|
2022-04-21 17:09:06 +00:00
|
|
|
}
|
2022-02-24 00:52:19 +00:00
|
|
|
|
2022-07-19 19:54:42 +00:00
|
|
|
const subject = `Comment on ${question}`
|
2022-06-22 20:01:03 +00:00
|
|
|
const from = `${commentorName} on Manifold <no-reply@manifold.markets>`
|
2022-02-23 01:35:25 +00:00
|
|
|
|
2022-05-18 13:25:38 +00:00
|
|
|
if (contract.outcomeType === 'FREE_RESPONSE' && answerId && answerText) {
|
|
|
|
const answerNumber = `#${answerId}`
|
2022-02-24 06:36:27 +00:00
|
|
|
|
2022-08-16 05:13:38 +00:00
|
|
|
return await sendTemplateEmail(
|
2022-02-24 06:36:27 +00:00
|
|
|
privateUser.email,
|
|
|
|
subject,
|
|
|
|
'market-answer-comment',
|
|
|
|
{
|
|
|
|
answer: answerText,
|
|
|
|
answerNumber,
|
|
|
|
commentorName,
|
|
|
|
commentorAvatarUrl: commentorAvatarUrl ?? '',
|
|
|
|
comment: text,
|
|
|
|
marketUrl,
|
|
|
|
unsubscribeUrl,
|
|
|
|
betDescription,
|
|
|
|
},
|
|
|
|
{ from }
|
|
|
|
)
|
|
|
|
} else {
|
2022-04-21 17:09:06 +00:00
|
|
|
if (bet) {
|
|
|
|
betDescription = `${betDescription} of ${toDisplayResolution(
|
|
|
|
contract,
|
|
|
|
bet.outcome
|
|
|
|
)}`
|
|
|
|
}
|
2022-08-16 05:13:38 +00:00
|
|
|
return await sendTemplateEmail(
|
2022-02-24 06:36:27 +00:00
|
|
|
privateUser.email,
|
|
|
|
subject,
|
|
|
|
'market-comment',
|
|
|
|
{
|
|
|
|
commentorName,
|
|
|
|
commentorAvatarUrl: commentorAvatarUrl ?? '',
|
|
|
|
comment: text,
|
|
|
|
marketUrl,
|
|
|
|
unsubscribeUrl,
|
|
|
|
betDescription,
|
|
|
|
},
|
|
|
|
{ from }
|
|
|
|
)
|
|
|
|
}
|
2022-02-23 01:35:25 +00:00
|
|
|
}
|
2022-02-23 06:05:04 +00:00
|
|
|
|
|
|
|
export const sendNewAnswerEmail = async (
|
|
|
|
answer: Answer,
|
|
|
|
contract: Contract
|
|
|
|
) => {
|
|
|
|
// Send to just the creator for now.
|
|
|
|
const { creatorId: userId } = contract
|
2022-03-02 01:25:19 +00:00
|
|
|
|
|
|
|
// Don't send the creator's own answers.
|
|
|
|
if (answer.userId === userId) return
|
|
|
|
|
2022-02-23 06:05:04 +00:00
|
|
|
const privateUser = await getPrivateUser(userId)
|
|
|
|
if (
|
|
|
|
!privateUser ||
|
|
|
|
!privateUser.email ||
|
|
|
|
privateUser.unsubscribedFromAnswerEmails
|
|
|
|
)
|
|
|
|
return
|
|
|
|
|
|
|
|
const { question, creatorUsername, slug } = contract
|
|
|
|
const { name, avatarUrl, text } = answer
|
|
|
|
|
2022-03-09 02:43:30 +00:00
|
|
|
const marketUrl = `https://${DOMAIN}/${creatorUsername}/${slug}`
|
2022-07-10 20:46:00 +00:00
|
|
|
const emailType = 'market-answer'
|
2022-07-10 22:03:15 +00:00
|
|
|
const unsubscribeUrl = `${UNSUBSCRIBE_ENDPOINT}?id=${userId}&type=${emailType}`
|
2022-02-23 06:05:04 +00:00
|
|
|
|
|
|
|
const subject = `New answer on ${question}`
|
|
|
|
const from = `${name} <info@manifold.markets>`
|
|
|
|
|
2022-08-16 05:13:38 +00:00
|
|
|
return await sendTemplateEmail(
|
2022-02-23 06:05:04 +00:00
|
|
|
privateUser.email,
|
|
|
|
subject,
|
|
|
|
'market-answer',
|
|
|
|
{
|
|
|
|
name,
|
|
|
|
avatarUrl: avatarUrl ?? '',
|
|
|
|
answer: text,
|
|
|
|
marketUrl,
|
|
|
|
unsubscribeUrl,
|
|
|
|
},
|
|
|
|
{ from }
|
|
|
|
)
|
|
|
|
}
|
2022-08-19 17:43:57 +00:00
|
|
|
|
|
|
|
export const sendInterestingMarketsEmail = async (
|
|
|
|
user: User,
|
|
|
|
privateUser: PrivateUser,
|
|
|
|
contractsToSend: Contract[],
|
|
|
|
deliveryTime?: string
|
|
|
|
) => {
|
|
|
|
if (
|
|
|
|
!privateUser ||
|
|
|
|
!privateUser.email ||
|
|
|
|
privateUser?.unsubscribedFromWeeklyTrendingEmails
|
|
|
|
)
|
|
|
|
return
|
|
|
|
|
|
|
|
const emailType = 'weekly-trending'
|
|
|
|
const unsubscribeUrl = `${UNSUBSCRIBE_ENDPOINT}?id=${privateUser.id}&type=${emailType}`
|
|
|
|
|
|
|
|
const { name } = user
|
|
|
|
const firstName = name.split(' ')[0]
|
|
|
|
|
|
|
|
await sendTemplateEmail(
|
|
|
|
privateUser.email,
|
|
|
|
`${contractsToSend[0].question} & 5 more interesting markets on Manifold`,
|
|
|
|
'interesting-markets',
|
|
|
|
{
|
|
|
|
name: firstName,
|
|
|
|
unsubscribeLink: unsubscribeUrl,
|
|
|
|
|
|
|
|
question1Title: contractsToSend[0].question,
|
|
|
|
question1Link: contractUrl(contractsToSend[0]),
|
|
|
|
question1ImgSrc: imageSourceUrl(contractsToSend[0]),
|
|
|
|
question2Title: contractsToSend[1].question,
|
|
|
|
question2Link: contractUrl(contractsToSend[1]),
|
|
|
|
question2ImgSrc: imageSourceUrl(contractsToSend[1]),
|
|
|
|
question3Title: contractsToSend[2].question,
|
|
|
|
question3Link: contractUrl(contractsToSend[2]),
|
|
|
|
question3ImgSrc: imageSourceUrl(contractsToSend[2]),
|
|
|
|
question4Title: contractsToSend[3].question,
|
|
|
|
question4Link: contractUrl(contractsToSend[3]),
|
|
|
|
question4ImgSrc: imageSourceUrl(contractsToSend[3]),
|
|
|
|
question5Title: contractsToSend[4].question,
|
|
|
|
question5Link: contractUrl(contractsToSend[4]),
|
|
|
|
question5ImgSrc: imageSourceUrl(contractsToSend[4]),
|
|
|
|
question6Title: contractsToSend[5].question,
|
|
|
|
question6Link: contractUrl(contractsToSend[5]),
|
|
|
|
question6ImgSrc: imageSourceUrl(contractsToSend[5]),
|
|
|
|
},
|
|
|
|
deliveryTime ? { 'o:deliverytime': deliveryTime } : undefined
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
|
|
|
function contractUrl(contract: Contract) {
|
|
|
|
return `https://manifold.markets/${contract.creatorUsername}/${contract.slug}`
|
|
|
|
}
|
|
|
|
|
|
|
|
function imageSourceUrl(contract: Contract) {
|
|
|
|
return buildCardUrl(getOpenGraphProps(contract))
|
|
|
|
}
|