add recipient field to messages and phone calls

This commit is contained in:
m5r
2022-05-22 01:17:43 +02:00
parent 6684dcc0e5
commit 1f37eb45d5
6 changed files with 78 additions and 58 deletions

View File

@ -1,14 +1,14 @@
import type { LoaderFunction } from "@remix-run/node";
import { json } from "superjson-remix";
import { parsePhoneNumber } from "awesome-phonenumber";
import { type Message, Prisma, Direction } from "@prisma/client";
import { type Message, Prisma } from "@prisma/client";
import db from "~/utils/db.server";
import { requireLoggedIn, type SessionData } from "~/utils/auth.server";
export type MessagesLoaderData = {
user: { hasPhoneNumber: boolean };
conversations: Record<string, Conversation> | undefined;
conversations: Conversations | undefined;
};
type Conversation = {
@ -18,23 +18,23 @@ type Conversation = {
};
const loader: LoaderFunction = async ({ request }) => {
const sessionData = await requireLoggedIn(request);
const { phoneNumber } = await requireLoggedIn(request);
return json<MessagesLoaderData>({
user: { hasPhoneNumber: Boolean(sessionData.phoneNumber) },
conversations: await getConversations(sessionData.phoneNumber),
user: { hasPhoneNumber: Boolean(phoneNumber) },
conversations: await getConversations(phoneNumber),
});
};
export default loader;
type Conversations = Record<string, Conversation>;
async function getConversations(sessionPhoneNumber: SessionData["phoneNumber"]) {
if (!sessionPhoneNumber) {
return;
}
const phoneNumber = await db.phoneNumber.findUnique({
where: { id: sessionPhoneNumber.id },
});
const phoneNumber = await db.phoneNumber.findUnique({ where: { id: sessionPhoneNumber.id } });
if (!phoneNumber || phoneNumber.isFetchingMessages) {
return;
}
@ -42,34 +42,22 @@ async function getConversations(sessionPhoneNumber: SessionData["phoneNumber"])
const messages = await db.message.findMany({
where: { phoneNumberId: phoneNumber.id },
orderBy: { sentAt: Prisma.SortOrder.desc },
distinct: "recipient",
});
let conversations: Record<string, Conversation> = {};
for (const message of messages) {
let recipient: string;
if (message.direction === Direction.Outbound) {
recipient = message.to;
} else {
recipient = message.from;
}
return messages.reduce<Conversations>((conversations, message) => {
const recipient = message.recipient;
const formattedPhoneNumber = parsePhoneNumber(recipient).getNumber("international");
if (!conversations[recipient]) {
conversations[recipient] = {
recipient,
formattedPhoneNumber,
lastMessage: message,
};
}
if (message.sentAt > conversations[recipient].lastMessage.sentAt) {
conversations[recipient].lastMessage = message;
}
conversations[recipient] = {
recipient,
formattedPhoneNumber,
lastMessage: message,
};
/*conversations[recipient]!.messages.push({
...message,
content: decrypt(message.content, organization.encryptionKey),
});*/
}
return conversations;
return conversations;
}, {});
}

View File

@ -4,7 +4,8 @@ import { z } from "zod";
import db from "~/utils/db.server";
import { type FormError, validate } from "~/utils/validation.server";
import { requireLoggedIn } from "~/utils/auth.server";
import { refreshSessionData, requireLoggedIn } from "~/utils/auth.server";
import { commitSession } from "~/utils/session.server";
import setTwilioWebhooksQueue from "~/queues/set-twilio-webhooks.server";
type SetPhoneNumberFailureActionData = { errors: FormError<typeof bodySchema>; submitted?: never };
@ -39,9 +40,16 @@ const action: ActionFunction = async ({ request }) => {
phoneNumberId: validation.data.phoneNumberSid,
organizationId: organization.id,
});
console.log("queued");
const { session } = await refreshSessionData(request);
return json<SetPhoneNumberActionData>({ submitted: true });
return json<SetPhoneNumberActionData>(
{ submitted: true },
{
headers: {
"Set-Cookie": await commitSession(session),
},
},
);
};
export default action;

View File

@ -1,5 +1,5 @@
import type { MessageInstance } from "twilio/lib/rest/api/v2010/account/message";
import type { Message } from "@prisma/client";
import { type Message, Direction } from "@prisma/client";
import { Queue } from "~/utils/queue.server";
import db from "~/utils/db.server";
@ -22,20 +22,25 @@ export default Queue<Payload>("insert messages", async ({ data }) => {
}
const sms = messages
.map<Message>((message) => ({
id: message.sid,
phoneNumberId: phoneNumber.id,
content: message.body,
from: message.from,
to: message.to,
status: translateMessageStatus(message.status),
direction: translateMessageDirection(message.direction),
sentAt: new Date(message.dateCreated),
}))
.map<Message>((message) => {
const status = translateMessageStatus(message.status);
const direction = translateMessageDirection(message.direction);
return {
id: message.sid,
phoneNumberId: phoneNumber.id,
content: message.body,
recipient: direction === Direction.Outbound ? message.to : message.from,
from: message.from,
to: message.to,
status,
direction,
sentAt: new Date(message.dateCreated),
};
})
.sort((a, b) => a.sentAt.getTime() - b.sentAt.getTime());
const { count } = await db.message.createMany({ data: sms, skipDuplicates: true });
logger.info(`inserted ${count} new messages for phoneNumberId=${phoneNumberId}`)
logger.info(`inserted ${count} new messages for phoneNumberId=${phoneNumberId}`);
if (!phoneNumber.isFetchingMessages) {
return;

View File

@ -1,5 +1,5 @@
import type { CallInstance } from "twilio/lib/rest/api/v2010/account/call";
import type { PhoneCall } from "@prisma/client";
import { type PhoneCall, Direction } from "@prisma/client";
import { Queue } from "~/utils/queue.server";
import db from "~/utils/db.server";
@ -22,16 +22,21 @@ export default Queue<Payload>("insert phone calls", async ({ data }) => {
}
const phoneCalls = calls
.map<PhoneCall>((call) => ({
phoneNumberId,
id: call.sid,
from: call.from,
to: call.to,
direction: translateCallDirection(call.direction),
status: translateCallStatus(call.status),
duration: call.duration,
createdAt: new Date(call.dateCreated),
}))
.map<PhoneCall>((call) => {
const direction = translateCallDirection(call.direction);
const status = translateCallStatus(call.status);
return {
phoneNumberId,
id: call.sid,
recipient: direction === Direction.Outbound ? call.to : call.from,
from: call.from,
to: call.to,
direction,
status,
duration: call.duration,
createdAt: new Date(call.dateCreated),
};
})
.sort((a, b) => a.createdAt.getTime() - b.createdAt.getTime());
const ddd = await db.phoneCall.createMany({ data: phoneCalls, skipDuplicates: true });