|
1 |
| -import { inspect } from "util"; |
2 |
| -import { |
3 |
| - PlainClient, |
4 |
| - PlainSDKError, |
5 |
| - ThreadFieldSchemaType, |
6 |
| - UpsertCustomerInput, |
7 |
| -} from "@team-plain/typescript-sdk"; |
8 |
| -import type { NextApiRequest, NextApiResponse } from "next"; |
9 | 1 | import { z } from "zod";
|
10 | 2 | import { auth0 } from "server/auth0";
|
11 | 3 | import { captureException, captureMessage } from "@sentry/nextjs";
|
12 |
| -import { retryingFetch } from "lib/ssr"; |
13 |
| -import { Team, ProjectDetails, DeploymentResponse } from "generatedApi"; |
14 |
| - |
15 |
| -const apiKey = process.env.PLAIN_API_KEY; |
16 |
| - |
17 |
| -if (!apiKey) { |
18 |
| - throw new Error("PLAIN_API_KEY environment variable is not set"); |
19 |
| -} |
20 |
| - |
21 |
| -const client = new PlainClient({ |
22 |
| - apiKey, |
23 |
| -}); |
| 4 | +import type { NextApiRequest, NextApiResponse } from "next"; |
24 | 5 |
|
25 | 6 | export type ResponseData = {
|
26 | 7 | error: string | null;
|
@@ -68,196 +49,28 @@ export default async function handler(
|
68 | 49 | return res.status(400).json({ error: error.message });
|
69 | 50 | }
|
70 | 51 |
|
71 |
| - const profileDataResp = await retryingFetch( |
72 |
| - `${process.env.NEXT_PUBLIC_BIG_BRAIN_URL}/api/dashboard/profile`, |
73 |
| - { |
74 |
| - headers: { |
75 |
| - authorization: `Bearer ${session.accessToken}`, |
76 |
| - }, |
77 |
| - }, |
78 |
| - ); |
79 |
| - if (!profileDataResp.ok) { |
80 |
| - const responseText = await profileDataResp.text(); |
81 |
| - captureMessage(`Couldn't fetch profile data: ${responseText}`); |
82 |
| - return { |
83 |
| - error: "Internal server Error", |
84 |
| - }; |
85 |
| - } |
86 |
| - |
87 |
| - const { id, email: profileEmail } = await profileDataResp.json(); |
| 52 | + try { |
| 53 | + // Get the host from the request headers |
| 54 | + const protocol = req.headers["x-forwarded-proto"] || "http"; |
| 55 | + const host = req.headers["x-forwarded-host"] || req.headers.host; |
| 56 | + const baseUrl = `${protocol}://${host}`; |
88 | 57 |
|
89 |
| - const memberDataResp = await retryingFetch( |
90 |
| - `${process.env.NEXT_PUBLIC_BIG_BRAIN_URL}/api/dashboard/member_data`, |
91 |
| - { |
| 58 | + void fetch(`${baseUrl}/api/send-plain-message`, { |
| 59 | + method: "POST", |
92 | 60 | headers: {
|
93 |
| - authorization: `Bearer ${session.accessToken}`, |
| 61 | + "Content-Type": "application/json", |
| 62 | + "X-Plain-Api-Key": process.env.PLAIN_API_KEY || "", |
| 63 | + "X-Convex-Access-Token": session.accessToken || "", |
94 | 64 | },
|
95 |
| - }, |
96 |
| - ); |
97 |
| - if (!memberDataResp.ok) { |
98 |
| - const responseText = await memberDataResp.text(); |
99 |
| - captureMessage(`Couldn't fetch member data: ${responseText}`); |
100 |
| - return { |
101 |
| - error: "Internal server Error", |
102 |
| - }; |
103 |
| - } |
104 |
| - const { |
105 |
| - teams, |
106 |
| - projects, |
107 |
| - deployments, |
108 |
| - }: { |
109 |
| - teams: Team[]; |
110 |
| - projects: ProjectDetails[]; |
111 |
| - deployments: DeploymentResponse[]; |
112 |
| - } = await memberDataResp.json(); |
113 |
| - const { teamId, projectId, deploymentName } = body; |
114 |
| - |
115 |
| - let customerId: string | null = null; |
116 |
| - |
117 |
| - const upsertCustomerRes = await upsertPlainCustomer( |
118 |
| - { |
119 |
| - externalId: id.toString(), |
120 |
| - }, |
121 |
| - id, |
122 |
| - profileEmail, |
123 |
| - validatedUser, |
124 |
| - ); |
125 |
| - |
126 |
| - if (upsertCustomerRes.error) { |
127 |
| - const customerAlreadyExists = |
128 |
| - upsertCustomerRes.error.type === "mutation_error" && |
129 |
| - upsertCustomerRes.error.errorDetails.code === |
130 |
| - "customer_already_exists_with_email"; |
131 |
| - if (customerAlreadyExists) { |
132 |
| - const upsertCustomerWithEmailIdentifierRes = await upsertPlainCustomer( |
133 |
| - { emailAddress: profileEmail }, |
134 |
| - id, |
135 |
| - profileEmail, |
136 |
| - validatedUser, |
137 |
| - ); |
138 |
| - |
139 |
| - if (upsertCustomerWithEmailIdentifierRes.error) { |
140 |
| - return failedToUpsertPlainCustomer( |
141 |
| - upsertCustomerWithEmailIdentifierRes.error, |
142 |
| - res, |
143 |
| - ); |
144 |
| - } |
145 |
| - customerId = upsertCustomerWithEmailIdentifierRes.data.customer.id; |
146 |
| - } else { |
147 |
| - return failedToUpsertPlainCustomer(upsertCustomerRes.error, res); |
148 |
| - } |
149 |
| - } else { |
150 |
| - customerId = upsertCustomerRes.data.customer.id; |
151 |
| - } |
152 |
| - |
153 |
| - const team = teams.find((t) => t.id === teamId); |
154 |
| - const project = projects.find((p) => p.id === projectId); |
155 |
| - const deployment = deployments.find((d) => d.name === deploymentName); |
156 |
| - |
157 |
| - const threadFields = []; |
158 |
| - if (team) { |
159 |
| - threadFields.push({ |
160 |
| - key: "team_id", |
161 |
| - stringValue: team.id.toString(), |
162 |
| - type: ThreadFieldSchemaType.String, |
163 |
| - }); |
164 |
| - threadFields.push({ |
165 |
| - key: "team_slug", |
166 |
| - stringValue: team.slug, |
167 |
| - type: ThreadFieldSchemaType.String, |
168 |
| - }); |
169 |
| - } |
170 |
| - |
171 |
| - if (project) { |
172 |
| - threadFields.push({ |
173 |
| - key: "project_id", |
174 |
| - stringValue: project.id.toString(), |
175 |
| - type: ThreadFieldSchemaType.String, |
176 |
| - }); |
177 |
| - threadFields.push({ |
178 |
| - key: "project_slug", |
179 |
| - stringValue: project.slug, |
180 |
| - type: ThreadFieldSchemaType.String, |
| 65 | + body: JSON.stringify({ |
| 66 | + ...body, |
| 67 | + user: validatedUser, |
| 68 | + }), |
181 | 69 | });
|
182 |
| - } |
183 | 70 |
|
184 |
| - if (deployment) { |
185 |
| - threadFields.push({ |
186 |
| - key: "deployment_name", |
187 |
| - stringValue: deployment.name, |
188 |
| - type: ThreadFieldSchemaType.String, |
189 |
| - }); |
190 |
| - } |
191 |
| - |
192 |
| - const createThreadRes = await client.createThread({ |
193 |
| - customerIdentifier: { |
194 |
| - customerId, |
195 |
| - }, |
196 |
| - title: body.subject, |
197 |
| - threadFields, |
198 |
| - components: [ |
199 |
| - { |
200 |
| - componentText: { |
201 |
| - text: body.message, |
202 |
| - }, |
203 |
| - }, |
204 |
| - ], |
205 |
| - }); |
206 |
| - |
207 |
| - if (createThreadRes.error) { |
208 |
| - console.error( |
209 |
| - inspect(createThreadRes.error, { |
210 |
| - showHidden: false, |
211 |
| - depth: null, |
212 |
| - colors: true, |
213 |
| - }), |
214 |
| - ); |
215 |
| - captureMessage(createThreadRes.error.message); |
| 71 | + res.status(200).json({ error: null }); |
| 72 | + } catch (error: any) { |
| 73 | + captureException(error); |
216 | 74 | return res.status(500).json({ error: "Internal Server Error" });
|
217 | 75 | }
|
218 |
| - |
219 |
| - res.status(200).json({ error: null }); |
220 |
| -} |
221 |
| - |
222 |
| -function upsertPlainCustomer( |
223 |
| - customerIdentifier: UpsertCustomerInput["identifier"], |
224 |
| - memberId: number, |
225 |
| - profileEmail: string, |
226 |
| - validatedUser: z.infer<typeof UserSchema>, |
227 |
| -) { |
228 |
| - return client.upsertCustomer({ |
229 |
| - identifier: customerIdentifier, |
230 |
| - onCreate: { |
231 |
| - fullName: validatedUser.name || validatedUser.nickname || profileEmail, |
232 |
| - externalId: memberId.toString(), |
233 |
| - email: { |
234 |
| - email: profileEmail, |
235 |
| - isVerified: true, |
236 |
| - }, |
237 |
| - }, |
238 |
| - onUpdate: { |
239 |
| - email: { |
240 |
| - email: profileEmail, |
241 |
| - isVerified: true, |
242 |
| - }, |
243 |
| - fullName: { |
244 |
| - value: validatedUser.name || validatedUser.nickname || profileEmail, |
245 |
| - }, |
246 |
| - }, |
247 |
| - }); |
248 |
| -} |
249 |
| - |
250 |
| -function failedToUpsertPlainCustomer( |
251 |
| - error: PlainSDKError, |
252 |
| - res: NextApiResponse, |
253 |
| -) { |
254 |
| - console.error( |
255 |
| - inspect(error, { |
256 |
| - showHidden: false, |
257 |
| - depth: null, |
258 |
| - colors: true, |
259 |
| - }), |
260 |
| - ); |
261 |
| - captureMessage(error.message); |
262 |
| - return res.status(500).json({ error: "Internal Server Error" }); |
263 | 76 | }
|
0 commit comments