├── .env.example
├── .gitignore
├── LICENSE.md
├── README.md
├── components.json
├── docker-compose.yaml
├── drizzle.config.ts
├── echo.ts
├── next.config.js
├── package.json
├── pnpm-lock.yaml
├── postcss.config.js
├── prettier.config.js
├── public
└── favicon.ico
├── screenshot.png
├── src
├── app
│ ├── [orgSlug]
│ │ ├── _components
│ │ │ ├── actions.ts
│ │ │ ├── destinations.tsx
│ │ │ ├── endpoints.tsx
│ │ │ ├── new-destination.tsx
│ │ │ ├── new-endpoint.tsx
│ │ │ └── user-dropdown.tsx
│ │ ├── dashboard
│ │ │ ├── messages
│ │ │ │ └── [endpointId]
│ │ │ │ │ ├── _components
│ │ │ │ │ ├── endpoint-header.tsx
│ │ │ │ │ └── endpoint-messages.tsx
│ │ │ │ │ └── page.tsx
│ │ │ └── page.tsx
│ │ ├── endpoint
│ │ │ └── [slug]
│ │ │ │ └── [[...path]]
│ │ │ │ └── route.ts
│ │ ├── layout.tsx
│ │ └── route.ts
│ ├── api
│ │ ├── login
│ │ │ ├── callback
│ │ │ │ └── route.ts
│ │ │ └── route.ts
│ │ └── trpc
│ │ │ └── [trpc]
│ │ │ └── route.ts
│ ├── layout.tsx
│ └── page.tsx
├── components
│ └── ui
│ │ ├── avatar.tsx
│ │ ├── badge.tsx
│ │ ├── button.tsx
│ │ ├── dialog.tsx
│ │ ├── dropdown-menu.tsx
│ │ ├── form.tsx
│ │ ├── input.tsx
│ │ ├── label.tsx
│ │ ├── scroll-area.tsx
│ │ ├── select.tsx
│ │ ├── skeleton.tsx
│ │ ├── sonner.tsx
│ │ ├── table.tsx
│ │ └── tooltip.tsx
├── env.js
├── lib
│ ├── trpc.server.ts
│ ├── trpc.tsx
│ └── utils.ts
├── server
│ ├── auth
│ │ ├── adapter.ts
│ │ └── index.ts
│ ├── db
│ │ ├── index.ts
│ │ └── schema.ts
│ ├── trpc
│ │ ├── index.ts
│ │ ├── routers
│ │ │ ├── destinations.ts
│ │ │ ├── endpoints.ts
│ │ │ └── messages.ts
│ │ └── trpc.ts
│ └── utils
│ │ ├── send-to-destinations.ts
│ │ └── typeid.ts
└── styles
│ └── globals.css
├── tailwind.config.ts
└── tsconfig.json
/.env.example:
--------------------------------------------------------------------------------
1 | # This is setup to use the local docker container
2 |
3 | DATABASE_URL="postgresql://postgres:secretpassword@localhost:5432/unwebhook"
4 |
5 | GITHUB_CLIENT_ID="your-github-client-id"
6 | GITHUB_CLIENT_SECRET="your-github-client-secret"
7 |
8 | NEXT_PUBLIC_PRIMARY_DOMAIN="localhost:3000"
9 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | /node_modules
5 | /.pnp
6 | .pnp.js
7 |
8 | # testing
9 | /coverage
10 |
11 | # next.js
12 | /.next/
13 | /out/
14 | next-env.d.ts
15 |
16 | # production
17 | /build
18 |
19 | # misc
20 | .DS_Store
21 | *.pem
22 |
23 | # debug
24 | npm-debug.log*
25 | yarn-debug.log*
26 | yarn-error.log*
27 | .pnpm-debug.log*
28 |
29 | # local env files
30 | .env
31 | .env*.local
32 |
33 | # vercel
34 | .vercel
35 |
36 | # typescript
37 | *.tsbuildinfo
38 |
--------------------------------------------------------------------------------
/LICENSE.md:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2024 Unproprietary Corporation
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | This is a [Next.js](https://nextjs.org/) project bootstrapped with [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app).
2 |
3 | ## Getting Started
4 |
5 | First, run the development server:
6 |
7 | ---
8 |
9 | 
10 |
11 | ## About
12 |
13 | A simple tool for working with webhooks.
14 | Great for teams and staging environments.
15 |
16 | Watch the introduction video [on youtube](https://youtu.be/q3dS1leG1wQ)
17 |
18 | Capabilities
19 |
20 | - add multiple endpoints
21 | - save received messages (for 7 days)
22 | - automatically forward incoming messages to one or more destinations
23 | - choose forwarding strategy (send to: first in list, all in list)
24 | - support fallback forwarding (if first is down, forward to next)
25 | - replay webhook delivery (resend the data to destinations)
26 |
27 | _Want to send messages to your local machine and need a tunnel?
28 | Check out [untun](https://github.com/unjs/untun) by the UnJs team_
29 |
30 | ---
31 |
32 | ## Tech Stack
33 |
34 | `UnWebhook` is built with the following epic technologies & tools:
35 |
36 | - [Next JS](https://nextjs.com) React based FrontEnd & Backend
37 | - [Tailwind](https://tailwindcss.com/) CSS Engine
38 | - [tRPC](https://trpc.io/) Typesafe APIs
39 | - [DrizzleORM](https://orm.drizzle.team/) ORM + MySQL
40 |
41 | ## Running Locally
42 |
43 | To get a local copy up and running, follow these simple steps.
44 |
45 | ### Prerequisites
46 |
47 | Here is what you need to be able to run UnInbox locally.
48 |
49 | - A Supabase database
50 | - Node.js (Version: >=20.x)
51 | - NVM (Node Version Manager) (see https://github.com/nvm-sh/nvm)
52 | - pnpm (see https://pnpm.io/installation)
53 |
54 | ### Setup
55 |
56 | 1. Clone the repo into a public GitHub repository (or fork https://github.com/un/webhook-proxy/fork).
57 |
58 | ```sh
59 | git clone https://github.com/un/webhook-proxy.git UnWebhook
60 | ```
61 |
62 | > If you are on Windows, run the following command on `gitbash` with admin privileges:
> `git clone -c core.symlinks=true https://github.com/un/webhook-proxy.git`
63 | > See [docs](https://cal.com/docs/how-to-guides/how-to-troubleshoot-symbolic-link-issues-on-windows#enable-symbolic-links) for more details.
64 |
65 | 2. Go to the project folder
66 |
67 | ```sh
68 | cd UnWebhook
69 | ```
70 |
71 | 3. Check and install the correct node/pnpm versions
72 |
73 | ```sh
74 | nvm install
75 | ```
76 |
77 | 4. Install packages with pnpm
78 |
79 | ```sh
80 | pnpm i
81 | ```
82 |
83 | 5. Set up your `.env` file
84 |
85 | - Duplicate `.env.example` to `.env`. This file is already pre-configured for use with the local docker containers
86 |
87 | mac
88 |
89 | ```sh
90 | cp .env.example .env
91 | ```
92 |
93 | windows
94 |
95 | ```sh
96 | copy .env.example .env
97 | ```
98 |
99 | 6. Set your env variables
100 |
101 | Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.
102 |
103 | You can start editing the page by modifying `app/page.tsx`. The page auto-updates as you edit the file.
104 |
105 | This project uses [`next/font`](https://nextjs.org/docs/basic-features/font-optimization) to automatically optimize and load Inter, a custom Google Font.
106 |
107 | ## Learn More
108 |
109 | To learn more about Next.js, take a look at the following resources:
110 |
111 | - [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API.
112 | - [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial.
113 |
114 | You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js/) - your feedback and contributions are welcome!
115 |
116 | ## Deploy on Vercel
117 |
118 | The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js.
119 |
120 | Check out our [Next.js deployment documentation](https://nextjs.org/docs/deployment) for more details.
121 |
--------------------------------------------------------------------------------
/components.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://ui.shadcn.com/schema.json",
3 | "style": "default",
4 | "rsc": true,
5 | "tsx": true,
6 | "tailwind": {
7 | "config": "tailwind.config.ts",
8 | "css": "src/styles/globals.css",
9 | "baseColor": "slate",
10 | "cssVariables": true,
11 | "prefix": ""
12 | },
13 | "aliases": {
14 | "components": "~/components",
15 | "utils": "~/lib/utils"
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/docker-compose.yaml:
--------------------------------------------------------------------------------
1 | services:
2 | db:
3 | image: postgres:16
4 | environment:
5 | POSTGRES_USER: postgres
6 | POSTGRES_PASSWORD: secretpassword
7 | POSTGRES_DB: unwebhook
8 | ports:
9 | - "5432:5432"
10 |
--------------------------------------------------------------------------------
/drizzle.config.ts:
--------------------------------------------------------------------------------
1 | import "dotenv/config"
2 | import { type Config } from "drizzle-kit";
3 |
4 | export default {
5 | schema: "./src/server/db/schema.ts",
6 | dialect: "postgresql",
7 | dbCredentials: {
8 | url: process.env.DATABASE_URL!,
9 | },
10 | tablesFilter: ["unwebhook_*"],
11 | } satisfies Config;
12 |
--------------------------------------------------------------------------------
/echo.ts:
--------------------------------------------------------------------------------
1 | import http from "http";
2 | const server = http.createServer();
3 |
4 | server
5 | .on("request", (request, response) => {
6 | let body: any[] = [];
7 | request
8 | .on("data", (chunk) => {
9 | body.push(chunk);
10 | })
11 | .on("end", () => {
12 | const wholeBody = Buffer.concat(body).toString();
13 | console.log(`[${new Date().toLocaleString()}]`);
14 | console.log(`==== ${request.method} ${request.url}`);
15 | console.log("> Headers");
16 | console.log(request.headers);
17 | console.log("> Body");
18 | console.log(wholeBody);
19 | response.end();
20 | });
21 | })
22 | .listen(3001)
23 | .once("listening", () => {
24 | console.log("Test server is listening on port 3001");
25 | });
26 |
--------------------------------------------------------------------------------
/next.config.js:
--------------------------------------------------------------------------------
1 | await import("./src/env.js");
2 |
3 | /** @type {import('next').NextConfig} */
4 | const nextConfig = {
5 | redirects: async () => [
6 | { source: "/github", destination: "https://github.com/un/webhook-proxy", permanent: true },
7 | ],
8 | };
9 |
10 | export default nextConfig;
11 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@u22n/webhook",
3 | "type": "module",
4 | "version": "0.1.0",
5 | "private": true,
6 | "scripts": {
7 | "dev": "next dev --turbo",
8 | "build": "next build",
9 | "start": "next start",
10 | "lint": "next lint",
11 | "db:studio": "drizzle-kit studio",
12 | "db:push": "drizzle-kit push",
13 | "format": "prettier --write ."
14 | },
15 | "dependencies": {
16 | "@hookform/resolvers": "^3.6.0",
17 | "@lucia-auth/adapter-drizzle": "^1.0.7",
18 | "@phosphor-icons/react": "^2.1.5",
19 | "@radix-ui/react-avatar": "^1.0.4",
20 | "@radix-ui/react-dialog": "^1.0.5",
21 | "@radix-ui/react-dropdown-menu": "^2.0.6",
22 | "@radix-ui/react-label": "^2.0.2",
23 | "@radix-ui/react-scroll-area": "^1.0.5",
24 | "@radix-ui/react-select": "^2.0.0",
25 | "@radix-ui/react-slot": "^1.0.2",
26 | "@radix-ui/react-tooltip": "^1.0.7",
27 | "@t3-oss/env-nextjs": "^0.10.1",
28 | "@tanstack/react-query": "^5.40.1",
29 | "@trpc/client": "11.0.0-rc.377",
30 | "@trpc/react-query": "11.0.0-rc.377",
31 | "@trpc/server": "11.0.0-rc.377",
32 | "arctic": "^1.9.0",
33 | "class-variance-authority": "^0.7.0",
34 | "clsx": "^2.1.1",
35 | "date-fns": "^3.6.0",
36 | "drizzle-orm": "^0.31.1",
37 | "lucia": "^3.2.0",
38 | "nanoid": "^5.0.7",
39 | "next": "14.2.3",
40 | "next-themes": "^0.3.0",
41 | "nuqs": "^1.17.4",
42 | "postgres": "^3.4.4",
43 | "react": "^18.3.1",
44 | "react-code-blocks": "^0.1.6",
45 | "react-dom": "^18.3.1",
46 | "react-hook-form": "^7.51.5",
47 | "server-only": "^0.0.1",
48 | "sonner": "^1.4.41",
49 | "superjson": "^2.2.1",
50 | "tailwind-merge": "^2.3.0",
51 | "tailwindcss-animate": "^1.0.7",
52 | "typeid-js": "^0.7.0",
53 | "zod": "^3.23.8"
54 | },
55 | "devDependencies": {
56 | "@types/node": "^20.14.2",
57 | "@types/react": "^18.3.3",
58 | "@types/react-dom": "^18.3.0",
59 | "@u22n/tsconfig": "^0.0.2",
60 | "dotenv": "^16.4.5",
61 | "drizzle-kit": "^0.22.2",
62 | "postcss": "^8.4.38",
63 | "prettier": "^3.3.1",
64 | "prettier-plugin-sort-imports": "^1.8.5",
65 | "prettier-plugin-tailwindcss": "^0.6.1",
66 | "tailwindcss": "^3.4.4",
67 | "typescript": "^5.4.5"
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/postcss.config.js:
--------------------------------------------------------------------------------
1 | /** @type {import('postcss-load-config').Config} */
2 | const config = {
3 | plugins: {
4 | tailwindcss: {},
5 | },
6 | };
7 |
8 | export default config;
9 |
--------------------------------------------------------------------------------
/prettier.config.js:
--------------------------------------------------------------------------------
1 | /** @type {import('prettier').Config} */
2 | const config = {
3 | printWidth: 100,
4 | tabWidth: 2,
5 | useTabs: false,
6 | singleQuote: false,
7 | plugins: ["prettier-plugin-sort-imports", "prettier-plugin-tailwindcss"],
8 | };
9 |
10 | export default config;
11 |
--------------------------------------------------------------------------------
/public/favicon.ico:
--------------------------------------------------------------------------------
1 | ( F ( n 00 (- � � �F ( $ ] � � ] $ � � � � � � � � 8 � � � � � � � � � � 8 � � � � � � � � � � � � � � � � � � � � � � � � � � # � � �OOO�������������������������ggg� � � � # Y � � ��������������������������555� � � � Y � � � � �kkk��������������������� � � � � � � � � � � ������������������ � � � � � Y � � � � �JJJ���������kkk� � � � � � Y # � � � � ���������� � � � � � � # � � � � � �111�DDD� � � � � � � � � � � � � � � � � � � 8 � � � � � � � � � � 8 � � � � � � � � $ ] � � ] $ ( @ , U � � � � U , * � � � � � � � � � � � � * � � � � � � � � � � � � � � � � Q � � � � � � � � � � � � � � � � � � Q r � � � � � � � � � � � � � � � � � � � � r r � � � � � � � � � � � � � � � � � � � � � � r O � � � � � � � � � � � � � � � � � � � � � � � � O � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � ( � � � � � � � � � � � � � � � � � � � � � � � � � � � � ' � � � � � � �888���������������������������������������������������������___� � � � � � � � � � � � � � ����������������������������������������������������������SSS� � � � � � � � + � � � � � � � �hhh����������������������������������������������������� � � � � � � � � + T � � � � � � � ��������������������������������������������������,,,� � � � � � � � � T � � � � � � � � � �GGG��������������������������������������������� � � � � � � � � � � � � � � � � � � � � ������������������������������������������ � � � � � � � � � � � � � � � � � � � � �+++���������������������������������jjj� � � � � � � � � � � � � � � � � � � � � � � ���������������������������������� � � � � � � � � � � � T � � � � � � � � � � ��������������������������III� � � � � � � � � � � � T + � � � � � � � � � � � �hhh���������������������� � � � � � � � � � � � + � � � � � � � � � � � ������������������,,,� � � � � � � � � � � � � � � � � � � � � � � � � �GGG������������� � � � � � � � � � � � � � ' � � � � � � � � � � � � ���������� � � � � � � � � � � � � ( � � � � � � � � � � � � �333�___� � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � O � � � � � � � � � � � � � � � � � � � � � � � � O r � � � � � � � � � � � � � � � � � � � � � � r r � � � � � � � � � � � � � � � � � � � � r Q � � � � � � � � � � � � � � � � � � Q � � � � � � � � � � � � � � � � * � � � � � � � � � � � � * , U � � � � U , ( 0 ` - ( L j � � � � j K ( V � � � � � � � � � � � � � � U % � � � � � � � � � � � � � � � � � � � � &