@jiggai/kitchen-plugin-marketing 0.2.1
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 +236 -0
- package/db/migrations/0001_initial.sql +146 -0
- package/dist/api/routes.js +1486 -0
- package/dist/db/migrations/0001_initial.sql +146 -0
- package/dist/index.js +1521 -0
- package/dist/tabs/accounts.js +44 -0
- package/dist/tabs/analytics.js +39 -0
- package/dist/tabs/content-calendar.js +33 -0
- package/dist/tabs/content-library.js +29 -0
- package/package.json +76 -0
- package/scripts/kitchen-cli.js +233 -0
package/README.md
ADDED
|
@@ -0,0 +1,236 @@
|
|
|
1
|
+
# Kitchen Plugin Marketing
|
|
2
|
+
|
|
3
|
+
A comprehensive marketing suite plugin for ClawKitchen that provides content management, scheduling, analytics, and social media integration.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
### 🎯 **Complete API Access**
|
|
8
|
+
Every feature available in the UI is accessible via REST APIs, allowing developers to:
|
|
9
|
+
- Build custom frontends (React, Vue, mobile apps)
|
|
10
|
+
- Create headless integrations
|
|
11
|
+
- Develop CLI tools and automation
|
|
12
|
+
- Integrate with external systems
|
|
13
|
+
|
|
14
|
+
### 📱 **Plugin Tabs**
|
|
15
|
+
- **Content Library** - Manage marketing assets, templates, and media
|
|
16
|
+
- **Content Calendar** - Schedule and plan content across platforms
|
|
17
|
+
- **Analytics** - Track engagement, reach, and performance metrics
|
|
18
|
+
- **Accounts** - Connect and manage social media accounts
|
|
19
|
+
|
|
20
|
+
## API Reference
|
|
21
|
+
|
|
22
|
+
All plugin APIs are available under the path:
|
|
23
|
+
```
|
|
24
|
+
/api/plugins/kitchen-plugin-marketing/<endpoint>
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
### Content Management
|
|
28
|
+
|
|
29
|
+
#### Posts
|
|
30
|
+
```bash
|
|
31
|
+
# Get all posts
|
|
32
|
+
GET /api/plugins/kitchen-plugin-marketing/posts
|
|
33
|
+
|
|
34
|
+
# Create new post
|
|
35
|
+
POST /api/plugins/kitchen-plugin-marketing/posts
|
|
36
|
+
{
|
|
37
|
+
"content": "Your post content",
|
|
38
|
+
"platforms": ["twitter", "linkedin"],
|
|
39
|
+
"scheduledAt": "2026-04-06T10:00:00Z",
|
|
40
|
+
"status": "draft"
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
# Get specific post
|
|
44
|
+
GET /api/plugins/kitchen-plugin-marketing/posts/{id}
|
|
45
|
+
|
|
46
|
+
# Update post
|
|
47
|
+
PUT /api/plugins/kitchen-plugin-marketing/posts/{id}
|
|
48
|
+
|
|
49
|
+
# Delete post
|
|
50
|
+
DELETE /api/plugins/kitchen-plugin-marketing/posts/{id}
|
|
51
|
+
|
|
52
|
+
# Publish post immediately
|
|
53
|
+
POST /api/plugins/kitchen-plugin-marketing/posts/{id}/publish
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
#### Content Library
|
|
57
|
+
```bash
|
|
58
|
+
# Get all media assets
|
|
59
|
+
GET /api/plugins/kitchen-plugin-marketing/media
|
|
60
|
+
|
|
61
|
+
# Upload new asset
|
|
62
|
+
POST /api/plugins/kitchen-plugin-marketing/media
|
|
63
|
+
Content-Type: multipart/form-data
|
|
64
|
+
|
|
65
|
+
# Get templates
|
|
66
|
+
GET /api/plugins/kitchen-plugin-marketing/templates
|
|
67
|
+
|
|
68
|
+
# Create template
|
|
69
|
+
POST /api/plugins/kitchen-plugin-marketing/templates
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
### Analytics
|
|
73
|
+
|
|
74
|
+
```bash
|
|
75
|
+
# Get overview metrics
|
|
76
|
+
GET /api/plugins/kitchen-plugin-marketing/analytics/overview
|
|
77
|
+
|
|
78
|
+
# Get engagement data
|
|
79
|
+
GET /api/plugins/kitchen-plugin-marketing/analytics/engagement
|
|
80
|
+
?platform=twitter&start=2026-04-01&end=2026-04-07
|
|
81
|
+
|
|
82
|
+
# Get reach metrics
|
|
83
|
+
GET /api/plugins/kitchen-plugin-marketing/analytics/reach
|
|
84
|
+
|
|
85
|
+
# Get performance by post
|
|
86
|
+
GET /api/plugins/kitchen-plugin-marketing/analytics/posts/{id}/performance
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
### Social Accounts
|
|
90
|
+
|
|
91
|
+
```bash
|
|
92
|
+
# Get connected accounts
|
|
93
|
+
GET /api/plugins/kitchen-plugin-marketing/accounts
|
|
94
|
+
|
|
95
|
+
# Connect new account
|
|
96
|
+
POST /api/plugins/kitchen-plugin-marketing/accounts
|
|
97
|
+
{
|
|
98
|
+
"platform": "twitter",
|
|
99
|
+
"credentials": {...}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
# Disconnect account
|
|
103
|
+
DELETE /api/plugins/kitchen-plugin-marketing/accounts/{id}
|
|
104
|
+
|
|
105
|
+
# Get account metrics
|
|
106
|
+
GET /api/plugins/kitchen-plugin-marketing/accounts/{id}/metrics
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
### Calendar & Scheduling
|
|
110
|
+
|
|
111
|
+
```bash
|
|
112
|
+
# Get calendar view
|
|
113
|
+
GET /api/plugins/kitchen-plugin-marketing/calendar
|
|
114
|
+
?start=2026-04-01&end=2026-04-30
|
|
115
|
+
|
|
116
|
+
# Schedule post
|
|
117
|
+
POST /api/plugins/kitchen-plugin-marketing/calendar/schedule
|
|
118
|
+
{
|
|
119
|
+
"postId": "123",
|
|
120
|
+
"scheduledAt": "2026-04-06T14:00:00Z",
|
|
121
|
+
"platforms": ["twitter"]
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
# Get scheduled posts
|
|
125
|
+
GET /api/plugins/kitchen-plugin-marketing/calendar/scheduled
|
|
126
|
+
|
|
127
|
+
# Reschedule post
|
|
128
|
+
PUT /api/plugins/kitchen-plugin-marketing/calendar/scheduled/{id}
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
## Installation
|
|
132
|
+
|
|
133
|
+
### Via NPM
|
|
134
|
+
```bash
|
|
135
|
+
npm install kitchen-plugin-marketing
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
### Via Kitchen CLI (when CLI commands are available)
|
|
139
|
+
```bash
|
|
140
|
+
openclaw kitchen plugin add kitchen-plugin-marketing
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
### Manual Installation
|
|
144
|
+
```bash
|
|
145
|
+
cd /path/to/clawkitchen
|
|
146
|
+
npm install kitchen-plugin-marketing
|
|
147
|
+
npm run build
|
|
148
|
+
# Restart gateway
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
## Development
|
|
152
|
+
|
|
153
|
+
### Building the Plugin
|
|
154
|
+
```bash
|
|
155
|
+
npm run build
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
### Development Mode
|
|
159
|
+
```bash
|
|
160
|
+
npm run dev
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
### Plugin Structure
|
|
164
|
+
```
|
|
165
|
+
src/
|
|
166
|
+
├── api/
|
|
167
|
+
│ └── routes.ts # REST API endpoints
|
|
168
|
+
├── tabs/
|
|
169
|
+
│ ├── content-library.tsx
|
|
170
|
+
│ ├── content-calendar.tsx
|
|
171
|
+
│ ├── analytics.tsx
|
|
172
|
+
│ └── accounts.tsx
|
|
173
|
+
├── db/
|
|
174
|
+
│ └── schema.ts # Database schema
|
|
175
|
+
└── types/
|
|
176
|
+
└── index.ts # TypeScript types
|
|
177
|
+
|
|
178
|
+
dist/ # Built output
|
|
179
|
+
├── api/routes.js
|
|
180
|
+
└── tabs/*.js
|
|
181
|
+
|
|
182
|
+
db/migrations/ # Database migrations
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
## Plugin Architecture
|
|
186
|
+
|
|
187
|
+
### Database
|
|
188
|
+
Each plugin gets an isolated SQLite database with encrypted credentials storage.
|
|
189
|
+
|
|
190
|
+
### Security
|
|
191
|
+
- Credentials encrypted at rest using AES-256-GCM
|
|
192
|
+
- Team-scoped access controls
|
|
193
|
+
- No cross-plugin data access
|
|
194
|
+
|
|
195
|
+
### Integration Points
|
|
196
|
+
- **Team Detection**: Automatically shows for teams with `marketing-team` or `claw-marketing-team` frontmatter
|
|
197
|
+
- **Kitchen Auth**: Uses existing Kitchen authentication
|
|
198
|
+
- **API Discovery**: All endpoints automatically available via Kitchen's plugin router
|
|
199
|
+
|
|
200
|
+
## Custom Frontend Integration
|
|
201
|
+
|
|
202
|
+
Since all features are API-accessible, you can build custom interfaces:
|
|
203
|
+
|
|
204
|
+
```javascript
|
|
205
|
+
// Example: Custom React component using plugin APIs
|
|
206
|
+
const useMarketingPosts = () => {
|
|
207
|
+
return fetch('/api/plugins/kitchen-plugin-marketing/posts')
|
|
208
|
+
.then(res => res.json());
|
|
209
|
+
};
|
|
210
|
+
|
|
211
|
+
// Example: Mobile app integration
|
|
212
|
+
const schedulePost = async (content, platforms, scheduledAt) => {
|
|
213
|
+
return fetch('/api/plugins/kitchen-plugin-marketing/posts', {
|
|
214
|
+
method: 'POST',
|
|
215
|
+
headers: { 'Content-Type': 'application/json' },
|
|
216
|
+
body: JSON.stringify({ content, platforms, scheduledAt })
|
|
217
|
+
});
|
|
218
|
+
};
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
## Contributing
|
|
222
|
+
|
|
223
|
+
1. Fork the repository
|
|
224
|
+
2. Create a feature branch
|
|
225
|
+
3. Make your changes
|
|
226
|
+
4. Add tests
|
|
227
|
+
5. Submit a pull request
|
|
228
|
+
|
|
229
|
+
## License
|
|
230
|
+
|
|
231
|
+
MIT
|
|
232
|
+
|
|
233
|
+
## Support
|
|
234
|
+
|
|
235
|
+
- Issues: [GitHub Issues](https://github.com/JIGGAI/kitchen-plugin-marketing/issues)
|
|
236
|
+
- Documentation: [Plugin Documentation](https://docs.clawkitchen.ai/plugins/marketing)
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
-- Migration: Initial schema for kitchen-plugin-marketing
|
|
2
|
+
-- Created: 2026-04-05
|
|
3
|
+
-- Description: Create tables for posts, media, templates, social accounts, metrics, and webhooks
|
|
4
|
+
|
|
5
|
+
-- Posts table
|
|
6
|
+
CREATE TABLE IF NOT EXISTS posts (
|
|
7
|
+
id TEXT PRIMARY KEY,
|
|
8
|
+
team_id TEXT NOT NULL,
|
|
9
|
+
content TEXT NOT NULL,
|
|
10
|
+
platforms TEXT NOT NULL, -- JSON array of platform names
|
|
11
|
+
status TEXT NOT NULL CHECK (status IN ('draft', 'scheduled', 'published', 'failed')),
|
|
12
|
+
scheduled_at TEXT, -- ISO 8601 timestamp
|
|
13
|
+
published_at TEXT, -- ISO 8601 timestamp
|
|
14
|
+
tags TEXT, -- JSON array of tags
|
|
15
|
+
media_ids TEXT, -- JSON array of media IDs
|
|
16
|
+
template_id TEXT,
|
|
17
|
+
created_at TEXT NOT NULL,
|
|
18
|
+
updated_at TEXT NOT NULL,
|
|
19
|
+
created_by TEXT NOT NULL
|
|
20
|
+
);
|
|
21
|
+
|
|
22
|
+
-- Media/Assets table
|
|
23
|
+
CREATE TABLE IF NOT EXISTS media (
|
|
24
|
+
id TEXT PRIMARY KEY,
|
|
25
|
+
team_id TEXT NOT NULL,
|
|
26
|
+
filename TEXT NOT NULL,
|
|
27
|
+
original_name TEXT NOT NULL,
|
|
28
|
+
mime_type TEXT NOT NULL,
|
|
29
|
+
size INTEGER NOT NULL,
|
|
30
|
+
width INTEGER,
|
|
31
|
+
height INTEGER,
|
|
32
|
+
alt TEXT,
|
|
33
|
+
tags TEXT, -- JSON array of tags
|
|
34
|
+
url TEXT NOT NULL,
|
|
35
|
+
thumbnail_url TEXT,
|
|
36
|
+
created_at TEXT NOT NULL,
|
|
37
|
+
created_by TEXT NOT NULL
|
|
38
|
+
);
|
|
39
|
+
|
|
40
|
+
-- Templates table
|
|
41
|
+
CREATE TABLE IF NOT EXISTS templates (
|
|
42
|
+
id TEXT PRIMARY KEY,
|
|
43
|
+
team_id TEXT NOT NULL,
|
|
44
|
+
name TEXT NOT NULL,
|
|
45
|
+
content TEXT NOT NULL,
|
|
46
|
+
variables TEXT, -- JSON array of variable definitions
|
|
47
|
+
tags TEXT, -- JSON array of tags
|
|
48
|
+
created_at TEXT NOT NULL,
|
|
49
|
+
updated_at TEXT NOT NULL,
|
|
50
|
+
created_by TEXT NOT NULL
|
|
51
|
+
);
|
|
52
|
+
|
|
53
|
+
-- Social accounts table
|
|
54
|
+
CREATE TABLE IF NOT EXISTS social_accounts (
|
|
55
|
+
id TEXT PRIMARY KEY,
|
|
56
|
+
team_id TEXT NOT NULL,
|
|
57
|
+
platform TEXT NOT NULL CHECK (platform IN ('twitter', 'linkedin', 'instagram', 'facebook', 'tiktok', 'youtube')),
|
|
58
|
+
display_name TEXT NOT NULL,
|
|
59
|
+
username TEXT,
|
|
60
|
+
avatar TEXT,
|
|
61
|
+
is_active INTEGER DEFAULT 1 CHECK (is_active IN (0, 1)),
|
|
62
|
+
credentials BLOB NOT NULL, -- Encrypted JSON credentials
|
|
63
|
+
settings TEXT, -- JSON object for platform-specific settings
|
|
64
|
+
last_sync TEXT, -- ISO 8601 timestamp
|
|
65
|
+
created_at TEXT NOT NULL,
|
|
66
|
+
updated_at TEXT NOT NULL
|
|
67
|
+
);
|
|
68
|
+
|
|
69
|
+
-- Post metrics table
|
|
70
|
+
CREATE TABLE IF NOT EXISTS post_metrics (
|
|
71
|
+
id TEXT PRIMARY KEY,
|
|
72
|
+
post_id TEXT NOT NULL,
|
|
73
|
+
platform TEXT NOT NULL,
|
|
74
|
+
impressions INTEGER DEFAULT 0,
|
|
75
|
+
likes INTEGER DEFAULT 0,
|
|
76
|
+
shares INTEGER DEFAULT 0,
|
|
77
|
+
comments INTEGER DEFAULT 0,
|
|
78
|
+
clicks INTEGER DEFAULT 0,
|
|
79
|
+
engagement_rate TEXT, -- Stored as string to avoid float precision issues
|
|
80
|
+
synced_at TEXT NOT NULL, -- When metrics were last fetched
|
|
81
|
+
FOREIGN KEY (post_id) REFERENCES posts(id) ON DELETE CASCADE
|
|
82
|
+
);
|
|
83
|
+
|
|
84
|
+
-- Account metrics table (daily snapshots)
|
|
85
|
+
CREATE TABLE IF NOT EXISTS account_metrics (
|
|
86
|
+
id TEXT PRIMARY KEY,
|
|
87
|
+
account_id TEXT NOT NULL,
|
|
88
|
+
date TEXT NOT NULL, -- YYYY-MM-DD format
|
|
89
|
+
followers INTEGER DEFAULT 0,
|
|
90
|
+
following INTEGER DEFAULT 0,
|
|
91
|
+
posts INTEGER DEFAULT 0,
|
|
92
|
+
engagement INTEGER DEFAULT 0,
|
|
93
|
+
reach INTEGER DEFAULT 0,
|
|
94
|
+
synced_at TEXT NOT NULL,
|
|
95
|
+
FOREIGN KEY (account_id) REFERENCES social_accounts(id) ON DELETE CASCADE,
|
|
96
|
+
UNIQUE(account_id, date)
|
|
97
|
+
);
|
|
98
|
+
|
|
99
|
+
-- Webhooks table
|
|
100
|
+
CREATE TABLE IF NOT EXISTS webhooks (
|
|
101
|
+
id TEXT PRIMARY KEY,
|
|
102
|
+
team_id TEXT NOT NULL,
|
|
103
|
+
url TEXT NOT NULL,
|
|
104
|
+
events TEXT NOT NULL, -- JSON array of event types
|
|
105
|
+
secret TEXT, -- Webhook signature secret
|
|
106
|
+
is_active INTEGER DEFAULT 1 CHECK (is_active IN (0, 1)),
|
|
107
|
+
created_at TEXT NOT NULL,
|
|
108
|
+
last_triggered TEXT -- ISO 8601 timestamp
|
|
109
|
+
);
|
|
110
|
+
|
|
111
|
+
-- Create indexes for better query performance
|
|
112
|
+
|
|
113
|
+
-- Posts indexes
|
|
114
|
+
CREATE INDEX IF NOT EXISTS idx_posts_team_id ON posts(team_id);
|
|
115
|
+
CREATE INDEX IF NOT EXISTS idx_posts_status ON posts(status);
|
|
116
|
+
CREATE INDEX IF NOT EXISTS idx_posts_scheduled_at ON posts(scheduled_at) WHERE scheduled_at IS NOT NULL;
|
|
117
|
+
CREATE INDEX IF NOT EXISTS idx_posts_published_at ON posts(published_at) WHERE published_at IS NOT NULL;
|
|
118
|
+
CREATE INDEX IF NOT EXISTS idx_posts_created_at ON posts(created_at);
|
|
119
|
+
CREATE INDEX IF NOT EXISTS idx_posts_template_id ON posts(template_id) WHERE template_id IS NOT NULL;
|
|
120
|
+
|
|
121
|
+
-- Media indexes
|
|
122
|
+
CREATE INDEX IF NOT EXISTS idx_media_team_id ON media(team_id);
|
|
123
|
+
CREATE INDEX IF NOT EXISTS idx_media_created_at ON media(created_at);
|
|
124
|
+
CREATE INDEX IF NOT EXISTS idx_media_mime_type ON media(mime_type);
|
|
125
|
+
|
|
126
|
+
-- Templates indexes
|
|
127
|
+
CREATE INDEX IF NOT EXISTS idx_templates_team_id ON templates(team_id);
|
|
128
|
+
CREATE INDEX IF NOT EXISTS idx_templates_name ON templates(name);
|
|
129
|
+
|
|
130
|
+
-- Social accounts indexes
|
|
131
|
+
CREATE INDEX IF NOT EXISTS idx_social_accounts_team_id ON social_accounts(team_id);
|
|
132
|
+
CREATE INDEX IF NOT EXISTS idx_social_accounts_platform ON social_accounts(platform);
|
|
133
|
+
CREATE INDEX IF NOT EXISTS idx_social_accounts_active ON social_accounts(is_active);
|
|
134
|
+
|
|
135
|
+
-- Post metrics indexes
|
|
136
|
+
CREATE INDEX IF NOT EXISTS idx_post_metrics_post_id ON post_metrics(post_id);
|
|
137
|
+
CREATE INDEX IF NOT EXISTS idx_post_metrics_platform ON post_metrics(platform);
|
|
138
|
+
CREATE INDEX IF NOT EXISTS idx_post_metrics_synced_at ON post_metrics(synced_at);
|
|
139
|
+
|
|
140
|
+
-- Account metrics indexes
|
|
141
|
+
CREATE INDEX IF NOT EXISTS idx_account_metrics_account_id ON account_metrics(account_id);
|
|
142
|
+
CREATE INDEX IF NOT EXISTS idx_account_metrics_date ON account_metrics(date);
|
|
143
|
+
|
|
144
|
+
-- Webhooks indexes
|
|
145
|
+
CREATE INDEX IF NOT EXISTS idx_webhooks_team_id ON webhooks(team_id);
|
|
146
|
+
CREATE INDEX IF NOT EXISTS idx_webhooks_active ON webhooks(is_active);
|