From e113241b79b4748bd13207d83b07ec4c551d2f00 Mon Sep 17 00:00:00 2001 From: XmerOriginals <108153683+xmeroriginals@users.noreply.github.com> Date: Wed, 31 Dec 2025 21:11:27 +0300 Subject: [PATCH 1/9] Create ntfyscratch.js Send notifications from your Scratch project to your phone, tablet, or computer using ntfy.sh --- extensions/XmerOriginals/ntfyscratch.js | 134 ++++++++++++++++++++++++ 1 file changed, 134 insertions(+) create mode 100644 extensions/XmerOriginals/ntfyscratch.js diff --git a/extensions/XmerOriginals/ntfyscratch.js b/extensions/XmerOriginals/ntfyscratch.js new file mode 100644 index 0000000000..ec2e78b843 --- /dev/null +++ b/extensions/XmerOriginals/ntfyscratch.js @@ -0,0 +1,134 @@ +// Name: ntfyScratch +// ID: ntfyScratch +// Description: Send notifications from your Scratch project to your phone, tablet, or computer using ntfy.sh. Instantly receive messages, alerts, and status updates from your project in real time. +// By: XmerOriginals +// License: MPL-2.0 + +(function(Scratch) { + 'use strict'; + + class ntfyScratch { + getInfo() { + return { + id: 'ntfyScratch', + name: 'ntfyScratch', + color1: '#55bba6', + color2: '#358876', + blocks: [ + { + func: 'openDoc', + blockType: Scratch.BlockType.BUTTON, + text: 'Documentation' + }, + { + func: 'openDocNtfy', + blockType: Scratch.BlockType.BUTTON, + text: 'ntfy.sh Documentation' + }, + '---', + { + opcode: 'sendSimpleNotification', + blockType: Scratch.BlockType.COMMAND, + text: 'send message [MESSAGE] to topic [TOPIC]', + arguments: { + TOPIC: { + type: Scratch.ArgumentType.STRING, + defaultValue: 'mytopic' + }, + MESSAGE: { + type: Scratch.ArgumentType.STRING, + defaultValue: 'Hello from TurboWarp!' + } + } + }, + { + opcode: 'sendFullNotification', + blockType: Scratch.BlockType.COMMAND, + text: 'send notification to [TOPIC] title [TITLE] message [MESSAGE] priority [PRIORITY] tags [TAGS]', + arguments: { + TOPIC: { + type: Scratch.ArgumentType.STRING, + defaultValue: 'mytopic' + }, + TITLE: { + type: Scratch.ArgumentType.STRING, + defaultValue: 'Alert' + }, + MESSAGE: { + type: Scratch.ArgumentType.STRING, + defaultValue: 'Project is running' + }, + PRIORITY: { + type: Scratch.ArgumentType.NUMBER, + defaultValue: 3, + menu: 'priorityMenu' + }, + TAGS: { + type: Scratch.ArgumentType.STRING, + defaultValue: 'star,computer' + } + } + } + ], + menus: { + priorityMenu: { + acceptReporters: true, + items: [ + { text: 'Max (5)', value: '5' }, + { text: 'High (4)', value: '4' }, + { text: 'Default (3)', value: '3' }, + { text: 'Low (2)', value: '2' }, + { text: 'Min (1)', value: '1' } + ] + } + } + }; + } + + sendSimpleNotification(args) { + const topic = args.TOPIC; + const message = args.MESSAGE; + + fetch(`https://ntfy.sh/${topic}`, { + method: 'POST', + body: message + }).catch(() => {}); + } + + sendFullNotification(args) { + const bodyData = { + topic: args.TOPIC, + title: args.TITLE, + message: args.MESSAGE, + priority: parseInt(args.PRIORITY), + tags: args.TAGS.split(',').map(tag => tag.trim()) + }; + + fetch('https://ntfy.sh/', { + method: 'POST', + body: JSON.stringify(bodyData), + headers: { + 'Content-Type': 'application/json' + } + }).catch(() => {}); + } + + openDoc() { + Scratch.canOpenWindow('http://xelabs.xmeroriginals.com/docs/ntfyScratch/').then((allowed) => { + if (allowed) { + window.open('http://xelabs.xmeroriginals.com/docs/ntfyScratch/', '_blank'); + } + }); + } + + openDocNtfy() { + Scratch.canOpenWindow('https://ntfy.sh/docs/').then((allowed) => { + if (allowed) { + window.open('https://ntfy.sh/docs/', '_blank'); + } + }); + } + } + + Scratch.extensions.register(new ntfyScratch()); +})(Scratch); From c637655364b8a6f67df73972345bb16674c8d822 Mon Sep 17 00:00:00 2001 From: XmerOriginals <108153683+xmeroriginals@users.noreply.github.com> Date: Wed, 31 Dec 2025 21:22:14 +0300 Subject: [PATCH 2/9] format - lint --- extensions/XmerOriginals/ntfyscratch.js | 36 ++++++++++++++----------- 1 file changed, 20 insertions(+), 16 deletions(-) diff --git a/extensions/XmerOriginals/ntfyscratch.js b/extensions/XmerOriginals/ntfyscratch.js index ec2e78b843..a7d3ad9377 100644 --- a/extensions/XmerOriginals/ntfyscratch.js +++ b/extensions/XmerOriginals/ntfyscratch.js @@ -4,7 +4,7 @@ // By: XmerOriginals // License: MPL-2.0 -(function(Scratch) { +(function (Scratch) { 'use strict'; class ntfyScratch { @@ -20,12 +20,12 @@ blockType: Scratch.BlockType.BUTTON, text: 'Documentation' }, - { + { func: 'openDocNtfy', blockType: Scratch.BlockType.BUTTON, text: 'ntfy.sh Documentation' }, - '---', + '---', { opcode: 'sendSimpleNotification', blockType: Scratch.BlockType.COMMAND, @@ -92,7 +92,9 @@ fetch(`https://ntfy.sh/${topic}`, { method: 'POST', body: message - }).catch(() => {}); + }).catch((err) => { + console.warn('ntfyScratch: Failed to send simple notification', err); + }); } sendFullNotification(args) { @@ -101,7 +103,7 @@ title: args.TITLE, message: args.MESSAGE, priority: parseInt(args.PRIORITY), - tags: args.TAGS.split(',').map(tag => tag.trim()) + tags: args.TAGS.split(',').map((tag) => tag.trim()) }; fetch('https://ntfy.sh/', { @@ -110,23 +112,25 @@ headers: { 'Content-Type': 'application/json' } - }).catch(() => {}); + }).catch((err) => { + console.warn('ntfyScratch: Failed to send full notification', err); + }); } - openDoc() { - Scratch.canOpenWindow('http://xelabs.xmeroriginals.com/docs/ntfyScratch/').then((allowed) => { + _openUrl(url) { + Scratch.canOpenWindow(url).then((allowed) => { if (allowed) { - window.open('http://xelabs.xmeroriginals.com/docs/ntfyScratch/', '_blank'); + window.open(url, '_blank'); } }); } - - openDocNtfy() { - Scratch.canOpenWindow('https://ntfy.sh/docs/').then((allowed) => { - if (allowed) { - window.open('https://ntfy.sh/docs/', '_blank'); - } - }); + + openDoc() { + this._openUrl('http://xelabs.xmeroriginals.com/docs/ntfyScratch/'); + } + + openDocNtfy() { + this._openUrl('https://ntfy.sh/docs/'); } } From f9b349780adecab5d607f27af3c6b70bc62fe740 Mon Sep 17 00:00:00 2001 From: XmerOriginals <108153683+xmeroriginals@users.noreply.github.com> Date: Wed, 31 Dec 2025 21:28:11 +0300 Subject: [PATCH 3/9] Scratch used --- extensions/XmerOriginals/ntfyscratch.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/extensions/XmerOriginals/ntfyscratch.js b/extensions/XmerOriginals/ntfyscratch.js index a7d3ad9377..daea124b11 100644 --- a/extensions/XmerOriginals/ntfyscratch.js +++ b/extensions/XmerOriginals/ntfyscratch.js @@ -89,7 +89,7 @@ const topic = args.TOPIC; const message = args.MESSAGE; - fetch(`https://ntfy.sh/${topic}`, { + Scratch.fetch(`https://ntfy.sh/${topic}`, { method: 'POST', body: message }).catch((err) => { @@ -106,7 +106,7 @@ tags: args.TAGS.split(',').map((tag) => tag.trim()) }; - fetch('https://ntfy.sh/', { + Scratch.fetch('https://ntfy.sh/', { method: 'POST', body: JSON.stringify(bodyData), headers: { @@ -120,7 +120,7 @@ _openUrl(url) { Scratch.canOpenWindow(url).then((allowed) => { if (allowed) { - window.open(url, '_blank'); + Scratch.openWindow(url, '_blank'); } }); } From 01121273492d899caf9262d45d9ab72895d406d9 Mon Sep 17 00:00:00 2001 From: "DangoCat[bot]" Date: Thu, 1 Jan 2026 17:43:40 +0000 Subject: [PATCH 4/9] [Automated] Format code --- extensions/XmerOriginals/ntfyscratch.js | 92 ++++++++++++------------- 1 file changed, 46 insertions(+), 46 deletions(-) diff --git a/extensions/XmerOriginals/ntfyscratch.js b/extensions/XmerOriginals/ntfyscratch.js index daea124b11..76f9330da3 100644 --- a/extensions/XmerOriginals/ntfyscratch.js +++ b/extensions/XmerOriginals/ntfyscratch.js @@ -5,83 +5,83 @@ // License: MPL-2.0 (function (Scratch) { - 'use strict'; + "use strict"; class ntfyScratch { getInfo() { return { - id: 'ntfyScratch', - name: 'ntfyScratch', - color1: '#55bba6', - color2: '#358876', + id: "ntfyScratch", + name: "ntfyScratch", + color1: "#55bba6", + color2: "#358876", blocks: [ { - func: 'openDoc', + func: "openDoc", blockType: Scratch.BlockType.BUTTON, - text: 'Documentation' + text: "Documentation", }, { - func: 'openDocNtfy', + func: "openDocNtfy", blockType: Scratch.BlockType.BUTTON, - text: 'ntfy.sh Documentation' + text: "ntfy.sh Documentation", }, - '---', + "---", { - opcode: 'sendSimpleNotification', + opcode: "sendSimpleNotification", blockType: Scratch.BlockType.COMMAND, - text: 'send message [MESSAGE] to topic [TOPIC]', + text: "send message [MESSAGE] to topic [TOPIC]", arguments: { TOPIC: { type: Scratch.ArgumentType.STRING, - defaultValue: 'mytopic' + defaultValue: "mytopic", }, MESSAGE: { type: Scratch.ArgumentType.STRING, - defaultValue: 'Hello from TurboWarp!' - } - } + defaultValue: "Hello from TurboWarp!", + }, + }, }, { - opcode: 'sendFullNotification', + opcode: "sendFullNotification", blockType: Scratch.BlockType.COMMAND, - text: 'send notification to [TOPIC] title [TITLE] message [MESSAGE] priority [PRIORITY] tags [TAGS]', + text: "send notification to [TOPIC] title [TITLE] message [MESSAGE] priority [PRIORITY] tags [TAGS]", arguments: { TOPIC: { type: Scratch.ArgumentType.STRING, - defaultValue: 'mytopic' + defaultValue: "mytopic", }, TITLE: { type: Scratch.ArgumentType.STRING, - defaultValue: 'Alert' + defaultValue: "Alert", }, MESSAGE: { type: Scratch.ArgumentType.STRING, - defaultValue: 'Project is running' + defaultValue: "Project is running", }, PRIORITY: { type: Scratch.ArgumentType.NUMBER, defaultValue: 3, - menu: 'priorityMenu' + menu: "priorityMenu", }, TAGS: { type: Scratch.ArgumentType.STRING, - defaultValue: 'star,computer' - } - } - } + defaultValue: "star,computer", + }, + }, + }, ], menus: { priorityMenu: { acceptReporters: true, items: [ - { text: 'Max (5)', value: '5' }, - { text: 'High (4)', value: '4' }, - { text: 'Default (3)', value: '3' }, - { text: 'Low (2)', value: '2' }, - { text: 'Min (1)', value: '1' } - ] - } - } + { text: "Max (5)", value: "5" }, + { text: "High (4)", value: "4" }, + { text: "Default (3)", value: "3" }, + { text: "Low (2)", value: "2" }, + { text: "Min (1)", value: "1" }, + ], + }, + }, }; } @@ -90,10 +90,10 @@ const message = args.MESSAGE; Scratch.fetch(`https://ntfy.sh/${topic}`, { - method: 'POST', - body: message + method: "POST", + body: message, }).catch((err) => { - console.warn('ntfyScratch: Failed to send simple notification', err); + console.warn("ntfyScratch: Failed to send simple notification", err); }); } @@ -103,34 +103,34 @@ title: args.TITLE, message: args.MESSAGE, priority: parseInt(args.PRIORITY), - tags: args.TAGS.split(',').map((tag) => tag.trim()) + tags: args.TAGS.split(",").map((tag) => tag.trim()), }; - Scratch.fetch('https://ntfy.sh/', { - method: 'POST', + Scratch.fetch("https://ntfy.sh/", { + method: "POST", body: JSON.stringify(bodyData), headers: { - 'Content-Type': 'application/json' - } + "Content-Type": "application/json", + }, }).catch((err) => { - console.warn('ntfyScratch: Failed to send full notification', err); + console.warn("ntfyScratch: Failed to send full notification", err); }); } _openUrl(url) { Scratch.canOpenWindow(url).then((allowed) => { if (allowed) { - Scratch.openWindow(url, '_blank'); + Scratch.openWindow(url, "_blank"); } }); } openDoc() { - this._openUrl('http://xelabs.xmeroriginals.com/docs/ntfyScratch/'); + this._openUrl("http://xelabs.xmeroriginals.com/docs/ntfyScratch/"); } openDocNtfy() { - this._openUrl('https://ntfy.sh/docs/'); + this._openUrl("https://ntfy.sh/docs/"); } } From 01a9c12e4fd6d51038095d1c0ff2667613891feb Mon Sep 17 00:00:00 2001 From: XmerOriginals <108153683+xmeroriginals@users.noreply.github.com> Date: Thu, 1 Jan 2026 21:21:50 +0300 Subject: [PATCH 5/9] !format --- extensions/XmerOriginals/ntfyscratch.js | 1 + 1 file changed, 1 insertion(+) diff --git a/extensions/XmerOriginals/ntfyscratch.js b/extensions/XmerOriginals/ntfyscratch.js index 76f9330da3..a01cc9d50f 100644 --- a/extensions/XmerOriginals/ntfyscratch.js +++ b/extensions/XmerOriginals/ntfyscratch.js @@ -1,3 +1,4 @@ +// !format // Name: ntfyScratch // ID: ntfyScratch // Description: Send notifications from your Scratch project to your phone, tablet, or computer using ntfy.sh. Instantly receive messages, alerts, and status updates from your project in real time. From 3c38b7d99592c14e112436b7d322fe252038bd74 Mon Sep 17 00:00:00 2001 From: XmerOriginals <108153683+xmeroriginals@users.noreply.github.com> Date: Sat, 3 Jan 2026 11:52:31 +0300 Subject: [PATCH 6/9] Replace "text"s to Scratch.translate("text") texts --- extensions/XmerOriginals/ntfyscratch.js | 92 ++++++++++++------------- 1 file changed, 46 insertions(+), 46 deletions(-) diff --git a/extensions/XmerOriginals/ntfyscratch.js b/extensions/XmerOriginals/ntfyscratch.js index a01cc9d50f..78cdd7662d 100644 --- a/extensions/XmerOriginals/ntfyscratch.js +++ b/extensions/XmerOriginals/ntfyscratch.js @@ -6,83 +6,83 @@ // License: MPL-2.0 (function (Scratch) { - "use strict"; + 'use strict'; class ntfyScratch { getInfo() { return { - id: "ntfyScratch", - name: "ntfyScratch", - color1: "#55bba6", - color2: "#358876", + id: 'ntfyScratch', + name: Scratch.translate("ntfyScratch"), + color1: '#55bba6', + color2: '#358876', blocks: [ { - func: "openDoc", + func: 'openDoc', blockType: Scratch.BlockType.BUTTON, - text: "Documentation", + text: Scratch.translate("Documentation") }, { - func: "openDocNtfy", + func: 'openDocNtfy', blockType: Scratch.BlockType.BUTTON, - text: "ntfy.sh Documentation", + text: Scratch.translate("ntfy.sh Documentation") }, - "---", + '---', { - opcode: "sendSimpleNotification", + opcode: 'sendSimpleNotification', blockType: Scratch.BlockType.COMMAND, - text: "send message [MESSAGE] to topic [TOPIC]", + text: Scratch.translate("send message [MESSAGE] to topic [TOPIC]"), arguments: { TOPIC: { type: Scratch.ArgumentType.STRING, - defaultValue: "mytopic", + defaultValue: 'mytopic' }, MESSAGE: { type: Scratch.ArgumentType.STRING, - defaultValue: "Hello from TurboWarp!", - }, - }, + defaultValue: 'Hello from TurboWarp!' + } + } }, { - opcode: "sendFullNotification", + opcode: 'sendFullNotification', blockType: Scratch.BlockType.COMMAND, - text: "send notification to [TOPIC] title [TITLE] message [MESSAGE] priority [PRIORITY] tags [TAGS]", + text: Scratch.translate("send notification to [TOPIC] title [TITLE] message [MESSAGE] priority [PRIORITY] tags [TAGS]"), arguments: { TOPIC: { type: Scratch.ArgumentType.STRING, - defaultValue: "mytopic", + defaultValue: 'mytopic' }, TITLE: { type: Scratch.ArgumentType.STRING, - defaultValue: "Alert", + defaultValue: 'Alert' }, MESSAGE: { type: Scratch.ArgumentType.STRING, - defaultValue: "Project is running", + defaultValue: 'Project is running' }, PRIORITY: { type: Scratch.ArgumentType.NUMBER, defaultValue: 3, - menu: "priorityMenu", + menu: 'priorityMenu' }, TAGS: { type: Scratch.ArgumentType.STRING, - defaultValue: "star,computer", - }, - }, - }, + defaultValue: 'star,computer' + } + } + } ], menus: { priorityMenu: { acceptReporters: true, items: [ - { text: "Max (5)", value: "5" }, - { text: "High (4)", value: "4" }, - { text: "Default (3)", value: "3" }, - { text: "Low (2)", value: "2" }, - { text: "Min (1)", value: "1" }, - ], - }, - }, + { text: 'Max (5)', value: '5' }, + { text: 'High (4)', value: '4' }, + { text: 'Default (3)', value: '3' }, + { text: 'Low (2)', value: '2' }, + { text: 'Min (1)', value: '1' } + ] + } + } }; } @@ -91,10 +91,10 @@ const message = args.MESSAGE; Scratch.fetch(`https://ntfy.sh/${topic}`, { - method: "POST", - body: message, + method: 'POST', + body: message }).catch((err) => { - console.warn("ntfyScratch: Failed to send simple notification", err); + console.warn('ntfyScratch: Failed to send simple notification', err); }); } @@ -104,34 +104,34 @@ title: args.TITLE, message: args.MESSAGE, priority: parseInt(args.PRIORITY), - tags: args.TAGS.split(",").map((tag) => tag.trim()), + tags: args.TAGS.split(',').map((tag) => tag.trim()) }; - Scratch.fetch("https://ntfy.sh/", { - method: "POST", + Scratch.fetch('https://ntfy.sh/', { + method: 'POST', body: JSON.stringify(bodyData), headers: { - "Content-Type": "application/json", - }, + 'Content-Type': 'application/json' + } }).catch((err) => { - console.warn("ntfyScratch: Failed to send full notification", err); + console.warn('ntfyScratch: Failed to send full notification', err); }); } _openUrl(url) { Scratch.canOpenWindow(url).then((allowed) => { if (allowed) { - Scratch.openWindow(url, "_blank"); + Scratch.openWindow(url, '_blank'); } }); } openDoc() { - this._openUrl("http://xelabs.xmeroriginals.com/docs/ntfyScratch/"); + this._openUrl('http://xelabs.xmeroriginals.com/docs/ntfyScratch/'); } openDocNtfy() { - this._openUrl("https://ntfy.sh/docs/"); + this._openUrl('https://ntfy.sh/docs/'); } } From f04dc6501e719f65028b52e63ab3bd546def48b7 Mon Sep 17 00:00:00 2001 From: Brackets-Coder <142950368+Brackets-Coder@users.noreply.github.com> Date: Sat, 3 Jan 2026 09:10:57 -0500 Subject: [PATCH 7/9] remove format line at top --- extensions/XmerOriginals/ntfyscratch.js | 1 - 1 file changed, 1 deletion(-) diff --git a/extensions/XmerOriginals/ntfyscratch.js b/extensions/XmerOriginals/ntfyscratch.js index 78cdd7662d..ca49b55ca6 100644 --- a/extensions/XmerOriginals/ntfyscratch.js +++ b/extensions/XmerOriginals/ntfyscratch.js @@ -1,4 +1,3 @@ -// !format // Name: ntfyScratch // ID: ntfyScratch // Description: Send notifications from your Scratch project to your phone, tablet, or computer using ntfy.sh. Instantly receive messages, alerts, and status updates from your project in real time. From 4541d7280fe3e6a6cda542943a9ace33ff103bb7 Mon Sep 17 00:00:00 2001 From: "DangoCat[bot]" Date: Sat, 3 Jan 2026 14:12:43 +0000 Subject: [PATCH 8/9] [Automated] Format code --- extensions/XmerOriginals/ntfyscratch.js | 90 +++++++++++++------------ 1 file changed, 46 insertions(+), 44 deletions(-) diff --git a/extensions/XmerOriginals/ntfyscratch.js b/extensions/XmerOriginals/ntfyscratch.js index ca49b55ca6..e64a9dba77 100644 --- a/extensions/XmerOriginals/ntfyscratch.js +++ b/extensions/XmerOriginals/ntfyscratch.js @@ -5,83 +5,85 @@ // License: MPL-2.0 (function (Scratch) { - 'use strict'; + "use strict"; class ntfyScratch { getInfo() { return { - id: 'ntfyScratch', + id: "ntfyScratch", name: Scratch.translate("ntfyScratch"), - color1: '#55bba6', - color2: '#358876', + color1: "#55bba6", + color2: "#358876", blocks: [ { - func: 'openDoc', + func: "openDoc", blockType: Scratch.BlockType.BUTTON, - text: Scratch.translate("Documentation") + text: Scratch.translate("Documentation"), }, { - func: 'openDocNtfy', + func: "openDocNtfy", blockType: Scratch.BlockType.BUTTON, - text: Scratch.translate("ntfy.sh Documentation") + text: Scratch.translate("ntfy.sh Documentation"), }, - '---', + "---", { - opcode: 'sendSimpleNotification', + opcode: "sendSimpleNotification", blockType: Scratch.BlockType.COMMAND, text: Scratch.translate("send message [MESSAGE] to topic [TOPIC]"), arguments: { TOPIC: { type: Scratch.ArgumentType.STRING, - defaultValue: 'mytopic' + defaultValue: "mytopic", }, MESSAGE: { type: Scratch.ArgumentType.STRING, - defaultValue: 'Hello from TurboWarp!' - } - } + defaultValue: "Hello from TurboWarp!", + }, + }, }, { - opcode: 'sendFullNotification', + opcode: "sendFullNotification", blockType: Scratch.BlockType.COMMAND, - text: Scratch.translate("send notification to [TOPIC] title [TITLE] message [MESSAGE] priority [PRIORITY] tags [TAGS]"), + text: Scratch.translate( + "send notification to [TOPIC] title [TITLE] message [MESSAGE] priority [PRIORITY] tags [TAGS]" + ), arguments: { TOPIC: { type: Scratch.ArgumentType.STRING, - defaultValue: 'mytopic' + defaultValue: "mytopic", }, TITLE: { type: Scratch.ArgumentType.STRING, - defaultValue: 'Alert' + defaultValue: "Alert", }, MESSAGE: { type: Scratch.ArgumentType.STRING, - defaultValue: 'Project is running' + defaultValue: "Project is running", }, PRIORITY: { type: Scratch.ArgumentType.NUMBER, defaultValue: 3, - menu: 'priorityMenu' + menu: "priorityMenu", }, TAGS: { type: Scratch.ArgumentType.STRING, - defaultValue: 'star,computer' - } - } - } + defaultValue: "star,computer", + }, + }, + }, ], menus: { priorityMenu: { acceptReporters: true, items: [ - { text: 'Max (5)', value: '5' }, - { text: 'High (4)', value: '4' }, - { text: 'Default (3)', value: '3' }, - { text: 'Low (2)', value: '2' }, - { text: 'Min (1)', value: '1' } - ] - } - } + { text: "Max (5)", value: "5" }, + { text: "High (4)", value: "4" }, + { text: "Default (3)", value: "3" }, + { text: "Low (2)", value: "2" }, + { text: "Min (1)", value: "1" }, + ], + }, + }, }; } @@ -90,10 +92,10 @@ const message = args.MESSAGE; Scratch.fetch(`https://ntfy.sh/${topic}`, { - method: 'POST', - body: message + method: "POST", + body: message, }).catch((err) => { - console.warn('ntfyScratch: Failed to send simple notification', err); + console.warn("ntfyScratch: Failed to send simple notification", err); }); } @@ -103,34 +105,34 @@ title: args.TITLE, message: args.MESSAGE, priority: parseInt(args.PRIORITY), - tags: args.TAGS.split(',').map((tag) => tag.trim()) + tags: args.TAGS.split(",").map((tag) => tag.trim()), }; - Scratch.fetch('https://ntfy.sh/', { - method: 'POST', + Scratch.fetch("https://ntfy.sh/", { + method: "POST", body: JSON.stringify(bodyData), headers: { - 'Content-Type': 'application/json' - } + "Content-Type": "application/json", + }, }).catch((err) => { - console.warn('ntfyScratch: Failed to send full notification', err); + console.warn("ntfyScratch: Failed to send full notification", err); }); } _openUrl(url) { Scratch.canOpenWindow(url).then((allowed) => { if (allowed) { - Scratch.openWindow(url, '_blank'); + Scratch.openWindow(url, "_blank"); } }); } openDoc() { - this._openUrl('http://xelabs.xmeroriginals.com/docs/ntfyScratch/'); + this._openUrl("http://xelabs.xmeroriginals.com/docs/ntfyScratch/"); } openDocNtfy() { - this._openUrl('https://ntfy.sh/docs/'); + this._openUrl("https://ntfy.sh/docs/"); } } From bb128d37c75b4c61b61d853b2a451dded47293ef Mon Sep 17 00:00:00 2001 From: XmerOriginals <108153683+xmeroriginals@users.noreply.github.com> Date: Sun, 4 Jan 2026 14:15:09 +0300 Subject: [PATCH 9/9] Enhance "ntfyScratch" with advanced notification features Updated notification functionality to support advanced features including attachments, click actions, and scheduled notifications. --- extensions/XmerOriginals/ntfyscratch.js | 78 ++++++++++++++++++++++--- 1 file changed, 71 insertions(+), 7 deletions(-) diff --git a/extensions/XmerOriginals/ntfyscratch.js b/extensions/XmerOriginals/ntfyscratch.js index e64a9dba77..c2e35f8c19 100644 --- a/extensions/XmerOriginals/ntfyscratch.js +++ b/extensions/XmerOriginals/ntfyscratch.js @@ -1,6 +1,6 @@ // Name: ntfyScratch // ID: ntfyScratch -// Description: Send notifications from your Scratch project to your phone, tablet, or computer using ntfy.sh. Instantly receive messages, alerts, and status updates from your project in real time. +// Description: Send notifications from your Scratch project to your phone, tablet, or computer using ntfy.sh. Includes support for attachments, emails, click actions, and scheduling. // By: XmerOriginals // License: MPL-2.0 @@ -41,11 +41,12 @@ }, }, }, + "---", { - opcode: "sendFullNotification", + opcode: "sendAdvancedNotification", blockType: Scratch.BlockType.COMMAND, text: Scratch.translate( - "send notification to [TOPIC] title [TITLE] message [MESSAGE] priority [PRIORITY] tags [TAGS]" + "send instant to [TOPIC] title [TITLE] message [MESSAGE] priority [PRIORITY] tags [TAGS] click [CLICK] attach url [ATTACH] filename [FILENAME] email [EMAIL]" ), arguments: { TOPIC: { @@ -69,6 +70,50 @@ type: Scratch.ArgumentType.STRING, defaultValue: "star,computer", }, + CLICK: { + type: Scratch.ArgumentType.STRING, + defaultValue: "https://scratch.mit.edu", + }, + ATTACH: { type: Scratch.ArgumentType.STRING, defaultValue: "" }, + FILENAME: { type: Scratch.ArgumentType.STRING, defaultValue: "" }, + EMAIL: { type: Scratch.ArgumentType.STRING, defaultValue: "" }, + }, + }, + { + opcode: "sendScheduledNotification", + blockType: Scratch.BlockType.COMMAND, + text: Scratch.translate( + "send scheduled to [TOPIC] title [TITLE] message [MESSAGE] priority [PRIORITY] tags [TAGS] click [CLICK] attach url [ATTACH] filename [FILENAME] delay [DELAY]" + ), + arguments: { + TOPIC: { + type: Scratch.ArgumentType.STRING, + defaultValue: "mytopic", + }, + TITLE: { + type: Scratch.ArgumentType.STRING, + defaultValue: "Scheduled Alert", + }, + MESSAGE: { + type: Scratch.ArgumentType.STRING, + defaultValue: "See you later!", + }, + PRIORITY: { + type: Scratch.ArgumentType.NUMBER, + defaultValue: 3, + menu: "priorityMenu", + }, + TAGS: { + type: Scratch.ArgumentType.STRING, + defaultValue: "clock,calendar", + }, + CLICK: { + type: Scratch.ArgumentType.STRING, + defaultValue: "https://xelabs.xmeroriginals.com", + }, + ATTACH: { type: Scratch.ArgumentType.STRING, defaultValue: "" }, + FILENAME: { type: Scratch.ArgumentType.STRING, defaultValue: "" }, + DELAY: { type: Scratch.ArgumentType.STRING, defaultValue: "10s" }, }, }, ], @@ -99,15 +144,26 @@ }); } - sendFullNotification(args) { + _sendComplexNtfy(args, isScheduled) { const bodyData = { topic: args.TOPIC, title: args.TITLE, message: args.MESSAGE, priority: parseInt(args.PRIORITY), - tags: args.TAGS.split(",").map((tag) => tag.trim()), + tags: args.TAGS ? args.TAGS.split(",").map((tag) => tag.trim()) : [], }; + if (args.CLICK && args.CLICK.length > 0) bodyData.click = args.CLICK; + if (args.ATTACH && args.ATTACH.length > 0) bodyData.attach = args.ATTACH; + if (args.FILENAME && args.FILENAME.length > 0) + bodyData.filename = args.FILENAME; + + if (isScheduled) { + if (args.DELAY && args.DELAY.length > 0) bodyData.delay = args.DELAY; + } else { + if (args.EMAIL && args.EMAIL.length > 0) bodyData.email = args.EMAIL; + } + Scratch.fetch("https://ntfy.sh/", { method: "POST", body: JSON.stringify(bodyData), @@ -115,10 +171,18 @@ "Content-Type": "application/json", }, }).catch((err) => { - console.warn("ntfyScratch: Failed to send full notification", err); + console.warn("ntfyScratch: Failed to send notification", err); }); } + sendAdvancedNotification(args) { + this._sendComplexNtfy(args, false); + } + + sendScheduledNotification(args) { + this._sendComplexNtfy(args, true); + } + _openUrl(url) { Scratch.canOpenWindow(url).then((allowed) => { if (allowed) { @@ -128,7 +192,7 @@ } openDoc() { - this._openUrl("http://xelabs.xmeroriginals.com/docs/ntfyScratch/"); + this._openUrl("https://xelabs.xmeroriginals.com/docs/ntfyScratch/"); } openDocNtfy() {