Skip to content

Commit 28d6e01

Browse files
authored
chore: Update gmail recipe to reauth if receiving a 401 and retrying (#1095)
chore: Update gmail recipe to reauth if receiving a 401 and retrying. If still unable to request, considered a failure and stop charm.
1 parent 418cc28 commit 28d6e01

File tree

1 file changed

+50
-31
lines changed

1 file changed

+50
-31
lines changed

recipes/gmail.tsx

Lines changed: 50 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -180,15 +180,16 @@ const refreshAuthToken = async (auth: Cell<Auth>) => {
180180

181181
console.log("refreshAuthToken", body);
182182

183-
const refresh_response = await fetch(
183+
const res = await fetch(
184184
new URL("/api/integrations/google-oauth/refresh", env.apiUrl),
185185
{
186186
method: "POST",
187187
body: JSON.stringify(body),
188188
},
189-
).then((res) => res.json());
190-
191-
return refresh_response.tokenInfo as Auth;
189+
);
190+
const json = await res.json();
191+
const authData = json.tokenInfo as Auth;
192+
auth.update(authData);
192193
};
193194

194195
const googleUpdater = handler(
@@ -214,7 +215,7 @@ const googleUpdater = handler(
214215

215216
console.log("gmailFilterQuery", gmailFilterQuery);
216217

217-
return fetchEmail(
218+
return process(
218219
state.auth,
219220
state.settings.limit,
220221
gmailFilterQuery,
@@ -395,25 +396,48 @@ Accept: application/json
395396
}).filter((message): message is Email => message !== null);
396397
}
397398

398-
export async function fetchEmail(
399+
async function fetchEmail(
400+
auth: Cell<Auth>,
401+
maxResults: number = 100,
402+
gmailFilterQuery: string = "in:INBOX",
403+
): Promise<object | undefined> {
404+
const url = `https://gmail.googleapis.com/gmail/v1/users/me/messages?q=${
405+
encodeURIComponent(gmailFilterQuery)
406+
}&maxResults=${maxResults}`;
407+
const query = async (auth: Cell<Auth>): Promise<Response> => {
408+
const authData = auth.get();
409+
const res = await fetch(url, {
410+
headers: {
411+
Authorization: `Bearer ${authData.token}`,
412+
},
413+
});
414+
console.log(`${url}: ${res.status} ${res.statusText}`);
415+
return res;
416+
};
417+
418+
const res = await query(auth);
419+
if (res.status === 200) {
420+
return await res.json();
421+
} else if (res.status === 401) {
422+
await refreshAuthToken(auth);
423+
const res = await query(auth);
424+
if (res.status === 200) {
425+
return await res.json();
426+
}
427+
throw new Error("Fetching email failed upon reauthorization.");
428+
}
429+
}
430+
431+
export async function process(
399432
auth: Cell<Auth>,
400433
maxResults: number = 100,
401434
gmailFilterQuery: string = "in:INBOX",
402435
state: {
403436
emails: Cell<Email[]>;
404437
},
405438
) {
406-
let cur = auth.get();
407-
408-
if (cur.expiresAt && Date.now() > cur.expiresAt) {
409-
const resp = await refreshAuthToken(auth);
410-
auth.update(resp);
411-
console.log("refresh_data", resp);
412-
}
413-
414-
cur = auth.get();
415-
416-
if (!cur.token) {
439+
const authData = auth.get();
440+
if (!authData.token) {
417441
console.warn("no token");
418442
return;
419443
}
@@ -422,21 +446,16 @@ export async function fetchEmail(
422446
state.emails.get().map((email) => email.id),
423447
);
424448

425-
const listResponse = await fetch(
426-
`https://gmail.googleapis.com/gmail/v1/users/me/messages?q=${
427-
encodeURIComponent(gmailFilterQuery)
428-
}&maxResults=${maxResults}`,
429-
{
430-
headers: {
431-
Authorization: `Bearer ${cur.token}`,
432-
},
433-
},
449+
const listData = await fetchEmail(
450+
auth,
451+
maxResults,
452+
gmailFilterQuery,
434453
);
435454

436-
const listData = await listResponse.json();
437-
438-
if (!listData.messages || !Array.isArray(listData.messages)) {
439-
console.log("No messages found in response");
455+
if (
456+
!listData || !("messages" in listData) || !Array.isArray(listData.messages)
457+
) {
458+
console.log(`No messages found in response: ${JSON.stringify(listData)}`);
440459
return;
441460
}
442461

@@ -463,7 +482,7 @@ export async function fetchEmail(
463482
);
464483

465484
try {
466-
const emails = await processBatch(batchMessages, cur.token);
485+
const emails = await processBatch(batchMessages, authData.token);
467486

468487
// Filter out any duplicates by ID
469488
const newEmails = emails.filter((email) =>

0 commit comments

Comments
 (0)