0

I have not much idea about JavaScript but I really like the Node-Red framework to connect to IoT devices. I've built a small flow that connects an http-request node (to get a picture) to a function node and the function node to a msg-debug node (to see what is going on).

The picture is successfully grabbed by the request node and I used this javascript function in the function node to send the payload (image) off to IPFS to upload it and to get the hash of the uploaded file back but it doesn't work. What am I doing wrong?

Note, the IPFS daemon is up and running on my machine on: http://localhost:5001/

I've tried different scripts (from node.js or other online examples) but none worked.

Here is the code in the function node:

//const ipfsAPI = require('ipfs-api');

var payload=msg.payload;

function toIPFS(file) {
    return new Promise(resolve => {
        const reader = new FileReader();
        reader.onloadend = function() {
        const ipfs = IpfsApi('ipfs', 5001,{protocol : "http"}) // Connect to IPFS
        const buf = buffer.Buffer(reader.result) // Convert data into buffer
        ipfs.files.add(buf, (err, result) => { // Upload buffer to IPFS
            if(err) {
              return "error";
            }
              let url = `https://ipfs.io/ipfs/${result[0].hash}`
              resolve('resolved url');
          })
        }
        reader.readAsArrayBuffer(file); // Read Provided File
        //console.log(`done!!!!`)
   });
  }
//var test = toIPFS(payload);
toIPFS(payload);

return msg;

The message object that I get from the msg-debug node in the end looks like this:

object
_msgid: "80561394.e873e"
topic: ""
payload: ""
statusCode: 200
headers: object
accept-ranges: "bytes"
access-control-allow-origin: "*"
access-control-expose-headers: "Content-Length"
cache-control: "max-age=604800, must-revalidate"
content-type: "image/jpeg"
date: "Sun, 16 Jun 2019 16:39:46 GMT"
last-modified: "Thu, 28 Jun 2018 04:32:21 GMT"
server: "ECS (lcy/1D6A)"
strict-transport-security: "max-age=631138519"
surrogate-key: "media media/bucket/2 media/1012192454752301056"
x-cache: "HIT"
x-connection-hash: "4d2ce5d9ed372dccc93b26cf6e8ce8c4"
x-content-type-options: "nosniff"
x-response-time: "460"
content-length: "127686"
connection: "close"
x-node-red-request-node: "6f2e7990"
responseUrl: "https://upload.wikimedia.org/wikipedia/commons/1/12/K2_2006b.jpg"
redirectList: array[0]
Felipe Augusto
  • 7,733
  • 10
  • 39
  • 73
user1091883
  • 147
  • 1
  • 1
  • 10

1 Answers1

0

There should be no need for any of the file handling, as you already have the content of the file in a buffer (in msg.payload).

So you should be able to just call:

const ipfs = IpfsApi('ipfs', 5001,{protocol : "http"})
ipfs.files.add(buf, (err, result) => {
    msg.payload = result[0].hash;
    node.send(msg)
})

(assuming you've added the ipfs module to the global context so it is in scope.)

hardillb
  • 54,545
  • 11
  • 67
  • 105
  • Hi thank you, but how do I get the file hash back? isn't it handled by the file handling? I tried to do something like ```msg.topic="object?";``` as topic is a string variable I can see in the debug message output. – user1091883 Jun 17 '19 at 10:12
  • To be honest you would be better writing a proper IPFS Node-RED node rather than trying to do this with a function node. – hardillb Jun 17 '19 at 10:14
  • ```const ipfs = IpfsApi('ipfs', 5001,{protocol : "http"}) ipfs.files.add(buf, (err, result) => { msg.payload = result[0].hash; node.send(msg) })``` works but I don't see the hash in the payload. its the same object output as before? – user1091883 Jun 18 '19 at 15:32
  • Remove the `return msg` from the end of the function node – hardillb Jun 18 '19 at 16:14
  • ok that results in: ```"TypeError: Cannot read property '0' of undefined"``` – user1091883 Jun 18 '19 at 16:46
  • Ok that also result in no the same error ```const ipfsAPI = require('ipfs-api'); file = msg.payload; const ipfs = IpfsApi('ipfs', 5001,{protocol : "http"}) ipfs.files.add(file, (err, result) => { if (err){ msg.topic = err.toString(); } msg.payload = result[0].hash; node.send(msg) }) ``` – user1091883 Jun 18 '19 at 16:53
  • it cannot find ```result``` so I think the ```.hash[0]``` doesn't work. – user1091883 Jun 18 '19 at 16:54
  • Of course it does, because you are still executing the code to access the result even if there is an error – hardillb Jun 18 '19 at 16:54
  • could you post a snippet that works on your end, please? – user1091883 Jun 18 '19 at 16:56
  • No, I don't have a ipfs instance. As I said at the start you REALLY should write a custom node for this. – hardillb Jun 18 '19 at 16:58
  • ok by using ```msg.topic = err.toString();``` I finally see an error message: "Error: first arg must be a buffer, readable stream, pull stream, an object or array of objects" – user1091883 Jun 18 '19 at 17:00
  • as I stated in my original post I have no idea about JavaScript how can I write a custom node? Not helpful comment – user1091883 Jun 18 '19 at 17:07