WIP
This commit is contained in:
parent
1da51639fa
commit
60e673c07b
4 changed files with 151 additions and 35 deletions
119
apps/emails-and-messages/src/lib/webhooks.ts
Normal file
119
apps/emails-and-messages/src/lib/webhooks.ts
Normal file
|
@ -0,0 +1,119 @@
|
||||||
|
import { SaleorAsyncWebhook } from "@saleor/app-sdk/handlers/next";
|
||||||
|
import { Client, gql } from "urql";
|
||||||
|
import {
|
||||||
|
AppWebhooksDocument,
|
||||||
|
WebhookCreateDocument,
|
||||||
|
WebhookDeleteDocument,
|
||||||
|
} from "../../generated/graphql";
|
||||||
|
import { invoiceSentWebhook } from "../pages/api/webhooks/invoice-sent";
|
||||||
|
|
||||||
|
const WebhookDetails = gql`
|
||||||
|
fragment WebhookDetails on Webhook {
|
||||||
|
id
|
||||||
|
isActive
|
||||||
|
name
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
const WebhookCreateMutation = gql`
|
||||||
|
${WebhookDetails}
|
||||||
|
mutation WebhookCreate($input: WebhookCreateInput!) {
|
||||||
|
webhookCreate(input: $input) {
|
||||||
|
webhook {
|
||||||
|
...WebhookDetails
|
||||||
|
}
|
||||||
|
errors {
|
||||||
|
field
|
||||||
|
message
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
const AppWebhooksQuery = gql`
|
||||||
|
query AppWebhooks {
|
||||||
|
app {
|
||||||
|
webhooks {
|
||||||
|
id
|
||||||
|
name
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
const WebhookDeleteMutation = gql`
|
||||||
|
mutation WebhookDelete($id: ID!) {
|
||||||
|
webhookDelete(id: $id) {
|
||||||
|
errors {
|
||||||
|
field
|
||||||
|
message
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
export const setupWebhooks = async (client: Client, configurationID: string) => {
|
||||||
|
const eventName = "INVOICE_SENT";
|
||||||
|
|
||||||
|
const newWebhook = await createWebhookMutate(client, {});
|
||||||
|
};
|
||||||
|
|
||||||
|
export const createWebhookMutate = async (client: Client, webhook: SaleorAsyncWebhook) => {
|
||||||
|
// TODO: The base URL should be configurable
|
||||||
|
const manifest = invoiceSentWebhook.getWebhookManifest("https://example.com");
|
||||||
|
|
||||||
|
const { error, data } = await client
|
||||||
|
.mutation(WebhookCreateDocument, {
|
||||||
|
input: {
|
||||||
|
name: manifest.name,
|
||||||
|
targetUrl: manifest.targetUrl,
|
||||||
|
isActive: true,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.toPromise();
|
||||||
|
|
||||||
|
if (error || data?.webhookCreate?.errors?.length) {
|
||||||
|
throw new Error("Could not create webhook");
|
||||||
|
}
|
||||||
|
|
||||||
|
return data?.webhookCreate?.webhook;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const deleteWebhookMutate = async (client: Client, webhookId: string) => {
|
||||||
|
const { error, data } = await client
|
||||||
|
.mutation(WebhookDeleteDocument, {
|
||||||
|
id: webhookId,
|
||||||
|
})
|
||||||
|
.toPromise();
|
||||||
|
|
||||||
|
if (error || data?.webhookDelete?.errors?.length) {
|
||||||
|
throw new Error("Could not delete webhook");
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
// export const updateWebhook = async (client: Client, webhook: SaleorAsyncWebhook) => {
|
||||||
|
// const { error, data } = await client
|
||||||
|
// .mutation(UpdateWebhookDocument, {
|
||||||
|
// id: webhook.id,
|
||||||
|
// input: webhook,
|
||||||
|
// })
|
||||||
|
// .toPromise();
|
||||||
|
|
||||||
|
// if (error) {
|
||||||
|
// throw new Error("Could not update webhook");
|
||||||
|
// }
|
||||||
|
|
||||||
|
// return data?.webhookUpdate?.webhook;
|
||||||
|
// };
|
||||||
|
|
||||||
|
export const getAllWebhooks = async (client: Client) => {
|
||||||
|
const { error, data } = await client.query(AppWebhooksDocument, {}).toPromise();
|
||||||
|
|
||||||
|
if (error) {
|
||||||
|
throw new Error("Could not fetch webhooks");
|
||||||
|
}
|
||||||
|
|
||||||
|
return data?.app?.webhooks;
|
||||||
|
};
|
|
@ -12,6 +12,7 @@ import { SendgridConfigurationService } from "./get-sendgrid-configuration.servi
|
||||||
import { router } from "../../trpc/trpc-server";
|
import { router } from "../../trpc/trpc-server";
|
||||||
import { protectedClientProcedure } from "../../trpc/protected-client-procedure";
|
import { protectedClientProcedure } from "../../trpc/protected-client-procedure";
|
||||||
import { TRPCError } from "@trpc/server";
|
import { TRPCError } from "@trpc/server";
|
||||||
|
import { createWebhookMutate, deleteWebhookMutate, getAllWebhooks } from "../../../lib/webhooks";
|
||||||
|
|
||||||
// Allow access only for the dashboard users and attaches the
|
// Allow access only for the dashboard users and attaches the
|
||||||
// configuration service to the context
|
// configuration service to the context
|
||||||
|
@ -57,6 +58,21 @@ export const sendgridConfigurationRouter = router({
|
||||||
logger.debug(input, "sendgridConfigurationRouter.create called");
|
logger.debug(input, "sendgridConfigurationRouter.create called");
|
||||||
return await ctx.configurationService.createConfiguration(input);
|
return await ctx.configurationService.createConfiguration(input);
|
||||||
}),
|
}),
|
||||||
|
createWebhook: protectedWithConfigurationService
|
||||||
|
.meta({ requiredClientPermissions: ["MANAGE_APPS"] })
|
||||||
|
// .input(sendgridCreateConfigurationSchema)
|
||||||
|
.mutation(async ({ ctx, input }) => {
|
||||||
|
const logger = pinoLogger.child({ saleorApiUrl: ctx.saleorApiUrl });
|
||||||
|
logger.debug(input, "create webhook called");
|
||||||
|
const r = await getAllWebhooks(ctx.apiClient);
|
||||||
|
if (!r?.length) {
|
||||||
|
console.log("None found");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const lastHook = r[r.length - 1];
|
||||||
|
const r2 = await deleteWebhookMutate(ctx.apiClient, lastHook.id);
|
||||||
|
return;
|
||||||
|
}),
|
||||||
deleteConfiguration: protectedWithConfigurationService
|
deleteConfiguration: protectedWithConfigurationService
|
||||||
.meta({ requiredClientPermissions: ["MANAGE_APPS"] })
|
.meta({ requiredClientPermissions: ["MANAGE_APPS"] })
|
||||||
.input(sendgridDeleteConfigurationInputSchema)
|
.input(sendgridDeleteConfigurationInputSchema)
|
||||||
|
|
|
@ -303,40 +303,6 @@ export const SendgridConfigurationForm = (props: Props) => {
|
||||||
</Typography>
|
</Typography>
|
||||||
)}
|
)}
|
||||||
</FormControl>
|
</FormControl>
|
||||||
|
|
||||||
<Controller
|
|
||||||
name="senderName"
|
|
||||||
control={control}
|
|
||||||
render={({ field: { onChange, value }, fieldState: { error } }) => (
|
|
||||||
<TextField
|
|
||||||
label="Sender name"
|
|
||||||
disabled={true}
|
|
||||||
error={!!error}
|
|
||||||
helperText={error?.message}
|
|
||||||
value={value}
|
|
||||||
onChange={onChange}
|
|
||||||
{...CommonFieldProps}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<Controller
|
|
||||||
name="senderEmail"
|
|
||||||
control={control}
|
|
||||||
render={({ field: { onChange, value }, fieldState: { error } }) => (
|
|
||||||
<>
|
|
||||||
<TextField
|
|
||||||
label="Sender email"
|
|
||||||
value={value}
|
|
||||||
disabled={true}
|
|
||||||
helperText={error?.message}
|
|
||||||
error={!!error}
|
|
||||||
onChange={onChange}
|
|
||||||
{...CommonFieldProps}
|
|
||||||
/>
|
|
||||||
</>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
<Button type="submit" fullWidth variant="primary">
|
<Button type="submit" fullWidth variant="primary">
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
import { Link, Paper, Typography } from "@material-ui/core";
|
import { Link, Paper, Typography } from "@material-ui/core";
|
||||||
import { actions, useAppBridge } from "@saleor/app-sdk/app-bridge";
|
import { actions, useAppBridge } from "@saleor/app-sdk/app-bridge";
|
||||||
import { makeStyles } from "@saleor/macaw-ui";
|
import { Button, makeStyles } from "@saleor/macaw-ui";
|
||||||
|
import { useQuery } from "@tanstack/react-query";
|
||||||
|
import { trpcClient } from "../../../trpc/trpc-client";
|
||||||
|
|
||||||
const useStyles = makeStyles((theme) => {
|
const useStyles = makeStyles((theme) => {
|
||||||
return {
|
return {
|
||||||
|
@ -10,6 +12,18 @@ const useStyles = makeStyles((theme) => {
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const TestButton = () => {
|
||||||
|
const { mutate } = trpcClient.sendgridConfiguration.createWebhook.useMutation({
|
||||||
|
onSuccess: () => {
|
||||||
|
console.log("success");
|
||||||
|
},
|
||||||
|
onError: (err) => {
|
||||||
|
console.log("error", err);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
return <button onClick={() => mutate()}>Test</button>;
|
||||||
|
};
|
||||||
|
|
||||||
export const SendgridInstructions = () => {
|
export const SendgridInstructions = () => {
|
||||||
const styles = useStyles();
|
const styles = useStyles();
|
||||||
|
|
||||||
|
@ -17,6 +31,7 @@ export const SendgridInstructions = () => {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Paper elevation={0} className={styles.instructionsContainer}>
|
<Paper elevation={0} className={styles.instructionsContainer}>
|
||||||
|
<TestButton />
|
||||||
<Typography paragraph variant="h4">
|
<Typography paragraph variant="h4">
|
||||||
Sendgrid Provider
|
Sendgrid Provider
|
||||||
</Typography>
|
</Typography>
|
||||||
|
|
Loading…
Reference in a new issue