2020-10-21 14:30:07 -07:00
import {
IExecuteFunctions ,
} from 'n8n-core' ;
import {
IBinaryData ,
IBinaryKeyData ,
IDataObject ,
2020-10-21 14:32:07 -07:00
ILoadOptionsFunctions ,
2020-10-21 14:30:07 -07:00
INodeExecutionData ,
2020-10-21 14:32:07 -07:00
INodePropertyOptions ,
2020-10-21 14:30:07 -07:00
INodeType ,
INodeTypeDescription ,
2021-04-16 09:33:36 -07:00
NodeOperationError ,
2020-10-21 14:30:07 -07:00
} from 'n8n-workflow' ;
import {
pushoverApiRequest ,
} from './GenericFunctions' ;
export class Pushover implements INodeType {
description : INodeTypeDescription = {
displayName : 'Pushover' ,
name : 'pushover' ,
2022-05-07 04:25:53 -07:00
icon : 'file:pushover.svg' ,
2020-10-21 14:30:07 -07:00
group : [ 'input' ] ,
version : 1 ,
subtitle : '={{$parameter["operation"] + ": " + $parameter["resource"]}}' ,
2021-07-03 05:40:16 -07:00
description : 'Consume Pushover API' ,
2020-10-21 14:30:07 -07:00
defaults : {
name : 'Pushover' ,
} ,
inputs : [ 'main' ] ,
outputs : [ 'main' ] ,
credentials : [
{
name : 'pushoverApi' ,
required : true ,
} ,
] ,
properties : [
{
displayName : 'Resource' ,
name : 'resource' ,
type : 'options' ,
2022-05-07 04:25:53 -07:00
noDataExpression : true ,
2020-10-21 14:30:07 -07:00
options : [
{
name : 'Message' ,
value : 'message' ,
} ,
] ,
default : 'message' ,
} ,
{
displayName : 'Operation' ,
name : 'operation' ,
type : 'options' ,
2022-05-07 04:25:53 -07:00
noDataExpression : true ,
2020-10-21 14:30:07 -07:00
displayOptions : {
show : {
resource : [
'message' ,
] ,
} ,
} ,
options : [
{
name : 'Push' ,
value : 'push' ,
2022-07-10 13:50:51 -07:00
action : 'Push a message' ,
2020-10-21 14:30:07 -07:00
} ,
] ,
default : 'push' ,
} ,
{
displayName : 'User Key' ,
name : 'userKey' ,
type : 'string' ,
required : true ,
displayOptions : {
show : {
resource : [
'message' ,
] ,
operation : [
'push' ,
] ,
} ,
} ,
default : '' ,
2022-05-06 14:01:25 -07:00
description : 'The user/group key (not e-mail address) of your user (or you), viewable when logged into the <a href="https://pushover.net/">dashboard</a> (often referred to as <code>USER_KEY</code> in the <a href="https://support.pushover.net/i44-example-code-and-pushover-libraries">libraries</a> and code examples)' ,
2020-10-21 14:30:07 -07:00
} ,
{
displayName : 'Message' ,
name : 'message' ,
type : 'string' ,
required : true ,
displayOptions : {
show : {
resource : [
'message' ,
] ,
operation : [
'push' ,
] ,
} ,
} ,
default : '' ,
2022-05-06 14:01:25 -07:00
description : 'Your message' ,
2020-10-21 14:30:07 -07:00
} ,
2022-04-22 09:29:51 -07:00
// eslint-disable-next-line n8n-nodes-base/node-param-default-missing
2020-10-21 14:30:07 -07:00
{
displayName : 'Priority' ,
name : 'priority' ,
type : 'options' ,
displayOptions : {
show : {
resource : [
'message' ,
] ,
operation : [
'push' ,
] ,
} ,
} ,
2022-06-03 10:23:49 -07:00
// eslint-disable-next-line n8n-nodes-base/node-param-options-type-unsorted-items
2020-10-21 14:30:07 -07:00
options : [
{
name : 'Lowest Priority' ,
value : - 2 ,
} ,
{
name : 'Low Priority' ,
value : - 1 ,
} ,
{
name : 'Normal Priority' ,
value : 0 ,
} ,
{
name : 'High Priority' ,
value : 1 ,
} ,
{
name : 'Emergency Priority' ,
value : 2 ,
} ,
] ,
default : - 2 ,
2022-05-06 14:01:25 -07:00
description : 'Send as -2 to generate no notification/alert, -1 to always send as a quiet notification, 1 to display as high-priority and bypass the user\'s quiet hours, or 2 to also require confirmation from the user' ,
2020-10-21 14:30:07 -07:00
} ,
{
2022-05-07 04:25:53 -07:00
displayName : 'Retry (Seconds)' ,
2020-10-21 14:30:07 -07:00
name : 'retry' ,
type : 'number' ,
typeOptions : {
minValue : 0 ,
} ,
required : true ,
displayOptions : {
show : {
resource : [
'message' ,
] ,
operation : [
'push' ,
] ,
priority : [
2 ,
] ,
} ,
} ,
default : 30 ,
2022-05-06 14:01:25 -07:00
description : 'Specifies how often (in seconds) the Pushover servers will send the same notification to the user. This parameter must have a value of at least 30 seconds between retries.' ,
2020-10-21 14:30:07 -07:00
} ,
{
2022-05-07 04:25:53 -07:00
displayName : 'Expire (Seconds)' ,
2020-10-21 14:30:07 -07:00
name : 'expire' ,
type : 'number' ,
typeOptions : {
minValue : 0 ,
maxValue : 10800 ,
} ,
required : true ,
displayOptions : {
show : {
resource : [
'message' ,
] ,
operation : [
'push' ,
] ,
priority : [
2 ,
] ,
} ,
} ,
default : 30 ,
2022-05-06 14:01:25 -07:00
description : 'Specifies how many seconds your notification will continue to be retried for (every retry seconds)' ,
2020-10-21 14:30:07 -07:00
} ,
{
displayName : 'Additional Fields' ,
name : 'additionalFields' ,
type : 'collection' ,
placeholder : 'Add Field' ,
displayOptions : {
show : {
resource : [
'message' ,
] ,
operation : [
'push' ,
] ,
} ,
} ,
default : { } ,
options : [
{
displayName : 'Attachment' ,
name : 'attachmentsUi' ,
placeholder : 'Add Attachments' ,
type : 'fixedCollection' ,
typeOptions : {
multipleValues : false ,
} ,
options : [
{
name : 'attachmentsValues' ,
displayName : 'Attachment Property' ,
values : [
{
displayName : 'Binary Property' ,
name : 'binaryPropertyName' ,
type : 'string' ,
default : '' ,
placeholder : 'data' ,
description : 'Name of the binary properties which contain data which should be added to email as attachment' ,
} ,
] ,
} ,
] ,
2022-04-22 09:29:51 -07:00
default : { } ,
2020-10-21 14:30:07 -07:00
} ,
{
displayName : 'Device' ,
name : 'device' ,
type : 'string' ,
default : '' ,
2022-05-06 14:01:25 -07:00
description : 'Your user\'s device name to send the message directly to that device, rather than all of the user\'s devices (multiple devices may be separated by a comma)' ,
2020-10-21 14:30:07 -07:00
} ,
2022-05-07 04:25:53 -07:00
{
displayName : 'HTML Formatting' ,
name : 'html' ,
type : 'boolean' ,
default : false ,
description : 'Whether to enable messages formatting with HTML tags' ,
} ,
2020-10-21 14:30:07 -07:00
{
2022-06-03 10:23:49 -07:00
displayName : 'Sound Name or ID' ,
2020-10-21 14:30:07 -07:00
name : 'sound' ,
type : 'options' ,
typeOptions : {
loadOptionsMethod : 'getSounds' ,
} ,
default : '' ,
2022-06-03 10:23:49 -07:00
description : 'The name of one of the sounds supported by device clients to override the user\'s default sound choice. Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/nodes/expressions.html#expressions">expression</a>.' ,
2020-10-21 14:30:07 -07:00
} ,
2022-05-07 04:25:53 -07:00
{
displayName : 'Timestamp' ,
name : 'timestamp' ,
type : 'dateTime' ,
default : '' ,
description : 'A Unix timestamp of your message\'s date and time to display to the user, rather than the time your message is received by our API' ,
} ,
2020-10-21 14:30:07 -07:00
{
displayName : 'Title' ,
name : 'title' ,
type : 'string' ,
default : '' ,
2022-05-06 14:01:25 -07:00
description : 'Your message\'s title, otherwise your app\'s name is used' ,
2020-10-21 14:30:07 -07:00
} ,
{
displayName : 'Timestamp' ,
name : 'timestamp' ,
type : 'dateTime' ,
default : '' ,
2022-05-06 14:01:25 -07:00
description : 'A Unix timestamp of your message\'s date and time to display to the user, rather than the time your message is received by our API' ,
2020-10-21 14:30:07 -07:00
} ,
{
displayName : 'URL' ,
name : 'url' ,
type : 'string' ,
default : '' ,
2022-05-07 04:25:53 -07:00
description : 'A supplementary URL to show with your message' ,
2020-10-21 14:30:07 -07:00
} ,
{
displayName : 'URL Title' ,
name : 'url_title' ,
type : 'string' ,
default : '' ,
2022-05-06 14:01:25 -07:00
description : 'A title for your supplementary URL, otherwise just the URL is shown' ,
2020-10-21 14:30:07 -07:00
} ,
] ,
} ,
] ,
} ;
methods = {
loadOptions : {
async getSounds ( this : ILoadOptionsFunctions ) : Promise < INodePropertyOptions [ ] > {
const { sounds } = await pushoverApiRequest . call ( this , 'GET' , '/sounds.json' , { } ) ;
const returnData : INodePropertyOptions [ ] = [ ] ;
for ( const key of Object . keys ( sounds ) ) {
returnData . push ( {
name : sounds [ key ] ,
value : key ,
} ) ;
}
return returnData ;
} ,
} ,
} ;
async execute ( this : IExecuteFunctions ) : Promise < INodeExecutionData [ ] [ ] > {
const items = this . getInputData ( ) ;
const returnData : IDataObject [ ] = [ ] ;
2022-04-22 09:29:51 -07:00
const length = items . length ;
2020-10-21 14:30:07 -07:00
const qs : IDataObject = { } ;
let responseData ;
const resource = this . getNodeParameter ( 'resource' , 0 ) as string ;
const operation = this . getNodeParameter ( 'operation' , 0 ) as string ;
for ( let i = 0 ; i < length ; i ++ ) {
2021-07-19 23:58:54 -07:00
try {
if ( resource === 'message' ) {
if ( operation === 'push' ) {
const userKey = this . getNodeParameter ( 'userKey' , i ) as string ;
2020-10-21 14:30:07 -07:00
2021-07-19 23:58:54 -07:00
const message = this . getNodeParameter ( 'message' , i ) as string ;
2020-10-21 14:30:07 -07:00
2021-07-19 23:58:54 -07:00
const priority = this . getNodeParameter ( 'priority' , i ) as number ;
2020-10-21 14:30:07 -07:00
2021-07-19 23:58:54 -07:00
const additionalFields = this . getNodeParameter ( 'additionalFields' , i ) as IDataObject ;
2020-10-21 14:30:07 -07:00
2022-05-07 04:25:53 -07:00
if ( additionalFields . html !== undefined ) {
additionalFields . html = additionalFields . html ? '1' : '' ;
}
2021-07-19 23:58:54 -07:00
const body : IDataObject = {
user : userKey ,
message ,
priority ,
} ;
2020-10-21 14:30:07 -07:00
2021-07-19 23:58:54 -07:00
if ( priority === 2 ) {
body . retry = this . getNodeParameter ( 'retry' , i ) as number ;
2020-10-21 14:30:07 -07:00
2021-07-19 23:58:54 -07:00
body . expire = this . getNodeParameter ( 'expire' , i ) as number ;
}
2020-10-21 14:30:07 -07:00
2021-07-19 23:58:54 -07:00
Object . assign ( body , additionalFields ) ;
2020-10-21 14:30:07 -07:00
2021-07-19 23:58:54 -07:00
if ( body . attachmentsUi ) {
const attachment = ( body . attachmentsUi as IDataObject ) . attachmentsValues as IDataObject ;
2020-10-21 14:30:07 -07:00
2021-07-19 23:58:54 -07:00
if ( attachment ) {
2020-10-21 14:30:07 -07:00
2021-07-19 23:58:54 -07:00
const binaryPropertyName = attachment . binaryPropertyName as string ;
2020-10-21 14:30:07 -07:00
2021-07-19 23:58:54 -07:00
if ( items [ i ] . binary === undefined ) {
2022-07-12 08:51:01 -07:00
throw new NodeOperationError ( this . getNode ( ) , 'No binary data exists on item!' , { itemIndex : i } ) ;
2021-07-19 23:58:54 -07:00
}
2020-10-21 14:30:07 -07:00
2021-07-19 23:58:54 -07:00
const item = items [ i ] . binary as IBinaryKeyData ;
2020-10-21 14:30:07 -07:00
2021-07-19 23:58:54 -07:00
const binaryData = item [ binaryPropertyName ] as IBinaryData ;
2020-10-21 14:30:07 -07:00
2021-07-19 23:58:54 -07:00
if ( binaryData === undefined ) {
2022-07-12 08:51:01 -07:00
throw new NodeOperationError ( this . getNode ( ) , ` No binary data property " ${ binaryPropertyName } " does not exists on item! ` , { itemIndex : i } ) ;
2021-07-19 23:58:54 -07:00
}
2020-10-21 14:30:07 -07:00
2021-08-20 09:08:40 -07:00
const dataBuffer = await this . helpers . getBinaryDataBuffer ( i , binaryPropertyName ) ;
2021-07-19 23:58:54 -07:00
body . attachment = {
2021-08-20 09:08:40 -07:00
value : dataBuffer ,
2021-07-19 23:58:54 -07:00
options : {
filename : binaryData.fileName ,
} ,
} ;
2020-10-21 14:30:07 -07:00
2021-07-19 23:58:54 -07:00
delete body . attachmentsUi ;
}
2020-10-21 14:30:07 -07:00
}
2021-07-19 23:58:54 -07:00
responseData = await pushoverApiRequest . call (
this ,
'POST' ,
` /messages.json ` ,
body ,
) ;
}
}
} catch ( error ) {
if ( this . continueOnFail ( ) ) {
returnData . push ( { error : error.message } ) ;
continue ;
2020-10-21 14:30:07 -07:00
}
2021-07-19 23:58:54 -07:00
throw error ;
2020-10-21 14:30:07 -07:00
}
}
if ( Array . isArray ( responseData ) ) {
returnData . push . apply ( returnData , responseData as IDataObject [ ] ) ;
} else if ( responseData !== undefined ) {
returnData . push ( responseData as IDataObject ) ;
}
return [ this . helpers . returnJsonArray ( returnData ) ] ;
}
}