@firela/billclaw-openclaw 0.1.3
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/LICENSE +21 -0
- package/README.md +275 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/oauth/index.d.ts.map +1 -0
- package/dist/oauth/plaid.d.ts.map +1 -0
- package/dist/oauth/plaid.js +108 -0
- package/dist/oauth/plaid.js.map +1 -0
- package/dist/plugin.d.ts.map +1 -0
- package/dist/runtime/context.d.ts +53 -0
- package/dist/runtime/context.d.ts.map +1 -0
- package/dist/runtime/context.js +136 -0
- package/dist/runtime/context.js.map +1 -0
- package/dist/services/index.d.ts.map +1 -0
- package/dist/services/webhook-handler.d.ts.map +1 -0
- package/dist/services/webhook-handler.js +176 -0
- package/dist/services/webhook-handler.js.map +1 -0
- package/dist/tools/index.d.ts.map +1 -0
- package/dist/tools/index.js +253 -0
- package/dist/tools/index.js.map +1 -0
- package/openclaw.plugin.json +79 -0
- package/package.json +76 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024 fire-la
|
|
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
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,275 @@
|
|
|
1
|
+
# @firela/billclaw-openclaw
|
|
2
|
+
|
|
3
|
+
OpenClaw plugin adapter for BillClaw financial data import.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
This package provides an OpenClaw plugin that integrates BillClaw's financial data capabilities with the OpenClaw AI framework. It exposes:
|
|
8
|
+
|
|
9
|
+
- **Agent Tools**: Plaid sync, Gmail fetch, bill parsing, conversational interface
|
|
10
|
+
- **CLI Commands**: `bills setup`, `bills sync`, `bills status`, `bills config`
|
|
11
|
+
- **OAuth Providers**: Plaid Link and Gmail OAuth flows
|
|
12
|
+
- **Background Services**: Sync service and webhook handler
|
|
13
|
+
|
|
14
|
+
## Installation
|
|
15
|
+
|
|
16
|
+
### As OpenClaw Extension
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
cd ~/.openclaw/extensions
|
|
20
|
+
npm install @firela/billclaw-openclaw
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
### Manual Registration
|
|
24
|
+
|
|
25
|
+
Add to your OpenClaw configuration:
|
|
26
|
+
|
|
27
|
+
```json
|
|
28
|
+
{
|
|
29
|
+
"extensions": ["@firela/billclaw-openclaw"]
|
|
30
|
+
}
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## Quick Start
|
|
34
|
+
|
|
35
|
+
### Using Agent Tools
|
|
36
|
+
|
|
37
|
+
```typescript
|
|
38
|
+
// In an OpenClaw agent context
|
|
39
|
+
const result = await agent.useTool("plaid_sync", {
|
|
40
|
+
accountId: "plaid-123"
|
|
41
|
+
});
|
|
42
|
+
// Returns: { success: true, transactionsAdded: 42, ... }
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
### Using CLI Commands
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
# In OpenClaw CLI
|
|
49
|
+
openclaw bills setup
|
|
50
|
+
openclaw bills sync
|
|
51
|
+
openclaw bills status
|
|
52
|
+
openclaw bills config storage.path
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
### OAuth Integration
|
|
56
|
+
|
|
57
|
+
```typescript
|
|
58
|
+
// In OpenClaw OAuth flow
|
|
59
|
+
const oauth = await openclaw.getOAuthProvider("plaid");
|
|
60
|
+
const { url, token } = await oauth.handler(context);
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
## Available Tools
|
|
64
|
+
|
|
65
|
+
### plaid_sync
|
|
66
|
+
|
|
67
|
+
Sync transactions from Plaid-connected bank accounts.
|
|
68
|
+
|
|
69
|
+
```typescript
|
|
70
|
+
await agent.useTool("plaid_sync", {
|
|
71
|
+
accountId: "plaid-123" // Optional - syncs all if omitted
|
|
72
|
+
});
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
**Response:**
|
|
76
|
+
```json
|
|
77
|
+
{
|
|
78
|
+
"success": true,
|
|
79
|
+
"accountsSynced": 1,
|
|
80
|
+
"transactionsAdded": 42,
|
|
81
|
+
"transactionsUpdated": 5
|
|
82
|
+
}
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
### gmail_fetch_bills
|
|
86
|
+
|
|
87
|
+
Fetch and parse bills from Gmail.
|
|
88
|
+
|
|
89
|
+
```typescript
|
|
90
|
+
await agent.useTool("gmail_fetch_bills", {
|
|
91
|
+
accountId: "gmail-123",
|
|
92
|
+
days: 30 // Optional - default 30
|
|
93
|
+
});
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
**Response:**
|
|
97
|
+
```json
|
|
98
|
+
{
|
|
99
|
+
"success": true,
|
|
100
|
+
"accountsProcessed": 1,
|
|
101
|
+
"emailsProcessed": 150,
|
|
102
|
+
"billsExtracted": 12,
|
|
103
|
+
"transactionsAdded": 12
|
|
104
|
+
}
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
### bill_parse
|
|
108
|
+
|
|
109
|
+
Parse bill data from various formats.
|
|
110
|
+
|
|
111
|
+
```typescript
|
|
112
|
+
await agent.useTool("bill_parse", {
|
|
113
|
+
source: "email",
|
|
114
|
+
data: "raw email content"
|
|
115
|
+
});
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
### conversational_sync
|
|
119
|
+
|
|
120
|
+
Sync with natural language support.
|
|
121
|
+
|
|
122
|
+
```typescript
|
|
123
|
+
await agent.useTool("conversational_sync", {
|
|
124
|
+
prompt: "Sync my accounts"
|
|
125
|
+
});
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
### conversational_status
|
|
129
|
+
|
|
130
|
+
Show account status with natural language.
|
|
131
|
+
|
|
132
|
+
```typescript
|
|
133
|
+
await agent.useTool("conversational_status", {});
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
### conversational_help
|
|
137
|
+
|
|
138
|
+
Get help with BillClaw commands.
|
|
139
|
+
|
|
140
|
+
```typescript
|
|
141
|
+
await agent.useTool("conversational_help", {
|
|
142
|
+
topic: "sync"
|
|
143
|
+
});
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
## CLI Commands
|
|
147
|
+
|
|
148
|
+
### bills setup
|
|
149
|
+
|
|
150
|
+
Interactive setup wizard for connecting accounts.
|
|
151
|
+
|
|
152
|
+
```bash
|
|
153
|
+
openclaw bills setup
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
### bills sync
|
|
157
|
+
|
|
158
|
+
Manually trigger transaction sync.
|
|
159
|
+
|
|
160
|
+
```bash
|
|
161
|
+
# Sync all accounts
|
|
162
|
+
openclaw bills sync
|
|
163
|
+
|
|
164
|
+
# Sync specific account
|
|
165
|
+
openclaw bills sync plaid-123
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
### bills status
|
|
169
|
+
|
|
170
|
+
Show connection status and recent sync results.
|
|
171
|
+
|
|
172
|
+
```bash
|
|
173
|
+
openclaw bills status
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
### bills config
|
|
177
|
+
|
|
178
|
+
Manage plugin configuration.
|
|
179
|
+
|
|
180
|
+
```bash
|
|
181
|
+
# View all config
|
|
182
|
+
openclaw bills config
|
|
183
|
+
|
|
184
|
+
# View specific key
|
|
185
|
+
openclaw bills config storage.path
|
|
186
|
+
|
|
187
|
+
# Set value
|
|
188
|
+
openclaw bills config storage.format json
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
## OAuth Providers
|
|
192
|
+
|
|
193
|
+
### Plaid
|
|
194
|
+
|
|
195
|
+
```typescript
|
|
196
|
+
const oauth = await openclaw.getOAuthProvider("plaid");
|
|
197
|
+
const { url } = await oauth.handler(context);
|
|
198
|
+
// Redirect user to Plaid Link
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
### Gmail
|
|
202
|
+
|
|
203
|
+
```typescript
|
|
204
|
+
const oauth = await openclaw.getOAuthProvider("gmail");
|
|
205
|
+
const { url } = await oauth.handler(context);
|
|
206
|
+
// Redirect user to Google OAuth
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
## Background Services
|
|
210
|
+
|
|
211
|
+
### billclaw-sync
|
|
212
|
+
|
|
213
|
+
Automatic sync service that runs on configured intervals.
|
|
214
|
+
|
|
215
|
+
### billclaw-webhook
|
|
216
|
+
|
|
217
|
+
HTTP webhook handler for real-time transaction updates from Plaid.
|
|
218
|
+
|
|
219
|
+
## Configuration
|
|
220
|
+
|
|
221
|
+
Plugin configuration is managed through OpenClaw's plugin config system:
|
|
222
|
+
|
|
223
|
+
```json
|
|
224
|
+
{
|
|
225
|
+
"accounts": [],
|
|
226
|
+
"storage": {
|
|
227
|
+
"path": "~/.openclaw/billclaw",
|
|
228
|
+
"format": "json"
|
|
229
|
+
},
|
|
230
|
+
"sync": {
|
|
231
|
+
"defaultFrequency": "daily",
|
|
232
|
+
"maxRetries": 3
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
## Architecture
|
|
238
|
+
|
|
239
|
+
```
|
|
240
|
+
┌─────────────────────────────────────────┐
|
|
241
|
+
│ OpenClaw Framework │
|
|
242
|
+
├─────────────────────────────────────────┤
|
|
243
|
+
│ BillClaw Plugin │
|
|
244
|
+
│ ├── Agent Tools (6) │
|
|
245
|
+
│ ├── CLI Commands (4) │
|
|
246
|
+
│ ├── OAuth Providers (2) │
|
|
247
|
+
│ └── Background Services (2) │
|
|
248
|
+
├─────────────────────────────────────────┤
|
|
249
|
+
│ @firela/billclaw-core │
|
|
250
|
+
│ (Framework-agnostic core logic) │
|
|
251
|
+
└─────────────────────────────────────────┘
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
## Development
|
|
255
|
+
|
|
256
|
+
```bash
|
|
257
|
+
# Build
|
|
258
|
+
pnpm build
|
|
259
|
+
|
|
260
|
+
# Watch mode
|
|
261
|
+
pnpm dev
|
|
262
|
+
|
|
263
|
+
# Test
|
|
264
|
+
pnpm test
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
## License
|
|
268
|
+
|
|
269
|
+
MIT
|
|
270
|
+
|
|
271
|
+
## See Also
|
|
272
|
+
|
|
273
|
+
- [@firela/billclaw-core](https://github.com/fire-la/billclaw/tree/main/packages/core)
|
|
274
|
+
- [@firela/billclaw-cli](https://github.com/fire-la/billclaw/tree/main/packages/cli)
|
|
275
|
+
- [OpenClaw Documentation](https://openclaw.dev)
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAA;AAGrC,OAAO,EACL,aAAa,EACb,cAAc,EACd,aAAa,EACb,sBAAsB,EACtB,wBAAwB,EACxB,sBAAsB,GACvB,MAAM,kBAAkB,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/oauth/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plaid.d.ts","sourceRoot":"","sources":["../../src/oauth/plaid.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAA;AAwFpE;;;;;;;;;;;;;;GAcG;AACH,wBAAsB,iBAAiB,CACrC,GAAG,EAAE,iBAAiB,EACtB,WAAW,CAAC,EAAE,MAAM,GACnB,OAAO,CAAC;IACT,GAAG,EAAE,MAAM,CAAA;IACX,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,WAAW,CAAC,EAAE,MAAM,CAAA;CACrB,CAAC,CA2BD"}
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Plaid OAuth handler - implements Plaid Link flow
|
|
3
|
+
*
|
|
4
|
+
* This module handles the Plaid Link OAuth flow for connecting bank accounts.
|
|
5
|
+
* It supports two modes:
|
|
6
|
+
* 1. Link token creation (for initializing Plaid Link frontend)
|
|
7
|
+
* 2. Public token exchange (for completing the connection)
|
|
8
|
+
*/
|
|
9
|
+
import { createPlaidClient } from "@firela/billclaw-core";
|
|
10
|
+
/**
|
|
11
|
+
* Get Plaid configuration from OpenClaw config
|
|
12
|
+
*
|
|
13
|
+
* Checks both pluginConfig and environment variables for credentials.
|
|
14
|
+
*/
|
|
15
|
+
function getPlaidConfig(api) {
|
|
16
|
+
const pluginConfig = api.pluginConfig;
|
|
17
|
+
const plaidConfig = pluginConfig?.plaid || {};
|
|
18
|
+
const clientId = plaidConfig.clientId || process.env.PLAID_CLIENT_ID;
|
|
19
|
+
const secret = plaidConfig.secret || process.env.PLAID_SECRET;
|
|
20
|
+
const environment = plaidConfig.environment || "sandbox";
|
|
21
|
+
if (!clientId || !secret) {
|
|
22
|
+
throw new Error("Plaid credentials not configured. Set PLAID_CLIENT_ID and PLAID_SECRET environment variables, or configure them in billclaw settings.");
|
|
23
|
+
}
|
|
24
|
+
return {
|
|
25
|
+
clientId,
|
|
26
|
+
secret,
|
|
27
|
+
environment: environment,
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Create Plaid Link token for initializing Link frontend
|
|
32
|
+
*/
|
|
33
|
+
async function createLinkToken(api, accountId) {
|
|
34
|
+
const plaidConfig = getPlaidConfig(api);
|
|
35
|
+
const plaidClient = createPlaidClient(plaidConfig);
|
|
36
|
+
const request = {
|
|
37
|
+
user: {
|
|
38
|
+
client_user_id: accountId || `user_${Date.now()}`,
|
|
39
|
+
},
|
|
40
|
+
client_name: "BillClaw",
|
|
41
|
+
products: ["transactions"],
|
|
42
|
+
country_codes: ["US"],
|
|
43
|
+
language: "en",
|
|
44
|
+
};
|
|
45
|
+
const axiosResponse = await plaidClient.linkTokenCreate(request);
|
|
46
|
+
const response = axiosResponse.data;
|
|
47
|
+
api.logger.info?.("Plaid Link token created successfully");
|
|
48
|
+
return { linkToken: response.link_token };
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Exchange Plaid public token for access token
|
|
52
|
+
*/
|
|
53
|
+
async function exchangePublicToken(api, publicToken) {
|
|
54
|
+
const plaidConfig = getPlaidConfig(api);
|
|
55
|
+
const plaidClient = createPlaidClient(plaidConfig);
|
|
56
|
+
const request = {
|
|
57
|
+
public_token: publicToken,
|
|
58
|
+
};
|
|
59
|
+
const axiosResponse = await plaidClient.itemPublicTokenExchange(request);
|
|
60
|
+
const response = axiosResponse.data;
|
|
61
|
+
api.logger.info?.("Plaid public token exchanged successfully");
|
|
62
|
+
return {
|
|
63
|
+
accessToken: response.access_token,
|
|
64
|
+
itemId: response.item_id,
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Handle Plaid Link OAuth flow
|
|
69
|
+
*
|
|
70
|
+
* This integrates Plaid Link (https://plaid.com/docs/link/)
|
|
71
|
+
* for secure bank account connection.
|
|
72
|
+
*
|
|
73
|
+
* Flow:
|
|
74
|
+
* 1. Create Link token (no params) - Returns { url, token: linkToken }
|
|
75
|
+
* 2. Handle Link success callback - Receives publicToken
|
|
76
|
+
* 3. Exchange public_token for access_token - Returns { url: "", token: accessToken, itemId }
|
|
77
|
+
*
|
|
78
|
+
* @param api - OpenClaw plugin API
|
|
79
|
+
* @param publicToken - Optional public token from Plaid Link callback
|
|
80
|
+
* @returns OAuthResult with URL and token
|
|
81
|
+
*/
|
|
82
|
+
export async function plaidOAuthHandler(api, publicToken) {
|
|
83
|
+
try {
|
|
84
|
+
if (!publicToken) {
|
|
85
|
+
// No public token provided - create Link token for initializing Link
|
|
86
|
+
const { linkToken } = await createLinkToken(api);
|
|
87
|
+
// Return Plaid Link URL and the link token
|
|
88
|
+
return {
|
|
89
|
+
url: "https://cdn.plaid.com/link/v2/stable/link.html",
|
|
90
|
+
token: linkToken,
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
// Public token provided - exchange for access token
|
|
94
|
+
const { accessToken, itemId } = await exchangePublicToken(api, publicToken);
|
|
95
|
+
// Return the access token and item ID for storage
|
|
96
|
+
return {
|
|
97
|
+
url: "",
|
|
98
|
+
token: accessToken,
|
|
99
|
+
itemId,
|
|
100
|
+
accessToken,
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
catch (error) {
|
|
104
|
+
api.logger.error?.("Plaid OAuth error:", error);
|
|
105
|
+
throw error;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
//# sourceMappingURL=plaid.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plaid.js","sourceRoot":"","sources":["../../src/oauth/plaid.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,4BAA4B,CAAA;AAYnE;;GAEG;;;;;;kBAQa,iBAAiB;;AAPjC,wBA0NC"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OpenClaw runtime context adapter
|
|
3
|
+
*
|
|
4
|
+
* Adapts OpenClaw's plugin API to BillClaw's runtime abstractions.
|
|
5
|
+
*/
|
|
6
|
+
import type { OpenClawPluginApi } from "../types/openclaw-plugin.js";
|
|
7
|
+
import type { RuntimeContext, ConfigProvider, Logger, EventEmitter } from "@firela/billclaw-core";
|
|
8
|
+
import type { BillclawConfig } from "@firela/billclaw-core";
|
|
9
|
+
/**
|
|
10
|
+
* OpenClaw logger adapter
|
|
11
|
+
*/
|
|
12
|
+
export declare class OpenClawLogger implements Logger {
|
|
13
|
+
private api;
|
|
14
|
+
constructor(api: OpenClawPluginApi);
|
|
15
|
+
info(...args: unknown[]): void;
|
|
16
|
+
error(...args: unknown[]): void;
|
|
17
|
+
warn(...args: unknown[]): void;
|
|
18
|
+
debug(...args: unknown[]): void;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* OpenClaw config provider
|
|
22
|
+
*/
|
|
23
|
+
export declare class OpenClawConfigProvider implements ConfigProvider {
|
|
24
|
+
private api;
|
|
25
|
+
private cachedConfig?;
|
|
26
|
+
constructor(api: OpenClawPluginApi);
|
|
27
|
+
getConfig(): Promise<BillclawConfig>;
|
|
28
|
+
getStorageConfig(): Promise<any>;
|
|
29
|
+
updateAccount(accountId: string, updates: Partial<any>): Promise<void>;
|
|
30
|
+
getAccount(accountId: string): Promise<any | null>;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* OpenClaw event emitter adapter
|
|
34
|
+
*/
|
|
35
|
+
export declare class OpenClawEventEmitter implements EventEmitter {
|
|
36
|
+
private listeners;
|
|
37
|
+
emit(event: string, data?: unknown): void;
|
|
38
|
+
on(event: string, handler: (...args: any[]) => void): void;
|
|
39
|
+
off(event: string, handler: (...args: any[]) => void): void;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* OpenClaw runtime context
|
|
43
|
+
*/
|
|
44
|
+
export declare class OpenClawRuntimeContext implements RuntimeContext {
|
|
45
|
+
private _logger;
|
|
46
|
+
private _config;
|
|
47
|
+
private _events;
|
|
48
|
+
constructor(api: OpenClawPluginApi);
|
|
49
|
+
get logger(): Logger;
|
|
50
|
+
get config(): ConfigProvider;
|
|
51
|
+
get events(): EventEmitter;
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=context.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../src/runtime/context.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAA;AACpE,OAAO,KAAK,EACV,cAAc,EACd,cAAc,EACd,MAAM,EACN,YAAY,EACb,MAAM,uBAAuB,CAAA;AAC9B,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAA;AAE3D;;GAEG;AACH,qBAAa,cAAe,YAAW,MAAM;IAC/B,OAAO,CAAC,GAAG;gBAAH,GAAG,EAAE,iBAAiB;IAE1C,IAAI,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI;IAI9B,KAAK,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI;IAI/B,IAAI,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI;IAI9B,KAAK,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI;CAKhC;AAED;;GAEG;AACH,qBAAa,sBAAuB,YAAW,cAAc;IAG/C,OAAO,CAAC,GAAG;IAFvB,OAAO,CAAC,YAAY,CAAC,CAAgB;gBAEjB,GAAG,EAAE,iBAAiB;IAEpC,SAAS,IAAI,OAAO,CAAC,cAAc,CAAC;IAUpC,gBAAgB,IAAI,OAAO,CAAC,GAAG,CAAC;IAWhC,aAAa,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,GAAG,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAMtE,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,GAAG,IAAI,CAAC;CAIzD;AAED;;GAEG;AACH,qBAAa,oBAAqB,YAAW,YAAY;IACvD,OAAO,CAAC,SAAS,CAAmD;IAEpE,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,GAAG,IAAI;IAazC,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,IAAI,GAAG,IAAI;IAO1D,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,IAAI,GAAG,IAAI;CAM5D;AAED;;GAEG;AACH,qBAAa,sBAAuB,YAAW,cAAc;IAC3D,OAAO,CAAC,OAAO,CAAQ;IACvB,OAAO,CAAC,OAAO,CAAgB;IAC/B,OAAO,CAAC,OAAO,CAAc;gBAEjB,GAAG,EAAE,iBAAiB;IA4BlC,IAAI,MAAM,IAAI,MAAM,CAEnB;IAED,IAAI,MAAM,IAAI,cAAc,CAE3B;IAED,IAAI,MAAM,IAAI,YAAY,CAEzB;CACF"}
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OpenClaw runtime context adapter
|
|
3
|
+
*
|
|
4
|
+
* Adapts OpenClaw's plugin API to BillClaw's runtime abstractions.
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* OpenClaw logger adapter
|
|
8
|
+
*/
|
|
9
|
+
export class OpenClawLogger {
|
|
10
|
+
api;
|
|
11
|
+
constructor(api) {
|
|
12
|
+
this.api = api;
|
|
13
|
+
}
|
|
14
|
+
info(...args) {
|
|
15
|
+
this.api.logger.info?.(...args);
|
|
16
|
+
}
|
|
17
|
+
error(...args) {
|
|
18
|
+
this.api.logger.error?.(...args);
|
|
19
|
+
}
|
|
20
|
+
warn(...args) {
|
|
21
|
+
this.api.logger.warn?.(...args);
|
|
22
|
+
}
|
|
23
|
+
debug(...args) {
|
|
24
|
+
if (process.env.DEBUG) {
|
|
25
|
+
this.api.logger.debug?.(...args);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* OpenClaw config provider
|
|
31
|
+
*/
|
|
32
|
+
export class OpenClawConfigProvider {
|
|
33
|
+
api;
|
|
34
|
+
cachedConfig;
|
|
35
|
+
constructor(api) {
|
|
36
|
+
this.api = api;
|
|
37
|
+
}
|
|
38
|
+
async getConfig() {
|
|
39
|
+
if (!this.cachedConfig) {
|
|
40
|
+
// Get config from OpenClaw's plugin config
|
|
41
|
+
const config = this.api.pluginConfig;
|
|
42
|
+
this.cachedConfig = config;
|
|
43
|
+
}
|
|
44
|
+
return this.cachedConfig;
|
|
45
|
+
}
|
|
46
|
+
async getStorageConfig() {
|
|
47
|
+
const config = await this.getConfig();
|
|
48
|
+
return (config.storage || {
|
|
49
|
+
path: "~/.openclaw/billclaw",
|
|
50
|
+
format: "json",
|
|
51
|
+
encryption: { enabled: false },
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
async updateAccount(accountId, updates) {
|
|
55
|
+
// This would need to update OpenClaw's config
|
|
56
|
+
// For now, just log the update
|
|
57
|
+
this.api.logger.info?.(`Account ${accountId} updated:`, updates);
|
|
58
|
+
}
|
|
59
|
+
async getAccount(accountId) {
|
|
60
|
+
const config = await this.getConfig();
|
|
61
|
+
return config.accounts.find((a) => a.id === accountId) || null;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* OpenClaw event emitter adapter
|
|
66
|
+
*/
|
|
67
|
+
export class OpenClawEventEmitter {
|
|
68
|
+
listeners = new Map();
|
|
69
|
+
emit(event, data) {
|
|
70
|
+
const handlers = this.listeners.get(event);
|
|
71
|
+
if (handlers) {
|
|
72
|
+
for (const handler of handlers) {
|
|
73
|
+
try {
|
|
74
|
+
handler(data);
|
|
75
|
+
}
|
|
76
|
+
catch (error) {
|
|
77
|
+
console.error(`Error in event handler for ${event}:`, error);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
on(event, handler) {
|
|
83
|
+
if (!this.listeners.has(event)) {
|
|
84
|
+
this.listeners.set(event, new Set());
|
|
85
|
+
}
|
|
86
|
+
this.listeners.get(event).add(handler);
|
|
87
|
+
}
|
|
88
|
+
off(event, handler) {
|
|
89
|
+
const handlers = this.listeners.get(event);
|
|
90
|
+
if (handlers) {
|
|
91
|
+
handlers.delete(handler);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* OpenClaw runtime context
|
|
97
|
+
*/
|
|
98
|
+
export class OpenClawRuntimeContext {
|
|
99
|
+
_logger;
|
|
100
|
+
_config;
|
|
101
|
+
_events;
|
|
102
|
+
constructor(api) {
|
|
103
|
+
this._logger = new OpenClawLogger(api);
|
|
104
|
+
this._config = new OpenClawConfigProvider(api);
|
|
105
|
+
this._events = new OpenClawEventEmitter();
|
|
106
|
+
// Define readonly properties at runtime
|
|
107
|
+
Object.defineProperty(this, "logger", {
|
|
108
|
+
value: this._logger,
|
|
109
|
+
writable: false,
|
|
110
|
+
enumerable: true,
|
|
111
|
+
configurable: false,
|
|
112
|
+
});
|
|
113
|
+
Object.defineProperty(this, "config", {
|
|
114
|
+
value: this._config,
|
|
115
|
+
writable: false,
|
|
116
|
+
enumerable: true,
|
|
117
|
+
configurable: false,
|
|
118
|
+
});
|
|
119
|
+
Object.defineProperty(this, "events", {
|
|
120
|
+
value: this._events,
|
|
121
|
+
writable: false,
|
|
122
|
+
enumerable: true,
|
|
123
|
+
configurable: false,
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
get logger() {
|
|
127
|
+
return this._logger;
|
|
128
|
+
}
|
|
129
|
+
get config() {
|
|
130
|
+
return this._config;
|
|
131
|
+
}
|
|
132
|
+
get events() {
|
|
133
|
+
return this._events;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
//# sourceMappingURL=context.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context.js","sourceRoot":"","sources":["../../src/runtime/context.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/services/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,uBAAuB,EAAE,MAAM,sBAAsB,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"webhook-handler.d.ts","sourceRoot":"","sources":["../../src/services/webhook-handler.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAA;AAIpE;;GAEG;AACH,UAAU,0BAA0B;IAClC,GAAG,EAAE,iBAAiB,CAAA;IACtB,kBAAkB,CAAC,EAAE,MAAM,CAAA;CAC5B;AAgCD;;;;;;;GAOG;AACH,wBAAgB,uBAAuB,CACrC,YAAY,EAAE,0BAA0B,GACvC,IAAI,CA+BN"}
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Webhook handlers for BillClaw OpenClaw plugin
|
|
3
|
+
*
|
|
4
|
+
* This module provides HTTP route handlers for receiving webhooks from
|
|
5
|
+
* external services (Plaid, GoCardless, etc.) and forwarding them to
|
|
6
|
+
* configured external webhook endpoints.
|
|
7
|
+
*/
|
|
8
|
+
import { emitEvent, verifySignature } from "@firela/billclaw-core";
|
|
9
|
+
// Global API reference for webhook handlers
|
|
10
|
+
let api = null;
|
|
11
|
+
let configWebhooks = [];
|
|
12
|
+
let plaidWebhookSecret;
|
|
13
|
+
/**
|
|
14
|
+
* Convert OpenClaw logger to BillClaw Logger interface
|
|
15
|
+
*/
|
|
16
|
+
function toLogger(logger) {
|
|
17
|
+
// Ensure all methods are defined and callable
|
|
18
|
+
const log = logger?.info || (() => { });
|
|
19
|
+
const logError = logger?.error || (() => { });
|
|
20
|
+
const logWarn = logger?.warn || (() => console.warn);
|
|
21
|
+
const logDebug = logger?.debug || (() => { });
|
|
22
|
+
return {
|
|
23
|
+
info: log,
|
|
24
|
+
error: logError,
|
|
25
|
+
warn: logWarn,
|
|
26
|
+
debug: logDebug,
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Register webhook handlers with OpenClaw HTTP routes
|
|
31
|
+
*
|
|
32
|
+
* This function registers HTTP routes for:
|
|
33
|
+
* - /webhook/plaid - Plaid webhook handler
|
|
34
|
+
* - /webhook/gocardless - GoCardless webhook handler
|
|
35
|
+
* - /webhook/test - Test webhook endpoint
|
|
36
|
+
*/
|
|
37
|
+
export function registerWebhookHandlers(dependencies) {
|
|
38
|
+
api = dependencies.api;
|
|
39
|
+
plaidWebhookSecret = dependencies.plaidWebhookSecret;
|
|
40
|
+
// Get webhooks from config
|
|
41
|
+
const pluginConfig = api.pluginConfig;
|
|
42
|
+
configWebhooks = pluginConfig?.webhooks || [];
|
|
43
|
+
api.logger.info?.("billclaw webhook handler registered");
|
|
44
|
+
// Register HTTP routes
|
|
45
|
+
api.http?.register({
|
|
46
|
+
path: "/webhook/plaid",
|
|
47
|
+
method: "POST",
|
|
48
|
+
description: "Plaid webhook handler",
|
|
49
|
+
handler: handlePlaidWebhook,
|
|
50
|
+
});
|
|
51
|
+
api.http?.register({
|
|
52
|
+
path: "/webhook/gocardless",
|
|
53
|
+
method: "POST",
|
|
54
|
+
description: "GoCardless webhook handler",
|
|
55
|
+
handler: handleGoCardlessWebhook,
|
|
56
|
+
});
|
|
57
|
+
api.http?.register({
|
|
58
|
+
path: "/webhook/test",
|
|
59
|
+
method: "POST",
|
|
60
|
+
description: "Test webhook endpoint",
|
|
61
|
+
handler: handleTestWebhook,
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Handle Plaid webhook
|
|
66
|
+
*
|
|
67
|
+
* Processes webhooks from Plaid:
|
|
68
|
+
* - TRANSACTIONS/SYNC_UPDATES_AVAILABLE: Trigger sync for the item
|
|
69
|
+
* - ITEM/ERROR: Emit account.error event
|
|
70
|
+
* - ITEM/LOGIN_REQUIRED: Notify user to re-authenticate
|
|
71
|
+
*/
|
|
72
|
+
async function handlePlaidWebhook(request) {
|
|
73
|
+
try {
|
|
74
|
+
const body = request.body;
|
|
75
|
+
const webhookType = body.webhook_type;
|
|
76
|
+
const webhookCode = body.webhook_code;
|
|
77
|
+
const itemId = body.item_id;
|
|
78
|
+
api?.logger.info?.(`Received Plaid webhook: ${webhookType}.${webhookCode} for item ${itemId}`);
|
|
79
|
+
// Verify signature if configured
|
|
80
|
+
const signature = request.headers["plaid-verification"];
|
|
81
|
+
const timestamp = request.headers["plaid-timestamp"];
|
|
82
|
+
if (plaidWebhookSecret && signature && timestamp) {
|
|
83
|
+
const payload = JSON.stringify(body);
|
|
84
|
+
if (!verifySignature(payload, signature, plaidWebhookSecret)) {
|
|
85
|
+
return {
|
|
86
|
+
status: 401,
|
|
87
|
+
body: { received: false, error: "Invalid signature" },
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
// Handle webhook events
|
|
92
|
+
switch (webhookType) {
|
|
93
|
+
case "TRANSACTIONS":
|
|
94
|
+
if (webhookCode === "SYNC_UPDATES_AVAILABLE") {
|
|
95
|
+
// Find the account associated with this item
|
|
96
|
+
const pluginConfig = api?.pluginConfig;
|
|
97
|
+
const account = pluginConfig?.accounts?.find((acc) => acc.type === "plaid" && acc.plaidItemId === itemId && acc.enabled);
|
|
98
|
+
if (account && api) {
|
|
99
|
+
// Trigger async sync (don't wait for completion)
|
|
100
|
+
const { plaidSyncTool } = await import("../tools/index.js");
|
|
101
|
+
plaidSyncTool
|
|
102
|
+
.execute(api, { accountId: account.id })
|
|
103
|
+
.catch((error) => {
|
|
104
|
+
api?.logger.error?.(`Webhook-triggered sync failed:`, error);
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
break;
|
|
109
|
+
case "ITEM":
|
|
110
|
+
if (webhookCode === "ERROR" || webhookCode === "LOGIN_REQUIRED") {
|
|
111
|
+
const error = body.error ?? {
|
|
112
|
+
error_code: webhookCode,
|
|
113
|
+
error_message: "Item login required",
|
|
114
|
+
};
|
|
115
|
+
// Emit account error event
|
|
116
|
+
await emitEvent(toLogger(api.logger), configWebhooks, "account.error", {
|
|
117
|
+
accountId: itemId,
|
|
118
|
+
accountType: "plaid",
|
|
119
|
+
error: JSON.stringify(error),
|
|
120
|
+
}).catch((err) => api?.logger.debug?.(`Event emission failed:`, err));
|
|
121
|
+
}
|
|
122
|
+
break;
|
|
123
|
+
}
|
|
124
|
+
return { status: 200, body: { received: true } };
|
|
125
|
+
}
|
|
126
|
+
catch (error) {
|
|
127
|
+
api?.logger.error?.(`Error handling Plaid webhook:`, error);
|
|
128
|
+
return {
|
|
129
|
+
status: 500,
|
|
130
|
+
body: { received: false, error: "Internal server error" },
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Handle GoCardless webhook
|
|
136
|
+
*
|
|
137
|
+
* Processes webhooks from GoCardless (placeholder implementation)
|
|
138
|
+
*/
|
|
139
|
+
async function handleGoCardlessWebhook(_request) {
|
|
140
|
+
try {
|
|
141
|
+
api?.logger.info?.("Received GoCardless webhook");
|
|
142
|
+
// TODO: Implement GoCardless webhook handling
|
|
143
|
+
// - Verify signature
|
|
144
|
+
// - Process mandate events
|
|
145
|
+
// - Trigger sync if needed
|
|
146
|
+
return { status: 200, body: { received: true } };
|
|
147
|
+
}
|
|
148
|
+
catch (error) {
|
|
149
|
+
api?.logger.error?.(`Error handling GoCardless webhook:`, error);
|
|
150
|
+
return { status: 500, body: { received: false } };
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* Handle test webhook
|
|
155
|
+
*
|
|
156
|
+
* Sends a test event to all configured webhooks to verify connectivity
|
|
157
|
+
*/
|
|
158
|
+
async function handleTestWebhook(_request) {
|
|
159
|
+
try {
|
|
160
|
+
api?.logger.info?.("Received test webhook request");
|
|
161
|
+
// Emit test event to all configured webhooks
|
|
162
|
+
await emitEvent(toLogger(api.logger), configWebhooks, "webhook.test", {
|
|
163
|
+
message: "Test webhook from BillClaw",
|
|
164
|
+
triggeredBy: "user",
|
|
165
|
+
});
|
|
166
|
+
return { status: 200, body: { sent: true } };
|
|
167
|
+
}
|
|
168
|
+
catch (error) {
|
|
169
|
+
api?.logger.error?.(`Error handling test webhook:`, error);
|
|
170
|
+
return {
|
|
171
|
+
status: 500,
|
|
172
|
+
body: { sent: false, error: "Internal server error" },
|
|
173
|
+
};
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
//# sourceMappingURL=webhook-handler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"webhook-handler.js","sourceRoot":"","sources":["../../src/services/webhook-handler.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAA;AAYpE;;GAEG;AACH,eAAO,MAAM,aAAa;;;;;;;;;;;iBAYL,iBAAiB,UAAU;QAAE,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE;;;;;;CAgCrE,CAAA;AAED;;GAEG;AACH,eAAO,MAAM,cAAc;;;;;;;;;;;;;;;;iBAkBlB,iBAAiB,UACd;QAAE,SAAS,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE;;;;;;CAiChD,CAAA;AAED;;GAEG;AACH,eAAO,MAAM,aAAa;;;;;;;;;;;;;;kBAgBhB,iBAAiB,UACf;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE;;;;;;CAqB3C,CAAA;AAED;;GAEG;AACH,eAAO,MAAM,sBAAsB;;;;;;;;;;;;;;;;iBAkB1B,iBAAiB,UACd;QAAE,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE;;;;;;CAsClD,CAAA;AAED;;GAEG;AACH,eAAO,MAAM,wBAAwB;;;;;;;;;;;iBAYhB,iBAAiB,WAAW;QAAE,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE;;;;;;CAoBnE,CAAA;AAED;;GAEG;AACH,eAAO,MAAM,sBAAsB;;;;;;;;;;;kBAYb,iBAAiB,UAAU;QAAE,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE;;;;;;CAmBlE,CAAA"}
|
|
@@ -0,0 +1,253 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OpenClaw tool adapters for BillClaw
|
|
3
|
+
*
|
|
4
|
+
* These adapters wrap the core BillClaw functionality to work with
|
|
5
|
+
* OpenClaw's tool API.
|
|
6
|
+
*/
|
|
7
|
+
import { Billclaw } from "@firela/billclaw-core";
|
|
8
|
+
import { OpenClawRuntimeContext } from "../runtime/context.js";
|
|
9
|
+
/**
|
|
10
|
+
* Create a BillClaw instance from OpenClaw API
|
|
11
|
+
*/
|
|
12
|
+
function createBillclaw(api) {
|
|
13
|
+
const runtime = new OpenClawRuntimeContext(api);
|
|
14
|
+
return new Billclaw(runtime);
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Plaid sync tool
|
|
18
|
+
*/
|
|
19
|
+
export const plaidSyncTool = {
|
|
20
|
+
name: "plaid_sync",
|
|
21
|
+
label: "Plaid Sync",
|
|
22
|
+
description: "Sync transactions from Plaid-connected bank accounts",
|
|
23
|
+
parameters: {
|
|
24
|
+
accountId: {
|
|
25
|
+
type: "string",
|
|
26
|
+
optional: true,
|
|
27
|
+
description: "Specific account ID to sync (omits to sync all)",
|
|
28
|
+
},
|
|
29
|
+
},
|
|
30
|
+
async execute(api, params) {
|
|
31
|
+
const billclaw = createBillclaw(api);
|
|
32
|
+
const results = await billclaw.syncPlaid(params.accountId ? [params.accountId] : undefined);
|
|
33
|
+
const totalAdded = results.reduce((sum, r) => sum + r.transactionsAdded, 0);
|
|
34
|
+
const totalUpdated = results.reduce((sum, r) => sum + r.transactionsUpdated, 0);
|
|
35
|
+
const errors = results.flatMap((r) => r.errors || []);
|
|
36
|
+
return {
|
|
37
|
+
content: [
|
|
38
|
+
{
|
|
39
|
+
type: "text",
|
|
40
|
+
text: JSON.stringify({
|
|
41
|
+
success: errors.length === 0,
|
|
42
|
+
accountsSynced: results.length,
|
|
43
|
+
transactionsAdded: totalAdded,
|
|
44
|
+
transactionsUpdated: totalUpdated,
|
|
45
|
+
errors: errors.length > 0 ? errors : undefined,
|
|
46
|
+
}, null, 2),
|
|
47
|
+
},
|
|
48
|
+
],
|
|
49
|
+
};
|
|
50
|
+
},
|
|
51
|
+
};
|
|
52
|
+
/**
|
|
53
|
+
* Gmail fetch bills tool
|
|
54
|
+
*/
|
|
55
|
+
export const gmailFetchTool = {
|
|
56
|
+
name: "gmail_fetch_bills",
|
|
57
|
+
label: "Gmail Fetch Bills",
|
|
58
|
+
description: "Fetch and parse bills from Gmail",
|
|
59
|
+
parameters: {
|
|
60
|
+
accountId: {
|
|
61
|
+
type: "string",
|
|
62
|
+
optional: true,
|
|
63
|
+
description: "Specific Gmail account ID to sync (omit for all)",
|
|
64
|
+
},
|
|
65
|
+
days: {
|
|
66
|
+
type: "number",
|
|
67
|
+
optional: true,
|
|
68
|
+
description: "Number of days to look back (default: 30)",
|
|
69
|
+
},
|
|
70
|
+
},
|
|
71
|
+
async execute(api, params) {
|
|
72
|
+
const billclaw = createBillclaw(api);
|
|
73
|
+
const results = await billclaw.syncGmail(params.accountId ? [params.accountId] : undefined, params.days ?? 30);
|
|
74
|
+
const totalEmails = results.reduce((sum, r) => sum + r.emailsProcessed, 0);
|
|
75
|
+
const totalBills = results.reduce((sum, r) => sum + r.billsExtracted, 0);
|
|
76
|
+
const totalAdded = results.reduce((sum, r) => sum + r.transactionsAdded, 0);
|
|
77
|
+
const errors = results.flatMap((r) => r.errors || []);
|
|
78
|
+
return {
|
|
79
|
+
content: [
|
|
80
|
+
{
|
|
81
|
+
type: "text",
|
|
82
|
+
text: JSON.stringify({
|
|
83
|
+
success: errors.length === 0,
|
|
84
|
+
accountsProcessed: results.length,
|
|
85
|
+
emailsProcessed: totalEmails,
|
|
86
|
+
billsExtracted: totalBills,
|
|
87
|
+
transactionsAdded: totalAdded,
|
|
88
|
+
errors: errors.length > 0 ? errors : undefined,
|
|
89
|
+
}, null, 2),
|
|
90
|
+
},
|
|
91
|
+
],
|
|
92
|
+
};
|
|
93
|
+
},
|
|
94
|
+
};
|
|
95
|
+
/**
|
|
96
|
+
* Bill parse tool
|
|
97
|
+
*/
|
|
98
|
+
export const billParseTool = {
|
|
99
|
+
name: "bill_parse",
|
|
100
|
+
label: "Bill Parse",
|
|
101
|
+
description: "Parse bill data from various formats (PDF, CSV, email)",
|
|
102
|
+
parameters: {
|
|
103
|
+
source: {
|
|
104
|
+
type: "string",
|
|
105
|
+
description: "Source type: plaid, gmail, file, or email",
|
|
106
|
+
},
|
|
107
|
+
data: {
|
|
108
|
+
type: "string",
|
|
109
|
+
description: "Raw data or file path to parse",
|
|
110
|
+
},
|
|
111
|
+
},
|
|
112
|
+
async execute(_api, params) {
|
|
113
|
+
// This is a stub - the actual implementation would depend on the source type
|
|
114
|
+
return {
|
|
115
|
+
content: [
|
|
116
|
+
{
|
|
117
|
+
type: "text",
|
|
118
|
+
text: JSON.stringify({
|
|
119
|
+
success: false,
|
|
120
|
+
source: params.source,
|
|
121
|
+
transactions: [],
|
|
122
|
+
errors: ["Bill parsing not yet implemented"],
|
|
123
|
+
}, null, 2),
|
|
124
|
+
},
|
|
125
|
+
],
|
|
126
|
+
};
|
|
127
|
+
},
|
|
128
|
+
};
|
|
129
|
+
/**
|
|
130
|
+
* Conversational sync tool
|
|
131
|
+
*/
|
|
132
|
+
export const conversationalSyncTool = {
|
|
133
|
+
name: "conversational_sync",
|
|
134
|
+
label: "Conversational Sync",
|
|
135
|
+
description: "Sync transactions with natural language support",
|
|
136
|
+
parameters: {
|
|
137
|
+
prompt: {
|
|
138
|
+
type: "string",
|
|
139
|
+
optional: true,
|
|
140
|
+
description: "Natural language prompt (e.g., 'Sync my accounts')",
|
|
141
|
+
},
|
|
142
|
+
accountId: {
|
|
143
|
+
type: "string",
|
|
144
|
+
optional: true,
|
|
145
|
+
description: "Explicit account ID to sync",
|
|
146
|
+
},
|
|
147
|
+
},
|
|
148
|
+
async execute(api, params) {
|
|
149
|
+
const billclaw = createBillclaw(api);
|
|
150
|
+
// If accountId is specified, sync that account
|
|
151
|
+
if (params.accountId) {
|
|
152
|
+
return plaidSyncTool.execute(api, { accountId: params.accountId });
|
|
153
|
+
}
|
|
154
|
+
// Otherwise, sync all due accounts
|
|
155
|
+
const results = await billclaw.syncDueAccounts();
|
|
156
|
+
const totalAdded = results.reduce((sum, r) => sum + r.transactionsAdded, 0);
|
|
157
|
+
const totalUpdated = results.reduce((sum, r) => sum + r.transactionsUpdated, 0);
|
|
158
|
+
const errors = results.flatMap((r) => r.errors || []);
|
|
159
|
+
return {
|
|
160
|
+
content: [
|
|
161
|
+
{
|
|
162
|
+
type: "text",
|
|
163
|
+
text: JSON.stringify({
|
|
164
|
+
success: errors.length === 0,
|
|
165
|
+
accountsSynced: results.length,
|
|
166
|
+
transactionsAdded: totalAdded,
|
|
167
|
+
transactionsUpdated: totalUpdated,
|
|
168
|
+
errors: errors.length > 0 ? errors : undefined,
|
|
169
|
+
}, null, 2),
|
|
170
|
+
},
|
|
171
|
+
],
|
|
172
|
+
};
|
|
173
|
+
},
|
|
174
|
+
};
|
|
175
|
+
/**
|
|
176
|
+
* Conversational status tool
|
|
177
|
+
*/
|
|
178
|
+
export const conversationalStatusTool = {
|
|
179
|
+
name: "conversational_status",
|
|
180
|
+
label: "Conversational Status",
|
|
181
|
+
description: "Show account status with natural language",
|
|
182
|
+
parameters: {
|
|
183
|
+
prompt: {
|
|
184
|
+
type: "string",
|
|
185
|
+
optional: true,
|
|
186
|
+
description: "Natural language prompt",
|
|
187
|
+
},
|
|
188
|
+
},
|
|
189
|
+
async execute(api, _params) {
|
|
190
|
+
const billclaw = createBillclaw(api);
|
|
191
|
+
const accounts = await billclaw.getAccounts();
|
|
192
|
+
return {
|
|
193
|
+
content: [
|
|
194
|
+
{
|
|
195
|
+
type: "text",
|
|
196
|
+
text: JSON.stringify({
|
|
197
|
+
accounts,
|
|
198
|
+
message: `Found ${accounts.length} configured accounts`,
|
|
199
|
+
}, null, 2),
|
|
200
|
+
},
|
|
201
|
+
],
|
|
202
|
+
};
|
|
203
|
+
},
|
|
204
|
+
};
|
|
205
|
+
/**
|
|
206
|
+
* Conversational help tool
|
|
207
|
+
*/
|
|
208
|
+
export const conversationalHelpTool = {
|
|
209
|
+
name: "conversational_help",
|
|
210
|
+
label: "Conversational Help",
|
|
211
|
+
description: "Get help with billclaw commands and features",
|
|
212
|
+
parameters: {
|
|
213
|
+
topic: {
|
|
214
|
+
type: "string",
|
|
215
|
+
optional: true,
|
|
216
|
+
description: "Specific help topic (sync, export, webhook, etc.)",
|
|
217
|
+
},
|
|
218
|
+
},
|
|
219
|
+
async execute(_api, params) {
|
|
220
|
+
const helpText = getHelpText(params.topic);
|
|
221
|
+
return {
|
|
222
|
+
content: [
|
|
223
|
+
{
|
|
224
|
+
type: "text",
|
|
225
|
+
text: JSON.stringify({
|
|
226
|
+
topic: params.topic || "general",
|
|
227
|
+
help: helpText,
|
|
228
|
+
}, null, 2),
|
|
229
|
+
},
|
|
230
|
+
],
|
|
231
|
+
};
|
|
232
|
+
},
|
|
233
|
+
};
|
|
234
|
+
/**
|
|
235
|
+
* Get help text for a topic
|
|
236
|
+
*/
|
|
237
|
+
function getHelpText(topic) {
|
|
238
|
+
const helps = {
|
|
239
|
+
sync: "Sync transactions from connected accounts. Use 'bills sync' to manually trigger sync.",
|
|
240
|
+
export: "Export transactions to Beancount or Ledger format. Configure export options in config.",
|
|
241
|
+
webhook: "Configure webhooks for real-time transaction updates. Set webhook URL and HMAC secret in config.",
|
|
242
|
+
setup: "Run 'bills setup' to connect new bank accounts via Plaid Link or Gmail OAuth.",
|
|
243
|
+
};
|
|
244
|
+
if (topic && helps[topic]) {
|
|
245
|
+
return helps[topic];
|
|
246
|
+
}
|
|
247
|
+
return `Available commands: bills setup, bills sync, bills status, bills config
|
|
248
|
+
|
|
249
|
+
Available topics: ${Object.keys(helps).join(", ")}
|
|
250
|
+
|
|
251
|
+
For more information, visit: https://github.com/fire-la/billclaw`;
|
|
252
|
+
}
|
|
253
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://openclaw.dev/plugin.schema.json",
|
|
3
|
+
"name": "@firela/billclaw-openclaw",
|
|
4
|
+
"version": "0.0.1",
|
|
5
|
+
"description": "Financial data sovereignty plugin - Plaid, Gmail, GoCardless integration",
|
|
6
|
+
"author": "fire-zu",
|
|
7
|
+
"license": "MIT",
|
|
8
|
+
"capabilities": {
|
|
9
|
+
"tools": [
|
|
10
|
+
{
|
|
11
|
+
"name": "plaid_sync",
|
|
12
|
+
"description": "Sync transactions from Plaid-linked bank accounts"
|
|
13
|
+
},
|
|
14
|
+
{
|
|
15
|
+
"name": "gmail_fetch_bills",
|
|
16
|
+
"description": "Fetch bill statements from Gmail"
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
"name": "bill_parse",
|
|
20
|
+
"description": "Parse bill documents and extract transaction data"
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
"name": "conversational_sync",
|
|
24
|
+
"description": "Sync transactions with natural language support"
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
"name": "conversational_status",
|
|
28
|
+
"description": "Show account status with natural language"
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
"name": "conversational_help",
|
|
32
|
+
"description": "Get help with billclaw commands and features"
|
|
33
|
+
}
|
|
34
|
+
],
|
|
35
|
+
"cliCommands": [
|
|
36
|
+
{
|
|
37
|
+
"name": "bills",
|
|
38
|
+
"description": "Manage financial data accounts and sync",
|
|
39
|
+
"subcommands": ["setup", "sync", "status", "config"]
|
|
40
|
+
}
|
|
41
|
+
],
|
|
42
|
+
"oauthProviders": [
|
|
43
|
+
{
|
|
44
|
+
"name": "plaid",
|
|
45
|
+
"description": "Plaid Link OAuth flow for bank account linking"
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
"name": "gmail",
|
|
49
|
+
"description": "Gmail OAuth 2.0 flow for accessing email bills"
|
|
50
|
+
}
|
|
51
|
+
],
|
|
52
|
+
"backgroundServices": [
|
|
53
|
+
{
|
|
54
|
+
"name": "billclaw-sync",
|
|
55
|
+
"description": "Automated transaction sync scheduler"
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
"name": "billclaw-webhook",
|
|
59
|
+
"description": "Webhook handler for bank notifications"
|
|
60
|
+
}
|
|
61
|
+
],
|
|
62
|
+
"httpRoutes": [
|
|
63
|
+
{
|
|
64
|
+
"path": "/webhook/plaid",
|
|
65
|
+
"method": "POST",
|
|
66
|
+
"description": "Plaid webhook handler for transaction updates"
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
"path": "/webhook/gocardless",
|
|
70
|
+
"method": "POST",
|
|
71
|
+
"description": "GoCardless webhook handler for mandate events"
|
|
72
|
+
}
|
|
73
|
+
]
|
|
74
|
+
},
|
|
75
|
+
"config": {
|
|
76
|
+
"schema": "./dist/config.schema.js",
|
|
77
|
+
"uiHints": "./dist/config-ui-hints.js"
|
|
78
|
+
}
|
|
79
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@firela/billclaw-openclaw",
|
|
3
|
+
"version": "0.1.3",
|
|
4
|
+
"description": "BillClaw OpenClaw Plugin - Adapter for OpenClaw AI framework",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/index.js",
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
11
|
+
"import": "./dist/index.js",
|
|
12
|
+
"default": "./dist/index.js"
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
"files": [
|
|
16
|
+
"dist",
|
|
17
|
+
"openclaw.plugin.json",
|
|
18
|
+
"README.md"
|
|
19
|
+
],
|
|
20
|
+
"publishConfig": {
|
|
21
|
+
"access": "public"
|
|
22
|
+
},
|
|
23
|
+
"keywords": [
|
|
24
|
+
"openclaw",
|
|
25
|
+
"plugin",
|
|
26
|
+
"financial-data",
|
|
27
|
+
"plaid",
|
|
28
|
+
"gocardless",
|
|
29
|
+
"banking",
|
|
30
|
+
"transactions",
|
|
31
|
+
"bills"
|
|
32
|
+
],
|
|
33
|
+
"author": "fire-la",
|
|
34
|
+
"license": "MIT",
|
|
35
|
+
"repository": {
|
|
36
|
+
"type": "git",
|
|
37
|
+
"url": "https://github.com/fire-la/billclaw.git",
|
|
38
|
+
"directory": "packages/openclaw"
|
|
39
|
+
},
|
|
40
|
+
"devDependencies": {
|
|
41
|
+
"@sinclair/typebox": "^0.34.48",
|
|
42
|
+
"@types/node": "^25.2.0",
|
|
43
|
+
"@vitest/coverage-v8": "^4.0.18",
|
|
44
|
+
"openclaw": "^0.0.1",
|
|
45
|
+
"oxfmt": "^0.1.0",
|
|
46
|
+
"oxlint": "^0.15.0",
|
|
47
|
+
"typescript": "^5.8.0",
|
|
48
|
+
"vitest": "^3.0.0"
|
|
49
|
+
},
|
|
50
|
+
"dependencies": {
|
|
51
|
+
"plaid": "^32.0.0",
|
|
52
|
+
"zod": "^3.25.0",
|
|
53
|
+
"@firela/billclaw-core": "0.1.3"
|
|
54
|
+
},
|
|
55
|
+
"peerDependencies": {
|
|
56
|
+
"openclaw": "^0.0.1"
|
|
57
|
+
},
|
|
58
|
+
"openclaw": {
|
|
59
|
+
"extensions": [
|
|
60
|
+
"./dist/index.js"
|
|
61
|
+
]
|
|
62
|
+
},
|
|
63
|
+
"engines": {
|
|
64
|
+
"node": ">=20.0.0"
|
|
65
|
+
},
|
|
66
|
+
"scripts": {
|
|
67
|
+
"build": "tsc",
|
|
68
|
+
"dev": "tsc --watch",
|
|
69
|
+
"test": "vitest",
|
|
70
|
+
"test:coverage": "vitest --coverage",
|
|
71
|
+
"lint": "oxlint",
|
|
72
|
+
"format": "oxfmt src/",
|
|
73
|
+
"format:write": "oxfmt -w src/",
|
|
74
|
+
"clean": "rm -rf dist"
|
|
75
|
+
}
|
|
76
|
+
}
|