Skip to content

Commit 2df7588

Browse files
committed
Merge remote-tracking branch 'origin/ben/get-emails' into integration/all-prs
# Conflicts: # apps/dashboard/convex/_shared/adminToken.ts # apps/dashboard/convex/crons.ts # apps/dashboard/convex/gmailConnection.ts # apps/dashboard/convex/gmailOAuth.ts # apps/dashboard/convex/ingestion.ts # apps/dashboard/convex/listservAdmin.ts # apps/dashboard/convex/parser.ts # apps/dashboard/convex/sourceAdmin.ts # apps/dashboard/eslint.config.js # apps/dashboard/src/pages/Admin.tsx # src/App.tsx
2 parents ab8fc2c + 779f513 commit 2df7588

15 files changed

Lines changed: 5290 additions & 1 deletion

File tree

apps/dashboard/convex/_generated/api.d.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,17 +8,25 @@
88
* @module
99
*/
1010

11+
import type * as _shared_adminToken from "../_shared/adminToken.js";
1112
import type * as auth from "../auth.js";
1213
import type * as bookmarks from "../bookmarks.js";
1314
import type * as dev from "../dev.js";
1415
import type * as events from "../events.js";
1516
import type * as follows from "../follows.js";
17+
import type * as crons from "../crons.js";
18+
import type * as gmailConnection from "../gmailConnection.js";
19+
import type * as gmailOAuth from "../gmailOAuth.js";
1620
import type * as http from "../http.js";
1721
import type * as orgs from "../orgs.js";
1822
import type * as rsvps from "../rsvps.js";
1923
import type * as seed from "../seed.js";
2024
import type * as seedData from "../seedData.js";
2125
import type * as users from "../users.js";
26+
import type * as ingestion from "../ingestion.js";
27+
import type * as listservAdmin from "../listservAdmin.js";
28+
import type * as parser from "../parser.js";
29+
import type * as sourceAdmin from "../sourceAdmin.js";
2230

2331
import type {
2432
ApiFromModules,
@@ -27,17 +35,25 @@ import type {
2735
} from "convex/server";
2836

2937
declare const fullApi: ApiFromModules<{
38+
"_shared/adminToken": typeof _shared_adminToken;
3039
auth: typeof auth;
3140
bookmarks: typeof bookmarks;
3241
dev: typeof dev;
3342
events: typeof events;
3443
follows: typeof follows;
44+
crons: typeof crons;
45+
gmailConnection: typeof gmailConnection;
46+
gmailOAuth: typeof gmailOAuth;
3547
http: typeof http;
3648
orgs: typeof orgs;
3749
rsvps: typeof rsvps;
3850
seed: typeof seed;
3951
seedData: typeof seedData;
4052
users: typeof users;
53+
ingestion: typeof ingestion;
54+
listservAdmin: typeof listservAdmin;
55+
parser: typeof parser;
56+
sourceAdmin: typeof sourceAdmin;
4157
}>;
4258

4359
/**
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
declare const process: { env: Record<string, string | undefined> };
2+
3+
export function requireAdminToken(token: string) {
4+
const expected = process.env.ADMIN_TOKEN;
5+
6+
if (!expected) {
7+
throw new Error("ADMIN_TOKEN is not configured.");
8+
}
9+
10+
if (token !== expected) {
11+
throw new Error("Invalid admin token.");
12+
}
13+
}

apps/dashboard/convex/crons.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import { cronJobs } from "convex/server";
2+
import { internal } from "./_generated/api";
3+
4+
const crons = cronJobs();
5+
6+
crons.interval(
7+
"poll listserv inbox",
8+
{ minutes: 10 },
9+
internal.ingestion.pollListservInbox,
10+
{ trigger: "cron" },
11+
);
12+
13+
export default crons;
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import { v } from "convex/values";
2+
import { internalMutation, internalQuery } from "./_generated/server";
3+
4+
const CONNECTION_KEY = "primary";
5+
6+
export const getConnection = internalQuery({
7+
args: {},
8+
handler: async (ctx) => {
9+
const connection = await ctx.db
10+
.query("gmailConnections")
11+
.withIndex("by_key", (q) => q.eq("key", CONNECTION_KEY))
12+
.unique();
13+
14+
if (!connection || connection.status !== "connected") return null;
15+
return {
16+
email: connection.email,
17+
refreshToken: connection.refreshToken,
18+
};
19+
},
20+
});
21+
22+
export const markInvalid = internalMutation({
23+
args: { error: v.string() },
24+
handler: async (ctx, args) => {
25+
const connection = await ctx.db
26+
.query("gmailConnections")
27+
.withIndex("by_key", (q) => q.eq("key", CONNECTION_KEY))
28+
.unique();
29+
30+
if (!connection) return;
31+
32+
await ctx.db.patch(connection._id, {
33+
status: "invalid",
34+
lastError: args.error,
35+
updatedAt: Date.now(),
36+
});
37+
},
38+
});

0 commit comments

Comments
 (0)