Hello World

This commit is contained in:
Shikiryu
2025-10-11 17:09:39 +02:00
commit e904cf52c5
9 changed files with 6917 additions and 0 deletions

8
.idea/.gitignore generated vendored Normal file
View File

@@ -0,0 +1,8 @@
# Default ignored files
/shelf/
/workspace.xml
# Editor-based HTTP Client requests
/httpRequests/
# Datasource local storage ignored files
/dataSources/
/dataSources.local.xml

42
accept-quest.html Normal file
View File

@@ -0,0 +1,42 @@
<script type="text/javascript">
RED.nodes.registerType('habitica-accept-quest', {
category: 'Habitica',
color: '#a6bbcf',
defaults: {
name: {value: ''},
apiAccount: {value: '', type: 'habitica-account', required: true},
account: {value: '', type: 'habitica-account', required: true},
},
inputs: 1,
outputs: 1,
icon: 'file.png',
label: function() {
return this.name || 'Habitica: Accepting quest';
}
});
</script>
<script type="text/html" data-template-name="habitica-accept-quest">
<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-row">
<label for="node-input-apiAccount">
<i class="fa fa-tag"></i> API Account
</label>
<input type="text" id="node-input-apiAccount" placeholder="API Account" />
</div>
<div class="form-row">
<label for="node-input-account">
<i class="fa fa-tag"></i> Account
</label>
<input type="text" id="node-input-account" placeholder="Account" />
</div>
</script>
<script type="text/html" data-help-name="habitica-accept-quest">
<p>Accept pending quest from the Habitica API.</p>
</script>

59
accept-quest.js Normal file
View File

@@ -0,0 +1,59 @@
const https = require('https');
module.exports = RED => {
function UserProfileNode(config) {
const node = this;
RED.nodes.createNode(node, config);
node.apiAccount = RED.nodes.getNode(config.apiAccount);
node.account = RED.nodes.getNode(config.account);
const handleErr = (err, debugErr) => {
console.log(debugErr);
node.error('Something done broke: '+err);
node.status({fill: 'red', shape: 'ring', text: 'Error accepting quest: '+err});
};
node.on('input', async function(msg) {
const group_id = 'party';
const opts = {
host: 'habitica.com',
path: `/api/v3/groups/${group_id}/quests/accept`,
headers: {
'X-Client': `${node.apiAccount.username}-NodeRED`,
'X-API-User': node.account.userId,
'X-API-Key': node.account.apiToken,
},
};
https.get(opts, req => {
req.setEncoding('utf-8');
let body = '',
response = null;
req.on('data', data => {
body += data;
});
req.on('end', () => {
response = JSON.parse(body);
msg.payload = response.data;
if (response.success) {
node.send(msg);
node.status({fill: 'green', shape: 'dot', text: 'Quest accepted'});
}
else {
handleErr('The response was not successful: '+response.message, body);
}
});
}).on('error', err => handleErr(err));
});
}
RED.nodes.registerType('habitica-accept-quest', UserProfileNode);
};

52
group.html Normal file
View File

@@ -0,0 +1,52 @@
<script type="text/javascript">
RED.nodes.registerType('habitica-group', {
category: 'Habitica',
color: '#a6bbcf',
defaults: {
name: {value: ''},
apiAccount: {value: '', type: 'habitica-account', required: true},
account: {value: '', type: 'habitica-account', required: true},
fields: {value: ''},
},
inputs: 1,
outputs: 1,
icon: 'file.png',
label: function() {
return this.name || 'Habitica: Group';
}
});
</script>
<script type="text/html" data-template-name="habitica-group">
<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-row">
<label for="node-input-apiAccount">
<i class="fa fa-tag"></i> API Account
</label>
<input type="text" id="node-input-apiAccount" placeholder="API Account" />
</div>
<div class="form-row">
<label for="node-input-account">
<i class="fa fa-tag"></i> Account
</label>
<input type="text" id="node-input-account" placeholder="Account" />
</div>
<div class="form-row">
<label for="node-input-fields-editor">
<i class="fa fa-tag"></i> Fields
</label>
<div style="height: 250px; min-height:150px;" class="node-text-editor" id="node-input-fields-editor"></div>
<small>Enter one or more fields, separated by commas or line breaks. For sub-fields, use &quot;dot-notation&quot; such as <code>items.gear</code>. <a href="https://github.com/HabitRPG/habitica/blob/develop/website/server/models/user/schema.js">See the Habitica user schema</a> for more information.</small>
<br />
<small><em>Example: <code>stats,achievements,items.gear</code></em></small>
</div>
</script>
<script type="text/html" data-help-name="habitica-group">
<p>Retrieve profile information for a given user from the Habitica API.</p>
</script>

