Merge pull request #777 from automatisch/feature/ntfy
Add ntfy support with sending message
This commit is contained in:
3
packages/backend/src/apps/ntfy/actions/index.ts
Normal file
3
packages/backend/src/apps/ntfy/actions/index.ts
Normal file
@@ -0,0 +1,3 @@
|
||||
import sendMessage from './send-message';
|
||||
|
||||
export default [sendMessage];
|
103
packages/backend/src/apps/ntfy/actions/send-message/index.ts
Normal file
103
packages/backend/src/apps/ntfy/actions/send-message/index.ts
Normal file
@@ -0,0 +1,103 @@
|
||||
import qs from 'qs';
|
||||
import defineAction from '../../../../helpers/define-action';
|
||||
|
||||
export default defineAction({
|
||||
name: 'Send message',
|
||||
key: 'sendMessage',
|
||||
description: 'Sends a message to a topic you specify.',
|
||||
arguments: [
|
||||
{
|
||||
label: 'Topic',
|
||||
key: 'topic',
|
||||
type: 'string' as const,
|
||||
required: true,
|
||||
description: 'Target topic name.',
|
||||
variables: true,
|
||||
},
|
||||
{
|
||||
label: 'Message body',
|
||||
key: 'message',
|
||||
type: 'string' as const,
|
||||
required: true,
|
||||
description: 'Message body to be sent, set to triggered if empty or not passed.',
|
||||
variables: true,
|
||||
},
|
||||
{
|
||||
label: 'Title',
|
||||
key: 'title',
|
||||
type: 'string' as const,
|
||||
required: false,
|
||||
description: 'Message title.',
|
||||
variables: true,
|
||||
},
|
||||
{
|
||||
label: 'Email',
|
||||
key: 'email',
|
||||
type: 'string' as const,
|
||||
required: false,
|
||||
description: 'E-mail address for e-mail notifications.',
|
||||
variables: true,
|
||||
},
|
||||
{
|
||||
label: 'Click URL',
|
||||
key: 'click',
|
||||
type: 'string' as const,
|
||||
required: false,
|
||||
description: 'Website opened when notification is clicked.',
|
||||
variables: true,
|
||||
},
|
||||
{
|
||||
label: 'Attach file by URL',
|
||||
key: 'attach',
|
||||
type: 'string' as const,
|
||||
required: false,
|
||||
description: 'URL of an attachment.',
|
||||
variables: true,
|
||||
},
|
||||
{
|
||||
label: 'Filename',
|
||||
key: 'filename',
|
||||
type: 'string' as const,
|
||||
required: false,
|
||||
description: 'File name of the attachment.',
|
||||
variables: true,
|
||||
},
|
||||
{
|
||||
label: 'Delay',
|
||||
key: 'delay',
|
||||
type: 'string' as const,
|
||||
required: false,
|
||||
description: 'Timestamp or duration for delayed delivery. For example, 30min or 9am.',
|
||||
variables: true,
|
||||
},
|
||||
],
|
||||
|
||||
async run($) {
|
||||
const {
|
||||
topic,
|
||||
message,
|
||||
title,
|
||||
email,
|
||||
click,
|
||||
attach,
|
||||
filename,
|
||||
delay
|
||||
} = $.step.parameters;
|
||||
const payload = {
|
||||
topic,
|
||||
message,
|
||||
title,
|
||||
email,
|
||||
click,
|
||||
attach,
|
||||
filename,
|
||||
delay
|
||||
};
|
||||
|
||||
const response = await $.http.post('/', payload);
|
||||
|
||||
$.setActionItem({
|
||||
raw: response.data,
|
||||
});
|
||||
},
|
||||
});
|
1
packages/backend/src/apps/ntfy/assets/favicon.svg
Normal file
1
packages/backend/src/apps/ntfy/assets/favicon.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg width="50mm" height="50mm" viewBox="0 0 50 50" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg"><defs><linearGradient id="a"><stop style="stop-color:#348878;stop-opacity:1" offset="0"/><stop style="stop-color:#56bda8;stop-opacity:1" offset="1"/></linearGradient><linearGradient xlink:href="#a" id="b" x1="160.722" y1="128.533" x2="168.412" y2="134.326" gradientUnits="userSpaceOnUse" gradientTransform="translate(-845.726 -630.598) scale(5.59448)"/></defs><g style="display:inline"><path style="color:#000;fill:url(#b);stroke:none;stroke-width:3.72347;-inkscape-stroke:none" d="M94.237 89.912H59.499c-2.388 0-4.342 1.844-4.342 4.098l.033 27.754-.648 3.738 9.297-2.806h30.396c2.388 0 4.342-1.845 4.342-4.099V94.01c0-2.254-1.954-4.098-4.342-4.098z" transform="translate(-51.147 -81.516)"/><path style="color:#000;fill:#fff;stroke:none;stroke-width:.762343;-inkscape-stroke:none" d="M58.849 86.79c-3.62 0-6.72 2.848-6.72 6.47v.002l.035 30.273-.91 6.708 12.362-3.284h30.729c3.62 0 6.72-2.852 6.72-6.473V93.26c0-3.62-3.099-6.469-6.717-6.469h-.003zm0 4.566h35.499c1.272 0 2.151.927 2.151 1.903v27.227c0 .977-.88 1.924-2.154 1.903h-31.4l-6.28 1.898.065-.37-.035-30.658c0-.977.88-1.903 2.154-1.903z" transform="translate(-51.147 -81.516)"/><g style="font-size:8.48274px;font-family:sans-serif;letter-spacing:0;word-spacing:0;fill:#000;stroke:none;stroke-width:.525121"><path style="color:#000;-inkscape-font-specification:'JetBrains Mono, Bold';fill:#fff;stroke:none;-inkscape-stroke:none" d="M62.57 116.77v-1.312l3.28-1.459q.159-.068.306-.102.158-.045.283-.068l.271-.022v-.09q-.136-.012-.271-.046-.125-.023-.283-.057-.147-.045-.306-.113l-3.28-1.459v-1.323l5.068 2.319v1.413z" transform="matrix(2.1689 0 0 2.57844 -124.28 -268.742)"/><path style="color:#000;-inkscape-font-specification:'JetBrains Mono, Bold';fill:#fff;stroke:none;-inkscape-stroke:none" d="M62.309 110.31v1.903l3.437 1.53.022.007-.022.008-3.437 1.53v1.892l.37-.17 5.221-2.39v-1.75zm.525.817 4.541 2.08v1.076l-4.541 2.078v-.732l3.12-1.389.003-.002a1.56 1.56 0 0 1 .258-.086h.006l.008-.002c.094-.027.176-.047.246-.06l.498-.041v-.574l-.24-.02a1.411 1.411 0 0 1-.231-.04l-.008-.001-.008-.002a9.077 9.077 0 0 1-.263-.053 2.781 2.781 0 0 1-.266-.097l-.004-.002-3.119-1.39z" transform="matrix(2.1689 0 0 2.57844 -124.28 -268.742)"/></g><g style="font-size:8.48274px;font-family:sans-serif;letter-spacing:0;word-spacing:0;fill:#000;stroke:none;stroke-width:.525121"><path style="color:#000;-inkscape-font-specification:'JetBrains Mono, Bold';fill:#fff;stroke:none;-inkscape-stroke:none" d="M69.171 117.754h5.43v1.278h-5.43Z" transform="matrix(2.16247 0 0 2.48294 -122.76 -261.211)"/><path style="color:#000;-inkscape-font-specification:'JetBrains Mono, Bold';fill:#fff;stroke:none;-inkscape-stroke:none" d="M68.908 117.492v1.802h5.955v-1.802zm.526.524h4.904v.754h-4.904z" transform="matrix(2.16247 0 0 2.48294 -122.76 -261.211)"/></g></g></svg>
|
After Width: | Height: | Size: 2.9 KiB |
39
packages/backend/src/apps/ntfy/auth/index.ts
Normal file
39
packages/backend/src/apps/ntfy/auth/index.ts
Normal file
@@ -0,0 +1,39 @@
|
||||
import verifyCredentials from './verify-credentials';
|
||||
import isStillVerified from './is-still-verified';
|
||||
|
||||
export default {
|
||||
fields: [
|
||||
{
|
||||
key: 'serverUrl',
|
||||
label: 'Server URL',
|
||||
type: 'string' as const,
|
||||
required: true,
|
||||
readOnly: false,
|
||||
value: 'https://ntfy.sh',
|
||||
placeholder: null,
|
||||
description: 'ntfy server to use.',
|
||||
clickToCopy: false,
|
||||
},
|
||||
{
|
||||
key: 'username',
|
||||
label: 'Username',
|
||||
type: 'string' as const,
|
||||
required: false,
|
||||
readOnly: false,
|
||||
placeholder: null,
|
||||
clickToCopy: false,
|
||||
},
|
||||
{
|
||||
key: 'password',
|
||||
label: 'Password',
|
||||
type: 'string' as const,
|
||||
required: false,
|
||||
readOnly: false,
|
||||
placeholder: null,
|
||||
clickToCopy: false,
|
||||
},
|
||||
],
|
||||
|
||||
verifyCredentials,
|
||||
isStillVerified,
|
||||
};
|
9
packages/backend/src/apps/ntfy/auth/is-still-verified.ts
Normal file
9
packages/backend/src/apps/ntfy/auth/is-still-verified.ts
Normal file
@@ -0,0 +1,9 @@
|
||||
import { IGlobalVariable } from '@automatisch/types';
|
||||
import verifyCredentials from './verify-credentials';
|
||||
|
||||
const isStillVerified = async ($: IGlobalVariable) => {
|
||||
await verifyCredentials($);
|
||||
return true;
|
||||
};
|
||||
|
||||
export default isStillVerified;
|
16
packages/backend/src/apps/ntfy/auth/verify-credentials.ts
Normal file
16
packages/backend/src/apps/ntfy/auth/verify-credentials.ts
Normal file
@@ -0,0 +1,16 @@
|
||||
import { IGlobalVariable } from '@automatisch/types';
|
||||
|
||||
const verifyCredentials = async ($: IGlobalVariable) => {
|
||||
await $.http.post('/', { topic: 'automatisch' });
|
||||
let screenName = $.auth.data.serverUrl;
|
||||
|
||||
if ($.auth.data.username) {
|
||||
screenName = `${$.auth.data.username} @ ${screenName}`
|
||||
}
|
||||
|
||||
await $.auth.set({
|
||||
screenName,
|
||||
});
|
||||
};
|
||||
|
||||
export default verifyCredentials;
|
18
packages/backend/src/apps/ntfy/common/add-auth-header.ts
Normal file
18
packages/backend/src/apps/ntfy/common/add-auth-header.ts
Normal file
@@ -0,0 +1,18 @@
|
||||
import { TBeforeRequest } from '@automatisch/types';
|
||||
|
||||
const addAuthHeader: TBeforeRequest = ($, requestConfig) => {
|
||||
if ($.auth.data.apiBaseUrl) {
|
||||
requestConfig.baseURL = $.auth.data.apiBaseUrl as string;
|
||||
}
|
||||
|
||||
if ($.auth.data?.username && $.auth.data?.password) {
|
||||
requestConfig.auth = {
|
||||
username: $.auth.data.username as string,
|
||||
password: $.auth.data.password as string,
|
||||
}
|
||||
}
|
||||
|
||||
return requestConfig;
|
||||
};
|
||||
|
||||
export default addAuthHeader;
|
0
packages/backend/src/apps/ntfy/index.d.ts
vendored
Normal file
0
packages/backend/src/apps/ntfy/index.d.ts
vendored
Normal file
18
packages/backend/src/apps/ntfy/index.ts
Normal file
18
packages/backend/src/apps/ntfy/index.ts
Normal file
@@ -0,0 +1,18 @@
|
||||
import defineApp from '../../helpers/define-app';
|
||||
import addAuthHeader from './common/add-auth-header';
|
||||
import auth from './auth';
|
||||
import actions from './actions';
|
||||
|
||||
export default defineApp({
|
||||
name: 'Ntfy',
|
||||
key: 'ntfy',
|
||||
iconUrl: '{BASE_URL}/apps/ntfy/assets/favicon.svg',
|
||||
authDocUrl: 'https://automatisch.io/docs/apps/ntfy/connection',
|
||||
supportsConnections: true,
|
||||
baseUrl: 'https://ntfy.sh',
|
||||
apiBaseUrl: 'https://ntfy.sh',
|
||||
primaryColor: '56bda8',
|
||||
beforeRequest: [addAuthHeader],
|
||||
auth,
|
||||
actions,
|
||||
});
|
@@ -69,6 +69,14 @@ export default defineConfig({
|
||||
{ text: 'Connection', link: '/apps/github/connection' },
|
||||
],
|
||||
},
|
||||
{
|
||||
text: 'Ntfy',
|
||||
collapsible: true,
|
||||
items: [
|
||||
{ text: 'Actions', link: '/apps/ntfy/actions' },
|
||||
{ text: 'Connection', link: '/apps/ntfy/connection' },
|
||||
],
|
||||
},
|
||||
{
|
||||
text: 'RSS',
|
||||
collapsible: true,
|
||||
|
12
packages/docs/pages/apps/ntfy/actions.md
Normal file
12
packages/docs/pages/apps/ntfy/actions.md
Normal file
@@ -0,0 +1,12 @@
|
||||
---
|
||||
favicon: /favicons/ntfy.svg
|
||||
items:
|
||||
- name: Send a message
|
||||
desc: Sends a message to a topic you specify.
|
||||
---
|
||||
|
||||
<script setup>
|
||||
import CustomListing from '../../components/CustomListing.vue'
|
||||
</script>
|
||||
|
||||
<CustomListing />
|
10
packages/docs/pages/apps/ntfy/connection.md
Normal file
10
packages/docs/pages/apps/ntfy/connection.md
Normal file
@@ -0,0 +1,10 @@
|
||||
# Ntfy
|
||||
|
||||
:::info
|
||||
This page explains the steps you need to follow to set up the Ntfy
|
||||
connection in Automatisch. If any of the steps are outdated, please let us know!
|
||||
:::
|
||||
|
||||
If you use ntfy.sh, the official public server for this service, you do not need to set up a connection with a custom configuration. It's enough to create one with the default server URL.
|
||||
|
||||
However, if you have a ntfy installation, that's different than ntfy.sh, you need to specify your server URL on Automatisch while creating a connection. Additionally, you may need to provide your username and password if your installation requires authentication.
|
@@ -11,6 +11,7 @@ Following integrations are currently supported by Automatisch.
|
||||
- [Flickr](/apps/flickr/triggers)
|
||||
- [Github](/apps/github/triggers)
|
||||
- [RSS](/apps/rss/triggers)
|
||||
- [Ntfy](/apps/ntfy/triggers)
|
||||
- [Salesforce](/apps/salesforce/triggers)
|
||||
- [Scheduler](/apps/scheduler/triggers)
|
||||
- [Slack](/apps/slack/actions)
|
||||
|
1
packages/docs/pages/public/favicons/ntfy.svg
Normal file
1
packages/docs/pages/public/favicons/ntfy.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg width="50mm" height="50mm" viewBox="0 0 50 50" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg"><defs><linearGradient id="a"><stop style="stop-color:#348878;stop-opacity:1" offset="0"/><stop style="stop-color:#56bda8;stop-opacity:1" offset="1"/></linearGradient><linearGradient xlink:href="#a" id="b" x1="160.722" y1="128.533" x2="168.412" y2="134.326" gradientUnits="userSpaceOnUse" gradientTransform="translate(-845.726 -630.598) scale(5.59448)"/></defs><g style="display:inline"><path style="color:#000;fill:url(#b);stroke:none;stroke-width:3.72347;-inkscape-stroke:none" d="M94.237 89.912H59.499c-2.388 0-4.342 1.844-4.342 4.098l.033 27.754-.648 3.738 9.297-2.806h30.396c2.388 0 4.342-1.845 4.342-4.099V94.01c0-2.254-1.954-4.098-4.342-4.098z" transform="translate(-51.147 -81.516)"/><path style="color:#000;fill:#fff;stroke:none;stroke-width:.762343;-inkscape-stroke:none" d="M58.849 86.79c-3.62 0-6.72 2.848-6.72 6.47v.002l.035 30.273-.91 6.708 12.362-3.284h30.729c3.62 0 6.72-2.852 6.72-6.473V93.26c0-3.62-3.099-6.469-6.717-6.469h-.003zm0 4.566h35.499c1.272 0 2.151.927 2.151 1.903v27.227c0 .977-.88 1.924-2.154 1.903h-31.4l-6.28 1.898.065-.37-.035-30.658c0-.977.88-1.903 2.154-1.903z" transform="translate(-51.147 -81.516)"/><g style="font-size:8.48274px;font-family:sans-serif;letter-spacing:0;word-spacing:0;fill:#000;stroke:none;stroke-width:.525121"><path style="color:#000;-inkscape-font-specification:'JetBrains Mono, Bold';fill:#fff;stroke:none;-inkscape-stroke:none" d="M62.57 116.77v-1.312l3.28-1.459q.159-.068.306-.102.158-.045.283-.068l.271-.022v-.09q-.136-.012-.271-.046-.125-.023-.283-.057-.147-.045-.306-.113l-3.28-1.459v-1.323l5.068 2.319v1.413z" transform="matrix(2.1689 0 0 2.57844 -124.28 -268.742)"/><path style="color:#000;-inkscape-font-specification:'JetBrains Mono, Bold';fill:#fff;stroke:none;-inkscape-stroke:none" d="M62.309 110.31v1.903l3.437 1.53.022.007-.022.008-3.437 1.53v1.892l.37-.17 5.221-2.39v-1.75zm.525.817 4.541 2.08v1.076l-4.541 2.078v-.732l3.12-1.389.003-.002a1.56 1.56 0 0 1 .258-.086h.006l.008-.002c.094-.027.176-.047.246-.06l.498-.041v-.574l-.24-.02a1.411 1.411 0 0 1-.231-.04l-.008-.001-.008-.002a9.077 9.077 0 0 1-.263-.053 2.781 2.781 0 0 1-.266-.097l-.004-.002-3.119-1.39z" transform="matrix(2.1689 0 0 2.57844 -124.28 -268.742)"/></g><g style="font-size:8.48274px;font-family:sans-serif;letter-spacing:0;word-spacing:0;fill:#000;stroke:none;stroke-width:.525121"><path style="color:#000;-inkscape-font-specification:'JetBrains Mono, Bold';fill:#fff;stroke:none;-inkscape-stroke:none" d="M69.171 117.754h5.43v1.278h-5.43Z" transform="matrix(2.16247 0 0 2.48294 -122.76 -261.211)"/><path style="color:#000;-inkscape-font-specification:'JetBrains Mono, Bold';fill:#fff;stroke:none;-inkscape-stroke:none" d="M68.908 117.492v1.802h5.955v-1.802zm.526.524h4.904v.754h-4.904z" transform="matrix(2.16247 0 0 2.48294 -122.76 -261.211)"/></g></g></svg>
|
After Width: | Height: | Size: 2.9 KiB |
Reference in New Issue
Block a user