feat: prepare for webhooks

This commit is contained in:
Max Koon
2025-11-22 12:56:48 -05:00
parent c4bb0d3304
commit 284b8b6fc1
6 changed files with 35 additions and 15 deletions

View File

@@ -5,6 +5,7 @@ import { cors } from "hono/cors";
import { auth } from "./auth"; import { auth } from "./auth";
import { getHono } from "./hono"; import { getHono } from "./hono";
import { zero } from "./zero"; import { zero } from "./zero";
import { webhook } from "./webhook";
const app = getHono(); const app = getHono();
@@ -43,6 +44,7 @@ app.use("*", async (c, next) => {
app.route("/api/zero", zero); app.route("/api/zero", zero);
app.get("/api", (c) => c.text("OK")); app.get("/api", (c) => c.text("OK"));
app.get("/api/webhook_receiver", webhook);
app.get("/", (c) => c.text("OK")); app.get("/", (c) => c.text("OK"));
serve( serve(

13
apps/api/src/plaid.ts Normal file
View File

@@ -0,0 +1,13 @@
import { Configuration, PlaidApi, PlaidEnvironments } from "plaid";
const configuration = new Configuration({
basePath: process.env.PLAID_ENV == 'production' ? PlaidEnvironments.production : PlaidEnvironments.sandbox,
baseOptions: {
headers: {
'PLAID-CLIENT-ID': process.env.PLAID_CLIENT_ID,
'PLAID-SECRET': process.env.PLAID_SECRET,
}
},
});
export const plaidClient = new PlaidApi(configuration);

14
apps/api/src/webhook.ts Normal file
View File

@@ -0,0 +1,14 @@
import type { Context } from "hono";
import { plaidClient } from "./plaid";
// import { LinkSessionFinishedWebhook, WebhookType } from "plaid";
export const webhook = async (c: Context) => {
console.log("Got webhook");
const b = await c.req.text();
console.log("body:", b);
return c.text("Hi");
}

View File

@@ -25,19 +25,7 @@ import { randomUUID } from "crypto";
import { db } from "./db"; import { db } from "./db";
import { balance, plaidAccessTokens, plaidLink, transaction } from "@money/shared/db"; import { balance, plaidAccessTokens, plaidLink, transaction } from "@money/shared/db";
import { eq, inArray, sql, type InferInsertModel } from "drizzle-orm"; import { eq, inArray, sql, type InferInsertModel } from "drizzle-orm";
import { plaidClient } from "./plaid";
const configuration = new Configuration({
basePath: process.env.PLAID_ENV == 'production' ? PlaidEnvironments.production : PlaidEnvironments.sandbox,
baseOptions: {
headers: {
'PLAID-CLIENT-ID': process.env.PLAID_CLIENT_ID,
'PLAID-SECRET': process.env.PLAID_SECRET,
}
}
});
const plaidClient = new PlaidApi(configuration);
const processor = new PushProcessor( const processor = new PushProcessor(
new ZQLDatabase( new ZQLDatabase(
@@ -56,7 +44,6 @@ const createMutators = (authData: AuthData | null) => {
...mutators.link, ...mutators.link,
async create() { async create() {
isLoggedIn(authData); isLoggedIn(authData);
console.log("Creating Link token");
const r = await plaidClient.linkTokenCreate({ const r = await plaidClient.linkTokenCreate({
user: { user: {
client_user_id: authData.user.id, client_user_id: authData.user.id,
@@ -65,9 +52,9 @@ const createMutators = (authData: AuthData | null) => {
language: "en", language: "en",
products: [Products.Transactions], products: [Products.Transactions],
country_codes: [CountryCode.Us], country_codes: [CountryCode.Us],
webhook: "https://webhooks.koon.us/api/webhook_receiver",
hosted_link: {} hosted_link: {}
}); });
console.log("Result", r);
const { link_token, hosted_link_url } = r.data; const { link_token, hosted_link_url } = r.data;
if (!hosted_link_url) throw Error("No link in response"); if (!hosted_link_url) throw Error("No link in response");

View File

@@ -23,6 +23,7 @@
postgresql postgresql
process-compose process-compose
cloudflared
]; ];
}; };
}); });

View File

@@ -62,3 +62,6 @@ processes:
depends_on: depends_on:
db: db:
condition: process_healthy condition: process_healthy
tunnel:
command: cloudflared tunnel --config ~/.cloudflared/config.yml run