planflow-plugin 0.1.0
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 +93 -0
- package/bin/cli.js +169 -0
- package/bin/postinstall.js +87 -0
- package/commands/pfActivity/SKILL.md +725 -0
- package/commands/pfAssign/SKILL.md +623 -0
- package/commands/pfCloudLink/SKILL.md +192 -0
- package/commands/pfCloudList/SKILL.md +222 -0
- package/commands/pfCloudNew/SKILL.md +187 -0
- package/commands/pfCloudUnlink/SKILL.md +152 -0
- package/commands/pfComment/SKILL.md +227 -0
- package/commands/pfComments/SKILL.md +159 -0
- package/commands/pfConnectionStatus/SKILL.md +433 -0
- package/commands/pfDiscord/SKILL.md +740 -0
- package/commands/pfGithubBranch/SKILL.md +672 -0
- package/commands/pfGithubIssue/SKILL.md +963 -0
- package/commands/pfGithubLink/SKILL.md +859 -0
- package/commands/pfGithubPr/SKILL.md +1335 -0
- package/commands/pfGithubUnlink/SKILL.md +401 -0
- package/commands/pfLive/SKILL.md +185 -0
- package/commands/pfLogin/SKILL.md +249 -0
- package/commands/pfLogout/SKILL.md +155 -0
- package/commands/pfMyTasks/SKILL.md +198 -0
- package/commands/pfNotificationSettings/SKILL.md +619 -0
- package/commands/pfNotifications/SKILL.md +420 -0
- package/commands/pfNotificationsClear/SKILL.md +421 -0
- package/commands/pfReact/SKILL.md +232 -0
- package/commands/pfSlack/SKILL.md +659 -0
- package/commands/pfSyncPull/SKILL.md +210 -0
- package/commands/pfSyncPush/SKILL.md +299 -0
- package/commands/pfSyncStatus/SKILL.md +212 -0
- package/commands/pfTeamInvite/SKILL.md +161 -0
- package/commands/pfTeamList/SKILL.md +253 -0
- package/commands/pfTeamRemove/SKILL.md +115 -0
- package/commands/pfTeamRole/SKILL.md +160 -0
- package/commands/pfTestWebhooks/SKILL.md +722 -0
- package/commands/pfUnassign/SKILL.md +134 -0
- package/commands/pfWhoami/SKILL.md +258 -0
- package/commands/pfWorkload/SKILL.md +219 -0
- package/commands/planExportCsv/SKILL.md +106 -0
- package/commands/planExportGithub/SKILL.md +222 -0
- package/commands/planExportJson/SKILL.md +159 -0
- package/commands/planExportSummary/SKILL.md +158 -0
- package/commands/planNew/SKILL.md +641 -0
- package/commands/planNext/SKILL.md +1200 -0
- package/commands/planSettingsAutoSync/SKILL.md +199 -0
- package/commands/planSettingsLanguage/SKILL.md +201 -0
- package/commands/planSettingsReset/SKILL.md +237 -0
- package/commands/planSettingsShow/SKILL.md +482 -0
- package/commands/planSpec/SKILL.md +929 -0
- package/commands/planUpdate/SKILL.md +2518 -0
- package/commands/team/SKILL.md +740 -0
- package/locales/en.json +1499 -0
- package/locales/ka.json +1499 -0
- package/package.json +48 -0
- package/templates/PROJECT_PLAN.template.md +157 -0
- package/templates/backend-api.template.md +562 -0
- package/templates/frontend-spa.template.md +610 -0
- package/templates/fullstack.template.md +397 -0
- package/templates/ka/backend-api.template.md +562 -0
- package/templates/ka/frontend-spa.template.md +610 -0
- package/templates/ka/fullstack.template.md +397 -0
- package/templates/sections/architecture.md +21 -0
- package/templates/sections/overview.md +15 -0
- package/templates/sections/tasks.md +22 -0
- package/templates/sections/tech-stack.md +19 -0
|
@@ -0,0 +1,740 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: pfDiscord
|
|
3
|
+
description: Configure Discord webhook integration for PlanFlow notifications
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# PlanFlow Discord Integration
|
|
7
|
+
|
|
8
|
+
Configure Discord webhook integration to receive project notifications directly in your Discord server.
|
|
9
|
+
|
|
10
|
+
## Usage
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
/pfDiscord # Show current Discord integration status
|
|
14
|
+
/pfDiscord setup <webhook-url> # Set up Discord webhook
|
|
15
|
+
/pfDiscord test # Send a test notification to Discord
|
|
16
|
+
/pfDiscord disable # Disable Discord notifications
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
**Webhook URL Format:**
|
|
20
|
+
```
|
|
21
|
+
https://discord.com/api/webhooks/000000000000000000/XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## Process
|
|
25
|
+
|
|
26
|
+
### Step 0: Load Configuration & Translations
|
|
27
|
+
|
|
28
|
+
**CRITICAL: Execute this step FIRST, before any output!**
|
|
29
|
+
|
|
30
|
+
```javascript
|
|
31
|
+
// Merge global and local configs
|
|
32
|
+
function getMergedConfig() {
|
|
33
|
+
let globalConfig = {}
|
|
34
|
+
let localConfig = {}
|
|
35
|
+
|
|
36
|
+
const globalPath = expandPath("~/.config/claude/plan-plugin-config.json")
|
|
37
|
+
if (fileExists(globalPath)) {
|
|
38
|
+
try { globalConfig = JSON.parse(readFile(globalPath)) } catch (e) {}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
if (fileExists("./.plan-config.json")) {
|
|
42
|
+
try { localConfig = JSON.parse(readFile("./.plan-config.json")) } catch (e) {}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
return {
|
|
46
|
+
...globalConfig,
|
|
47
|
+
...localConfig,
|
|
48
|
+
cloud: {
|
|
49
|
+
...(globalConfig.cloud || {}),
|
|
50
|
+
...(localConfig.cloud || {})
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
const config = getMergedConfig()
|
|
56
|
+
const language = config.language || "en"
|
|
57
|
+
const cloudConfig = config.cloud || {}
|
|
58
|
+
const isAuthenticated = !!cloudConfig.apiToken
|
|
59
|
+
const projectId = cloudConfig.projectId
|
|
60
|
+
const apiUrl = cloudConfig.apiUrl || "https://api.planflow.tools"
|
|
61
|
+
|
|
62
|
+
// Load translations
|
|
63
|
+
const t = JSON.parse(readFile(`locales/${language}.json`))
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
### Step 1: Check Authentication
|
|
67
|
+
|
|
68
|
+
If not authenticated, show error:
|
|
69
|
+
|
|
70
|
+
```
|
|
71
|
+
╭──────────────────────────────────────────────────────────────────────────────╮
|
|
72
|
+
│ ❌ ERROR │
|
|
73
|
+
├──────────────────────────────────────────────────────────────────────────────┤
|
|
74
|
+
│ │
|
|
75
|
+
│ {t.commands.sync.notAuthenticated} │
|
|
76
|
+
│ │
|
|
77
|
+
│ Discord integration requires a cloud connection. │
|
|
78
|
+
│ │
|
|
79
|
+
│ 💡 Run /pfLogin to authenticate first. │
|
|
80
|
+
│ │
|
|
81
|
+
╰──────────────────────────────────────────────────────────────────────────────╯
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
If no project linked, show error:
|
|
85
|
+
|
|
86
|
+
```
|
|
87
|
+
╭──────────────────────────────────────────────────────────────────────────────╮
|
|
88
|
+
│ ❌ ERROR │
|
|
89
|
+
├──────────────────────────────────────────────────────────────────────────────┤
|
|
90
|
+
│ │
|
|
91
|
+
│ {t.commands.sync.notLinked} │
|
|
92
|
+
│ │
|
|
93
|
+
│ 💡 Run /pfCloudLink to link a project first. │
|
|
94
|
+
│ │
|
|
95
|
+
╰──────────────────────────────────────────────────────────────────────────────╯
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
### Step 2: Parse Arguments
|
|
99
|
+
|
|
100
|
+
```javascript
|
|
101
|
+
const args = commandArgs.trim()
|
|
102
|
+
const parts = args.split(/\s+/)
|
|
103
|
+
const action = parts[0] || null // "setup", "test", "disable", or null (show status)
|
|
104
|
+
const webhookUrl = parts[1] || null // Webhook URL for setup action
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
### Step 3: Handle Actions
|
|
108
|
+
|
|
109
|
+
#### If no action (show current status)
|
|
110
|
+
|
|
111
|
+
Fetch current Discord integration status from API.
|
|
112
|
+
|
|
113
|
+
**API Endpoint:** `GET /projects/:projectId/integrations/discord`
|
|
114
|
+
|
|
115
|
+
**Bash Implementation:**
|
|
116
|
+
|
|
117
|
+
```bash
|
|
118
|
+
API_URL="https://api.planflow.tools"
|
|
119
|
+
TOKEN="$API_TOKEN"
|
|
120
|
+
PROJECT_ID="$PROJECT_ID"
|
|
121
|
+
|
|
122
|
+
# Fetch current Discord integration status
|
|
123
|
+
RESPONSE=$(curl -s -w "\n%{http_code}" \
|
|
124
|
+
--connect-timeout 5 \
|
|
125
|
+
--max-time 10 \
|
|
126
|
+
-X GET \
|
|
127
|
+
-H "Accept: application/json" \
|
|
128
|
+
-H "Authorization: Bearer $TOKEN" \
|
|
129
|
+
"${API_URL}/projects/${PROJECT_ID}/integrations/discord")
|
|
130
|
+
|
|
131
|
+
HTTP_CODE=$(echo "$RESPONSE" | tail -n1)
|
|
132
|
+
BODY=$(echo "$RESPONSE" | sed '$d')
|
|
133
|
+
|
|
134
|
+
if [ "$HTTP_CODE" -ge 200 ] && [ "$HTTP_CODE" -lt 300 ]; then
|
|
135
|
+
echo "$BODY"
|
|
136
|
+
else
|
|
137
|
+
echo "Error: HTTP $HTTP_CODE"
|
|
138
|
+
fi
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
**Expected Response:**
|
|
142
|
+
|
|
143
|
+
```json
|
|
144
|
+
{
|
|
145
|
+
"success": true,
|
|
146
|
+
"data": {
|
|
147
|
+
"integration": {
|
|
148
|
+
"enabled": true,
|
|
149
|
+
"webhookConfigured": true,
|
|
150
|
+
"webhookUrl": "https://discord.com/api/webhooks/123.../XXX...",
|
|
151
|
+
"serverName": "My Development Server",
|
|
152
|
+
"channelName": "#planflow-updates",
|
|
153
|
+
"lastTestAt": "2026-02-20T10:30:00Z",
|
|
154
|
+
"lastNotificationAt": "2026-02-21T08:00:00Z",
|
|
155
|
+
"events": {
|
|
156
|
+
"taskCompleted": true,
|
|
157
|
+
"taskAssigned": true,
|
|
158
|
+
"mentions": true,
|
|
159
|
+
"comments": true
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
**Status Card (Discord configured):**
|
|
167
|
+
|
|
168
|
+
```
|
|
169
|
+
╭──────────────────────────────────────────────────────────────────────────────╮
|
|
170
|
+
│ 🎮 {t.commands.discord.title} │
|
|
171
|
+
├──────────────────────────────────────────────────────────────────────────────┤
|
|
172
|
+
│ │
|
|
173
|
+
│ 📁 Project: {projectName} │
|
|
174
|
+
│ │
|
|
175
|
+
│ ── {t.commands.discord.status} ─────────────────────────────────────────── │
|
|
176
|
+
│ │
|
|
177
|
+
│ ╭───────────────────────────────────────────────────────────────────────╮ │
|
|
178
|
+
│ │ ✅ {t.commands.discord.connected} │ │
|
|
179
|
+
│ ╰───────────────────────────────────────────────────────────────────────╯ │
|
|
180
|
+
│ │
|
|
181
|
+
│ 📍 Webhook: ···/webhooks/123.../XXX... (configured) │
|
|
182
|
+
│ 🖥️ Server: My Development Server │
|
|
183
|
+
│ 📢 Channel: #planflow-updates │
|
|
184
|
+
│ 🕐 Last Test: 2 hours ago │
|
|
185
|
+
│ 📨 Last Sent: 30 minutes ago │
|
|
186
|
+
│ │
|
|
187
|
+
│ ── {t.commands.discord.events} ─────────────────────────────────────────── │
|
|
188
|
+
│ │
|
|
189
|
+
│ [✓] Task completed │
|
|
190
|
+
│ [✓] Task assigned │
|
|
191
|
+
│ [✓] @mentions │
|
|
192
|
+
│ [✓] New comments │
|
|
193
|
+
│ │
|
|
194
|
+
├──────────────────────────────────────────────────────────────────────────────┤
|
|
195
|
+
│ │
|
|
196
|
+
│ 💡 {t.ui.labels.commands} │
|
|
197
|
+
│ • /pfDiscord test Send a test notification │
|
|
198
|
+
│ • /pfDiscord disable Disable Discord notifications │
|
|
199
|
+
│ │
|
|
200
|
+
╰──────────────────────────────────────────────────────────────────────────────╯
|
|
201
|
+
░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
**Status Card (Discord not configured):**
|
|
205
|
+
|
|
206
|
+
```
|
|
207
|
+
╭──────────────────────────────────────────────────────────────────────────────╮
|
|
208
|
+
│ 🎮 {t.commands.discord.title} │
|
|
209
|
+
├──────────────────────────────────────────────────────────────────────────────┤
|
|
210
|
+
│ │
|
|
211
|
+
│ 📁 Project: {projectName} │
|
|
212
|
+
│ │
|
|
213
|
+
│ ── {t.commands.discord.status} ─────────────────────────────────────────── │
|
|
214
|
+
│ │
|
|
215
|
+
│ ╭───────────────────────────────────────────────────────────────────────╮ │
|
|
216
|
+
│ │ ❌ {t.commands.discord.notConfigured} │ │
|
|
217
|
+
│ ╰───────────────────────────────────────────────────────────────────────╯ │
|
|
218
|
+
│ │
|
|
219
|
+
│ {t.commands.discord.notConfiguredHint} │
|
|
220
|
+
│ │
|
|
221
|
+
│ ── {t.commands.discord.howToSetup} ─────────────────────────────────────── │
|
|
222
|
+
│ │
|
|
223
|
+
│ 1. Go to your Discord server settings │
|
|
224
|
+
│ 2. Navigate to: Integrations → Webhooks │
|
|
225
|
+
│ 3. Click "New Webhook" │
|
|
226
|
+
│ 4. Choose the channel for notifications │
|
|
227
|
+
│ 5. Copy the webhook URL │
|
|
228
|
+
│ 6. Run: /pfDiscord setup <webhook-url> │
|
|
229
|
+
│ │
|
|
230
|
+
│ 📖 Guide: https://support.discord.com/hc/en-us/articles/228383668 │
|
|
231
|
+
│ │
|
|
232
|
+
├──────────────────────────────────────────────────────────────────────────────┤
|
|
233
|
+
│ │
|
|
234
|
+
│ 💡 {t.ui.labels.commands} │
|
|
235
|
+
│ • /pfDiscord setup <url> Configure Discord webhook │
|
|
236
|
+
│ │
|
|
237
|
+
╰──────────────────────────────────────────────────────────────────────────────╯
|
|
238
|
+
░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
#### If action is "setup"
|
|
242
|
+
|
|
243
|
+
Set up Discord webhook integration.
|
|
244
|
+
|
|
245
|
+
**Validation:**
|
|
246
|
+
1. Webhook URL is required
|
|
247
|
+
2. Must be a valid Discord webhook URL (starts with `https://discord.com/api/webhooks/` or `https://discordapp.com/api/webhooks/`)
|
|
248
|
+
|
|
249
|
+
**Invalid URL Error:**
|
|
250
|
+
|
|
251
|
+
```
|
|
252
|
+
╭──────────────────────────────────────────────────────────────────────────────╮
|
|
253
|
+
│ ❌ ERROR │
|
|
254
|
+
├──────────────────────────────────────────────────────────────────────────────┤
|
|
255
|
+
│ │
|
|
256
|
+
│ {t.commands.discord.invalidUrl} │
|
|
257
|
+
│ │
|
|
258
|
+
│ The webhook URL must be a valid Discord webhook URL. │
|
|
259
|
+
│ │
|
|
260
|
+
│ ── Expected Format ───────────────────────────────────────────────────── │
|
|
261
|
+
│ │
|
|
262
|
+
│ https://discord.com/api/webhooks/000000000000000000/XXXXXX... │
|
|
263
|
+
│ │
|
|
264
|
+
│ 💡 Get your webhook URL from: │
|
|
265
|
+
│ Discord Server → Settings → Integrations → Webhooks → New Webhook │
|
|
266
|
+
│ │
|
|
267
|
+
│ 📖 https://support.discord.com/hc/en-us/articles/228383668 │
|
|
268
|
+
│ │
|
|
269
|
+
╰──────────────────────────────────────────────────────────────────────────────╯
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
**Missing URL Error:**
|
|
273
|
+
|
|
274
|
+
```
|
|
275
|
+
╭──────────────────────────────────────────────────────────────────────────────╮
|
|
276
|
+
│ ❌ ERROR │
|
|
277
|
+
├──────────────────────────────────────────────────────────────────────────────┤
|
|
278
|
+
│ │
|
|
279
|
+
│ {t.commands.discord.missingUrl} │
|
|
280
|
+
│ │
|
|
281
|
+
│ Please provide the Discord webhook URL. │
|
|
282
|
+
│ │
|
|
283
|
+
│ 💡 Usage: /pfDiscord setup <webhook-url> │
|
|
284
|
+
│ │
|
|
285
|
+
│ 📖 Example: │
|
|
286
|
+
│ /pfDiscord setup https://discord.com/api/webhooks/123.../XXX │
|
|
287
|
+
│ │
|
|
288
|
+
╰──────────────────────────────────────────────────────────────────────────────╯
|
|
289
|
+
```
|
|
290
|
+
|
|
291
|
+
**API Request:**
|
|
292
|
+
|
|
293
|
+
```bash
|
|
294
|
+
API_URL="https://api.planflow.tools"
|
|
295
|
+
TOKEN="$API_TOKEN"
|
|
296
|
+
PROJECT_ID="$PROJECT_ID"
|
|
297
|
+
WEBHOOK_URL="$WEBHOOK_URL"
|
|
298
|
+
|
|
299
|
+
# Validate webhook URL format (supports both discord.com and discordapp.com)
|
|
300
|
+
if [[ ! "$WEBHOOK_URL" =~ ^https://(discord\.com|discordapp\.com)/api/webhooks/ ]]; then
|
|
301
|
+
echo "Invalid webhook URL format"
|
|
302
|
+
exit 1
|
|
303
|
+
fi
|
|
304
|
+
|
|
305
|
+
# Save Discord webhook configuration
|
|
306
|
+
RESPONSE=$(curl -s -w "\n%{http_code}" \
|
|
307
|
+
--connect-timeout 5 \
|
|
308
|
+
--max-time 10 \
|
|
309
|
+
-X POST \
|
|
310
|
+
-H "Content-Type: application/json" \
|
|
311
|
+
-H "Accept: application/json" \
|
|
312
|
+
-H "Authorization: Bearer $TOKEN" \
|
|
313
|
+
-d "{\"webhookUrl\": \"${WEBHOOK_URL}\"}" \
|
|
314
|
+
"${API_URL}/projects/${PROJECT_ID}/integrations/discord")
|
|
315
|
+
|
|
316
|
+
HTTP_CODE=$(echo "$RESPONSE" | tail -n1)
|
|
317
|
+
BODY=$(echo "$RESPONSE" | sed '$d')
|
|
318
|
+
|
|
319
|
+
if [ "$HTTP_CODE" -ge 200 ] && [ "$HTTP_CODE" -lt 300 ]; then
|
|
320
|
+
echo "Success"
|
|
321
|
+
else
|
|
322
|
+
echo "Error: HTTP $HTTP_CODE"
|
|
323
|
+
fi
|
|
324
|
+
```
|
|
325
|
+
|
|
326
|
+
**Success Card:**
|
|
327
|
+
|
|
328
|
+
```
|
|
329
|
+
╭──────────────────────────────────────────────────────────────────────────────╮
|
|
330
|
+
│ ✅ SUCCESS │
|
|
331
|
+
├──────────────────────────────────────────────────────────────────────────────┤
|
|
332
|
+
│ │
|
|
333
|
+
│ {t.commands.discord.setupSuccess} │
|
|
334
|
+
│ │
|
|
335
|
+
│ ── Discord Integration ──────────────────────────────────────────────── │
|
|
336
|
+
│ │
|
|
337
|
+
│ ╭───────────────────────────────────────────────────────────────────────╮ │
|
|
338
|
+
│ │ ✅ Connected │ │
|
|
339
|
+
│ ╰───────────────────────────────────────────────────────────────────────╯ │
|
|
340
|
+
│ │
|
|
341
|
+
│ 📍 Webhook: ···/webhooks/123.../XXX... (configured) │
|
|
342
|
+
│ 📁 Project: {projectName} │
|
|
343
|
+
│ │
|
|
344
|
+
│ {t.commands.discord.willReceive} │
|
|
345
|
+
│ • Task status changes │
|
|
346
|
+
│ • Task assignments │
|
|
347
|
+
│ • @mentions in comments │
|
|
348
|
+
│ • New comments on your tasks │
|
|
349
|
+
│ │
|
|
350
|
+
├──────────────────────────────────────────────────────────────────────────────┤
|
|
351
|
+
│ │
|
|
352
|
+
│ 💡 {t.ui.labels.nextSteps} │
|
|
353
|
+
│ • /pfDiscord test Send a test notification │
|
|
354
|
+
│ • /pfDiscord View current status │
|
|
355
|
+
│ │
|
|
356
|
+
╰──────────────────────────────────────────────────────────────────────────────╯
|
|
357
|
+
░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
|
|
358
|
+
```
|
|
359
|
+
|
|
360
|
+
#### If action is "test"
|
|
361
|
+
|
|
362
|
+
Send a test notification to verify the webhook is working.
|
|
363
|
+
|
|
364
|
+
**API Request:**
|
|
365
|
+
|
|
366
|
+
```bash
|
|
367
|
+
API_URL="https://api.planflow.tools"
|
|
368
|
+
TOKEN="$API_TOKEN"
|
|
369
|
+
PROJECT_ID="$PROJECT_ID"
|
|
370
|
+
|
|
371
|
+
# Send test notification
|
|
372
|
+
RESPONSE=$(curl -s -w "\n%{http_code}" \
|
|
373
|
+
--connect-timeout 5 \
|
|
374
|
+
--max-time 15 \
|
|
375
|
+
-X POST \
|
|
376
|
+
-H "Content-Type: application/json" \
|
|
377
|
+
-H "Accept: application/json" \
|
|
378
|
+
-H "Authorization: Bearer $TOKEN" \
|
|
379
|
+
"${API_URL}/projects/${PROJECT_ID}/integrations/discord/test")
|
|
380
|
+
|
|
381
|
+
HTTP_CODE=$(echo "$RESPONSE" | tail -n1)
|
|
382
|
+
BODY=$(echo "$RESPONSE" | sed '$d')
|
|
383
|
+
|
|
384
|
+
if [ "$HTTP_CODE" -ge 200 ] && [ "$HTTP_CODE" -lt 300 ]; then
|
|
385
|
+
echo "Test notification sent"
|
|
386
|
+
else
|
|
387
|
+
echo "Error: HTTP $HTTP_CODE"
|
|
388
|
+
fi
|
|
389
|
+
```
|
|
390
|
+
|
|
391
|
+
**Success Card:**
|
|
392
|
+
|
|
393
|
+
```
|
|
394
|
+
╭──────────────────────────────────────────────────────────────────────────────╮
|
|
395
|
+
│ ✅ SUCCESS │
|
|
396
|
+
├──────────────────────────────────────────────────────────────────────────────┤
|
|
397
|
+
│ │
|
|
398
|
+
│ {t.commands.discord.testSuccess} │
|
|
399
|
+
│ │
|
|
400
|
+
│ ── Test Notification ────────────────────────────────────────────────── │
|
|
401
|
+
│ │
|
|
402
|
+
│ 📨 A test notification was sent to your Discord channel. │
|
|
403
|
+
│ │
|
|
404
|
+
│ ╭───────────────────────────────────────────────────────────────────────╮ │
|
|
405
|
+
│ │ 🔔 PlanFlow Test │ │
|
|
406
|
+
│ │ This is a test notification from PlanFlow. │ │
|
|
407
|
+
│ │ If you see this, Discord integration is working correctly! │ │
|
|
408
|
+
│ │ Project: {projectName} │ │
|
|
409
|
+
│ ╰───────────────────────────────────────────────────────────────────────╯ │
|
|
410
|
+
│ │
|
|
411
|
+
│ Check your Discord channel to verify the message arrived. │
|
|
412
|
+
│ │
|
|
413
|
+
├──────────────────────────────────────────────────────────────────────────────┤
|
|
414
|
+
│ │
|
|
415
|
+
│ 💡 {t.ui.labels.commands} │
|
|
416
|
+
│ • /pfDiscord View current status │
|
|
417
|
+
│ • /pfDiscord disable Disable Discord notifications │
|
|
418
|
+
│ │
|
|
419
|
+
╰──────────────────────────────────────────────────────────────────────────────╯
|
|
420
|
+
░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
|
|
421
|
+
```
|
|
422
|
+
|
|
423
|
+
**Test Failed Card:**
|
|
424
|
+
|
|
425
|
+
```
|
|
426
|
+
╭──────────────────────────────────────────────────────────────────────────────╮
|
|
427
|
+
│ ❌ ERROR │
|
|
428
|
+
├──────────────────────────────────────────────────────────────────────────────┤
|
|
429
|
+
│ │
|
|
430
|
+
│ {t.commands.discord.testFailed} │
|
|
431
|
+
│ │
|
|
432
|
+
│ Could not send test notification to Discord. │
|
|
433
|
+
│ │
|
|
434
|
+
│ ── Possible Issues ───────────────────────────────────────────────────── │
|
|
435
|
+
│ │
|
|
436
|
+
│ • Webhook URL may be invalid or deleted │
|
|
437
|
+
│ • Webhook may have been removed from the channel │
|
|
438
|
+
│ • Discord API rate limiting │
|
|
439
|
+
│ • Network connectivity issues │
|
|
440
|
+
│ │
|
|
441
|
+
│ 💡 {t.ui.labels.commands} │
|
|
442
|
+
│ • /pfDiscord setup <new-url> Reconfigure with new webhook │
|
|
443
|
+
│ • /pfDiscord View current configuration │
|
|
444
|
+
│ │
|
|
445
|
+
╰──────────────────────────────────────────────────────────────────────────────╯
|
|
446
|
+
```
|
|
447
|
+
|
|
448
|
+
**Not Configured Error:**
|
|
449
|
+
|
|
450
|
+
```
|
|
451
|
+
╭──────────────────────────────────────────────────────────────────────────────╮
|
|
452
|
+
│ ❌ ERROR │
|
|
453
|
+
├──────────────────────────────────────────────────────────────────────────────┤
|
|
454
|
+
│ │
|
|
455
|
+
│ {t.commands.discord.notConfiguredError} │
|
|
456
|
+
│ │
|
|
457
|
+
│ Discord webhook is not configured for this project. │
|
|
458
|
+
│ │
|
|
459
|
+
│ 💡 Set up Discord first: │
|
|
460
|
+
│ /pfDiscord setup <webhook-url> │
|
|
461
|
+
│ │
|
|
462
|
+
╰──────────────────────────────────────────────────────────────────────────────╯
|
|
463
|
+
```
|
|
464
|
+
|
|
465
|
+
#### If action is "disable"
|
|
466
|
+
|
|
467
|
+
Disable Discord notifications for this project.
|
|
468
|
+
|
|
469
|
+
**API Request:**
|
|
470
|
+
|
|
471
|
+
```bash
|
|
472
|
+
API_URL="https://api.planflow.tools"
|
|
473
|
+
TOKEN="$API_TOKEN"
|
|
474
|
+
PROJECT_ID="$PROJECT_ID"
|
|
475
|
+
|
|
476
|
+
# Disable Discord integration
|
|
477
|
+
RESPONSE=$(curl -s -w "\n%{http_code}" \
|
|
478
|
+
--connect-timeout 5 \
|
|
479
|
+
--max-time 10 \
|
|
480
|
+
-X DELETE \
|
|
481
|
+
-H "Accept: application/json" \
|
|
482
|
+
-H "Authorization: Bearer $TOKEN" \
|
|
483
|
+
"${API_URL}/projects/${PROJECT_ID}/integrations/discord")
|
|
484
|
+
|
|
485
|
+
HTTP_CODE=$(echo "$RESPONSE" | tail -n1)
|
|
486
|
+
BODY=$(echo "$RESPONSE" | sed '$d')
|
|
487
|
+
|
|
488
|
+
if [ "$HTTP_CODE" -ge 200 ] && [ "$HTTP_CODE" -lt 300 ]; then
|
|
489
|
+
echo "Discord integration disabled"
|
|
490
|
+
else
|
|
491
|
+
echo "Error: HTTP $HTTP_CODE"
|
|
492
|
+
fi
|
|
493
|
+
```
|
|
494
|
+
|
|
495
|
+
**Success Card:**
|
|
496
|
+
|
|
497
|
+
```
|
|
498
|
+
╭──────────────────────────────────────────────────────────────────────────────╮
|
|
499
|
+
│ ✅ SUCCESS │
|
|
500
|
+
├──────────────────────────────────────────────────────────────────────────────┤
|
|
501
|
+
│ │
|
|
502
|
+
│ {t.commands.discord.disableSuccess} │
|
|
503
|
+
│ │
|
|
504
|
+
│ ── Discord Integration ──────────────────────────────────────────────── │
|
|
505
|
+
│ │
|
|
506
|
+
│ ╭───────────────────────────────────────────────────────────────────────╮ │
|
|
507
|
+
│ │ ❌ Disabled │ │
|
|
508
|
+
│ ╰───────────────────────────────────────────────────────────────────────╯ │
|
|
509
|
+
│ │
|
|
510
|
+
│ Discord notifications have been disabled for this project. │
|
|
511
|
+
│ The webhook URL has been removed. │
|
|
512
|
+
│ │
|
|
513
|
+
├──────────────────────────────────────────────────────────────────────────────┤
|
|
514
|
+
│ │
|
|
515
|
+
│ 💡 {t.ui.labels.commands} │
|
|
516
|
+
│ • /pfDiscord setup <url> Re-enable with a new webhook │
|
|
517
|
+
│ │
|
|
518
|
+
╰──────────────────────────────────────────────────────────────────────────────╯
|
|
519
|
+
░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
|
|
520
|
+
```
|
|
521
|
+
|
|
522
|
+
### Step 4: Error Handling
|
|
523
|
+
|
|
524
|
+
**Invalid Action Error:**
|
|
525
|
+
|
|
526
|
+
```
|
|
527
|
+
╭──────────────────────────────────────────────────────────────────────────────╮
|
|
528
|
+
│ ❌ ERROR │
|
|
529
|
+
├──────────────────────────────────────────────────────────────────────────────┤
|
|
530
|
+
│ │
|
|
531
|
+
│ {t.commands.discord.invalidAction} │
|
|
532
|
+
│ │
|
|
533
|
+
│ Unknown action: "{action}" │
|
|
534
|
+
│ │
|
|
535
|
+
│ ── Valid Actions ────────────────────────────────────────────────────── │
|
|
536
|
+
│ │
|
|
537
|
+
│ • setup <url> Configure Discord webhook │
|
|
538
|
+
│ • test Send a test notification │
|
|
539
|
+
│ • disable Disable Discord notifications │
|
|
540
|
+
│ │
|
|
541
|
+
│ 💡 Run /pfDiscord without arguments to view current status. │
|
|
542
|
+
│ │
|
|
543
|
+
╰──────────────────────────────────────────────────────────────────────────────╯
|
|
544
|
+
```
|
|
545
|
+
|
|
546
|
+
**Network Error:**
|
|
547
|
+
|
|
548
|
+
```
|
|
549
|
+
╭──────────────────────────────────────────────────────────────────────────────╮
|
|
550
|
+
│ ❌ ERROR │
|
|
551
|
+
├──────────────────────────────────────────────────────────────────────────────┤
|
|
552
|
+
│ │
|
|
553
|
+
│ {t.commands.discord.networkError} │
|
|
554
|
+
│ │
|
|
555
|
+
│ Could not connect to PlanFlow API. │
|
|
556
|
+
│ │
|
|
557
|
+
│ {t.commands.discord.tryAgain} │
|
|
558
|
+
│ │
|
|
559
|
+
╰──────────────────────────────────────────────────────────────────────────────╯
|
|
560
|
+
```
|
|
561
|
+
|
|
562
|
+
**Permission Error:**
|
|
563
|
+
|
|
564
|
+
```
|
|
565
|
+
╭──────────────────────────────────────────────────────────────────────────────╮
|
|
566
|
+
│ ❌ ERROR │
|
|
567
|
+
├──────────────────────────────────────────────────────────────────────────────┤
|
|
568
|
+
│ │
|
|
569
|
+
│ {t.commands.discord.noPermission} │
|
|
570
|
+
│ │
|
|
571
|
+
│ You don't have permission to manage Discord integration. │
|
|
572
|
+
│ │
|
|
573
|
+
│ {t.commands.discord.noPermissionHint} │
|
|
574
|
+
│ │
|
|
575
|
+
╰──────────────────────────────────────────────────────────────────────────────╯
|
|
576
|
+
```
|
|
577
|
+
|
|
578
|
+
## Discord Message Format
|
|
579
|
+
|
|
580
|
+
When PlanFlow sends notifications to Discord, they use embedded messages with rich formatting:
|
|
581
|
+
|
|
582
|
+
**Task Completed:**
|
|
583
|
+
```
|
|
584
|
+
┌────────────────────────────────────────────┐
|
|
585
|
+
│ 🎉 Task Completed │
|
|
586
|
+
├────────────────────────────────────────────┤
|
|
587
|
+
│ T2.1: Implement login API │
|
|
588
|
+
│ was marked as done by John Doe │
|
|
589
|
+
│ │
|
|
590
|
+
│ Project: My Project │
|
|
591
|
+
│ │
|
|
592
|
+
│ ────────────────────────────────────── │
|
|
593
|
+
│ 🟢 PlanFlow │
|
|
594
|
+
└────────────────────────────────────────────┘
|
|
595
|
+
```
|
|
596
|
+
|
|
597
|
+
**Task Assigned:**
|
|
598
|
+
```
|
|
599
|
+
┌────────────────────────────────────────────┐
|
|
600
|
+
│ 📋 Task Assigned │
|
|
601
|
+
├────────────────────────────────────────────┤
|
|
602
|
+
│ T2.3: Add validation │
|
|
603
|
+
│ was assigned to you by Jane Smith │
|
|
604
|
+
│ │
|
|
605
|
+
│ Project: My Project │
|
|
606
|
+
│ │
|
|
607
|
+
│ ────────────────────────────────────── │
|
|
608
|
+
│ 🟢 PlanFlow │
|
|
609
|
+
└────────────────────────────────────────────┘
|
|
610
|
+
```
|
|
611
|
+
|
|
612
|
+
**Mention:**
|
|
613
|
+
```
|
|
614
|
+
┌────────────────────────────────────────────┐
|
|
615
|
+
│ 💬 You were mentioned │
|
|
616
|
+
├────────────────────────────────────────────┤
|
|
617
|
+
│ John Doe mentioned you in: │
|
|
618
|
+
│ T2.1: Implement login API │
|
|
619
|
+
│ │
|
|
620
|
+
│ > @jane please review this when you │
|
|
621
|
+
│ > have time │
|
|
622
|
+
│ │
|
|
623
|
+
│ Project: My Project │
|
|
624
|
+
│ │
|
|
625
|
+
│ ────────────────────────────────────── │
|
|
626
|
+
│ 🟢 PlanFlow │
|
|
627
|
+
└────────────────────────────────────────────┘
|
|
628
|
+
```
|
|
629
|
+
|
|
630
|
+
**Comment:**
|
|
631
|
+
```
|
|
632
|
+
┌────────────────────────────────────────────┐
|
|
633
|
+
│ 💭 New Comment │
|
|
634
|
+
├────────────────────────────────────────────┤
|
|
635
|
+
│ Jane Smith commented on: │
|
|
636
|
+
│ T2.1: Implement login API │
|
|
637
|
+
│ │
|
|
638
|
+
│ > Looks good! Just one small fix needed. │
|
|
639
|
+
│ │
|
|
640
|
+
│ Project: My Project │
|
|
641
|
+
│ │
|
|
642
|
+
│ ────────────────────────────────────── │
|
|
643
|
+
│ 🟢 PlanFlow │
|
|
644
|
+
└────────────────────────────────────────────┘
|
|
645
|
+
```
|
|
646
|
+
|
|
647
|
+
## Translation Keys Required
|
|
648
|
+
|
|
649
|
+
Add these to `locales/en.json` and `locales/ka.json`:
|
|
650
|
+
|
|
651
|
+
```json
|
|
652
|
+
{
|
|
653
|
+
"commands": {
|
|
654
|
+
"discord": {
|
|
655
|
+
"title": "Discord Integration",
|
|
656
|
+
"status": "Status",
|
|
657
|
+
"events": "Notification Events",
|
|
658
|
+
"connected": "Connected",
|
|
659
|
+
"notConfigured": "Not Configured",
|
|
660
|
+
"notConfiguredHint": "Discord notifications are not set up for this project.",
|
|
661
|
+
"howToSetup": "How to Set Up",
|
|
662
|
+
"setupSuccess": "Discord integration configured successfully!",
|
|
663
|
+
"willReceive": "You will receive notifications for:",
|
|
664
|
+
"testSuccess": "Test notification sent!",
|
|
665
|
+
"testFailed": "Failed to send test notification.",
|
|
666
|
+
"disableSuccess": "Discord integration disabled.",
|
|
667
|
+
"invalidUrl": "Invalid Discord webhook URL.",
|
|
668
|
+
"missingUrl": "Webhook URL is required.",
|
|
669
|
+
"invalidAction": "Invalid action.",
|
|
670
|
+
"networkError": "Network error. Could not connect to PlanFlow API.",
|
|
671
|
+
"tryAgain": "Please check your connection and try again.",
|
|
672
|
+
"noPermission": "You don't have permission to manage Discord integration.",
|
|
673
|
+
"noPermissionHint": "Only project owners and admins can configure integrations.",
|
|
674
|
+
"notConfiguredError": "Discord is not configured.",
|
|
675
|
+
"webhookLabel": "Webhook",
|
|
676
|
+
"serverLabel": "Server",
|
|
677
|
+
"channelLabel": "Channel",
|
|
678
|
+
"lastTestLabel": "Last Test",
|
|
679
|
+
"lastSentLabel": "Last Sent",
|
|
680
|
+
"configured": "Configured",
|
|
681
|
+
"eventTaskCompleted": "Task completed",
|
|
682
|
+
"eventTaskAssigned": "Task assigned",
|
|
683
|
+
"eventMentions": "@mentions",
|
|
684
|
+
"eventComments": "New comments"
|
|
685
|
+
}
|
|
686
|
+
}
|
|
687
|
+
}
|
|
688
|
+
```
|
|
689
|
+
|
|
690
|
+
**Georgian translations:**
|
|
691
|
+
|
|
692
|
+
```json
|
|
693
|
+
{
|
|
694
|
+
"commands": {
|
|
695
|
+
"discord": {
|
|
696
|
+
"title": "Discord ინტეგრაცია",
|
|
697
|
+
"status": "სტატუსი",
|
|
698
|
+
"events": "შეტყობინებების მოვლენები",
|
|
699
|
+
"connected": "დაკავშირებული",
|
|
700
|
+
"notConfigured": "არ არის კონფიგურებული",
|
|
701
|
+
"notConfiguredHint": "Discord შეტყობინებები არ არის დაყენებული ამ პროექტისთვის.",
|
|
702
|
+
"howToSetup": "როგორ დავაყენოთ",
|
|
703
|
+
"setupSuccess": "Discord ინტეგრაცია წარმატებით კონფიგურებულია!",
|
|
704
|
+
"willReceive": "მიიღებთ შეტყობინებებს:",
|
|
705
|
+
"testSuccess": "სატესტო შეტყობინება გაიგზავნა!",
|
|
706
|
+
"testFailed": "სატესტო შეტყობინების გაგზავნა ვერ მოხერხდა.",
|
|
707
|
+
"disableSuccess": "Discord ინტეგრაცია გამორთულია.",
|
|
708
|
+
"invalidUrl": "არასწორი Discord webhook URL.",
|
|
709
|
+
"missingUrl": "Webhook URL აუცილებელია.",
|
|
710
|
+
"invalidAction": "არასწორი მოქმედება.",
|
|
711
|
+
"networkError": "ქსელის შეცდომა. PlanFlow API-სთან დაკავშირება ვერ მოხერხდა.",
|
|
712
|
+
"tryAgain": "გთხოვთ შეამოწმოთ კავშირი და სცადოთ თავიდან.",
|
|
713
|
+
"noPermission": "თქვენ არ გაქვთ Discord ინტეგრაციის მართვის უფლება.",
|
|
714
|
+
"noPermissionHint": "მხოლოდ პროექტის მფლობელებს და ადმინებს შეუძლიათ ინტეგრაციების კონფიგურაცია.",
|
|
715
|
+
"notConfiguredError": "Discord არ არის კონფიგურებული.",
|
|
716
|
+
"webhookLabel": "Webhook",
|
|
717
|
+
"serverLabel": "სერვერი",
|
|
718
|
+
"channelLabel": "არხი",
|
|
719
|
+
"lastTestLabel": "ბოლო ტესტი",
|
|
720
|
+
"lastSentLabel": "ბოლოს გაგზავნილი",
|
|
721
|
+
"configured": "კონფიგურებული",
|
|
722
|
+
"eventTaskCompleted": "ამოცანა დასრულებული",
|
|
723
|
+
"eventTaskAssigned": "ამოცანა მინიჭებული",
|
|
724
|
+
"eventMentions": "@მოხსენიებები",
|
|
725
|
+
"eventComments": "ახალი კომენტარები"
|
|
726
|
+
}
|
|
727
|
+
}
|
|
728
|
+
}
|
|
729
|
+
```
|
|
730
|
+
|
|
731
|
+
## Notes
|
|
732
|
+
|
|
733
|
+
- Webhook URLs are stored securely on the server (never exposed in full)
|
|
734
|
+
- Notifications are sent asynchronously and don't block plugin operations
|
|
735
|
+
- Test notifications help verify the webhook is working before real notifications
|
|
736
|
+
- Disabling removes the webhook URL completely (re-setup required to enable again)
|
|
737
|
+
- Only project owners and admins can configure integrations
|
|
738
|
+
- All team members benefit from configured notifications (based on their personal settings)
|
|
739
|
+
- Discord webhooks support both `discord.com` and `discordapp.com` domains
|
|
740
|
+
- Discord embeds provide rich formatting with colors and structured layout
|