Skip to content
This repository was archived by the owner on Feb 22, 2024. It is now read-only.
Merged
4 changes: 3 additions & 1 deletion src/botPage/bot/Interface/ToolsInterface.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import CandleInterface from './CandleInterface';
import MiscInterface from './MiscInterface';
import IndicatorsInterface from './IndicatorsInterface';
import WebhookInterface from './WebhookInterface';
import { translate } from '../../../common/i18n';

// prettier-ignore
export default Interface => class extends IndicatorsInterface(
MiscInterface(CandleInterface(Interface))) {
MiscInterface(CandleInterface(WebhookInterface(Interface)))) {
getToolsInterface() {
return {
getTime : () => parseInt(new Date().getTime() / 1000),
Expand Down Expand Up @@ -76,6 +77,7 @@ export default Interface => class extends IndicatorsInterface(
...this.getCandleInterface(),
...this.getMiscInterface(),
...this.getIndicatorsInterface(),
...this.getWebhookInterface(),
};
}
};
33 changes: 33 additions & 0 deletions src/botPage/bot/Interface/WebhookInterface.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { notify } from '../broadcast';
import { translate } from '../../../common/i18n';

export default Interface =>
class extends Interface {
// eslint-disable-next-line class-methods-use-this
sendWebhook(url, payload) {
const onError = () => notify('warn', translate('Unable to send webhook'));
const fetchOption = {
method : 'POST',
mode : 'cors',
headers: { 'Content-Type': 'application/json' },
};

if (payload) {
fetchOption.body = JSON.stringify(payload);
}

fetch(url, fetchOption)
.then(response => {
if (!response.ok) {
onError();
}
})
.catch(onError);
}

getWebhookInterface() {
return {
sendWebhook: this.sendWebhook,
};
}
};
2 changes: 2 additions & 0 deletions src/botPage/view/blockly/blocks/tools/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,5 @@ import './block_holder';
import './loader';
import './candle';
import './time';
import './webhook';
import './key_value_pair';
34 changes: 34 additions & 0 deletions src/botPage/view/blockly/blocks/tools/key_value_pair.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { translate } from '../../../../../common/i18n';

Blockly.Blocks.key_value_pair = {
init() {
this.jsonInit({
message0: translate('Key: %1 Value: %2'),
args0 : [
{
type: 'field_input',
name: 'KEY',
text: 'default',
},
{
type: 'input_value',
name: 'VALUE',
},
],
colour : '#dedede',
output : null,
tooltip: translate('Returns a string representation of a key value pair'),
});
},
};

Blockly.JavaScript.key_value_pair = block => {
const key = block.getFieldValue('KEY') || '';
const value = Blockly.JavaScript.valueToCode(block, 'VALUE', Blockly.JavaScript.ORDER_ATOMIC) || null;

if (!key) {
return '';
}

return [`{"${key}":${value}}`, Blockly.JavaScript.ORDER_ATOMIC];
};
151 changes: 151 additions & 0 deletions src/botPage/view/blockly/blocks/tools/webhook.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
/* eslint-disable no-underscore-dangle */
import { translate } from '../../../../../common/i18n';
import { expectValue } from '../shared';

Blockly.Blocks.webhook = {
init() {
this.jsonInit({
message0: translate('Webhook URL: %1'),
args0 : [
{
type: 'input_value',
name: 'WEBHOOK_URL',
},
],
colour : '#dedede',
previousStatement: null,
nextStatement : null,
tooltip : translate('Sends a POST request to a URL'),
});

this.itemCount_ = 1;
this.updateShape_(false);
this.setMutator(new Blockly.Mutator(['lists_create_with_item']));
},
/**
* Create XML to represent list inputs.
* @return {!Element} XML storage element.
* @this Blockly.Block
*/
mutationToDom() {
const container = document.createElement('mutation');
container.setAttribute('items', this.itemCount_);
return container;
},
/**
* Parse XML to restore the list inputs.
* @param {!Element} xmlElement XML storage element.
* @this Blockly.Block
*/
domToMutation(xmlElement) {
this.itemCount_ = parseInt(xmlElement.getAttribute('items'));
this.updateShape_(false);
},
/**
* Populate the mutator's dialog with this block's components.
* @param {!Blockly.Workspace} workspace Mutator's workspace.
* @return {!Blockly.Block} Root block in mutator.
* @this Blockly.Block
*/
decompose(workspace) {
const containerBlock = workspace.newBlock('lists_create_with_container');
containerBlock.initSvg();

let { connection } = containerBlock.getInput('STACK');
for (let i = 0; i < this.itemCount_; i++) {
const itemBlock = workspace.newBlock('lists_create_with_item');
itemBlock.initSvg();
connection.connect(itemBlock.previousConnection);
connection = itemBlock.nextConnection;
}
return containerBlock;
},
/**
* Reconfigure this block based on the mutator dialog's components.
* @param {!Blockly.Block} containerBlock Root block in mutator.
* @this Blockly.Block
*/
compose(containerBlock) {
let itemBlock = containerBlock.getInputTargetBlock('STACK');
// Count number of inputs.
const connections = [];
while (itemBlock) {
connections.push(itemBlock.valueConnection_);
itemBlock = itemBlock.nextConnection && itemBlock.nextConnection.targetBlock();
}
this.itemCount_ = connections.length;
this.updateShape_(true);
},
/**
* Modify this block to have the correct number of inputs.
* @private
* @this Blockly.Block
*/
updateShape_(attachInput) {
if (this.itemCount_ && this.getInput('EMPTY')) {
this.removeInput('EMPTY');
} else if (!this.itemCount_ && !this.getInput('EMPTY')) {
this.appendDummyInput('EMPTY').appendField(translate('Empty payload'));
}
let i;
for (i = 0; i < this.itemCount_; i++) {
if (!this.getInput(`ADD${i}`)) {
const input = this.appendValueInput(`ADD${i}`);

if (i === 0) {
input.appendField(translate('Payload:'));
}

if (!attachInput) {
return;
}
const { connection } = input;
const keypair = this.workspace.newBlock('key_value_pair', `keyvalue${i}`);
keypair.initSvg();
keypair.render();
keypair.outputConnection.connect(connection);
}
}
// Remove deleted inputs.
while (this.getInput(`ADD${i}`)) {
this.removeInput(`ADD${i}`);
i++;
}
},
onchange: function onchange(ev) {
if (!this.workspace || this.isInFlyout || this.workspace.isDragging()) {
return;
}

if (ev.type === Blockly.Events.MOVE) {
for (let i = 0; i < this.itemCount_; i++) {
const currentBlock = this.getInputTargetBlock(`ADD${i}`);
if (currentBlock && currentBlock.type !== 'key_value_pair') {
currentBlock.unplug(true);
}
}
}
},
};

Blockly.JavaScript.webhook = block => {
const url = expectValue(block, 'WEBHOOK_URL');

if (!block.itemCount_) {
return `Bot.sendWebhook(${url}, null);\n`;
}

const keypairs = new Array(block.itemCount_);
for (let i = 0; i < block.itemCount_; i++) {
keypairs[i] = Blockly.JavaScript.valueToCode(block, `ADD${i}`, Blockly.JavaScript.ORDER_ATOMIC) || null;
}

const params = keypairs
.filter(item => item !== null)
.map(item => {
const regExp = /^{(.*?)}$/;
return item && item.match(regExp)[1];
});

return `Bot.sendWebhook(${url}, {${params}});\n`;
};
13 changes: 13 additions & 0 deletions static/xml/toolbox.xml
Original file line number Diff line number Diff line change
Expand Up @@ -469,6 +469,19 @@
</block>
<block type="loader"></block>
<block type="block_holder"></block>
<block type="webhook">
<value name="WEBHOOK_URL">
<shadow type="text">
<field name="TEXT">https://example.com</field>
</shadow>
</value>
<value name="ADD0">
<block type="key_value_pair">
</block>
</value>
</block>
<block type="key_value_pair">
</block>
</category>
</category>
</category>
Expand Down