56
group.js Normal file
View File

@@ -0,0 +1,56 @@
const https = require('https');
module.exports = RED => {
function UserProfileNode(config) {
const node = this;
RED.nodes.createNode(node, config);
node.apiAccount = RED.nodes.getNode(config.apiAccount);
node.account = RED.nodes.getNode(config.account);
const handleErr = (err) => {
console.log(err);
node.error('Something done broke');
node.status({fill: 'red', shape: 'ring', text: 'Error retrieving profile'});
};
node.on('input', async function(msg) {
const opts = {
host: 'habitica.com',
path: `/api/v3/groups/party`,
headers: {
'X-Client': `${node.apiAccount.username}-NodeRED`,
'X-API-User': node.account.userId,
'X-API-Key': node.account.apiToken,
},
};
https.get(opts, req => {
req.setEncoding('utf-8');
let body = '',
response = null;
req.on('data', data => {
body += data;
});
req.on('end', () => {
response = JSON.parse(body);
if (response.success) {
msg.payload = response.data;
node.send(msg);
node.status({fill: 'green', shape: 'dot', text: 'Group retrieved'});
}
else {
handleErr('The response was not successful');
}
});
}).on('error', err => handleErr(err));
});
}
RED.nodes.registerType('habitica-group', UserProfileNode);
};

28
habitica-account.html Normal file
View File

@@ -0,0 +1,28 @@
<script type="text/javascript">
RED.nodes.registerType('habitica-account', {
category: 'config',
defaults: {
username: {value: '', required: true},
userId: {value: '', required: true},
apiToken: {value: '', required: true},
},
label: function() {
return this.username;
},
});
</script>
<script type="text/html" data-template-name="habitica-account">
<div class="form-row">
<label for="node-config-input-username"><i class="fa fa-bookmark"></i> Local user id</label>
<input type="text" id="node-config-input-username">
</div>
<div class="form-row">
<label for="node-config-input-userId"><i class="fa fa-bookmark"></i> Habitica User ID</label>
<input type="text" id="node-config-input-userId">
</div>
<div class="form-row">
<label for="node-config-input-apiToken"><i class="fa fa-bookmark"></i> Habitica API Token</label>
<input type="text" id="node-config-input-apiToken">
</div>
</script>

11
habitica-account.js Normal file
View File

@@ -0,0 +1,11 @@
module.exports = RED => {
function HabiticaAccountNode(n) {
RED.nodes.createNode(this, n);
this.username = n.username;
this.userId = n.userId;
this.apiToken = n.apiToken;
}
RED.nodes.registerType('habitica-account', HabiticaAccountNode);
};

6622
package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

39
package.json Normal file
View File

@@ -0,0 +1,39 @@
{
"name": "node-red-contrib-habitica-quest",
"description": "NodeRED plugin to provide nodes for interacting with the Habitica API.",
"version": "0.0.1",
"author": "Clément Desmidt <projets@shiki.fr>",
"license": "MIT",
"keywords": [
"node-red",
"habitica"
],
"devDependencies": {
"@commitlint/cli": "11.0.0",
"@commitlint/config-conventional": "11.0.0",
"@types/node": "^14.14.9",
"@types/node-red": "^1.1.1",
"commitizen": "4.2.2",
"cz-conventional-changelog": "3.3.0",
"husky": "5.0.0-beta.0",
"pinst": "2.0.0",
"standard-version": "9.0.0"
},
"config": {
"commitizen": {
"path": "./node_modules/cz-conventional-changelog"
}
},
"commitlint": {
"extends": [
"@commitlint/config-conventional"
]
},
"node-red": {
"nodes": {
"habitica-account": "habitica-account.js",
"habitica-group": "group.js",
"habitica-accept-quest": "accept-quest.js"
}
}
}