@idanbuzaglo/notifikations 1.0.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/install.js +16 -0
- package/package.json +25 -0
- package/skill.md +279 -0
package/install.js
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
const fs = require('fs');
|
|
4
|
+
const path = require('path');
|
|
5
|
+
const os = require('os');
|
|
6
|
+
|
|
7
|
+
const skillsDir = path.join(os.homedir(), '.claude', 'skills');
|
|
8
|
+
const dest = path.join(skillsDir, 'notifikations.md');
|
|
9
|
+
|
|
10
|
+
fs.mkdirSync(skillsDir, { recursive: true });
|
|
11
|
+
fs.copyFileSync(path.join(__dirname, 'skill.md'), dest);
|
|
12
|
+
|
|
13
|
+
console.log('Notifikations skill installed!');
|
|
14
|
+
console.log('Location: ' + dest);
|
|
15
|
+
console.log('');
|
|
16
|
+
console.log('Use /notifikations in Claude Code to get started.');
|
package/package.json
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@idanbuzaglo/notifikations",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Claude Code skill for sending push notifications via Notifikations",
|
|
5
|
+
"bin": {
|
|
6
|
+
"notifikations": "install.js"
|
|
7
|
+
},
|
|
8
|
+
"files": [
|
|
9
|
+
"install.js",
|
|
10
|
+
"skill.md"
|
|
11
|
+
],
|
|
12
|
+
"keywords": [
|
|
13
|
+
"claude",
|
|
14
|
+
"claude-code",
|
|
15
|
+
"skill",
|
|
16
|
+
"notifikations",
|
|
17
|
+
"push-notifications",
|
|
18
|
+
"webhook"
|
|
19
|
+
],
|
|
20
|
+
"author": "idanbuzaglo",
|
|
21
|
+
"license": "MIT",
|
|
22
|
+
"publishConfig": {
|
|
23
|
+
"access": "public"
|
|
24
|
+
}
|
|
25
|
+
}
|
package/skill.md
ADDED
|
@@ -0,0 +1,279 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: notifikations
|
|
3
|
+
description: >
|
|
4
|
+
Send push notifications to your iPhone or Mac using Notifikations webhook URLs.
|
|
5
|
+
Use this skill when a user wants to get notified on their phone from any script,
|
|
6
|
+
automation, deployment, CI/CD pipeline, smart home, or third-party service.
|
|
7
|
+
Covers all payload fields, scheduling, named webhooks, action buttons, and
|
|
8
|
+
ready-to-use code for curl, Python, JavaScript, GitHub Actions, Home Assistant,
|
|
9
|
+
Claude Code hooks, n8n, Zapier, Apple Shortcuts, and more.
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
## What is Notifikations?
|
|
13
|
+
|
|
14
|
+
Notifikations gives you a personal webhook URL. Hit it from anywhere — a script, a CI job, a cron task, a smart home — and a push notification lands on your iPhone or Mac instantly. No account. No login. The URL is the credential.
|
|
15
|
+
|
|
16
|
+
Get the app at **notifikations.com** and copy your webhook URL from the main screen.
|
|
17
|
+
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
## Sending a notification
|
|
21
|
+
|
|
22
|
+
The base URL is:
|
|
23
|
+
```
|
|
24
|
+
https://api.notifikations.com/api/v1/YOUR_SECRET
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
**Simplest possible call — plain text body:**
|
|
28
|
+
```bash
|
|
29
|
+
curl -X POST https://api.notifikations.com/api/v1/YOUR_SECRET \
|
|
30
|
+
-d 'Deploy finished ✅'
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
**GET request (useful when only URLs are supported):**
|
|
34
|
+
```
|
|
35
|
+
https://api.notifikations.com/api/v1/YOUR_SECRET?message=Hello&title=Alert
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
**JSON with full control:**
|
|
39
|
+
```bash
|
|
40
|
+
curl -X POST https://api.notifikations.com/api/v1/YOUR_SECRET \
|
|
41
|
+
-H 'Content-Type: application/json' \
|
|
42
|
+
-d '{
|
|
43
|
+
"title": "Build done",
|
|
44
|
+
"message": "All tests passed",
|
|
45
|
+
"sound": "brrr"
|
|
46
|
+
}'
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
---
|
|
50
|
+
|
|
51
|
+
## All payload fields
|
|
52
|
+
|
|
53
|
+
| Field | Type | Notes |
|
|
54
|
+
|-------|------|-------|
|
|
55
|
+
| `message` | string | **Required.** Notification body. |
|
|
56
|
+
| `title` | string | Bold heading above the message. |
|
|
57
|
+
| `subtitle` | string | Secondary line below title. |
|
|
58
|
+
| `sound` | string | `"default"`, `"none"`, or a custom sound name (e.g. `"brrr"`). |
|
|
59
|
+
| `thread_id` | string | Groups related notifications in Notification Center. |
|
|
60
|
+
| `open_url` | string | URL or deep link opened when the user taps. |
|
|
61
|
+
| `image_url` | string | Remote image shown in the expanded notification. |
|
|
62
|
+
| `interruption-level` | string | `"passive"` (silent), `"active"` (default), `"time-sensitive"` (breaks Focus). |
|
|
63
|
+
| `filter-criteria` | string | iOS Focus filter value. |
|
|
64
|
+
| `expiration_date` | ISO 8601 | Discard the notification after this time if undelivered. |
|
|
65
|
+
| `send_at` | ISO 8601 | Schedule delivery up to 30 days ahead (max 10 pending per URL). |
|
|
66
|
+
| `category` | string | Show action buttons: `"YES_NO"`, `"APPROVE_DISMISS"`, `"CONFIRM"`. |
|
|
67
|
+
| `callback_url` | string | Your server receives a POST `{"action":"yes"}` when the user taps a button. |
|
|
68
|
+
|
|
69
|
+
GET requests accept all the same fields as query parameters.
|
|
70
|
+
|
|
71
|
+
---
|
|
72
|
+
|
|
73
|
+
## Secrets and targeting
|
|
74
|
+
|
|
75
|
+
| Secret type | What it does |
|
|
76
|
+
|-------------|--------------|
|
|
77
|
+
| **Device secret** (`ntf_dev_…`) | Sends to one specific device only. |
|
|
78
|
+
| **User secret** (`ntf_usr_…`) | Fan-out — sends to all your registered devices simultaneously. |
|
|
79
|
+
| **Named webhook secret** | An independent URL you create in the app; can target one device or all. Max 10 per device. |
|
|
80
|
+
|
|
81
|
+
Both secrets are shown in the app. Store yours in an environment variable:
|
|
82
|
+
```bash
|
|
83
|
+
export NTF_SECRET="ntf_dev_xxxxxxxxxxxx"
|
|
84
|
+
curl -s -X POST "https://api.notifikations.com/api/v1/$NTF_SECRET" -d "Done"
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
---
|
|
88
|
+
|
|
89
|
+
## Scheduling
|
|
90
|
+
|
|
91
|
+
Add `send_at` (ISO 8601) to deliver later. Response includes a `jobId` you can use to cancel.
|
|
92
|
+
|
|
93
|
+
```bash
|
|
94
|
+
curl -X POST https://api.notifikations.com/api/v1/YOUR_SECRET \
|
|
95
|
+
-H 'Content-Type: application/json' \
|
|
96
|
+
-d '{
|
|
97
|
+
"title": "Reminder",
|
|
98
|
+
"message": "Stand-up in 5 minutes",
|
|
99
|
+
"send_at": "2026-04-01T09:55:00Z"
|
|
100
|
+
}'
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
Delivery precision is approximately ±1 minute. Max 10 pending scheduled jobs per webhook URL.
|
|
104
|
+
|
|
105
|
+
---
|
|
106
|
+
|
|
107
|
+
## Response codes
|
|
108
|
+
|
|
109
|
+
| Status | Body | Meaning |
|
|
110
|
+
|--------|------|---------|
|
|
111
|
+
| `200` | `{"success":true,"apnsId":"…"}` | Delivered to one device. |
|
|
112
|
+
| `200` | `{"success":true,"sent":2,"failures":0}` | User-secret fan-out result. |
|
|
113
|
+
| `400` | `{"error":"message is required"}` | Missing required field. |
|
|
114
|
+
| `404` | `{"error":"webhook not found"}` | Secret not registered — check URL. |
|
|
115
|
+
| `502` | `{"error":"…"}` | APNs rejected the notification. |
|
|
116
|
+
|
|
117
|
+
---
|
|
118
|
+
|
|
119
|
+
## Integration recipes
|
|
120
|
+
|
|
121
|
+
### Python (stdlib only)
|
|
122
|
+
```python
|
|
123
|
+
import urllib.request, json
|
|
124
|
+
|
|
125
|
+
def notify(message, title=None, secret="YOUR_SECRET"):
|
|
126
|
+
url = f"https://api.notifikations.com/api/v1/{secret}"
|
|
127
|
+
payload = {"message": message}
|
|
128
|
+
if title:
|
|
129
|
+
payload["title"] = title
|
|
130
|
+
data = json.dumps(payload).encode()
|
|
131
|
+
req = urllib.request.Request(url, data=data,
|
|
132
|
+
headers={"Content-Type": "application/json"})
|
|
133
|
+
urllib.request.urlopen(req)
|
|
134
|
+
|
|
135
|
+
notify("Training finished — val_loss 0.042", title="Model")
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
### JavaScript / Node.js
|
|
139
|
+
```javascript
|
|
140
|
+
async function notify(message, title) {
|
|
141
|
+
await fetch("https://api.notifikations.com/api/v1/YOUR_SECRET", {
|
|
142
|
+
method: "POST",
|
|
143
|
+
headers: { "Content-Type": "application/json" },
|
|
144
|
+
body: JSON.stringify({ message, title }),
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
await notify("Job finished", "Cron");
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
### GitHub Actions
|
|
152
|
+
```yaml
|
|
153
|
+
# .github/workflows/deploy.yml
|
|
154
|
+
steps:
|
|
155
|
+
- uses: actions/checkout@v4
|
|
156
|
+
- run: npm ci && npm run build
|
|
157
|
+
|
|
158
|
+
- name: Notify on success
|
|
159
|
+
if: success()
|
|
160
|
+
run: |
|
|
161
|
+
curl -s -X POST "https://api.notifikations.com/api/v1/${{ secrets.NTF_SECRET }}" \
|
|
162
|
+
-H 'Content-Type: application/json' \
|
|
163
|
+
-d '{"title":"Deploy succeeded 🚀","message":"${{ github.repository }} → ${{ github.ref_name }}"}'
|
|
164
|
+
|
|
165
|
+
- name: Notify on failure
|
|
166
|
+
if: failure()
|
|
167
|
+
run: |
|
|
168
|
+
curl -s -X POST "https://api.notifikations.com/api/v1/${{ secrets.NTF_SECRET }}" \
|
|
169
|
+
-H 'Content-Type: application/json' \
|
|
170
|
+
-d '{"title":"Build failed ❌","message":"${{ github.repository }} on ${{ github.ref_name }}"}'
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
Store the secret in **Settings → Secrets → Actions** as `NTF_SECRET`.
|
|
174
|
+
|
|
175
|
+
### Home Assistant
|
|
176
|
+
```yaml
|
|
177
|
+
# configuration.yaml
|
|
178
|
+
rest_command:
|
|
179
|
+
notifikations_send:
|
|
180
|
+
url: "https://api.notifikations.com/api/v1/YOUR_SECRET"
|
|
181
|
+
method: POST
|
|
182
|
+
content_type: "application/json"
|
|
183
|
+
payload: '{"title":"{{ title }}","message":"{{ message }}"}'
|
|
184
|
+
|
|
185
|
+
# automation.yaml — notify when washing machine finishes
|
|
186
|
+
automation:
|
|
187
|
+
- alias: "Washing machine done"
|
|
188
|
+
trigger:
|
|
189
|
+
- platform: state
|
|
190
|
+
entity_id: sensor.washing_machine_power
|
|
191
|
+
to: "0"
|
|
192
|
+
for: "00:01:00"
|
|
193
|
+
action:
|
|
194
|
+
- service: rest_command.notifikations_send
|
|
195
|
+
data:
|
|
196
|
+
title: "Laundry done 👕"
|
|
197
|
+
message: "Washing machine finished"
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
### Claude Code (notify when Claude finishes a task)
|
|
201
|
+
```json
|
|
202
|
+
// ~/.claude/settings.json
|
|
203
|
+
{
|
|
204
|
+
"hooks": {
|
|
205
|
+
"Stop": [
|
|
206
|
+
{
|
|
207
|
+
"matcher": "",
|
|
208
|
+
"hooks": [
|
|
209
|
+
{
|
|
210
|
+
"type": "command",
|
|
211
|
+
"command": "curl -s -X POST https://api.notifikations.com/api/v1/YOUR_SECRET -H 'Content-Type: application/json' -d '{\"title\":\"Claude done\",\"message\":\"Task finished\"}'"
|
|
212
|
+
}
|
|
213
|
+
]
|
|
214
|
+
}
|
|
215
|
+
]
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
### n8n
|
|
221
|
+
Add an **HTTP Request** node:
|
|
222
|
+
- Method: `POST`
|
|
223
|
+
- URL: `https://api.notifikations.com/api/v1/YOUR_SECRET`
|
|
224
|
+
- Body Content Type: JSON
|
|
225
|
+
- Body:
|
|
226
|
+
```json
|
|
227
|
+
{
|
|
228
|
+
"title": "n8n workflow done",
|
|
229
|
+
"message": "{{ $json.summary }}"
|
|
230
|
+
}
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
### Zapier
|
|
234
|
+
Add a **Webhooks by Zapier** action:
|
|
235
|
+
- Method: `POST`
|
|
236
|
+
- URL: `https://api.notifikations.com/api/v1/YOUR_SECRET`
|
|
237
|
+
- Payload Type: `JSON`
|
|
238
|
+
- Data: map `title` and `message` from the trigger step
|
|
239
|
+
|
|
240
|
+
### Bash one-liner (cron, Makefile, CI scripts)
|
|
241
|
+
```bash
|
|
242
|
+
# Add to the end of any long-running script
|
|
243
|
+
notify() { curl -s -X POST "https://api.notifikations.com/api/v1/$NTF_SECRET" \
|
|
244
|
+
-H 'Content-Type: application/json' \
|
|
245
|
+
-d "{\"title\":\"$1\",\"message\":\"$2\"}"; }
|
|
246
|
+
|
|
247
|
+
notify "Backup done" "$(date): 3.2 GB uploaded to S3"
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
---
|
|
251
|
+
|
|
252
|
+
## Interactive action buttons
|
|
253
|
+
|
|
254
|
+
Ask the user a yes/no question from anywhere:
|
|
255
|
+
|
|
256
|
+
```bash
|
|
257
|
+
curl -X POST https://api.notifikations.com/api/v1/YOUR_SECRET \
|
|
258
|
+
-H 'Content-Type: application/json' \
|
|
259
|
+
-d '{
|
|
260
|
+
"title": "Deploy to production?",
|
|
261
|
+
"message": "v2.4.1 is ready",
|
|
262
|
+
"category": "YES_NO",
|
|
263
|
+
"callback_url": "https://your-server.com/deploy-webhook"
|
|
264
|
+
}'
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
When the user taps **Yes** or **No**, Notifikations POSTs `{"action":"yes"}` or `{"action":"no"}` to your `callback_url`. The `callback_url` is never stored by Notifikations.
|
|
268
|
+
|
|
269
|
+
Available categories: `YES_NO`, `APPROVE_DISMISS`, `CONFIRM`.
|
|
270
|
+
|
|
271
|
+
---
|
|
272
|
+
|
|
273
|
+
## Tips
|
|
274
|
+
|
|
275
|
+
- **Keep the secret in an env var** — never hard-code it in source files.
|
|
276
|
+
- **Use the user secret** if you want all your devices to receive the notification simultaneously.
|
|
277
|
+
- **Use `interruption-level: "time-sensitive"`** only for urgent alerts — it breaks through Focus mode.
|
|
278
|
+
- **Use `open_url`** to deep-link into an app or open a dashboard directly from the notification tap.
|
|
279
|
+
- **Named webhooks** (created in the app) are useful for sharing a single URL with a service without exposing your main device secret.
|