Skip to content

Commit

Permalink
Add email invoice trigger (#88)
Browse files Browse the repository at this point in the history
  • Loading branch information
Jsnxyz authored May 6, 2024
1 parent f1749f1 commit 742dbf7
Show file tree
Hide file tree
Showing 7 changed files with 66 additions and 19 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "cobot-zapier",
"version": "2.2.0",
"version": "2.2.1",
"description": "",
"main": "index.js",
"scripts": {
Expand Down
32 changes: 23 additions & 9 deletions src/test/triggers/triggerInvoiceCreated.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,11 @@ const invoiceResponse: InvoiceApiResponse = {
},
};

const membership = {
id: "membership-1",
email: "[email protected]",
};

const appTester = createAppTester(App);
nock.disableNetConnect();
const trigger = App.triggers[triggerInvoiceCreated.key] as HookTrigger;
Expand Down Expand Up @@ -106,30 +111,36 @@ describe("triggerInvoiceCreated", () => {
const userResponse: UserApiResponse = {
included: [{ id: "space-1", attributes: { subdomain: "trial" } }],
};
const scope = nock("https://api.cobot.me");
scope.get("/user?include=adminOf").reply(200, userResponse);
scope
const api2Scope = nock("https://api.cobot.me");
const api1Scope = nock("https://trial.cobot.me");
api2Scope.get("/user?include=adminOf").reply(200, userResponse);
api1Scope.get("/api/memberships/membership-1").reply(200, membership);
api2Scope
.get(/\/spaces\/space-1\/invoices/)
.reply(200, { data: [invoiceResponse] });

const listRecentEvents = trigger.operation.performList;

const results = await appTester(listRecentEvents as any, bundle as any);

expect(nock.isDone()).toBe(true);
expect(results).toStrictEqual([
{
...attributes,
id: "1",
membershipId: "membership-1",
membership: {
id: "membership-1",
email: "[email protected]",
},
},
]);
});

it("triggers on new invoice", async () => {
const bundle = prepareBundle();
const scope = nock("https://api.cobot.me");
scope.get("/invoices/12345").reply(200, { data: invoiceResponse });

const api1Scope = nock("https://trial.cobot.me");
const api2Scope = nock("https://api.cobot.me");
api2Scope.get("/invoices/12345").reply(200, { data: invoiceResponse });
api1Scope.get("/api/memberships/membership-1").reply(200, membership);
const results = await appTester(
triggerInvoiceCreated.operation.perform as any,
bundle as any,
Expand All @@ -141,7 +152,10 @@ describe("triggerInvoiceCreated", () => {
{
...attributes,
id: "1",
membershipId: "membership-1",
membership: {
id: "membership-1",
email: "[email protected]",
},
},
]);
});
Expand Down
12 changes: 10 additions & 2 deletions src/triggers/triggerInvoiceCreated.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,11 @@ async function parsePayload(
bundle: KontentBundle<{}>,
): Promise<InvoiceOutput[]> {
const invoiceId = bundle.cleanedRequest.url.split("/").pop();
const api1MembershipsUrl =
new URL(bundle.cleanedRequest.url).origin + "/api/memberships";
const response = await getInvoiceFromApi2(z, invoiceId);
if (response) {
return [apiResponseToInvoiceOutput(response)];
return [await apiResponseToInvoiceOutput(z, response, api1MembershipsUrl)];
} else {
return [];
}
Expand All @@ -69,7 +71,13 @@ const trigger: HookTrigger = {
bundle: KontentBundle<SubscribeBundleInputType>,
): Promise<InvoiceOutput[]> => {
const invoices = await listRecentInvoices(z, bundle);
return invoices.map((invoice) => apiResponseToInvoiceOutput(invoice));
const subdomain = bundle.inputData.subdomain;
const api1MembershipsUrl = `https://${subdomain}.cobot.me/api/memberships`;
const invoiceOutputPromises = invoices.map((invoice) =>
apiResponseToInvoiceOutput(z, invoice, api1MembershipsUrl),
);
const invoiceOutputs = await Promise.all(invoiceOutputPromises);
return invoiceOutputs;
},

sample: invoiceSample,
Expand Down
7 changes: 6 additions & 1 deletion src/types/outputs.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,12 @@ export type MembershipOutput = {
payment_method_name: string | null;
};

export type InvoiceMembershipOutput = {
id: string;
email: string | null;
};

export type InvoiceOutput = BaseInvoiceProperties & {
membershipId?: string;
id: string;
membership?: InvoiceMembershipOutput;
};
24 changes: 20 additions & 4 deletions src/utils/api-to-output.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@ import {
MembershipOutput,
InvoiceOutput,
} from "../types/outputs";
import { ExternalBookingWithResourceApiResponse } from "./api";
import { ZObject } from "zapier-platform-core";
import { get } from "lodash";
import { ExternalBookingWithResourceApiResponse, apiCallUrl } from "./api";

export function apiResponseToMembershipOutput(
membership: MembershipApiResponse,
Expand All @@ -27,14 +29,28 @@ export function apiResponseToMembershipOutput(
};
}

export function apiResponseToInvoiceOutput(
export async function apiResponseToInvoiceOutput(
z: ZObject,
invoice: InvoiceApiResponse,
): InvoiceOutput {
api1MembershipsUrl: string,
): Promise<InvoiceOutput> {
const attributes = invoice.attributes;
const membershipId = get(invoice, "relationships.membership.data.id");
if (!membershipId) {
return {
...attributes,
id: invoice.id,
};
}
const url = `${api1MembershipsUrl}/${membershipId}`;
const membership: MembershipApiResponse = await apiCallUrl(z, url);
return {
...attributes,
id: invoice.id,
membershipId: invoice.relationships?.membership?.data?.id ?? undefined,
membership: {
id: membershipId,
email: membership.email,
},
};
}

Expand Down
3 changes: 2 additions & 1 deletion src/utils/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import {
UserApiResponse,
InvoiceApiResponse,
} from "../types/api-responses";
import { InvoiceMembershipOutput } from "../types/outputs";

type Space = {
id: string;
Expand Down Expand Up @@ -244,7 +245,7 @@ export const getInvoiceFromApi2 = async (
if (response.status === 404) {
return null;
}
return response.data.data as InvoiceApiResponse;
return response.data.data;
};

export const getExternalBooking = async (
Expand Down
5 changes: 4 additions & 1 deletion src/utils/samples.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,10 @@ export const invoiceSample: InvoiceOutput = {
taxId: "DE12345",
taxIdName: "UID",
customerNumber: "100",
membershipId: "c9a99a71ac8df98d29de357180d273d3",
membership: {
id: "14c12f62ac8df98d29de357180d673e1",
email: "[email protected]",
},
recipientAddress: {
name: "Jane Smith",
company: "Acme Inc.",
Expand Down

0 comments on commit 742dbf7

Please sign in to comment.