reformat with prettier with semicolons and tabs
This commit is contained in:
@ -1,4 +1,4 @@
|
||||
export type ApiError = {
|
||||
statusCode: number
|
||||
errorMessage: string
|
||||
}
|
||||
statusCode: number;
|
||||
errorMessage: string;
|
||||
};
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { BlitzApiRequest, BlitzApiResponse } from "blitz"
|
||||
import { BlitzApiRequest, BlitzApiResponse } from "blitz";
|
||||
|
||||
import db from "db"
|
||||
import db from "db";
|
||||
|
||||
export default async function ddd(req: BlitzApiRequest, res: BlitzApiResponse) {
|
||||
await Promise.all([
|
||||
@ -8,9 +8,9 @@ export default async function ddd(req: BlitzApiRequest, res: BlitzApiResponse) {
|
||||
db.phoneCall.deleteMany(),
|
||||
db.phoneNumber.deleteMany(),
|
||||
db.customer.deleteMany(),
|
||||
])
|
||||
]);
|
||||
|
||||
await db.user.deleteMany()
|
||||
await db.user.deleteMany();
|
||||
|
||||
res.status(200).end()
|
||||
res.status(200).end();
|
||||
}
|
||||
|
@ -1,21 +1,21 @@
|
||||
import getConfig from "next/config"
|
||||
import axios from "axios"
|
||||
import getConfig from "next/config";
|
||||
import got from "got";
|
||||
|
||||
const { serverRuntimeConfig } = getConfig()
|
||||
const { serverRuntimeConfig } = getConfig();
|
||||
|
||||
export async function addSubscriber(email: string) {
|
||||
const { apiKey, audienceId } = serverRuntimeConfig.mailChimp
|
||||
const region = apiKey.split("-")[1]
|
||||
const url = `https://${region}.api.mailchimp.com/3.0/lists/${audienceId}/members`
|
||||
const { apiKey, audienceId } = serverRuntimeConfig.mailChimp;
|
||||
const region = apiKey.split("-")[1];
|
||||
const url = `https://${region}.api.mailchimp.com/3.0/lists/${audienceId}/members`;
|
||||
const data = {
|
||||
email_address: email,
|
||||
status: "subscribed",
|
||||
}
|
||||
const base64ApiKey = Buffer.from(`any:${apiKey}`).toString("base64")
|
||||
};
|
||||
const base64ApiKey = Buffer.from(`any:${apiKey}`).toString("base64");
|
||||
const headers = {
|
||||
"Content-Type": "application/json",
|
||||
Authorization: `Basic ${base64ApiKey}`,
|
||||
}
|
||||
};
|
||||
|
||||
return axios.post(url, data, { headers })
|
||||
return got.post(url, { json: data, headers });
|
||||
}
|
||||
|
@ -1,59 +1,59 @@
|
||||
import type { NextApiRequest, NextApiResponse } from "next"
|
||||
import zod from "zod"
|
||||
import type { NextApiRequest, NextApiResponse } from "next";
|
||||
import zod from "zod";
|
||||
|
||||
import type { ApiError } from "../_types"
|
||||
import appLogger from "../../../integrations/logger"
|
||||
import { addSubscriber } from "./_mailchimp"
|
||||
import type { ApiError } from "../_types";
|
||||
import appLogger from "../../../integrations/logger";
|
||||
import { addSubscriber } from "./_mailchimp";
|
||||
|
||||
type Response = {} | ApiError
|
||||
type Response = {} | ApiError;
|
||||
|
||||
const logger = appLogger.child({ route: "/api/newsletter/subscribe" })
|
||||
const logger = appLogger.child({ route: "/api/newsletter/subscribe" });
|
||||
|
||||
const bodySchema = zod.object({
|
||||
email: zod.string().email(),
|
||||
})
|
||||
});
|
||||
|
||||
export default async function subscribeToNewsletter(
|
||||
req: NextApiRequest,
|
||||
res: NextApiResponse<Response>
|
||||
) {
|
||||
if (req.method !== "POST") {
|
||||
const statusCode = 405
|
||||
const statusCode = 405;
|
||||
const apiError: ApiError = {
|
||||
statusCode,
|
||||
errorMessage: `Method ${req.method} Not Allowed`,
|
||||
}
|
||||
logger.error(apiError)
|
||||
};
|
||||
logger.error(apiError);
|
||||
|
||||
res.setHeader("Allow", ["POST"])
|
||||
res.status(statusCode).send(apiError)
|
||||
return
|
||||
res.setHeader("Allow", ["POST"]);
|
||||
res.status(statusCode).send(apiError);
|
||||
return;
|
||||
}
|
||||
|
||||
let body
|
||||
let body;
|
||||
try {
|
||||
body = bodySchema.parse(req.body)
|
||||
body = bodySchema.parse(req.body);
|
||||
} catch (error) {
|
||||
const statusCode = 400
|
||||
const statusCode = 400;
|
||||
const apiError: ApiError = {
|
||||
statusCode,
|
||||
errorMessage: "Body is malformed",
|
||||
}
|
||||
logger.error(error)
|
||||
};
|
||||
logger.error(error);
|
||||
|
||||
res.status(statusCode).send(apiError)
|
||||
return
|
||||
res.status(statusCode).send(apiError);
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
await addSubscriber(body.email)
|
||||
await addSubscriber(body.email);
|
||||
} catch (error) {
|
||||
console.log("error", error.response?.data)
|
||||
console.log("error", error.response?.data);
|
||||
|
||||
if (error.response?.data.title !== "Member Exists") {
|
||||
return res.status(error.response?.status ?? 400).end()
|
||||
return res.status(error.response?.status ?? 400).end();
|
||||
}
|
||||
}
|
||||
|
||||
res.status(200).end()
|
||||
res.status(200).end();
|
||||
}
|
||||
|
@ -1,16 +1,16 @@
|
||||
import { Queue } from "quirrel/blitz"
|
||||
import twilio from "twilio"
|
||||
import { Queue } from "quirrel/blitz";
|
||||
import twilio from "twilio";
|
||||
|
||||
import db from "../../../db"
|
||||
import insertCallsQueue from "./insert-calls"
|
||||
import db from "../../../db";
|
||||
import insertCallsQueue from "./insert-calls";
|
||||
|
||||
type Payload = {
|
||||
customerId: string
|
||||
}
|
||||
customerId: string;
|
||||
};
|
||||
|
||||
const fetchCallsQueue = Queue<Payload>("api/queue/fetch-calls", async ({ customerId }) => {
|
||||
const customer = await db.customer.findFirst({ where: { id: customerId } })
|
||||
const phoneNumber = await db.phoneNumber.findFirst({ where: { customerId } })
|
||||
const customer = await db.customer.findFirst({ where: { id: customerId } });
|
||||
const phoneNumber = await db.phoneNumber.findFirst({ where: { customerId } });
|
||||
|
||||
const [callsSent, callsReceived] = await Promise.all([
|
||||
twilio(customer!.accountSid!, customer!.authToken!).calls.list({
|
||||
@ -19,10 +19,10 @@ const fetchCallsQueue = Queue<Payload>("api/queue/fetch-calls", async ({ custome
|
||||
twilio(customer!.accountSid!, customer!.authToken!).calls.list({
|
||||
to: phoneNumber!.phoneNumber,
|
||||
}),
|
||||
])
|
||||
]);
|
||||
const calls = [...callsSent, ...callsReceived].sort(
|
||||
(a, b) => a.dateCreated.getTime() - b.dateCreated.getTime()
|
||||
)
|
||||
);
|
||||
|
||||
await insertCallsQueue.enqueue(
|
||||
{
|
||||
@ -32,7 +32,7 @@ const fetchCallsQueue = Queue<Payload>("api/queue/fetch-calls", async ({ custome
|
||||
{
|
||||
id: `insert-calls-${customerId}`,
|
||||
}
|
||||
)
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
export default fetchCallsQueue
|
||||
export default fetchCallsQueue;
|
||||
|
@ -1,16 +1,16 @@
|
||||
import { Queue } from "quirrel/blitz"
|
||||
import twilio from "twilio"
|
||||
import { Queue } from "quirrel/blitz";
|
||||
import twilio from "twilio";
|
||||
|
||||
import db from "../../../db"
|
||||
import insertMessagesQueue from "./insert-messages"
|
||||
import db from "../../../db";
|
||||
import insertMessagesQueue from "./insert-messages";
|
||||
|
||||
type Payload = {
|
||||
customerId: string
|
||||
}
|
||||
customerId: string;
|
||||
};
|
||||
|
||||
const fetchMessagesQueue = Queue<Payload>("api/queue/fetch-messages", async ({ customerId }) => {
|
||||
const customer = await db.customer.findFirst({ where: { id: customerId } })
|
||||
const phoneNumber = await db.phoneNumber.findFirst({ where: { customerId } })
|
||||
const customer = await db.customer.findFirst({ where: { id: customerId } });
|
||||
const phoneNumber = await db.phoneNumber.findFirst({ where: { customerId } });
|
||||
|
||||
const [messagesSent, messagesReceived] = await Promise.all([
|
||||
twilio(customer!.accountSid!, customer!.authToken!).messages.list({
|
||||
@ -19,10 +19,10 @@ const fetchMessagesQueue = Queue<Payload>("api/queue/fetch-messages", async ({ c
|
||||
twilio(customer!.accountSid!, customer!.authToken!).messages.list({
|
||||
to: phoneNumber!.phoneNumber,
|
||||
}),
|
||||
])
|
||||
]);
|
||||
const messages = [...messagesSent, ...messagesReceived].sort(
|
||||
(a, b) => a.dateSent.getTime() - b.dateSent.getTime()
|
||||
)
|
||||
);
|
||||
|
||||
await insertMessagesQueue.enqueue(
|
||||
{
|
||||
@ -32,7 +32,7 @@ const fetchMessagesQueue = Queue<Payload>("api/queue/fetch-messages", async ({ c
|
||||
{
|
||||
id: `insert-messages-${customerId}`,
|
||||
}
|
||||
)
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
export default fetchMessagesQueue
|
||||
export default fetchMessagesQueue;
|
||||
|
@ -1,12 +1,12 @@
|
||||
import { Queue } from "quirrel/blitz"
|
||||
import type { CallInstance } from "twilio/lib/rest/api/v2010/account/call"
|
||||
import { Queue } from "quirrel/blitz";
|
||||
import type { CallInstance } from "twilio/lib/rest/api/v2010/account/call";
|
||||
|
||||
import db, { Direction, CallStatus } from "../../../db"
|
||||
import db, { Direction, CallStatus } from "../../../db";
|
||||
|
||||
type Payload = {
|
||||
customerId: string
|
||||
calls: CallInstance[]
|
||||
}
|
||||
customerId: string;
|
||||
calls: CallInstance[];
|
||||
};
|
||||
|
||||
const insertCallsQueue = Queue<Payload>("api/queue/insert-calls", async ({ calls, customerId }) => {
|
||||
const phoneCalls = calls
|
||||
@ -20,40 +20,40 @@ const insertCallsQueue = Queue<Payload>("api/queue/insert-calls", async ({ calls
|
||||
duration: call.duration,
|
||||
createdAt: new Date(call.dateCreated),
|
||||
}))
|
||||
.sort((a, b) => a.createdAt.getTime() - b.createdAt.getTime())
|
||||
.sort((a, b) => a.createdAt.getTime() - b.createdAt.getTime());
|
||||
|
||||
await db.phoneCall.createMany({ data: phoneCalls })
|
||||
})
|
||||
await db.phoneCall.createMany({ data: phoneCalls });
|
||||
});
|
||||
|
||||
export default insertCallsQueue
|
||||
export default insertCallsQueue;
|
||||
|
||||
function translateDirection(direction: CallInstance["direction"]): Direction {
|
||||
switch (direction) {
|
||||
case "inbound":
|
||||
return Direction.Inbound
|
||||
return Direction.Inbound;
|
||||
case "outbound":
|
||||
default:
|
||||
return Direction.Outbound
|
||||
return Direction.Outbound;
|
||||
}
|
||||
}
|
||||
|
||||
function translateStatus(status: CallInstance["status"]): CallStatus {
|
||||
switch (status) {
|
||||
case "busy":
|
||||
return CallStatus.Busy
|
||||
return CallStatus.Busy;
|
||||
case "canceled":
|
||||
return CallStatus.Canceled
|
||||
return CallStatus.Canceled;
|
||||
case "completed":
|
||||
return CallStatus.Completed
|
||||
return CallStatus.Completed;
|
||||
case "failed":
|
||||
return CallStatus.Failed
|
||||
return CallStatus.Failed;
|
||||
case "in-progress":
|
||||
return CallStatus.InProgress
|
||||
return CallStatus.InProgress;
|
||||
case "no-answer":
|
||||
return CallStatus.NoAnswer
|
||||
return CallStatus.NoAnswer;
|
||||
case "queued":
|
||||
return CallStatus.Queued
|
||||
return CallStatus.Queued;
|
||||
case "ringing":
|
||||
return CallStatus.Ringing
|
||||
return CallStatus.Ringing;
|
||||
}
|
||||
}
|
||||
|
@ -1,19 +1,19 @@
|
||||
import { Queue } from "quirrel/blitz"
|
||||
import type { MessageInstance } from "twilio/lib/rest/api/v2010/account/message"
|
||||
import { Queue } from "quirrel/blitz";
|
||||
import type { MessageInstance } from "twilio/lib/rest/api/v2010/account/message";
|
||||
|
||||
import db, { MessageStatus, Direction, Message } from "../../../db"
|
||||
import { encrypt } from "../../../db/_encryption"
|
||||
import db, { MessageStatus, Direction, Message } from "../../../db";
|
||||
import { encrypt } from "../../../db/_encryption";
|
||||
|
||||
type Payload = {
|
||||
customerId: string
|
||||
messages: MessageInstance[]
|
||||
}
|
||||
customerId: string;
|
||||
messages: MessageInstance[];
|
||||
};
|
||||
|
||||
const insertMessagesQueue = Queue<Payload>(
|
||||
"api/queue/insert-messages",
|
||||
async ({ messages, customerId }) => {
|
||||
const customer = await db.customer.findFirst({ where: { id: customerId } })
|
||||
const encryptionKey = customer!.encryptionKey
|
||||
const customer = await db.customer.findFirst({ where: { id: customerId } });
|
||||
const encryptionKey = customer!.encryptionKey;
|
||||
|
||||
const sms = messages
|
||||
.map<Omit<Message, "id">>((message) => ({
|
||||
@ -26,53 +26,53 @@ const insertMessagesQueue = Queue<Payload>(
|
||||
twilioSid: message.sid,
|
||||
sentAt: new Date(message.dateSent),
|
||||
}))
|
||||
.sort((a, b) => a.sentAt.getTime() - b.sentAt.getTime())
|
||||
.sort((a, b) => a.sentAt.getTime() - b.sentAt.getTime());
|
||||
|
||||
await db.message.createMany({ data: sms })
|
||||
await db.message.createMany({ data: sms });
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
export default insertMessagesQueue
|
||||
export default insertMessagesQueue;
|
||||
|
||||
function translateDirection(direction: MessageInstance["direction"]): Direction {
|
||||
switch (direction) {
|
||||
case "inbound":
|
||||
return Direction.Inbound
|
||||
return Direction.Inbound;
|
||||
case "outbound-api":
|
||||
case "outbound-call":
|
||||
case "outbound-reply":
|
||||
default:
|
||||
return Direction.Outbound
|
||||
return Direction.Outbound;
|
||||
}
|
||||
}
|
||||
|
||||
function translateStatus(status: MessageInstance["status"]): MessageStatus {
|
||||
switch (status) {
|
||||
case "accepted":
|
||||
return MessageStatus.Accepted
|
||||
return MessageStatus.Accepted;
|
||||
case "canceled":
|
||||
return MessageStatus.Canceled
|
||||
return MessageStatus.Canceled;
|
||||
case "delivered":
|
||||
return MessageStatus.Delivered
|
||||
return MessageStatus.Delivered;
|
||||
case "failed":
|
||||
return MessageStatus.Failed
|
||||
return MessageStatus.Failed;
|
||||
case "partially_delivered":
|
||||
return MessageStatus.PartiallyDelivered
|
||||
return MessageStatus.PartiallyDelivered;
|
||||
case "queued":
|
||||
return MessageStatus.Queued
|
||||
return MessageStatus.Queued;
|
||||
case "read":
|
||||
return MessageStatus.Read
|
||||
return MessageStatus.Read;
|
||||
case "received":
|
||||
return MessageStatus.Received
|
||||
return MessageStatus.Received;
|
||||
case "receiving":
|
||||
return MessageStatus.Receiving
|
||||
return MessageStatus.Receiving;
|
||||
case "scheduled":
|
||||
return MessageStatus.Scheduled
|
||||
return MessageStatus.Scheduled;
|
||||
case "sending":
|
||||
return MessageStatus.Sending
|
||||
return MessageStatus.Sending;
|
||||
case "sent":
|
||||
return MessageStatus.Sent
|
||||
return MessageStatus.Sent;
|
||||
case "undelivered":
|
||||
return MessageStatus.Undelivered
|
||||
return MessageStatus.Undelivered;
|
||||
}
|
||||
}
|
||||
|
@ -1,34 +1,34 @@
|
||||
import { Queue } from "quirrel/blitz"
|
||||
import twilio from "twilio"
|
||||
import { Queue } from "quirrel/blitz";
|
||||
import twilio from "twilio";
|
||||
|
||||
import db from "../../../db"
|
||||
import db from "../../../db";
|
||||
|
||||
type Payload = {
|
||||
id: string
|
||||
customerId: string
|
||||
to: string
|
||||
content: string
|
||||
}
|
||||
id: string;
|
||||
customerId: string;
|
||||
to: string;
|
||||
content: string;
|
||||
};
|
||||
|
||||
const sendMessageQueue = Queue<Payload>(
|
||||
"api/queue/send-message",
|
||||
async ({ id, customerId, to, content }) => {
|
||||
const customer = await db.customer.findFirst({ where: { id: customerId } })
|
||||
const phoneNumber = await db.phoneNumber.findFirst({ where: { customerId } })
|
||||
const customer = await db.customer.findFirst({ where: { id: customerId } });
|
||||
const phoneNumber = await db.phoneNumber.findFirst({ where: { customerId } });
|
||||
|
||||
const message = await twilio(customer!.accountSid!, customer!.authToken!).messages.create({
|
||||
body: content,
|
||||
to,
|
||||
from: phoneNumber!.phoneNumber,
|
||||
})
|
||||
});
|
||||
await db.message.update({
|
||||
where: { id },
|
||||
data: { twilioSid: message.sid },
|
||||
})
|
||||
});
|
||||
},
|
||||
{
|
||||
retry: ["1min"],
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
export default sendMessageQueue
|
||||
export default sendMessageQueue;
|
||||
|
@ -1,16 +1,16 @@
|
||||
import { Queue } from "quirrel/blitz"
|
||||
import twilio from "twilio"
|
||||
import { Queue } from "quirrel/blitz";
|
||||
import twilio from "twilio";
|
||||
|
||||
import db from "../../../db"
|
||||
import db from "../../../db";
|
||||
|
||||
type Payload = {
|
||||
customerId: string
|
||||
}
|
||||
customerId: string;
|
||||
};
|
||||
|
||||
const setTwilioWebhooks = Queue<Payload>(
|
||||
"api/queue/set-twilio-webhooks",
|
||||
async ({ customerId }) => {
|
||||
const customer = await db.customer.findFirst({ where: { id: customerId } })
|
||||
const customer = await db.customer.findFirst({ where: { id: customerId } });
|
||||
const twimlApp = customer!.twimlAppSid
|
||||
? await twilio(customer!.accountSid!, customer!.authToken!)
|
||||
.applications.get(customer!.twimlAppSid)
|
||||
@ -21,9 +21,9 @@ const setTwilioWebhooks = Queue<Payload>(
|
||||
smsMethod: "POST",
|
||||
voiceUrl: "https://phone.mokhtar.dev/api/webhook/incoming-call",
|
||||
voiceMethod: "POST",
|
||||
})
|
||||
const twimlAppSid = twimlApp.sid
|
||||
const phoneNumber = await db.phoneNumber.findFirst({ where: { customerId } })
|
||||
});
|
||||
const twimlAppSid = twimlApp.sid;
|
||||
const phoneNumber = await db.phoneNumber.findFirst({ where: { customerId } });
|
||||
|
||||
await Promise.all([
|
||||
db.customer.update({
|
||||
@ -36,8 +36,8 @@ const setTwilioWebhooks = Queue<Payload>(
|
||||
smsApplicationSid: twimlAppSid,
|
||||
voiceApplicationSid: twimlAppSid,
|
||||
}),
|
||||
])
|
||||
]);
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
export default setTwilioWebhooks
|
||||
export default setTwilioWebhooks;
|
||||
|
Reference in New Issue
Block a user