commune-ai 0.1.6 → 0.1.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +80 -15
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -29,6 +29,7 @@ Build agents that receive emails, reply in threads, access conversation history,
|
|
|
29
29
|
- [Reply in email threads](#reply-in-email-threads)
|
|
30
30
|
- [Access conversation history](#access-conversation-history)
|
|
31
31
|
- [Manage Inboxes Programmatically](#manage-inboxes-programmatically)
|
|
32
|
+
- [How Webhooks Work](#how-webhooks-work)
|
|
32
33
|
- [Listen for Specific Inbox Events](#listen-for-specific-inbox-events)
|
|
33
34
|
- [Semantic Search (Coming Soon)](#semantic-search-coming-soon)
|
|
34
35
|
- [Complete agent example](#complete-agent-example)
|
|
@@ -90,9 +91,24 @@ COMMUNE_BASE_URL=https://your-self-hosted-api.com
|
|
|
90
91
|
|
|
91
92
|
---
|
|
92
93
|
|
|
93
|
-
## Receive emails
|
|
94
|
+
## Receive emails at your webhook endpoint
|
|
94
95
|
|
|
95
|
-
|
|
96
|
+
Configure your inbox to send emails to your server, then mount the webhook handler at that endpoint.
|
|
97
|
+
|
|
98
|
+
### Step 1: Configure webhook URL for your inbox
|
|
99
|
+
|
|
100
|
+
First, set the webhook URL in your inbox settings (via dashboard or SDK):
|
|
101
|
+
|
|
102
|
+
```ts
|
|
103
|
+
await client.inboxes.setWebhook(domainId, inboxId, {
|
|
104
|
+
endpoint: "https://your-server.com/api/emails", // Your endpoint URL
|
|
105
|
+
events: ["email.received"],
|
|
106
|
+
});
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
### Step 2: Mount webhook handler at that URL
|
|
110
|
+
|
|
111
|
+
Your server must listen at the **exact same URL** you configured:
|
|
96
112
|
|
|
97
113
|
```ts
|
|
98
114
|
import "dotenv/config";
|
|
@@ -104,8 +120,8 @@ const client = new CommuneClient({
|
|
|
104
120
|
apiKey: process.env.COMMUNE_API_KEY, // ← From Step 3 above
|
|
105
121
|
});
|
|
106
122
|
|
|
107
|
-
//
|
|
108
|
-
const
|
|
123
|
+
// Create webhook handler to process incoming emails
|
|
124
|
+
const emailHandler = createWebhookHandler({
|
|
109
125
|
onEvent: async (message, context) => {
|
|
110
126
|
console.log(`📧 New email: ${message.content}`);
|
|
111
127
|
|
|
@@ -129,9 +145,11 @@ const handler = createWebhookHandler({
|
|
|
129
145
|
},
|
|
130
146
|
});
|
|
131
147
|
|
|
132
|
-
// Set up
|
|
148
|
+
// Set up your server
|
|
133
149
|
const app = express();
|
|
134
|
-
|
|
150
|
+
|
|
151
|
+
// This URL must match what you configured in Step 1
|
|
152
|
+
app.post("/api/emails", express.raw({ type: "*/*" }), emailHandler);
|
|
135
153
|
|
|
136
154
|
// Health check
|
|
137
155
|
app.get("/health", (req, res) => res.json({ status: "ok" }));
|
|
@@ -142,6 +160,12 @@ app.listen(3000, () => {
|
|
|
142
160
|
});
|
|
143
161
|
```
|
|
144
162
|
|
|
163
|
+
**Complete flow:**
|
|
164
|
+
1. Email arrives at your inbox
|
|
165
|
+
2. Resend sends webhook to Commune backend
|
|
166
|
+
3. Commune backend sends email to your configured endpoint (`/api/emails`)
|
|
167
|
+
4. Your `emailHandler` processes the email and replies
|
|
168
|
+
|
|
145
169
|
**Email structure:**
|
|
146
170
|
```ts
|
|
147
171
|
interface UnifiedMessage {
|
|
@@ -176,7 +200,8 @@ const client = new CommuneClient({
|
|
|
176
200
|
apiKey: process.env.COMMUNE_API_KEY,
|
|
177
201
|
});
|
|
178
202
|
|
|
179
|
-
|
|
203
|
+
// Create webhook handler
|
|
204
|
+
const emailHandler = createWebhookHandler({
|
|
180
205
|
onEvent: async (message, context) => {
|
|
181
206
|
const sender = message.participants.find(p => p.role === "sender")?.identity;
|
|
182
207
|
if (!sender) return;
|
|
@@ -193,9 +218,15 @@ const handler = createWebhookHandler({
|
|
|
193
218
|
},
|
|
194
219
|
});
|
|
195
220
|
|
|
221
|
+
// Set up your server
|
|
196
222
|
const app = express();
|
|
197
|
-
|
|
198
|
-
|
|
223
|
+
|
|
224
|
+
// Mount handler at your webhook endpoint
|
|
225
|
+
app.post("/api/emails", express.raw({ type: "*/*" }), emailHandler);
|
|
226
|
+
|
|
227
|
+
app.listen(3000, () => {
|
|
228
|
+
console.log("Agent running on port 3000");
|
|
229
|
+
});
|
|
199
230
|
```
|
|
200
231
|
|
|
201
232
|
---
|
|
@@ -323,14 +354,33 @@ await client.inboxes.remove(domainId, inboxId);
|
|
|
323
354
|
|
|
324
355
|
---
|
|
325
356
|
|
|
326
|
-
##
|
|
357
|
+
## How Webhooks Work
|
|
358
|
+
|
|
359
|
+
**Understanding the webhook flow:**
|
|
360
|
+
|
|
361
|
+
1. **Resend Webhooks** → When you verify a domain, the backend creates a webhook at Resend (email service) that points to the Commune backend
|
|
362
|
+
2. **Commune Backend** → Processes the webhook from Resend and looks up inbox configurations
|
|
363
|
+
3. **Your Webhook Endpoint** → If an inbox has a webhook URL set, Commune sends an HTTP POST to your endpoint
|
|
327
364
|
|
|
328
|
-
|
|
365
|
+
```typescript
|
|
366
|
+
// Webhook flow: Resend → Commune Backend → Your Server
|
|
367
|
+
// Your server uses createWebhookHandler to process webhooks from Commune
|
|
368
|
+
```
|
|
369
|
+
|
|
370
|
+
## Listen for specific inbox events
|
|
371
|
+
|
|
372
|
+
Route incoming emails based on which inbox received them. Set up different webhook endpoints for different inboxes.
|
|
329
373
|
|
|
330
374
|
```ts
|
|
331
|
-
import
|
|
375
|
+
import express from "express";
|
|
376
|
+
import { CommuneClient, createWebhookHandler } from "commune-ai";
|
|
377
|
+
|
|
378
|
+
const client = new CommuneClient({
|
|
379
|
+
apiKey: process.env.COMMUNE_API_KEY,
|
|
380
|
+
});
|
|
332
381
|
|
|
333
|
-
|
|
382
|
+
// Create webhook handler for routing
|
|
383
|
+
const emailRouter = createWebhookHandler({
|
|
334
384
|
onEvent: async (message, context) => {
|
|
335
385
|
const { inboxId, inboxAddress } = context.payload;
|
|
336
386
|
|
|
@@ -348,6 +398,18 @@ const handler = createWebhookHandler({
|
|
|
348
398
|
},
|
|
349
399
|
});
|
|
350
400
|
|
|
401
|
+
// Set up your server
|
|
402
|
+
const app = express();
|
|
403
|
+
|
|
404
|
+
// Mount the same handler at different endpoints for different inboxes
|
|
405
|
+
app.post("/api/support", express.raw({ type: "*/*" }), emailRouter); // For support inbox
|
|
406
|
+
app.post("/api/sales", express.raw({ type: "*/*" }), emailRouter); // For sales inbox
|
|
407
|
+
app.post("/api/general", express.raw({ type: "*/*" }), emailRouter); // For general inbox
|
|
408
|
+
|
|
409
|
+
app.listen(3000, () => {
|
|
410
|
+
console.log("Agent running with multiple inbox endpoints");
|
|
411
|
+
});
|
|
412
|
+
|
|
351
413
|
// Example handlers
|
|
352
414
|
async function handleSupportEmail(message: any, context: any) {
|
|
353
415
|
const sender = message.participants.find(p => p.role === "sender")?.identity;
|
|
@@ -427,7 +489,7 @@ const client = new CommuneClient({
|
|
|
427
489
|
apiKey: process.env.COMMUNE_API_KEY,
|
|
428
490
|
});
|
|
429
491
|
|
|
430
|
-
const
|
|
492
|
+
const emailProcessor = createWebhookHandler({
|
|
431
493
|
onEvent: async (message, context) => {
|
|
432
494
|
const sender = message.participants.find(p => p.role === "sender")?.identity;
|
|
433
495
|
if (!sender) return;
|
|
@@ -471,8 +533,11 @@ const handler = createWebhookHandler({
|
|
|
471
533
|
},
|
|
472
534
|
});
|
|
473
535
|
|
|
536
|
+
// Set up your server
|
|
474
537
|
const app = express();
|
|
475
|
-
|
|
538
|
+
|
|
539
|
+
// Mount webhook handler at your endpoint
|
|
540
|
+
app.post("/api/emails", express.raw({ type: "*/*" }), emailProcessor);
|
|
476
541
|
|
|
477
542
|
// Health check endpoint
|
|
478
543
|
app.get("/health", (req, res) => res.json({ status: "ok" }));
|