mirror of
https://github.com/node-red/node-red-nodes.git
synced 2025-03-01 10:37:43 +00:00
Updated pushbullet node with all push types, added new "pushbullet in" that emits pushes. Added unit tests.
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
<!--
|
||||
Copyright 2013 IBM Corp.
|
||||
Copyright 2013,2015 IBM Corp.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
@@ -14,94 +14,353 @@
|
||||
limitations under the License.
|
||||
-->
|
||||
|
||||
<!-- PUSHBULLET CONFIG -->
|
||||
|
||||
<script type="text/x-red" data-template-name="pushbullet-config">
|
||||
<div class="form-row">
|
||||
<label for="node-config-input-name"><i class="fa fa-tag"></i> Name</label>
|
||||
<input type="text" id="node-config-input-name" placeholder="Name">
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="node-config-input-apikey"><i class="fa fa-lock"></i> API-key</label>
|
||||
<input type="password" id="node-config-input-apikey">
|
||||
</div>
|
||||
</script>
|
||||
|
||||
<script type="text/javascript">
|
||||
RED.nodes.registerType('pushbullet-config', {
|
||||
category: 'config',
|
||||
color: "rgb(218, 196, 180)",
|
||||
defaults: {
|
||||
name: {value: ""}
|
||||
},
|
||||
credentials: {
|
||||
apikey: {type: "password"}
|
||||
},
|
||||
label: function() {
|
||||
return this.name || "Pushbullet config";
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<!-- PUSHBULLET OUT -->
|
||||
|
||||
<script type="text/x-red" data-template-name="pushbullet">
|
||||
<div class="form-row">
|
||||
<label for="node-input-title"><i class="fa fa-flag"></i> Title</label>
|
||||
<input type="text" id="node-input-title" placeholder="Node-RED">
|
||||
<label for="node-input-config"><i class="fa fa-user"></i> Config</label>
|
||||
<input type="text" id="node-input-config">
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="node-input-deviceid"><i class="fa fa-mobile"></i> Device ID</label>
|
||||
<select id="node-input-deviceid">
|
||||
<option value="">All</option>
|
||||
<option value="_msg_">- set from msg.deviceid -</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="node-input-chan"><i class="fa fa-random"></i> Channel</label>
|
||||
<input type="text" id="node-input-chan" placeholder="channel name">
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="node-config-input-deviceid"><i class="fa fa-user"></i> Device ID</label>
|
||||
<input type="text" id="node-config-input-deviceid">
|
||||
<label for="node-input-pushtype"><i class="fa fa-dot-circle-o"></i> Type</label>
|
||||
<select id="node-input-pushtype">
|
||||
<optgroup label="Push types">
|
||||
<option value="address">Address</option>
|
||||
<option value="file">File</option>
|
||||
<option value="link">Link</option>
|
||||
<option value="list">List</option>
|
||||
<option value="note">Note</option>
|
||||
<option value="">- set from msg.pushtype -</option>
|
||||
</optgroup>
|
||||
<optgroup label="Actions">
|
||||
<option value="delete">Delete push</option>
|
||||
<option value="dismissal">Dismiss push</option>
|
||||
<option value="updatelist">Update list</option>
|
||||
</optgroup>
|
||||
</select>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="node-config-input-pushkey"><i class="fa fa-lock"></i> API Key</label>
|
||||
<input type="password" id="node-config-input-pushkey">
|
||||
<label for="node-input-title"><i class="fa fa-random"></i> Title</label>
|
||||
<input type="text" id="node-input-title" placeholder="Node-RED">
|
||||
</div>
|
||||
<br/>
|
||||
<div class="form-row">
|
||||
<label for="node-input-name"><i class="fa fa-tag"></i> Name</label>
|
||||
<input type="text" id="node-input-name" placeholder="Name">
|
||||
</div>
|
||||
<div class="form-tips" id="node-tip"><b>Note:</b> Using credentials from global pushkey.js file.</div>
|
||||
<div class="form-tips" id="pushbullet-migration-info" style="display: none;">
|
||||
<p><i class="fa fa-random"></i> Configuration node has been migrated, please click Ok and then re-deploy flow to save settings.</p>
|
||||
</div>
|
||||
</script>
|
||||
|
||||
<script type="text/x-red" data-help-name="pushbullet">
|
||||
<p>Uses PushBullet to push the <b>msg.payload</b> to a device that has the PushBullet app installed.</p>
|
||||
<p>Optionally uses <b>msg.topic</b> to set the title, if not already set in the properties.</p>
|
||||
<p>You need to configure both your <i>API key</i> and the target <i>device ID</i>.
|
||||
The device ID may be passed in as <b>msg.deviceid</b>.</p>
|
||||
<p>You can also push to any channels that you own either configured or via <b>msg.channel</b>.</p>
|
||||
The old method of storing your credentials in the pushkey.js file in the directory <b>above</b> /node-red is deprecated.</p>
|
||||
<p>The deviceid can be found by clicking on your required device on the <a href="https://www.pushbullet.com/">PushBullet website</a>, once you have logged in.</p>
|
||||
<p>Uses PushBullet to push <code>msg.payload</code> to a device that has the PushBullet app installed.</p>
|
||||
<p>Optionally uses <code>msg.topic</code> to set the title, if not already set in the properties.</p>
|
||||
<p>Optionally uses <code>msg.pushtype</code> to set the type of the push, if not already set in the properties.</p>
|
||||
<p>Optionally uses <code>msg.deviceid</code> to set the device ID, if not already set in the properties.</p>
|
||||
<p>You can also push to any channels that you own either configured or via <code>msg.channel</code>.</p>
|
||||
<p>The node can also <i>dismiss</i> and <i>delete</i> and <i>update</i> items in a pushed list. In this case <code>msg.data.iden</code> must be set to a valid push id, if <code>msg</code> originates from the Pushbullet input node this value is already set.</p>
|
||||
<p>The old method of storing your credentials in the pushkey.js file in the directory above /node-red is deprecated.</p>
|
||||
</script>
|
||||
|
||||
<script type="text/javascript">
|
||||
RED.nodes.registerType('pushbullet',{
|
||||
category: 'output',
|
||||
category: 'social-output',
|
||||
defaults: {
|
||||
config: {type: "pushbullet-config", required: true},
|
||||
pushtype: {value:"note"},
|
||||
title: {value:""},
|
||||
chan: {value:"" },
|
||||
name: {value:""}
|
||||
},
|
||||
credentials: {
|
||||
deviceid: {value: ""},
|
||||
pushkey: {value: ""}
|
||||
},
|
||||
color:"#a7c9a0",
|
||||
inputs:1,
|
||||
outputs:0,
|
||||
icon: "bullet.png",
|
||||
align: "right",
|
||||
label: function() {
|
||||
return this.name||this.title||"pushbullet";
|
||||
var self = this;
|
||||
function getName(deviceid) {
|
||||
if(!self.devicename && deviceid && self.config) {
|
||||
$.getJSON('pushbullet/'+self.config+'/devices', function(data) {
|
||||
for(var i=0; i<data.length; i++) {
|
||||
if(data[i].iden === deviceid) {
|
||||
self.devicename = data[i].nickname;
|
||||
self.dirty = true;
|
||||
RED.view.redraw();
|
||||
return;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
getName(this.credentials.deviceid);
|
||||
}
|
||||
catch(err) {
|
||||
$.getJSON('credentials/pushbullet/'+this.id, function(data) {
|
||||
getName(data.deviceid);
|
||||
});
|
||||
}
|
||||
|
||||
return this.name||this.devicename||this.title||"pushbullet";
|
||||
},
|
||||
labelStyle: function() {
|
||||
return this.name?"node_label_italic":"";
|
||||
},
|
||||
oneditsave: function() {
|
||||
this.devicename = undefined;
|
||||
if(this.migrationData) {
|
||||
$.ajax('pushbullet/'+this.id+'/migrate?save=true');
|
||||
}
|
||||
},
|
||||
oneditprepare: function() {
|
||||
var node = this, ddConfig = $('#node-input-config'), ddDevice = $('#node-input-deviceid'), ddPushtype = $('#node-input-pushtype');
|
||||
|
||||
function updateDeviceList() {
|
||||
if(!ddConfig.val()) {
|
||||
ddDevice.children().remove();
|
||||
ddDevice.append('<option value="">All</option>')
|
||||
ddDevice.append('<option value="_msg_">- set from msg.deviceid -</option>')
|
||||
var currentDevice;
|
||||
if(node.credentials) {
|
||||
currentDevice = node.credentials.deviceid;
|
||||
}
|
||||
if(currentDevice && currentDevice !== "_msg_") {
|
||||
ddDevice.append('<option value="'+currentDevice+'">'+currentDevice+'</option>');
|
||||
ddDevice.val(currentDevice);
|
||||
}
|
||||
}
|
||||
else {
|
||||
var config = RED.nodes.node(ddConfig.val()),
|
||||
url = 'pushbullet/'+ddConfig.val()+'/devices';
|
||||
if(config && config.credentials && config.credentials.apikey) {
|
||||
url += '?apikey='+config.credentials.apikey;
|
||||
}
|
||||
$.getJSON(url, function(data) {
|
||||
ddDevice.children().remove();
|
||||
ddDevice.append('<option value="">All</option>')
|
||||
ddDevice.append('<option value="_msg_">- set from msg.deviceid -</option>')
|
||||
var currentDevice, addCurrent = true;
|
||||
if(node.credentials) {
|
||||
currentDevice = node.credentials.deviceid;
|
||||
}
|
||||
for(var i=0; i<data.length; i++) {
|
||||
var dev = data[i];
|
||||
ddDevice.append('<option value="'+dev.iden+'">'+dev.nickname+' ('+dev.kind+')</option>');
|
||||
if(dev.iden === currentDevice) {
|
||||
addCurrent = false;
|
||||
}
|
||||
}
|
||||
|
||||
if(currentDevice) {
|
||||
if(addCurrent && currentDevice !== "_msg_") {
|
||||
ddDevice.append('<option value="'+currentDevice+'">'+currentDevice+'</option>');
|
||||
}
|
||||
ddDevice.val(currentDevice);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function checkMigration(cb) {
|
||||
$.getJSON('pushbullet/'+node.id+'/migrate', function(data) {
|
||||
var showMigration = false;
|
||||
node.migrationData = data.config;
|
||||
if(data.migrated) {
|
||||
if(data.config) {
|
||||
var configId = data.config;
|
||||
var configType = 'pushbullet-config';
|
||||
var configTypeDef = RED.nodes.getType(configType);
|
||||
RED.nodes.add({
|
||||
type: configType,
|
||||
id: configId,
|
||||
name: "Imported",
|
||||
users: [node.id],
|
||||
label: configTypeDef.label,
|
||||
_def: configTypeDef,
|
||||
});
|
||||
}
|
||||
if(node.credentials) {
|
||||
if(node.credentials.pushkey) {
|
||||
if(ddConfig.find('option[value="'+data.config+'"]').length === 0) {
|
||||
ddConfig.append('<option value="'+data.config+'">Imported</option>');
|
||||
}
|
||||
ddConfig.val(data.config);
|
||||
showMigration = true;
|
||||
}
|
||||
else {
|
||||
ddConfig.val("_ADD_");
|
||||
}
|
||||
|
||||
if(node.credentials.deviceid) {
|
||||
ddDevice.append('<option value="'+node.credentials.deviceid+'">Imported</option>');
|
||||
ddDevice.val(node.credentials.deviceid);
|
||||
showMigration = true;
|
||||
}
|
||||
else {
|
||||
ddDevice.val("");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(showMigration) {
|
||||
ddPushtype.val("note");
|
||||
node.dirty = true;
|
||||
$('#pushbullet-migration-info').show();
|
||||
}
|
||||
if(cb) {
|
||||
cb(showMigration);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
checkMigration(function(migrated) {
|
||||
if(!migrated) {
|
||||
ddConfig.change(function() {
|
||||
if(ddConfig.val() && ddConfig.val() !== "_ADD_") {
|
||||
updateDeviceList();
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<!-- PUSHBULLET IN -->
|
||||
|
||||
<script type="text/x-red" data-template-name="pushbullet in">
|
||||
<div class="form-row">
|
||||
<label for="node-input-config"><i class="fa fa-user"></i> Config</label>
|
||||
<input type="text" id="node-input-config" placeholder="Node-RED">
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="node-input-filters"><i class="fa fa-mobile"></i> Device filter</label>
|
||||
<select id="node-input-filters" style="width: 60%;" multiple="multiple"></select>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="node-input-name"><i class="fa fa-tag"></i> Name</label>
|
||||
<input type="text" id="node-input-name" placeholder="Name">
|
||||
</div>
|
||||
<div class="form-tips">
|
||||
<i class="fa fa-mobile"></i> Device filter list is multi-selectable. No selections means no filtering, i.e. all pushes are emitted.
|
||||
</div>
|
||||
</script>
|
||||
|
||||
<script type="text/x-red" data-help-name="pushbullet in">
|
||||
<p>Receives Pushbullets from all devices. Messages contain the following data:</p>
|
||||
<p><code>msg.pushtype</code>: type of message</p>
|
||||
<p><code>msg.topic</code>: topic information from the push</p>
|
||||
<p><code>msg.payload</code>: main content of the push</p>
|
||||
<p><code>msg.data</code>: original object from the pushbullet API containing e.g. sender, receiver and message ids.</p>
|
||||
<p>Pushes of type <i>link</i> and <i>file</i> will also have <code>msg.message</code> containing the message associated with the push.</p>
|
||||
<p>For further details of see <a href="https://docs.pushbullet.com/stream/">Pushbullet Stream API</a> and <a href="https://docs.pushbullet.com/v2/pushes/">Pushbullet Push API</a>.</p>
|
||||
</script>
|
||||
|
||||
<script type="text/javascript">
|
||||
RED.nodes.registerType('pushbullet in',{
|
||||
category: 'social-input',
|
||||
defaults: {
|
||||
config: {type: "pushbullet-config", required: true},
|
||||
name: {value:""}
|
||||
},
|
||||
credentials: {
|
||||
filters: {value: []}
|
||||
},
|
||||
color:"#a7c9a0",
|
||||
inputs:0,
|
||||
outputs:1,
|
||||
icon: "bullet.png",
|
||||
label: function() {
|
||||
return this.name||"pushbullet";
|
||||
},
|
||||
labelStyle: function() {
|
||||
return this.name?"node_label_italic":"";
|
||||
},
|
||||
oneditprepare: function() {
|
||||
$.getJSON('pushbullet/'+this.id,function(data) {
|
||||
if (data.deviceid) {
|
||||
$('#node-config-input-deviceid').val(data.deviceid);
|
||||
var node = this, ddConfig = $('#node-input-config'), ddDevice = $('#node-input-filters');
|
||||
|
||||
function updateDeviceList() {
|
||||
var config = RED.nodes.node(ddConfig.val()),
|
||||
url = 'pushbullet/'+ddConfig.val()+'/devices';
|
||||
if(config && config.credentials && config.credentials.apikey) {
|
||||
url += '?apikey='+config.credentials.apikey;
|
||||
}
|
||||
if (data.hasPassword) {
|
||||
$('#node-config-input-pushkey').val('__PWRD__');
|
||||
} else {
|
||||
$('#node-config-input-pushkey').val('');
|
||||
}
|
||||
if (data.global) $('#node-tip').show();
|
||||
else $('#node-tip').hide();
|
||||
});
|
||||
},
|
||||
oneditsave: function() {
|
||||
var newUser = $('#node-config-input-deviceid').val();
|
||||
var newPass = $('#node-config-input-pushkey').val();
|
||||
var credentials = {};
|
||||
credentials.deviceid = newUser;
|
||||
if (newPass != '__PWRD__') {
|
||||
credentials.pushkey = newPass;
|
||||
$.getJSON(url, function(data) {
|
||||
var currentDevices = [], addDevices = [];
|
||||
if(node.credentials && node.credentials.filters) {
|
||||
currentDevices = node.credentials.filters;
|
||||
addDevices = node.credentials.filters.splice();
|
||||
}
|
||||
|
||||
var idx;
|
||||
ddDevice.children().remove();
|
||||
for(var i=0; i<data.length; i++) {
|
||||
var dev = data[i];
|
||||
ddDevice.append('<option value="'+dev.iden+'">'+dev.nickname+' ('+dev.kind+')</option>');
|
||||
|
||||
idx = addDevices.indexOf(dev.iden);
|
||||
if (idx > -1) {
|
||||
addDevices.splice(idx, 1);
|
||||
}
|
||||
}
|
||||
|
||||
for(var j=0;j<addDevices.length;j++) {
|
||||
ddDevice.append('<option value="'+addDevices[j]+'">'+addDevices[j]+'</option>');
|
||||
}
|
||||
ddDevice.val(currentDevices);
|
||||
});
|
||||
}
|
||||
$.ajax({
|
||||
url: 'pushbullet/'+this.id,
|
||||
type: 'POST',
|
||||
data: credentials,
|
||||
success:function(result){}
|
||||
});
|
||||
},
|
||||
ondelete: function() {
|
||||
$.ajax({
|
||||
url: 'pushbullet/'+this.id,
|
||||
type: 'DELETE',
|
||||
success: function(result) {}
|
||||
|
||||
ddConfig.change(function() {
|
||||
if(ddConfig.val() && ddConfig.val() !== "_ADD_") {
|
||||
updateDeviceList();
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
Reference in New Issue
Block a user