149 lines
4.9 KiB
TypeScript
149 lines
4.9 KiB
TypeScript
import nodemailer from 'nodemailer';
|
|
import sql from '$lib/db/db.server';
|
|
import jwt from 'jsonwebtoken';
|
|
import { type inquiryTokenPayload, Sender } from '$lib/types/inquiries';
|
|
import type { Item } from '$lib/types/item';
|
|
|
|
// Create a transporter object using SMTP transport
|
|
export const transporter = nodemailer.createTransport({
|
|
host: process.env.EMAIL_HOST,
|
|
port: Number(process.env.EMAIL_PORT),
|
|
secure: true, // true for 465, false for other ports
|
|
auth: {
|
|
user: process.env.EMAIL_USER,
|
|
pass: process.env.EMAIL_PASS
|
|
}
|
|
});
|
|
|
|
export async function sendNewInquiryEmail(inquiryId: number) {
|
|
// const item: Item = await sql`
|
|
// SELECT json_agg(item_data) AS result
|
|
// FROM (
|
|
// SELECT
|
|
// i.*,
|
|
// (
|
|
// SELECT json_agg(thread_data)
|
|
// FROM (
|
|
// SELECT
|
|
// it.id,
|
|
// it.item_id,
|
|
// (
|
|
// SELECT json_agg(im)
|
|
// FROM inquiry_messages im
|
|
// WHERE im.thread_id = it.id
|
|
// ) AS messages
|
|
// FROM inquiry_threads it
|
|
// WHERE it.id = ${inquiryId}
|
|
// ) AS thread_data
|
|
// ) AS threads
|
|
// FROM items i
|
|
// WHERE i.id = (
|
|
// SELECT item_id
|
|
// FROM inquiry_threads
|
|
// WHERE id = ${inquiryId}
|
|
// )
|
|
// ) AS item_data;
|
|
//
|
|
// `;
|
|
|
|
const [item]: Item[] = await sql`
|
|
SELECT
|
|
i.*,
|
|
json_agg(
|
|
jsonb_build_object(
|
|
'id', t.id,
|
|
'item_id', t.item_id,
|
|
'created_at', t.created_at,
|
|
'messages', m.messages
|
|
)
|
|
) FILTER ( WHERE t.id = ${inquiryId} ) AS threads
|
|
FROM items i
|
|
LEFT JOIN inquiry_threads t
|
|
ON t.item_id = i.id
|
|
LEFT JOIN LATERAL (
|
|
SELECT
|
|
json_agg(im.* ORDER BY im.created_at) AS messages
|
|
FROM inquiry_messages im
|
|
WHERE im.thread_id = t.id
|
|
) m ON TRUE
|
|
WHERE i.id = (SELECT item_id FROM inquiry_threads WHERE id = ${inquiryId})
|
|
GROUP BY i.id;`;
|
|
|
|
const tokenPayload: inquiryTokenPayload = {
|
|
threadId: inquiryId,
|
|
sender: Sender.FINDER
|
|
};
|
|
const replyToken = jwt.sign(tokenPayload, process.env.JWT_SECRET!);
|
|
|
|
console.log(item);
|
|
console.log(item.threads);
|
|
console.log(replyToken);
|
|
// Send mail with defined transport object
|
|
await transporter.sendMail({
|
|
from: `Westuffind Notifier <${process.env.EMAIL_USER}>`,
|
|
to: item.emails,
|
|
// to: 'drake@marinodev.com', // TEMPORARY EMAIL FOR TESTING
|
|
replyTo: `${process.env.EMAIL_USER!.split('@')[0]}+${replyToken}${process.env.EMAIL_USER!.split('@')[1]}`,
|
|
subject: 'New Item Inquiry!',
|
|
text: `Someone has made an inquiry on the item with description: ${item.description}\nThey ask: ${item.threads![0].messages[0].body}\n\n\nRespond to this email directly, or click the below link to reply on Westuffinder\n${process.env.BASE_URL}/items/${item.id}/inquiries/${inquiryId}?token=${replyToken}`
|
|
});
|
|
}
|
|
|
|
export async function sendInquiryMessageEmail(inquiryId: number, sender: Sender) {
|
|
const [item]: Item[] = await sql`
|
|
SELECT
|
|
i.*,
|
|
json_agg(
|
|
jsonb_build_object(
|
|
'id', t.id,
|
|
'item_id', t.item_id,
|
|
'created_at', t.created_at,
|
|
'messages', m.messages
|
|
)
|
|
) FILTER ( WHERE t.id = ${inquiryId} ) AS threads
|
|
FROM items i
|
|
LEFT JOIN inquiry_threads t
|
|
ON t.item_id = i.id
|
|
LEFT JOIN LATERAL (
|
|
SELECT
|
|
json_agg(im.* ORDER BY im.created_at) AS messages
|
|
FROM inquiry_messages im
|
|
WHERE im.thread_id = t.id
|
|
) m ON TRUE
|
|
WHERE i.id = (SELECT item_id FROM inquiry_threads WHERE id = ${inquiryId})
|
|
GROUP BY i.id;`;
|
|
|
|
const tokenPayload: inquiryTokenPayload = {
|
|
threadId: inquiryId,
|
|
sender
|
|
};
|
|
const replyToken = jwt.sign(tokenPayload, process.env.JWT_SECRET!);
|
|
|
|
// Send mail with defined transport object
|
|
await transporter.sendMail({
|
|
from: `Westuffind Notifier <${process.env.EMAIL_USER}>`,
|
|
to: item.emails,
|
|
// to: 'drake@marinodev.com', // TEMPORARY EMAIL FOR TESTING
|
|
replyTo: `${process.env.EMAIL_USER!.split('@')[0]}+${replyToken}${process.env.EMAIL_USER!.split('@')[1]}`,
|
|
subject: 'New Item Inquiry!',
|
|
text: `Someone has replied to the inquiry on the item with description: ${item.description}\nThey say: ${item.threads![0].messages[item.threads![0].messages.length - 1].body}\n\n\nRespond to this email directly, or click the below link to reply on Westuffinder\n${process.env.BASE_URL}/items/${item.id}/inquiries/${inquiryId}?token=${replyToken}`
|
|
});
|
|
}
|
|
|
|
export async function sendClaimEmail(id: number, email: string) {
|
|
const [item]: Item[] = await sql`
|
|
SELECT * FROM items WHERE id = ${id};`;
|
|
|
|
if (!item.transferred) {
|
|
// Send mail with defined transport object
|
|
await transporter.sendMail({
|
|
from: `Westuffind Notifier <${process.env.EMAIL_USER}>`,
|
|
to: item.emails,
|
|
replyTo: email,
|
|
// to: 'drake@marinodev.com', // TEMPORARY EMAIL FOR TESTING
|
|
subject: 'Your Item was Claimed!',
|
|
text: `Someone has claimed your item with description: ${item.description}\nReply to this email explaining how they can pick up the item from you. Replies to this email go directly to the claimer.`
|
|
});
|
|
}
|
|
}
|