Skip to content

Commit

Permalink
Migrate all API calls to threads
Browse files Browse the repository at this point in the history
  • Loading branch information
mattvagni committed Oct 17, 2023
1 parent 3a735ce commit 27d3a43
Show file tree
Hide file tree
Showing 10 changed files with 252 additions and 321 deletions.
10 changes: 5 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,11 +45,11 @@ You will then need to make a file called `.env.local` file with the following d
PLAIN_API_KEY=plainApiKey_XXX

# The issue type ids you created:
NEXT_PUBLIC_PLAIN_ISSUE_TYPE_ID_BUG=it_XXX
NEXT_PUBLIC_PLAIN_ISSUE_TYPE_ID_DEMO=it_XXX
NEXT_PUBLIC_PLAIN_ISSUE_TYPE_ID_FEATURE=it_XXX
NEXT_PUBLIC_PLAIN_ISSUE_TYPE_ID_SECURITY=it_XXX
NEXT_PUBLIC_PLAIN_ISSUE_TYPE_ID_QUESTION=it_XXX
NEXT_PUBLIC_PLAIN_LABEL_TYPE_ID_BUG=it_XXX
NEXT_PUBLIC_PLAIN_LABEL_TYPE_ID_DEMO=it_XXX
NEXT_PUBLIC_PLAIN_LABEL_TYPE_ID_FEATURE=it_XXX
NEXT_PUBLIC_PLAIN_LABEL_TYPE_ID_SECURITY=it_XXX
NEXT_PUBLIC_PLAIN_LABEL_TYPE_ID_QUESTION=it_XXX
```

After that you can run `npm install` followed by `npm run dev` to run the NextJS app and try it out!
100 changes: 4 additions & 96 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
"@radix-ui/react-checkbox": "1.0.3",
"@radix-ui/react-icons": "1.3.0",
"@radix-ui/react-select": "1.2.1",
"@team-plain/typescript-sdk": "2.11.0",
"@team-plain/typescript-sdk": "2.18.0",
"@types/lodash": "4.14.194",
"@types/ua-parser-js": "0.7.36",
"assert-ts": "0.3.4",
Expand Down
84 changes: 40 additions & 44 deletions pages/api/contact-form.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
import { inspect } from 'util';
import { PlainClient, UpsertCustomTimelineEntryInput } from '@team-plain/typescript-sdk';
import {
uiComponent,
CreateThreadInput,
PlainClient,
PlainSDKError,
} from '@team-plain/typescript-sdk';
import type { NextApiRequest, NextApiResponse } from 'next';
import UAParser from 'ua-parser-js';

const apiKey = process.env.PLAIN_API_KEY;

Expand All @@ -17,75 +23,65 @@ export type ResponseData = {
};

export type RequestBody = {
customer: {
name: string;
email: string;
};
customeTimelineEntry: {
title: string;
components: UpsertCustomTimelineEntryInput['components'];
};
issue: {
issueTypeId: string;
priority: number | null;
};
name: string;
email: string;
title: string;
components: CreateThreadInput['components'];
labelTypeIds: string[];
priority: 0 | 1 | 2 | 3 | number;
};

function logError(err: PlainSDKError) {
// This ensures the full error is logged
console.error(inspect(err, { showHidden: false, depth: null, colors: true }));
}



/**
* The API handler, this is what accepts our contact form request and submits it to Plain
*/
export default async function handler(req: NextApiRequest, res: NextApiResponse<ResponseData>) {
// In production validation of the request body might be necessary.
const body = JSON.parse(req.body) as RequestBody;
const reqBody = JSON.parse(req.body) as RequestBody;

const upsertCustomerRes = await client.upsertCustomer({
identifier: {
emailAddress: body.customer.email,
emailAddress: reqBody.email,
},
onCreate: {
fullName: body.customer.name,
fullName: reqBody.name,
email: {
email: body.customer.email,
email: reqBody.email,
isVerified: true,
},
},
onUpdate: {},
});

if (upsertCustomerRes.error) {
console.error(
inspect(upsertCustomerRes.error, { showHidden: false, depth: null, colors: true })
);
logError(upsertCustomerRes.error);
return res.status(500).json({ error: upsertCustomerRes.error.message });
}

console.log(`Customer upserted ${upsertCustomerRes.data.customer.id}`);

const upsertTimelineEntryRes = await client.upsertCustomTimelineEntry({
customerId: upsertCustomerRes.data.customer.id,
title: body.customeTimelineEntry.title,
components: body.customeTimelineEntry.components,
changeCustomerStatusToActive: true,
});

if (upsertTimelineEntryRes.error) {
console.error(
inspect(upsertTimelineEntryRes.error, { showHidden: false, depth: null, colors: true })
);
return res.status(500).json({ error: upsertTimelineEntryRes.error.message });
}

console.log(`Custom timeline entry upserted ${upsertTimelineEntryRes.data.timelineEntry.id}.`);

const createIssueRes = await client.createIssue({
customerId: upsertCustomerRes.data.customer.id,
issueTypeId: body.issue.issueTypeId,
priorityValue: body.issue.priority,
const createThreadRes = await client.createThread({
customerIdentifier: {
customerId: upsertCustomerRes.data.customer.id,
},
title: reqBody.title,
components: reqBody.components,
labelTypeIds: reqBody.labelTypeIds,
priority: reqBody.priority,
});

if (createIssueRes.error) {
console.error(inspect(createIssueRes.error, { showHidden: false, depth: null, colors: true }));
return res.status(500).json({ error: createIssueRes.error.message });
if (createThreadRes.error) {
logError(createThreadRes.error);
return res.status(500).json({ error: createThreadRes.error.message });
}

console.log(`Issue created ${createIssueRes.data.id}`);
console.log(`Thread created ${createThreadRes.data.id}`);

res.status(200).json({ error: null });
}
2 changes: 1 addition & 1 deletion pages/index.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import type { NextPage } from 'next';
import Head from 'next/head';
import { ContactForm } from '../src/components/contactForm';
import { ContactForm } from '../src/contactForm';
import { Layout } from '../src/components/layout';

const Home: NextPage = () => {
Expand Down
File renamed without changes.
Loading

0 comments on commit 27d3a43

Please sign in to comment.