Refactoring 2
This commit is contained in:
parent
dd14dfe72e
commit
e4b78ceec2
76 changed files with 870 additions and 734 deletions
72
packages/bridge-ui/lib/actions.ts
Normal file
72
packages/bridge-ui/lib/actions.ts
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
import { Database } from "bridge-common";
|
||||
import {
|
||||
createAction,
|
||||
updateAction,
|
||||
deleteAction,
|
||||
selectAllAction,
|
||||
} from "../actions/service";
|
||||
import { FieldDescription, Entity } from "./service";
|
||||
|
||||
type GenerateCreateActionArgs = {
|
||||
entity: Entity;
|
||||
table: keyof Database;
|
||||
fields: FieldDescription[];
|
||||
};
|
||||
|
||||
export function generateCreateAction({
|
||||
entity,
|
||||
table,
|
||||
fields,
|
||||
}: GenerateCreateActionArgs) {
|
||||
return async (currentState: any, formData: FormData) => {
|
||||
return createAction({
|
||||
entity,
|
||||
table,
|
||||
fields,
|
||||
currentState,
|
||||
formData,
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
type GenerateUpdateActionArgs = {
|
||||
entity: Entity;
|
||||
table: keyof Database;
|
||||
fields: FieldDescription[];
|
||||
};
|
||||
|
||||
export function generateUpdateAction({
|
||||
entity,
|
||||
table,
|
||||
fields,
|
||||
}: GenerateUpdateActionArgs) {
|
||||
return async (currentState: any, formData: FormData) => {
|
||||
return updateAction({
|
||||
entity,
|
||||
table,
|
||||
fields,
|
||||
currentState,
|
||||
formData,
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
type GenerateDeleteActionArgs = {
|
||||
entity: Entity;
|
||||
table: keyof Database;
|
||||
};
|
||||
|
||||
export function generateDeleteAction({
|
||||
entity,
|
||||
table,
|
||||
}: GenerateDeleteActionArgs) {
|
||||
return async (id: string) => {
|
||||
return deleteAction({ entity, table, id });
|
||||
};
|
||||
}
|
||||
|
||||
export function generateSelectAllAction(table: keyof Database) {
|
||||
return async () => {
|
||||
return selectAllAction(table);
|
||||
};
|
||||
}
|
||||
32
packages/bridge-ui/lib/facebook.ts
Normal file
32
packages/bridge-ui/lib/facebook.ts
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
import { NextRequest, NextResponse } from "next/server";
|
||||
import { Service } from "./service";
|
||||
import { db, getWorkerUtils } from "bridge-common";
|
||||
|
||||
export class Facebook extends Service {
|
||||
async handleWebhook(req: NextRequest) {
|
||||
const { searchParams } = req.nextUrl;
|
||||
const submittedToken = searchParams.get("hub.verify_token");
|
||||
|
||||
if (submittedToken) {
|
||||
await db
|
||||
.selectFrom("FacebookBot")
|
||||
.selectAll()
|
||||
.where("verifyToken", "=", submittedToken)
|
||||
.executeTakeFirstOrThrow();
|
||||
|
||||
if (searchParams.get("hub.mode") === "subscribe") {
|
||||
const challenge = searchParams.get("hub.challenge");
|
||||
|
||||
return NextResponse.json(challenge) as any;
|
||||
} else {
|
||||
return NextResponse.error();
|
||||
}
|
||||
}
|
||||
|
||||
const message = await req.json();
|
||||
const worker = await getWorkerUtils();
|
||||
await worker.addJob("receive_facebook_message", message);
|
||||
|
||||
return NextResponse.json({ response: "ok" });
|
||||
}
|
||||
}
|
||||
18
packages/bridge-ui/lib/routing.ts
Normal file
18
packages/bridge-ui/lib/routing.ts
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
import { NextRequest, NextResponse } from "next/server";
|
||||
import { ServiceParams } from "./service";
|
||||
import { getService } from "./utils";
|
||||
|
||||
export const getBot = async (
|
||||
_req: NextRequest,
|
||||
params: ServiceParams,
|
||||
): Promise<NextResponse> => getService(params)?.getBot(params);
|
||||
|
||||
export const sendMessage = async (
|
||||
req: NextRequest,
|
||||
params: ServiceParams,
|
||||
): Promise<NextResponse> => getService(params)?.sendMessage(req, params);
|
||||
|
||||
export const handleWebhook = async (
|
||||
req: NextRequest,
|
||||
params: ServiceParams,
|
||||
): Promise<NextResponse> => getService(params)?.handleWebhook(req);
|
||||
81
packages/bridge-ui/lib/service.ts
Normal file
81
packages/bridge-ui/lib/service.ts
Normal file
|
|
@ -0,0 +1,81 @@
|
|||
import { NextRequest, NextResponse } from "next/server";
|
||||
import { GridColDef } from "@mui/x-data-grid-pro";
|
||||
import { Database, db, getWorkerUtils } from "bridge-common";
|
||||
import { getServiceTable } from "../config/config";
|
||||
|
||||
const entities = [
|
||||
"facebook",
|
||||
"whatsapp",
|
||||
"signal",
|
||||
"voice",
|
||||
"webhooks",
|
||||
"users",
|
||||
] as const;
|
||||
|
||||
export type Entity = (typeof entities)[number];
|
||||
|
||||
export type SelectOption = {
|
||||
value: string;
|
||||
label: string;
|
||||
};
|
||||
|
||||
export type FieldDescription = {
|
||||
name: string;
|
||||
label: string;
|
||||
kind?: "text" | "phone" | "select" | "multi";
|
||||
getOptions?: (formState: any) => Promise<SelectOption[]>;
|
||||
autogenerated?: "token";
|
||||
hidden?: boolean;
|
||||
type?: string;
|
||||
lines?: number;
|
||||
copyable?: boolean;
|
||||
refreshable?: boolean;
|
||||
defaultValue?: string;
|
||||
required?: boolean;
|
||||
disabled?: boolean;
|
||||
size?: number;
|
||||
helperText?: string;
|
||||
};
|
||||
|
||||
export type ServiceConfig = {
|
||||
entity: Entity;
|
||||
table: keyof Database;
|
||||
displayName: string;
|
||||
createFields: FieldDescription[];
|
||||
updateFields: FieldDescription[];
|
||||
displayFields: FieldDescription[];
|
||||
listColumns: GridColDef[];
|
||||
};
|
||||
|
||||
export type ServiceParams = {
|
||||
service: string;
|
||||
token?: string;
|
||||
};
|
||||
|
||||
export class Service {
|
||||
async getBot({ service, token }: ServiceParams): Promise<NextResponse> {
|
||||
const table = getServiceTable(service);
|
||||
const row = await db
|
||||
.selectFrom(table)
|
||||
.selectAll()
|
||||
.where("token", "=", token ?? "NEVER_MATCH")
|
||||
.executeTakeFirstOrThrow();
|
||||
|
||||
return NextResponse.json(row);
|
||||
}
|
||||
|
||||
async sendMessage(
|
||||
req: NextRequest,
|
||||
{ service, token }: ServiceParams,
|
||||
): Promise<NextResponse> {
|
||||
const message = await req.json();
|
||||
const worker = await getWorkerUtils();
|
||||
await worker.addJob(`send_${service}_message`, { token, message });
|
||||
|
||||
return NextResponse.json({ response: "ok" });
|
||||
}
|
||||
|
||||
async handleWebhook(_req: NextRequest): Promise<NextResponse> {
|
||||
return NextResponse.error() as any;
|
||||
}
|
||||
}
|
||||
3
packages/bridge-ui/lib/signal.ts
Normal file
3
packages/bridge-ui/lib/signal.ts
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
import { Service } from "./service";
|
||||
|
||||
export class Signal extends Service {}
|
||||
16
packages/bridge-ui/lib/utils.ts
Normal file
16
packages/bridge-ui/lib/utils.ts
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
import { Service, ServiceParams } from "./service";
|
||||
import { Facebook } from "./facebook";
|
||||
import { Signal } from "./signal";
|
||||
import { Whatsapp } from "./whatsapp";
|
||||
|
||||
export const getService = ({ service }: ServiceParams): Service => {
|
||||
if (service === "facebook") {
|
||||
return new Facebook();
|
||||
} else if (service === "signal") {
|
||||
return new Signal();
|
||||
} else if (service === "whatsapp") {
|
||||
return new Whatsapp();
|
||||
}
|
||||
|
||||
throw new Error("Service not found");
|
||||
};
|
||||
3
packages/bridge-ui/lib/voice.ts
Normal file
3
packages/bridge-ui/lib/voice.ts
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
import { Service } from "./service";
|
||||
|
||||
export class Voice extends Service {}
|
||||
3
packages/bridge-ui/lib/whatsapp.ts
Normal file
3
packages/bridge-ui/lib/whatsapp.ts
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
import { Service } from "./service";
|
||||
|
||||
export class Whatsapp extends Service {}
|
||||
Loading…
Add table
Add a link
Reference in a new issue