Skip to content

Commit

Permalink
Support A2p brands and campaigns
Browse files Browse the repository at this point in the history
  • Loading branch information
aahung committed May 28, 2024
1 parent 87ec90c commit 9658667
Show file tree
Hide file tree
Showing 5 changed files with 79 additions and 4 deletions.
2 changes: 1 addition & 1 deletion manifest.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"manifest_version": 3,
"name": "Twilio Console Plus",
"version": "0.1.4",
"version": "0.1.5",
"description": "Add some secret saurce to Twilio console",
"icons": {
"48": "icons/icon-48.png"
Expand Down
10 changes: 9 additions & 1 deletion src/components/InspectResourceButton.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
import "react-tooltip/dist/react-tooltip.css";

import React, { useState } from "react";
import Popup from "reactjs-popup";
import { CopyBlock, dracula } from "react-code-blocks";
import { useQuery } from "@tanstack/react-query";
import { TwilioResource } from "../twilio-resources";
import styled from "styled-components";
import { Tooltip } from "react-tooltip";

const PopupContainer = styled.div`
.close {
Expand Down Expand Up @@ -31,7 +34,12 @@ const InspectResourceButton: React.FC<InspectResourceButtonProps> = ({
const openModal = () => setOpen(true);
return (
<>
<button onClick={openModal}>Inspect</button>
<button className={`inspect-${resource.sid}`} onClick={openModal}>
Inspect
</button>
<Tooltip anchorSelect={`.inspect-${resource.sid}`} place="top">
Click to inspect {resource.getName()}
</Tooltip>
<Popup
open={open}
modal
Expand Down
11 changes: 11 additions & 0 deletions src/twilio-request.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,14 @@ export const twilioGet = (apiUrl: string) => {
},
}).then((res) => res.json());
};

export async function* twilioGetPaged(
apiUrl: string,
): AsyncGenerator<unknown, void, unknown> {
const response = await twilioGet(apiUrl);
yield response;
const next_url = response.meta?.next_page_url;
if (next_url) {
yield* await twilioGetPaged(next_url);
}
}
9 changes: 9 additions & 0 deletions src/twilio-resource-loaders.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import {
TwilioA2pBrand,
TwilioAddress,
TwilioIncomingNumber,
TwilioMessagingService,
Expand Down Expand Up @@ -29,6 +30,14 @@ export const LOADERS: Loader[] = [
resourceUrl: /.+\/sms\/(\w+)\/messaging-service-properties(\?.*)$/,
resourceCreator: (match: string[]) => new TwilioMessagingService(match[1]),
},
{
resourceUrl: /.+\/sms\/services\/(\w+)\/[^/]+(\?.*)$/,
resourceCreator: (match: string[]) => new TwilioMessagingService(match[1]),
},
{
resourceUrl: /.+\/sms\/regulatory-compliance\/brands\/(\w+)$/,
resourceCreator: (match: string[]) => new TwilioA2pBrand(match[1]),
},
];

export const createTwilioResourceFromUrl = (
Expand Down
51 changes: 49 additions & 2 deletions src/twilio-resources.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { twilioGet } from "./twilio-request";
import { twilioGet, twilioGetPaged } from "./twilio-request";

interface Link {
label: string;
Expand Down Expand Up @@ -94,13 +94,60 @@ export class TwilioRegulatorySupportingDocument extends TwilioResource {

export class TwilioIncomingNumber extends TwilioResource {
getName = () => `Incoming number: ${this.sid}`;
getFullName = async () => {
const object = await this.getObject();
return `${this.getName()} (${object.friendly_name}; ${object.phone_number})`;
};
getRelatedResources = () => Promise.resolve([]);
getApiUrl = () =>
`https://api.twilio.com/2010-04-01/Accounts/${this._getAccountSid()}/IncomingPhoneNumbers/${this.sid}.json`;
}

export class TwilioMessagingService extends TwilioResource {
getName = () => `Messaging service: ${this.sid}`;
getRelatedResources = () => Promise.resolve([]);
getRelatedResources = async () => {
const response = await twilioGet(
`https://messaging.twilio.com/v1/Services/${this.sid}/Compliance/Usa2p`,
);
const results = response.compliance.map(
(campaign: Record<string, string>) =>
new TwllioA2pCampaign(campaign.sid, this.sid),
);
for await (const response of twilioGetPaged(
`https://messaging.twilio.com/v1/Services/${this.sid}/PhoneNumbers`,
)) {
const phones = (
response as Record<string, Record<string, string>[]>
).phone_numbers.map(
(phone: Record<string, string>) => new TwilioIncomingNumber(phone.sid),
);
results.push(...phones);
}

return results;
};
getApiUrl = () => `https://messaging.twilio.com/v1/Services/${this.sid}`;
}

export class TwllioA2pCampaign extends TwilioResource {
messagingServiceSid: string;
constructor(sid: string, messagingServiceSid: string) {
super(sid);
this.sid = sid;
this.messagingServiceSid = messagingServiceSid;
}
getName = () => `A2p campaign: ${this.sid}`;
getRelatedResources = async () => {
const object = await this.getObject();
return [new TwilioA2pBrand(object.brand_registration_sid as string)];
};
getApiUrl = () =>
`https://messaging.twilio.com/v1/Services/${this.messagingServiceSid}/Compliance/Usa2p/${this.sid}`;
}

export class TwilioA2pBrand extends TwilioResource {
getName = () => `A2p brand: ${this.sid}`;
getRelatedResources = () => Promise.resolve([]);
getApiUrl = () =>
`https://messaging.twilio.com/v1/a2p/BrandRegistrations/${this.sid}`;
}

0 comments on commit 9658667

Please sign in to comment.