allow switching phone numbers but delete previous phone number

This commit is contained in:
m5r 2021-10-19 23:49:28 +02:00
parent 29d24f9fb4
commit fd003f461b
4 changed files with 69 additions and 24 deletions

View File

@ -14,7 +14,7 @@ export default function PhoneInitLoader() {
d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"
/> />
</svg> </svg>
<p>We&#39;re finalizing your cloud phone initialization.</p> <p>We&#39;re finalizing your &#128026;phone initialization.</p>
<p> <p>
You don&#39;t have to refresh this page, we will do it automatically for you when your phone is ready. You don&#39;t have to refresh this page, we will do it automatically for you when your phone is ready.
</p> </p>

View File

@ -8,6 +8,7 @@ import useCurrentUser from "app/core/hooks/use-current-user";
import useUserPhoneNumber from "app/core/hooks/use-current-phone-number"; import useUserPhoneNumber from "app/core/hooks/use-current-phone-number";
import Button from "../button"; import Button from "../button";
import SettingsSection from "../settings-section"; import SettingsSection from "../settings-section";
import Alert from "app/core/components/alert";
type Form = { type Form = {
phoneNumberSid: string; phoneNumberSid: string;
@ -22,7 +23,7 @@ export default function PhoneNumberForm() {
setValue, setValue,
formState: { isSubmitting }, formState: { isSubmitting },
} = useForm<Form>(); } = useForm<Form>();
const [setPhoneNumberMutation] = useMutation(setPhoneNumber); const [setPhoneNumberMutation, { error, isError, isSuccess }] = useMutation(setPhoneNumber);
const [availablePhoneNumbers] = useQuery(getAvailablePhoneNumbers, {}, { enabled: hasFilledTwilioCredentials }); const [availablePhoneNumbers] = useQuery(getAvailablePhoneNumbers, {}, { enabled: hasFilledTwilioCredentials });
useEffect(() => { useEffect(() => {
@ -55,6 +56,22 @@ export default function PhoneNumberForm() {
</div> </div>
} }
> >
{isError ? (
<div className="mb-8">
<Alert
title="Oops, there was an issue"
message={parseErrorMessage(error as Error | null)}
variant="error"
/>
</div>
) : null}
{isSuccess ? (
<div className="mb-8">
<Alert title="Saved successfully" message="Your changes have been saved." variant="success" />
</div>
) : null}
<label htmlFor="phoneNumberSid" className="block text-sm font-medium text-gray-700"> <label htmlFor="phoneNumberSid" className="block text-sm font-medium text-gray-700">
Phone number Phone number
</label> </label>
@ -74,3 +91,15 @@ export default function PhoneNumberForm() {
</form> </form>
); );
} }
function parseErrorMessage(error: Error | null): string {
if (!error) {
return "";
}
if (error.name === "ZodError") {
return JSON.parse(error.message)[0].message;
}
return error.message;
}

View File

@ -1,4 +1,4 @@
import { resolver } from "blitz"; import { NotFoundError, resolver } from "blitz";
import { z } from "zod"; import { z } from "zod";
import twilio from "twilio"; import twilio from "twilio";
import RestException from "twilio/lib/base/RestException"; import RestException from "twilio/lib/base/RestException";
@ -24,15 +24,35 @@ export default resolver.pipe(resolver.zod(Body), resolver.authorize(), async ({
organization.twilioAccountSid, organization.twilioAccountSid,
organization.twilioAuthToken, organization.twilioAuthToken,
).incomingPhoneNumbers.list(); ).incomingPhoneNumbers.list();
const phoneNumber = phoneNumbers.find((phoneNumber) => phoneNumber.sid === phoneNumberSid)!; const twilioPhoneNumber = phoneNumbers.find((phoneNumber) => phoneNumber.sid === phoneNumberSid);
if (!twilioPhoneNumber) {
throw new NotFoundError();
}
const organizationId = organization.id; const organizationId = organization.id;
await db.phoneNumber.create({ const orgCurrentlyActivePhoneNumber = await db.phoneNumber.findFirst({ where: { organizationId } });
data: { if (orgCurrentlyActivePhoneNumber) {
organizationId, // TODO: delete this and allow switching phone numbers easily
id: phoneNumberSid, await db.phoneNumber.delete({
number: phoneNumber.phoneNumber, where: {
}, organizationId_id: {
}); organizationId,
id: orgCurrentlyActivePhoneNumber.id,
},
},
});
}
const phoneNumber = await db.phoneNumber.findFirst({ where: { id: phoneNumberSid } });
if (!phoneNumber) {
await db.phoneNumber.create({
data: {
organizationId,
id: phoneNumberSid,
number: twilioPhoneNumber.phoneNumber,
},
});
}
let newApiKey; let newApiKey;
const mainTwilioClient = twilio(organization.twilioAccountSid, organization.twilioAuthToken); const mainTwilioClient = twilio(organization.twilioAccountSid, organization.twilioAuthToken);
@ -61,7 +81,7 @@ export default resolver.pipe(resolver.zod(Body), resolver.authorize(), async ({
} }
const phoneNumberId = phoneNumberSid; const phoneNumberId = phoneNumberSid;
let promises = [ let promises: Promise<any>[] = [
setTwilioWebhooks.enqueue( setTwilioWebhooks.enqueue(
{ organizationId, phoneNumberId }, { organizationId, phoneNumberId },
{ id: `set-twilio-webhooks-${organizationId}-${phoneNumberId}` }, { id: `set-twilio-webhooks-${organizationId}-${phoneNumberId}` },
@ -71,6 +91,14 @@ export default resolver.pipe(resolver.zod(Body), resolver.authorize(), async ({
const hasActiveSubscription = organization.subscriptions.length > 0; const hasActiveSubscription = organization.subscriptions.length > 0;
if (hasActiveSubscription) { if (hasActiveSubscription) {
promises.push( promises.push(
db.processingPhoneNumber.create({
data: {
organizationId,
phoneNumberId,
hasFetchedMessages: false,
hasFetchedCalls: false,
},
}),
fetchMessagesQueue.enqueue( fetchMessagesQueue.enqueue(
{ organizationId, phoneNumberId }, { organizationId, phoneNumberId },
{ id: `fetch-messages-${organizationId}-${phoneNumberId}` }, { id: `fetch-messages-${organizationId}-${phoneNumberId}` },

View File

@ -26,17 +26,5 @@ export default resolver.pipe(
twilioAuthToken: twilioAuthToken, twilioAuthToken: twilioAuthToken,
}, },
}); });
const phoneNumber = await db.phoneNumber.findFirst({ where: { organizationId } });
if (phoneNumber) {
await db.phoneNumber.delete({
where: {
organizationId_id: {
organizationId,
id: phoneNumber.id,
},
},
});
}
}, },
); );