cyrillef / node-red-node-forge

Node-RED nodes to help with the Autodesk Forge API - https://forge.autodesk.com/
MIT License
8 stars 4 forks source link

Viewing API available? #5

Closed BerndGewehr closed 2 years ago

BerndGewehr commented 4 years ago

I would like to create a generic endpoint to leverage the Autodesk viewer in the following way:

POST any file against a node-red "HTTP in" node. Do something smart. Receive back the URL of the Content in the Autodesk viewer to embed it into your application (or any kind of error page saying "this content can not be previewed").

I am following this guide: https://forge.autodesk.com/en/docs/model-derivative/v2/tutorials/prep-file4viewer/

Any recommendations on how to do this with node-red on an http-in incoming file?

bigdoods commented 4 years ago

Sure, use [Http in] and a http client to post file to your node-red instance. Write that file to disk/cache. Create a flow with logic outlined in that guide to read the file, upload the file and convert it to SVF. Then, use a html template to generate a html page with the viewer for the derivative file and use this how you like.

Personally, I would just use a [file read] node and [inject] to read the file from local disk to start the process. I wouldn't bother creating a HTTP endpoint at all, but then again, what is your end goal here? Is it to offer this flow as an API for use by another service?

I would also suggest to join the node-red slack group https://nodered.org/slack/

BerndGewehr commented 4 years ago

Excellent, thank you!

I want to achieve a simpler integration of Autodesk viewer for some of our systems so that the other solution does not need to do more than post a file against an endpoint and get the preview URL or embed HTML back in the result.

Still the one question stays: How to hand over a file buffer - filled in whatever way in node red - to the upload OSS object node without having to use the native file system? Any solution that you know of? I do not want to care for growing disk space in my docker containers...

BerndGewehr commented 4 years ago

See also https://github.com/cyrillef/node-red-node-forge/issues/4 for this.

On the other hand: Can you suggest how to use the nodes from this repo to achieve the flow described in the documentation?

cyrillef commented 2 years ago

I posted a sample in the latest update v0.0.4 - It shows the 3 basics steps to get the Viewer up using node-red. Let me know if you need more help.

BerndGewehr commented 2 years ago

Will 0.0.4 be published soon?

cyrillef commented 2 years ago

It is published at https://www.npmjs.com/package/node-red-node-forge

BerndGewehr commented 2 years ago

OK, still not visible in "edit palette" menu in node-red, there it is still 0.0.3

BerndGewehr commented 2 years ago

Will you update in https://flows.nodered.org/node/node-red-node-forge also?

BerndGewehr commented 2 years ago

see also https://flows.nodered.org/user/cyrillef1

cyrillef commented 2 years ago

You are right, I will work on it

cyrillef commented 2 years ago

Done, thx @BerndGewehr

BerndGewehr commented 2 years ago

Great job, thank you! It looks like this method is not really feasible to take a file from wherever, upload it to the bucket, translate it, get the viewer URL from there and embed the result in an iframe, right? That was what I was initially looking for. Would you say this is in any way possible with this approach? How would you set this up? Thx for guiding me into the right direction...

BerndGewehr commented 2 years ago

What I was trying was to have an endpoint in Node-red to post a file against, that does all the trick and delivers a link to the file in the viewer as the result so that my calling page script can do the upload and embed the result in an iFrame in one step. There will be a spinner needed for sure. But hopefully never longer than a minute?

BerndGewehr commented 2 years ago

Did you try on the european datacenters? The nodes do partially support that but the html code does not. I made some changes here for explicitely go to eu:

I looked here for details: https://forge.autodesk.com/developer/idea/viewer-app


<html>

<head>
    <title>Sample</title>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0">

    <!-- Autodesk Forge Viewer files -->
    <link rel="stylesheet" href="https://developer.api.autodesk.com/modelderivative/v2/regions/eu/viewers/7.*/style.css">
    <script src="https://developer.api.autodesk.com/modelderivative/v2/regions/eu/viewers/7.*/viewer3D.js"></script>
    <script>
        var viewer = null;

        function launchViewer() {
            const options = {
                env: 'AutodeskProduction',
                api: 'derivativeV2_EU',  // for models uploaded to EMEA change this option to 'derivativeV2_EU'
                getAccessToken: getForgeToken
            };

            Autodesk.Viewing.Initializer(options, () => {
                viewer = new Autodesk.Viewing.GuiViewer3D(document.getElementById('forgeViewer'));
                viewer.start();
                const documentId = 'urn:{{payload.urn}}';
                Autodesk.Viewing.Document.load(documentId, onDocumentLoadSuccess, onDocumentLoadFailure);
            });
        }

        function onDocumentLoadSuccess(doc) {
            const viewables = doc.getRoot().getDefaultGeometry();
            viewer.loadDocumentNode(doc, viewables).then(i => {
                // documented loaded, any action?
            });
        }

        function onDocumentLoadFailure(viewerErrorCode) {
            console.error('onDocumentLoadFailure() - errorCode:' + viewerErrorCode);
        }

        function getForgeToken(callback) {
            fetch('/api/forge/oauth/token').then(res => {
                res.json().then(data => {
                    console.log (JSON.stringify(data));
                    callback(data.access_token, data.expires_in);
                });
            });
        }

    </script>
</head>

<body onload="launchViewer()">
    <div id="forgeViewer"></div>
</body>

</html>```
BerndGewehr commented 2 years ago

And YESS, that's working fine now.

I will continue to work on the following flow:

1) POST file -> upload to bucket -> start translating -> on end translating respond with URL with parameters bucket and key 2) GET Page with URL from above -> use template like above but with details from URL parameters for dynamic content to render the viewer

That way it should be possible to achieve a generic viewing facility with node-red nodes.

BerndGewehr commented 2 years ago

Now, after some successful uses of the flow, I get errors that I can not understand.

TypeError: Cannot read property 'forgeCredentials' of null at ForgeTokenNode.onInput [as _inputCallback] (/data/node_modules/node-red-node-forge/forge-get-token.js:61:72) at /usr/src/node-red/node_modules/@node-red/runtime/lib/nodes/Node.js:204:26 at Object.trigger (/usr/src/node-red/node_modules/@node-red/util/lib/hooks.js:149:13) at ForgeTokenNode.Node._emitInput (/usr/src/node-red/node_modules/@node-red/runtime/lib/nodes/Node.js:196:11) at ForgeTokenNode.Node.emit (/usr/src/node-red/node_modules/@node-red/runtime/lib/nodes/Node.js:180:25) at ForgeTokenNode.Node.receive (/usr/src/node-red/node_modules/@node-red/runtime/lib/nodes/Node.js:479:10) at Immediate._onImmediate (/usr/src/node-red/node_modules/@node-red/runtime/lib/flows/Flow.js:813:52) at processImmediate (internal/timers.js:464:21)

I did not change the cred config at all before this happened. Subscription is OK, cloud tokens are enough existing, why does this happen? Any idea?

cyrillef commented 2 years ago

@BerndGewehr - I am working on a sample, should be ready today

BerndGewehr commented 2 years ago

The forgeCredentials error disappeared after I created a new secret for my app. I do not understand why, but now it works again.

BerndGewehr commented 2 years ago

See here my modified subflow

[
    {
        "id": "fee8fd5f.f1b33",
        "type": "subflow",
        "name": "Translate and Wait",
        "info": "\n\n### Parameters\n\n* **urn**: The design URN; returned when uploading the file to Forge. The URN needs to be safe base64 encoded.\n\n* **region** [optional]: Region in which to store outputs. Possible values: ```US```, ```EMEA```. By default, it is set to ```US```.\n\n* **xAdsForce** [optional]: ```true```: the endpoint replaces previously translated output file types with the newly generated derivatives\n  ```false``` (default): previously created derivatives are not replaced\n    \n## Outputs\n\n* **response**: the final manifest\n\n* **progress**: an object containing a status and progress field.\n  * status: Overall status for translation jobs in the “manifest”. Possible values: pending, ```success```, ```inprogress```, ```failed```, ```timeout```\n  * progress: Overall progress for all translation jobs in the “manifest”. Possible values: ```complete```, ```##% complete```\n\n\n* **error**: an error occured\n",
        "category": "forge",
        "in": [
            {
                "x": 80,
                "y": 180,
                "wires": [
                    {
                        "id": "5321dbe4.7303a4"
                    }
                ]
            }
        ],
        "out": [
            {
                "x": 920,
                "y": 540,
                "wires": [
                    {
                        "id": "46a4e81e.d50348",
                        "port": "1"
                    }
                ]
            },
            {
                "x": 920,
                "y": 660,
                "wires": [
                    {
                        "id": "f144a2cc.6549d",
                        "port": 0
                    }
                ]
            },
            {
                "x": 920,
                "y": 360,
                "wires": [
                    {
                        "id": "d871abe2.ddd508",
                        "port": 1
                    },
                    {
                        "id": "49d295fd.e0f8fc",
                        "port": 1
                    },
                    {
                        "id": "eb17a986.c8f7f8",
                        "port": 1
                    },
                    {
                        "id": "46a4e81e.d50348",
                        "port": 0
                    }
                ]
            }
        ],
        "env": [],
        "meta": {},
        "color": "#DDAA99",
        "outputLabels": [
            "response",
            "progress",
            "error"
        ],
        "icon": "node-red-node-forge/forge.png",
        "status": {
            "x": 280,
            "y": 80,
            "wires": [
                {
                    "id": "e4667066.501b1",
                    "port": 0
                }
            ]
        }
    },
    {
        "id": "e79337df.431af8",
        "type": "change",
        "z": "fee8fd5f.f1b33",
        "name": "Inject",
        "rules": [
            {
                "t": "delete",
                "p": "err",
                "pt": "msg"
            },
            {
                "t": "delete",
                "p": "payload",
                "pt": "msg"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 110,
        "y": 360,
        "wires": [
            [
                "eb17a986.c8f7f8"
            ]
        ]
    },
    {
        "id": "eb17a986.c8f7f8",
        "type": "forge-model-derivative",
        "z": "fee8fd5f.f1b33",
        "name": "",
        "topic": "",
        "forge": "",
        "operation": "Translate",
        "raw": false,
        "all": false,
        "urn": "",
        "derivativeurn": "",
        "guid": "autodesk",
        "objectid": "",
        "xAdsForce": false,
        "forceget": false,
        "rootFilename": "",
        "range": "",
        "width": 200,
        "height": 200,
        "jobs": [
            {
                "type": "svf",
                "views": [
                    "2d",
                    "3d"
                ],
                "advanced": {
                    "switchLoader": false
                }
            }
        ],
        "checkReferences": false,
        "references": "[]",
        "noerr": 0,
        "ifModifiedSince": "",
        "acceptEncoding": "",
        "region": "EMEA",
        "datacenter": "EMEA",
        "workflow": "",
        "workflowAttribute": "",
        "x": 250,
        "y": 360,
        "wires": [
            [
                "c23d359d.b11e38",
                "debd3b88.be34b8"
            ],
            []
        ]
    },
    {
        "id": "c23d359d.b11e38",
        "type": "delay",
        "z": "fee8fd5f.f1b33",
        "name": "",
        "pauseType": "delay",
        "timeout": "10",
        "timeoutUnits": "seconds",
        "rate": "1",
        "nbRateUnits": "1",
        "rateUnits": "second",
        "randomFirst": "1",
        "randomLast": "5",
        "randomUnits": "seconds",
        "drop": false,
        "allowrate": false,
        "outputs": 1,
        "x": 510,
        "y": 400,
        "wires": [
            [
                "d871abe2.ddd508"
            ]
        ]
    },
    {
        "id": "d871abe2.ddd508",
        "type": "forge-model-derivative",
        "z": "fee8fd5f.f1b33",
        "name": "Manifest",
        "topic": "",
        "forge": "",
        "operation": "GetManifest",
        "raw": false,
        "all": false,
        "urn": "",
        "derivativeurn": "",
        "guid": "autodesk",
        "objectid": "",
        "xAdsForce": false,
        "forceget": false,
        "rootFilename": "",
        "range": "",
        "width": 200,
        "height": 200,
        "jobs": [
            {
                "type": "svf",
                "views": [],
                "advanced": {
                    "switchLoader": false
                }
            }
        ],
        "checkReferences": false,
        "references": "[]",
        "noerr": 0,
        "ifModifiedSince": "",
        "acceptEncoding": "",
        "region": "US",
        "datacenter": "EMEA",
        "workflow": "",
        "workflowAttribute": "",
        "x": 700,
        "y": 420,
        "wires": [
            [
                "46a4e81e.d50348"
            ],
            []
        ]
    },
    {
        "id": "91d8b317.96684",
        "type": "delay",
        "z": "fee8fd5f.f1b33",
        "name": "",
        "pauseType": "delay",
        "timeout": "10",
        "timeoutUnits": "seconds",
        "rate": "1",
        "nbRateUnits": "1",
        "rateUnits": "second",
        "randomFirst": "1",
        "randomLast": "5",
        "randomUnits": "seconds",
        "drop": false,
        "allowrate": false,
        "outputs": 1,
        "x": 510,
        "y": 440,
        "wires": [
            [
                "d871abe2.ddd508"
            ]
        ]
    },
    {
        "id": "46a4e81e.d50348",
        "type": "switch",
        "z": "fee8fd5f.f1b33",
        "name": "Ready?",
        "property": "payload.status",
        "propertyType": "msg",
        "rules": [
            {
                "t": "eq",
                "v": "failed",
                "vt": "str"
            },
            {
                "t": "eq",
                "v": "success",
                "vt": "str"
            },
            {
                "t": "else"
            }
        ],
        "checkall": "true",
        "repair": false,
        "outputs": 3,
        "x": 700,
        "y": 540,
        "wires": [
            [],
            [],
            [
                "91d8b317.96684",
                "f144a2cc.6549d"
            ]
        ]
    },
    {
        "id": "e4667066.501b1",
        "type": "status",
        "z": "fee8fd5f.f1b33",
        "name": "",
        "scope": null,
        "x": 120,
        "y": 80,
        "wires": [
            []
        ]
    },
    {
        "id": "5321dbe4.7303a4",
        "type": "function",
        "z": "fee8fd5f.f1b33",
        "name": "Inject",
        "func": "if ( msg.err )\n    delete msg.err;\n    \n//context.set / .get\n\n// Priority: payload, msg, env, default\nif ( msg.payload ) {\n    msg.urn =msg.payload.urn || msg.urn || env.get('urn');\n    msg.region =msg.payload.region || msg.region || env.get('region') || 'US';\n    msg.xAdsForce =false;\n    if (typeof msg.payload.xAdsForce === 'boolean')\n        msg.xAdsForce =msg.payload.xAdsForce === true;\n    else if (typeof msg.xAdsForce === 'boolean')\n        msg.xAdsForce =msg.xAdsForce === true;\n    else if (typeof env.get('bucket') === 'boolean')\n        msg.xAdsForce =env.get('bucket') === true ;\n} else {\n    msg.urn =msg.urn || env.get('urn');\n    msg.region =msg.region || env.get('region') || 'US';\n    if (typeof msg.xAdsForce === 'boolean')\n        msg.xAdsForce =msg.xAdsForce === true;\n    else if (typeof env.get('bucket') === 'boolean')\n        msg.xAdsForce =env.get('bucket') === true ;\n    else\n        msg.xAdsForce =false;\n}\n\nnode.status ({});\nif ( !msg.bucket || msg.bucket === '' ) {\n    node.status ({\n        fill: 'red',\n        shape: 'dot',\n        text: 'Invalid urn!'});\n    node.error('Provide a urn!');\n    delete msg.payload;\n    msg.err ={\n        reason: \"The parameter 'urn' should be a nonempty string.\"\n    };\n}\n    \nreturn (msg);",
        "outputs": 1,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "x": 190,
        "y": 180,
        "wires": [
            [
                "49d295fd.e0f8fc"
            ]
        ]
    },
    {
        "id": "49d295fd.e0f8fc",
        "type": "switch",
        "z": "fee8fd5f.f1b33",
        "name": "Params Ok?",
        "property": "err",
        "propertyType": "msg",
        "rules": [
            {
                "t": "null"
            },
            {
                "t": "else"
            }
        ],
        "checkall": "true",
        "repair": false,
        "outputs": 2,
        "x": 330,
        "y": 180,
        "wires": [
            [
                "e79337df.431af8"
            ],
            []
        ]
    },
    {
        "id": "debd3b88.be34b8",
        "type": "function",
        "z": "fee8fd5f.f1b33",
        "name": "Requested",
        "func": "msg.payload ={\n    status: 'pending',\n    progress: '0% complete'\n};\nreturn msg;",
        "outputs": 1,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "x": 490,
        "y": 660,
        "wires": [
            [
                "f144a2cc.6549d"
            ]
        ]
    },
    {
        "id": "f144a2cc.6549d",
        "type": "function",
        "z": "fee8fd5f.f1b33",
        "name": "",
        "func": "node.status ({\n    fill: 'yellow',\n    shape: 'square',\n    text: msg.payload.progress\n});\n\nreturn (msg);",
        "outputs": 1,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "x": 770,
        "y": 660,
        "wires": [
            []
        ]
    }
]
BerndGewehr commented 2 years ago

See here my modified main flow

[
    {
        "id": "fee8fd5f.f1b33",
        "type": "subflow",
        "name": "Translate and Wait",
        "info": "\n\n### Parameters\n\n* **urn**: The design URN; returned when uploading the file to Forge. The URN needs to be safe base64 encoded.\n\n* **region** [optional]: Region in which to store outputs. Possible values: ```US```, ```EMEA```. By default, it is set to ```US```.\n\n* **xAdsForce** [optional]: ```true```: the endpoint replaces previously translated output file types with the newly generated derivatives\n  ```false``` (default): previously created derivatives are not replaced\n    \n## Outputs\n\n* **response**: the final manifest\n\n* **progress**: an object containing a status and progress field.\n  * status: Overall status for translation jobs in the “manifest”. Possible values: pending, ```success```, ```inprogress```, ```failed```, ```timeout```\n  * progress: Overall progress for all translation jobs in the “manifest”. Possible values: ```complete```, ```##% complete```\n\n\n* **error**: an error occured\n",
        "category": "forge",
        "in": [
            {
                "x": 80,
                "y": 180,
                "wires": [
                    {
                        "id": "5321dbe4.7303a4"
                    }
                ]
            }
        ],
        "out": [
            {
                "x": 920,
                "y": 540,
                "wires": [
                    {
                        "id": "46a4e81e.d50348",
                        "port": "1"
                    }
                ]
            },
            {
                "x": 920,
                "y": 660,
                "wires": [
                    {
                        "id": "f144a2cc.6549d",
                        "port": 0
                    }
                ]
            },
            {
                "x": 920,
                "y": 360,
                "wires": [
                    {
                        "id": "d871abe2.ddd508",
                        "port": 1
                    },
                    {
                        "id": "49d295fd.e0f8fc",
                        "port": 1
                    },
                    {
                        "id": "eb17a986.c8f7f8",
                        "port": 1
                    },
                    {
                        "id": "46a4e81e.d50348",
                        "port": 0
                    }
                ]
            }
        ],
        "env": [],
        "meta": {},
        "color": "#DDAA99",
        "outputLabels": [
            "response",
            "progress",
            "error"
        ],
        "icon": "node-red-node-forge/forge.png",
        "status": {
            "x": 280,
            "y": 80,
            "wires": [
                {
                    "id": "e4667066.501b1",
                    "port": 0
                }
            ]
        }
    },
    {
        "id": "e79337df.431af8",
        "type": "change",
        "z": "fee8fd5f.f1b33",
        "name": "Inject",
        "rules": [
            {
                "t": "delete",
                "p": "err",
                "pt": "msg"
            },
            {
                "t": "delete",
                "p": "payload",
                "pt": "msg"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 110,
        "y": 360,
        "wires": [
            [
                "eb17a986.c8f7f8"
            ]
        ]
    },
    {
        "id": "eb17a986.c8f7f8",
        "type": "forge-model-derivative",
        "z": "fee8fd5f.f1b33",
        "name": "",
        "topic": "",
        "forge": "",
        "operation": "Translate",
        "raw": false,
        "all": false,
        "urn": "",
        "derivativeurn": "",
        "guid": "autodesk",
        "objectid": "",
        "xAdsForce": false,
        "forceget": false,
        "rootFilename": "",
        "range": "",
        "width": 200,
        "height": 200,
        "jobs": [
            {
                "type": "svf",
                "views": [
                    "2d",
                    "3d"
                ],
                "advanced": {
                    "switchLoader": false
                }
            }
        ],
        "checkReferences": false,
        "references": "[]",
        "noerr": 0,
        "ifModifiedSince": "",
        "acceptEncoding": "",
        "region": "EMEA",
        "datacenter": "EMEA",
        "workflow": "",
        "workflowAttribute": "",
        "x": 250,
        "y": 360,
        "wires": [
            [
                "c23d359d.b11e38",
                "debd3b88.be34b8"
            ],
            []
        ]
    },
    {
        "id": "c23d359d.b11e38",
        "type": "delay",
        "z": "fee8fd5f.f1b33",
        "name": "",
        "pauseType": "delay",
        "timeout": "10",
        "timeoutUnits": "seconds",
        "rate": "1",
        "nbRateUnits": "1",
        "rateUnits": "second",
        "randomFirst": "1",
        "randomLast": "5",
        "randomUnits": "seconds",
        "drop": false,
        "allowrate": false,
        "outputs": 1,
        "x": 510,
        "y": 400,
        "wires": [
            [
                "d871abe2.ddd508"
            ]
        ]
    },
    {
        "id": "d871abe2.ddd508",
        "type": "forge-model-derivative",
        "z": "fee8fd5f.f1b33",
        "name": "Manifest",
        "topic": "",
        "forge": "",
        "operation": "GetManifest",
        "raw": false,
        "all": false,
        "urn": "",
        "derivativeurn": "",
        "guid": "autodesk",
        "objectid": "",
        "xAdsForce": false,
        "forceget": false,
        "rootFilename": "",
        "range": "",
        "width": 200,
        "height": 200,
        "jobs": [
            {
                "type": "svf",
                "views": [],
                "advanced": {
                    "switchLoader": false
                }
            }
        ],
        "checkReferences": false,
        "references": "[]",
        "noerr": 0,
        "ifModifiedSince": "",
        "acceptEncoding": "",
        "region": "US",
        "datacenter": "EMEA",
        "workflow": "",
        "workflowAttribute": "",
        "x": 700,
        "y": 420,
        "wires": [
            [
                "46a4e81e.d50348"
            ],
            []
        ]
    },
    {
        "id": "91d8b317.96684",
        "type": "delay",
        "z": "fee8fd5f.f1b33",
        "name": "",
        "pauseType": "delay",
        "timeout": "10",
        "timeoutUnits": "seconds",
        "rate": "1",
        "nbRateUnits": "1",
        "rateUnits": "second",
        "randomFirst": "1",
        "randomLast": "5",
        "randomUnits": "seconds",
        "drop": false,
        "allowrate": false,
        "outputs": 1,
        "x": 510,
        "y": 440,
        "wires": [
            [
                "d871abe2.ddd508"
            ]
        ]
    },
    {
        "id": "46a4e81e.d50348",
        "type": "switch",
        "z": "fee8fd5f.f1b33",
        "name": "Ready?",
        "property": "payload.status",
        "propertyType": "msg",
        "rules": [
            {
                "t": "eq",
                "v": "failed",
                "vt": "str"
            },
            {
                "t": "eq",
                "v": "success",
                "vt": "str"
            },
            {
                "t": "else"
            }
        ],
        "checkall": "true",
        "repair": false,
        "outputs": 3,
        "x": 700,
        "y": 540,
        "wires": [
            [],
            [],
            [
                "91d8b317.96684",
                "f144a2cc.6549d"
            ]
        ]
    },
    {
        "id": "e4667066.501b1",
        "type": "status",
        "z": "fee8fd5f.f1b33",
        "name": "",
        "scope": null,
        "x": 120,
        "y": 80,
        "wires": [
            []
        ]
    },
    {
        "id": "5321dbe4.7303a4",
        "type": "function",
        "z": "fee8fd5f.f1b33",
        "name": "Inject",
        "func": "if ( msg.err )\n    delete msg.err;\n    \n//context.set / .get\n\n// Priority: payload, msg, env, default\nif ( msg.payload ) {\n    msg.urn =msg.payload.urn || msg.urn || env.get('urn');\n    msg.region =msg.payload.region || msg.region || env.get('region') || 'US';\n    msg.xAdsForce =false;\n    if (typeof msg.payload.xAdsForce === 'boolean')\n        msg.xAdsForce =msg.payload.xAdsForce === true;\n    else if (typeof msg.xAdsForce === 'boolean')\n        msg.xAdsForce =msg.xAdsForce === true;\n    else if (typeof env.get('bucket') === 'boolean')\n        msg.xAdsForce =env.get('bucket') === true ;\n} else {\n    msg.urn =msg.urn || env.get('urn');\n    msg.region =msg.region || env.get('region') || 'US';\n    if (typeof msg.xAdsForce === 'boolean')\n        msg.xAdsForce =msg.xAdsForce === true;\n    else if (typeof env.get('bucket') === 'boolean')\n        msg.xAdsForce =env.get('bucket') === true ;\n    else\n        msg.xAdsForce =false;\n}\n\nnode.status ({});\nif ( !msg.bucket || msg.bucket === '' ) {\n    node.status ({\n        fill: 'red',\n        shape: 'dot',\n        text: 'Invalid urn!'});\n    node.error('Provide a urn!');\n    delete msg.payload;\n    msg.err ={\n        reason: \"The parameter 'urn' should be a nonempty string.\"\n    };\n}\n    \nreturn (msg);",
        "outputs": 1,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "x": 190,
        "y": 180,
        "wires": [
            [
                "49d295fd.e0f8fc"
            ]
        ]
    },
    {
        "id": "49d295fd.e0f8fc",
        "type": "switch",
        "z": "fee8fd5f.f1b33",
        "name": "Params Ok?",
        "property": "err",
        "propertyType": "msg",
        "rules": [
            {
                "t": "null"
            },
            {
                "t": "else"
            }
        ],
        "checkall": "true",
        "repair": false,
        "outputs": 2,
        "x": 330,
        "y": 180,
        "wires": [
            [
                "e79337df.431af8"
            ],
            []
        ]
    },
    {
        "id": "debd3b88.be34b8",
        "type": "function",
        "z": "fee8fd5f.f1b33",
        "name": "Requested",
        "func": "msg.payload ={\n    status: 'pending',\n    progress: '0% complete'\n};\nreturn msg;",
        "outputs": 1,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "x": 490,
        "y": 660,
        "wires": [
            [
                "f144a2cc.6549d"
            ]
        ]
    },
    {
        "id": "f144a2cc.6549d",
        "type": "function",
        "z": "fee8fd5f.f1b33",
        "name": "",
        "func": "node.status ({\n    fill: 'yellow',\n    shape: 'square',\n    text: msg.payload.progress\n});\n\nreturn (msg);",
        "outputs": 1,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "x": 770,
        "y": 660,
        "wires": [
            []
        ]
    },
    {
        "id": "cfde8d96.fce87",
        "type": "tab",
        "label": "Autodesk Viewer",
        "disabled": false,
        "info": "",
        "env": []
    },
    {
        "id": "289c440f.a2f8cc",
        "type": "forge-default-credentials",
        "z": "cfde8d96.fce87",
        "name": "Dev Credentials",
        "forge": "",
        "x": 140,
        "y": 40,
        "wires": []
    },
    {
        "id": "cd3dc629.fd5a48",
        "type": "debug",
        "z": "cfde8d96.fce87",
        "name": "",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "true",
        "targetType": "full",
        "x": 2270,
        "y": 620,
        "wires": []
    },
    {
        "id": "3074bfac.7a2a1",
        "type": "debug",
        "z": "cfde8d96.fce87",
        "name": "",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "true",
        "targetType": "full",
        "x": 2270,
        "y": 660,
        "wires": []
    },
    {
        "id": "7c4fd902.916c78",
        "type": "forge-oss",
        "z": "cfde8d96.fce87",
        "name": "",
        "topic": "",
        "forge": "",
        "operation": "BucketDetails",
        "raw": false,
        "all": false,
        "bucket": "",
        "policyKey": "transient",
        "key": "",
        "contentType": "application/octet-stream",
        "contentDisposition": "",
        "copy": "",
        "localFilename": "",
        "limit": 10,
        "startAt": "",
        "beginsWith": "",
        "with": [],
        "ifMatch": "",
        "ifNoneMatch": "",
        "ifModifiedSince": "",
        "range": "",
        "access": "read",
        "singleUse": false,
        "minutesExpiration": 60,
        "acceptEncoding": "",
        "guid": "autodesk",
        "region": "US",
        "x": 870,
        "y": 260,
        "wires": [
            [
                "1cad6c5d.eb4614"
            ],
            [
                "1bfcb798.56ad58"
            ]
        ]
    },
    {
        "id": "48f6000a.518b4",
        "type": "forge-oss",
        "z": "cfde8d96.fce87",
        "name": "",
        "topic": "",
        "forge": "",
        "operation": "CreateBucket",
        "raw": true,
        "all": false,
        "bucket": "",
        "policyKey": "transient",
        "key": "",
        "contentType": "application/octet-stream",
        "contentDisposition": "",
        "copy": "",
        "localFilename": "",
        "limit": 10,
        "startAt": "",
        "beginsWith": "",
        "with": [],
        "ifMatch": "",
        "ifNoneMatch": "",
        "ifModifiedSince": "",
        "range": "",
        "access": "read",
        "singleUse": false,
        "minutesExpiration": 60,
        "acceptEncoding": "",
        "guid": "autodesk",
        "region": "EMEA",
        "x": 550,
        "y": 280,
        "wires": [
            [
                "7c4fd902.916c78",
                "be0ce380687b0256"
            ],
            [
                "d14a376e.ae7ee8",
                "be0ce380687b0256"
            ]
        ]
    },
    {
        "id": "7ad88c9d.47c724",
        "type": "function",
        "z": "cfde8d96.fce87",
        "name": "",
        "func": "msg = msg.payload;\nreturn msg;",
        "outputs": 1,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 340,
        "y": 280,
        "wires": [
            [
                "48f6000a.518b4"
            ]
        ]
    },
    {
        "id": "1cad6c5d.eb4614",
        "type": "forge-oss",
        "z": "cfde8d96.fce87",
        "name": "",
        "topic": "",
        "forge": "",
        "operation": "PutObject",
        "raw": false,
        "all": false,
        "bucket": "",
        "policyKey": "transient",
        "key": "",
        "contentType": "application/octet-stream",
        "contentDisposition": "",
        "copy": "",
        "localFilename": "",
        "limit": 10,
        "startAt": "",
        "beginsWith": "",
        "with": [],
        "ifMatch": "",
        "ifNoneMatch": "",
        "ifModifiedSince": "",
        "range": "",
        "access": "read",
        "singleUse": false,
        "minutesExpiration": 60,
        "acceptEncoding": "",
        "guid": "autodesk",
        "region": "US",
        "x": 1120,
        "y": 260,
        "wires": [
            [
                "4c73c9c6.c27108"
            ],
            [
                "1bfcb798.56ad58"
            ]
        ]
    },
    {
        "id": "d14a376e.ae7ee8",
        "type": "switch",
        "z": "cfde8d96.fce87",
        "name": "if 409",
        "property": "err.statusCode",
        "propertyType": "msg",
        "rules": [
            {
                "t": "eq",
                "v": "409",
                "vt": "num"
            },
            {
                "t": "else"
            }
        ],
        "checkall": "true",
        "repair": false,
        "outputs": 2,
        "x": 790,
        "y": 320,
        "wires": [
            [
                "7e3edb68.358e44"
            ],
            [
                "1bfcb798.56ad58"
            ]
        ]
    },
    {
        "id": "7e3edb68.358e44",
        "type": "change",
        "z": "cfde8d96.fce87",
        "name": "",
        "rules": [
            {
                "t": "delete",
                "p": "err",
                "pt": "msg"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 940,
        "y": 320,
        "wires": [
            [
                "7c4fd902.916c78"
            ]
        ]
    },
    {
        "id": "4c73c9c6.c27108",
        "type": "forge-oss",
        "z": "cfde8d96.fce87",
        "name": "",
        "topic": "",
        "forge": "",
        "operation": "ObjectDetails",
        "raw": false,
        "all": false,
        "bucket": "",
        "policyKey": "transient",
        "key": "",
        "contentType": "application/octet-stream",
        "contentDisposition": "",
        "copy": "",
        "localFilename": "",
        "limit": 10,
        "startAt": "",
        "beginsWith": "",
        "with": [],
        "ifMatch": "",
        "ifNoneMatch": "",
        "ifModifiedSince": "",
        "range": "",
        "access": "read",
        "singleUse": false,
        "minutesExpiration": 60,
        "acceptEncoding": "",
        "guid": "autodesk",
        "region": "US",
        "x": 1350,
        "y": 260,
        "wires": [
            [
                "9c36435d.5a5b5",
                "1ff67f2c.445741"
            ],
            [
                "1bfcb798.56ad58"
            ]
        ]
    },
    {
        "id": "9c36435d.5a5b5",
        "type": "debug",
        "z": "cfde8d96.fce87",
        "name": "Results",
        "active": true,
        "tosidebar": true,
        "console": true,
        "tostatus": false,
        "complete": "true",
        "targetType": "full",
        "statusVal": "",
        "statusType": "auto",
        "x": 1320,
        "y": 440,
        "wires": []
    },
    {
        "id": "1bfcb798.56ad58",
        "type": "debug",
        "z": "cfde8d96.fce87",
        "name": "Error",
        "active": true,
        "tosidebar": true,
        "console": true,
        "tostatus": false,
        "complete": "true",
        "targetType": "full",
        "statusVal": "",
        "statusType": "auto",
        "x": 1320,
        "y": 400,
        "wires": []
    },
    {
        "id": "8eeff612.bb9278",
        "type": "comment",
        "z": "cfde8d96.fce87",
        "name": "Setup - Readme",
        "info": "\nThe node below contains information to setup your environment. If you have a file already loaded and translate, you can skip that step.\n\n{\n    \"bucket\": \"your bucket name\",\n    \"key\": \"object name you want to use on OSS\",\n    \"localFilename\": \"full path to the file you want to uplaod\",\n    \"region\": \"US or EMEA - defines the region where you want to post the file\"\n    \n    \"sha1\": \"optional parameter to verify file content after upload\"\n}\n\nOnce the file is uploaded on OSS, you need to translate it, if this is not yet the case.",
        "x": 140,
        "y": 80,
        "wires": []
    },
    {
        "id": "9a72ea1f.294f78",
        "type": "inject",
        "z": "cfde8d96.fce87",
        "name": "Hook Model",
        "props": [
            {
                "p": "payload"
            },
            {
                "p": "topic",
                "vt": "str"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "{\"bucket\":\"vi-node-red-bucket-viewer3\",\"key\":\"Freiburgtunnel.rvt\",\"localFilename\":\"/data/files/Freiburgtunnel.rvt\",\"region\":\"EMEA\"}",
        "payloadType": "json",
        "x": 150,
        "y": 280,
        "wires": [
            [
                "7ad88c9d.47c724"
            ]
        ]
    },
    {
        "id": "1130b20c.4a181e",
        "type": "subflow:fee8fd5f.f1b33",
        "z": "cfde8d96.fce87",
        "name": "",
        "env": [],
        "x": 930,
        "y": 460,
        "wires": [
            [
                "c7d56299.6728f",
                "f66bef0f5ac06df7"
            ],
            [
                "9f61b893.68a4c8"
            ],
            [
                "2f23e0ef.ff095",
                "86af2e9ad94bde69"
            ]
        ]
    },
    {
        "id": "c7d56299.6728f",
        "type": "debug",
        "z": "cfde8d96.fce87",
        "name": "Results",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "true",
        "targetType": "full",
        "x": 1320,
        "y": 560,
        "wires": []
    },
    {
        "id": "9f61b893.68a4c8",
        "type": "debug",
        "z": "cfde8d96.fce87",
        "name": "Progress",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "true",
        "targetType": "full",
        "statusVal": "",
        "statusType": "auto",
        "x": 1320,
        "y": 600,
        "wires": []
    },
    {
        "id": "2f23e0ef.ff095",
        "type": "debug",
        "z": "cfde8d96.fce87",
        "name": "Error",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "true",
        "targetType": "full",
        "statusVal": "",
        "statusType": "auto",
        "x": 1310,
        "y": 640,
        "wires": []
    },
    {
        "id": "a567fc2a.a690f",
        "type": "inject",
        "z": "cfde8d96.fce87",
        "name": "Hook Model",
        "props": [
            {
                "p": "payload"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "{\"bucket\":\"vi-node-red-bucket-viewer3\",\"key\":\"Freiburgtunnel.rvt\",\"localFilename\":\"/data/files/Freiburgtunnel.rvt\",\"region\":\"EMEA\"}",
        "payloadType": "json",
        "x": 150,
        "y": 320,
        "wires": [
            [
                "bf74912821979376"
            ]
        ]
    },
    {
        "id": "1ff67f2c.445741",
        "type": "function",
        "z": "cfde8d96.fce87",
        "name": "",
        "func": "//msg = msg.payload;\nmsg.urn = `urn:adsk.objects:os.object:${msg.bucket}/${msg.key}`;\nreturn msg;",
        "outputs": 1,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 520,
        "y": 460,
        "wires": [
            [
                "e47058bd.de9d88"
            ]
        ]
    },
    {
        "id": "e47058bd.de9d88",
        "type": "base64",
        "z": "cfde8d96.fce87",
        "name": "",
        "action": "",
        "property": "urn",
        "x": 720,
        "y": 460,
        "wires": [
            [
                "1130b20c.4a181e"
            ]
        ]
    },
    {
        "id": "df982a48.5d4818",
        "type": "comment",
        "z": "cfde8d96.fce87",
        "name": "View my file",
        "info": "",
        "x": 130,
        "y": 720,
        "wires": []
    },
    {
        "id": "aa195124.3862d",
        "type": "http in",
        "z": "cfde8d96.fce87",
        "name": "/",
        "url": "/api/forge/",
        "method": "get",
        "upload": false,
        "swaggerDoc": "",
        "x": 110,
        "y": 760,
        "wires": [
            [
                "8c4094b0.d55118"
            ]
        ]
    },
    {
        "id": "80f105eb.5f97c8",
        "type": "http response",
        "z": "cfde8d96.fce87",
        "name": "",
        "statusCode": "200",
        "headers": {
            "content-type": "text/html"
        },
        "x": 960,
        "y": 760,
        "wires": []
    },
    {
        "id": "266c7c19.e20e84",
        "type": "template",
        "z": "cfde8d96.fce87",
        "name": "",
        "field": "payload",
        "fieldType": "msg",
        "format": "handlebars",
        "syntax": "mustache",
        "template": "<!DOCTYPE html>\n<html>\n\n<head>\n\t<title>Sample</title>\n\t<meta charset=\"utf-8\" />\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n\n\t<!-- Autodesk Forge Viewer files -->\n    <link rel=\"stylesheet\" href=\"https://developer.api.autodesk.com/modelderivative/v2/regions/eu/viewers/7.*/style.css\">\n    <script src=\"https://developer.api.autodesk.com/modelderivative/v2/regions/eu/viewers/7.*/viewer3D.js\"></script>\n\t<script>\n\t\tvar viewer = null;\n\n\t\tfunction launchViewer() {\n\t\t\tconst options = {\n\t\t\t\tenv: 'AutodeskProduction',\n                api: 'derivativeV2_EU',  // for models uploaded to EMEA change this option to 'derivativeV2_EU'\n\t\t\t\tgetAccessToken: getForgeToken\n\t\t\t};\n\n\t\t\tAutodesk.Viewing.Initializer(options, () => {\n\t\t\t\tviewer = new Autodesk.Viewing.GuiViewer3D(document.getElementById('forgeViewer'));\n\t\t\t\tviewer.start();\n\t\t\t\tconst documentId = 'urn:{{payload.urn}}';\n\t\t\t\tAutodesk.Viewing.Document.load(documentId, onDocumentLoadSuccess, onDocumentLoadFailure);\n\t\t\t});\n\t\t}\n\n\t\tfunction onDocumentLoadSuccess(doc) {\n\t\t\tconst viewables = doc.getRoot().getDefaultGeometry();\n\t\t\tviewer.loadDocumentNode(doc, viewables).then(i => {\n\t\t\t\t// documented loaded, any action?\n\t\t\t});\n\t\t}\n\n\t\tfunction onDocumentLoadFailure(viewerErrorCode) {\n\t\t\tconsole.error('onDocumentLoadFailure() - errorCode:' + viewerErrorCode);\n\t\t}\n\n\t\tfunction getForgeToken(callback) {\n\t\t\tfetch('/api/forge/oauth/token').then(res => {\n\t\t\t\tres.json().then(data => {\n\t\t\t\t    console.log (JSON.stringify(data));\n\t\t\t\t\tcallback(data.access_token, data.expires_in);\n\t\t\t\t});\n\t\t\t});\n\t\t}\n\n\t</script>\n</head>\n\n<body onload=\"launchViewer()\">\n\t<div id=\"forgeViewer\"></div>\n</body>\n\n</html>",
        "output": "str",
        "x": 780,
        "y": 760,
        "wires": [
            [
                "80f105eb.5f97c8"
            ]
        ]
    },
    {
        "id": "562f71e2.0e873",
        "type": "http in",
        "z": "cfde8d96.fce87",
        "name": "Get Token",
        "url": "/api/forge/oauth/token",
        "method": "get",
        "upload": false,
        "swaggerDoc": "",
        "x": 120,
        "y": 860,
        "wires": [
            [
                "724a8b77.6bef04"
            ]
        ]
    },
    {
        "id": "6f1f4e3f.49d89",
        "type": "http response",
        "z": "cfde8d96.fce87",
        "name": "",
        "statusCode": "200",
        "headers": {
            "content-type": "application/json"
        },
        "x": 960,
        "y": 860,
        "wires": []
    },
    {
        "id": "a63abd3e.6f02",
        "type": "function",
        "z": "cfde8d96.fce87",
        "name": "",
        "func": "msg.payload = msg.payload.token;\nreturn msg;",
        "outputs": 1,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "x": 780,
        "y": 860,
        "wires": [
            [
                "6f1f4e3f.49d89"
            ]
        ]
    },
    {
        "id": "724a8b77.6bef04",
        "type": "forge-get-token",
        "z": "cfde8d96.fce87",
        "name": "",
        "topic": "",
        "forge": "",
        "x": 470,
        "y": 860,
        "wires": [
            [
                "a63abd3e.6f02"
            ]
        ]
    },
    {
        "id": "8c4094b0.d55118",
        "type": "function",
        "z": "cfde8d96.fce87",
        "name": "",
        "func": "var obj = {\n    \"bucket\": \"vi-node-red-bucket-viewer3\",\n    \"key\": encodeURI(msg.req.query.filename)\n};\nmsg.payload = {\n    urn: `urn:adsk.objects:os.object:${obj.bucket}/${obj.key}`\n};\nreturn msg;",
        "outputs": 1,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 300,
        "y": 760,
        "wires": [
            [
                "de2c5e40.6e50e",
                "2c1c485898d38de3"
            ]
        ]
    },
    {
        "id": "de2c5e40.6e50e",
        "type": "base64",
        "z": "cfde8d96.fce87",
        "name": "",
        "action": "",
        "property": "payload.urn",
        "x": 460,
        "y": 760,
        "wires": [
            [
                "ac18f070.bf731"
            ]
        ]
    },
    {
        "id": "4a012231.91825c",
        "type": "http in",
        "z": "cfde8d96.fce87",
        "name": "/index.html",
        "url": "/api/forge/index.html",
        "method": "get",
        "upload": false,
        "swaggerDoc": "",
        "x": 120,
        "y": 800,
        "wires": [
            [
                "8c4094b0.d55118"
            ]
        ]
    },
    {
        "id": "ac18f070.bf731",
        "type": "function",
        "z": "cfde8d96.fce87",
        "name": "",
        "func": "msg.payload.urn = msg.payload.urn\n    .replace(/\\+/g, '-') // Convert '+' to '-'\n\t.replace(/\\//g, '_') // Convert '/' to '_'\n\t.replace(/=+$/, '')\nreturn msg;",
        "outputs": 1,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 620,
        "y": 760,
        "wires": [
            [
                "266c7c19.e20e84"
            ]
        ]
    },
    {
        "id": "be0ce380687b0256",
        "type": "debug",
        "z": "cfde8d96.fce87",
        "name": "",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "true",
        "targetType": "full",
        "statusVal": "",
        "statusType": "auto",
        "x": 630,
        "y": 360,
        "wires": []
    },
    {
        "id": "1be2ad07b8382968",
        "type": "template",
        "z": "cfde8d96.fce87",
        "name": "",
        "field": "payload",
        "fieldType": "msg",
        "format": "handlebars",
        "syntax": "mustache",
        "template": "<!DOCTYPE html>\n<html>\n\n<head>\n\t<title>Sample</title>\n\t<meta charset=\"utf-8\" />\n\n\t<!-- Autodesk Forge Viewer files -->\n\t<link rel=\"stylesheet\" href=\"https://developer.api.eu.autodesk.com/modelderivative/v2/regions/eu/viewers/7.*/style.min.css\"\n\t\ttype=\"text/css\">\n\t<script src=\"https://developer.api.autodesk.com/modelderivative/v2/regions/eu/viewers/7.*/viewer3D.min.js\"></script>\n\n\t<script>\n\t\tvar viewer = null;\n\n\t\tfunction launchViewer() {\n\t\t\tconst options = {\n\t\t\t\tenv: 'AutodeskProduction',\n\t\t\t\tgetAccessToken: getForgeToken\n\t\t\t};\n\n\t\t\tAutodesk.Viewing.Initializer(options, () => {\n\t\t\t\tviewer = new Autodesk.Viewing.GuiViewer3D(document.getElementById('forgeViewer'));\n\t\t\t\tviewer.start();\n\t\t\t\tconst documentId = 'urn:{{payload.urn}}';\n\t\t\t\tAutodesk.Viewing.Document.load(documentId, onDocumentLoadSuccess, onDocumentLoadFailure);\n\t\t\t});\n\t\t}\n\n\t\tfunction onDocumentLoadSuccess(doc) {\n\t\t\tconst viewables = doc.getRoot().getDefaultGeometry();\n\t\t\tviewer.loadDocumentNode(doc, viewables).then(i => {\n\t\t\t\t// documented loaded, any action?\n\t\t\t});\n\t\t}\n\n\t\tfunction onDocumentLoadFailure(viewerErrorCode) {\n\t\t\tconsole.error('onDocumentLoadFailure() - errorCode:' + viewerErrorCode);\n\t\t}\n\n\t\tfunction getForgeToken(callback) {\n\t\t\tfetch('/api/forge/oauth/token').then(res => {\n\t\t\t\tres.json().then(data => {\n\t\t\t\t    console.log (JSON.stringify(data));\n\t\t\t\t\tcallback(data.access_token, data.expires_in);\n\t\t\t\t});\n\t\t\t});\n\t\t}\n\n\t</script>\n</head>\n\n<body onload=\"launchViewer()\">\n\t<div id=\"forgeViewer\"></div>\n</body>\n\n</html>",
        "output": "str",
        "x": 780,
        "y": 800,
        "wires": [
            []
        ]
    },
    {
        "id": "08f1b710bca53ba6",
        "type": "http in",
        "z": "cfde8d96.fce87",
        "name": "",
        "url": "/api/forge/upload",
        "method": "post",
        "upload": true,
        "swaggerDoc": "",
        "x": 160,
        "y": 220,
        "wires": [
            [
                "a0edf38c24a0fcef"
            ]
        ]
    },
    {
        "id": "9d3f694934fb56e3",
        "type": "file",
        "z": "cfde8d96.fce87",
        "name": "",
        "filename": "",
        "appendNewline": false,
        "createDir": false,
        "overwriteFile": "true",
        "encoding": "none",
        "x": 500,
        "y": 220,
        "wires": [
            [
                "2b9a7f19356a072d"
            ]
        ]
    },
    {
        "id": "74291bf6713112ed",
        "type": "debug",
        "z": "cfde8d96.fce87",
        "name": "",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "true",
        "targetType": "full",
        "statusVal": "",
        "statusType": "auto",
        "x": 1310,
        "y": 220,
        "wires": []
    },
    {
        "id": "a0edf38c24a0fcef",
        "type": "function",
        "z": "cfde8d96.fce87",
        "name": "",
        "func": "msg.filename = \"/data/files/\" + msg.payload.filename;\nmsg.filename_only = msg.payload.filename;\nmsg.payload = msg.req.files[0].buffer;\nreturn msg;",
        "outputs": 1,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 340,
        "y": 220,
        "wires": [
            [
                "9d3f694934fb56e3",
                "46a3e14406d093c7"
            ]
        ]
    },
    {
        "id": "2b9a7f19356a072d",
        "type": "function",
        "z": "cfde8d96.fce87",
        "name": "",
        "func": "msg.bucket = \"vi-node-red-bucket-viewer3\";\nmsg.key = msg.filename_only;\nmsg.localFilename = msg.filename,\nmsg.region = \"EMEA\";\nreturn msg;",
        "outputs": 1,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 660,
        "y": 220,
        "wires": [
            [
                "48f6000a.518b4",
                "74291bf6713112ed"
            ]
        ]
    },
    {
        "id": "06aa46e2c604f6e7",
        "type": "http response",
        "z": "cfde8d96.fce87",
        "name": "",
        "statusCode": "200",
        "headers": {},
        "x": 1320,
        "y": 480,
        "wires": []
    },
    {
        "id": "f66bef0f5ac06df7",
        "type": "function",
        "z": "cfde8d96.fce87",
        "name": "",
        "func": "msg.payload.url=\"http://vidsyno01.voessing.de:1880/api/forge/index.html?filename=\" + encodeURI(msg.filename_only);\nreturn msg;",
        "outputs": 1,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 1140,
        "y": 440,
        "wires": [
            [
                "06aa46e2c604f6e7",
                "003d94201e10c8c1"
            ]
        ]
    },
    {
        "id": "003d94201e10c8c1",
        "type": "debug",
        "z": "cfde8d96.fce87",
        "name": "",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "true",
        "targetType": "full",
        "statusVal": "",
        "statusType": "auto",
        "x": 1310,
        "y": 520,
        "wires": []
    },
    {
        "id": "2c1c485898d38de3",
        "type": "debug",
        "z": "cfde8d96.fce87",
        "name": "",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "true",
        "targetType": "full",
        "statusVal": "",
        "statusType": "auto",
        "x": 450,
        "y": 800,
        "wires": []
    },
    {
        "id": "d3dca57e0b94edc3",
        "type": "catch",
        "z": "cfde8d96.fce87",
        "name": "",
        "scope": null,
        "uncaught": false,
        "x": 120,
        "y": 920,
        "wires": [
            [
                "f9e5b0b8b9925d8b"
            ]
        ]
    },
    {
        "id": "f9e5b0b8b9925d8b",
        "type": "debug",
        "z": "cfde8d96.fce87",
        "name": "",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "true",
        "targetType": "full",
        "statusVal": "",
        "statusType": "auto",
        "x": 280,
        "y": 920,
        "wires": []
    },
    {
        "id": "bf74912821979376",
        "type": "function",
        "z": "cfde8d96.fce87",
        "name": "",
        "func": "msg = msg.payload;\nmsg.urn = `urn:adsk.objects:os.object:${msg.bucket}/${msg.key}`;\nreturn msg;",
        "outputs": 1,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 340,
        "y": 320,
        "wires": [
            [
                "e47058bd.de9d88"
            ]
        ]
    },
    {
        "id": "854e8b01d12cac85",
        "type": "http response",
        "z": "cfde8d96.fce87",
        "name": "",
        "statusCode": "404",
        "headers": {},
        "x": 1320,
        "y": 680,
        "wires": []
    },
    {
        "id": "caf74d089cde3d22",
        "type": "comment",
        "z": "cfde8d96.fce87",
        "name": "Upload and translate",
        "info": "\nThe node below contains information to setup your environment. If you have a file already loaded and translate, you can skip that step.\n\n{\n    \"bucket\": \"your bucket name\",\n    \"key\": \"object name you want to use on OSS\",\n    \"localFilename\": \"full path to the file you want to uplaod\",\n    \"region\": \"US or EMEA - defines the region where you want to post the file\"\n    \n    \"sha1\": \"optional parameter to verify file content after upload\"\n}\n\nOnce the file is uploaded on OSS, you need to translate it, if this is not yet the case.",
        "x": 150,
        "y": 180,
        "wires": []
    },
    {
        "id": "46a3e14406d093c7",
        "type": "debug",
        "z": "cfde8d96.fce87",
        "name": "",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "true",
        "targetType": "full",
        "statusVal": "",
        "statusType": "auto",
        "x": 520,
        "y": 120,
        "wires": []
    },
    {
        "id": "86af2e9ad94bde69",
        "type": "function",
        "z": "cfde8d96.fce87",
        "name": "",
        "func": "if (msg.err){\n    msg.payload = msg.err;\n}\nreturn msg;",
        "outputs": 1,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 1160,
        "y": 680,
        "wires": [
            [
                "854e8b01d12cac85"
            ]
        ]
    }
]

Main issue stays the polling of the result, would be much better to enable an event driven flow.

BerndGewehr commented 2 years ago

I am doing postman post against the upload endpoint like this

image

BerndGewehr commented 2 years ago

In my res there is the URL I need to embed the viewer.

Got a better approach? Let's battle a bit...

cyrillef commented 2 years ago

@BerndGewehr - I updated the package to v0.0.5and fix your credentials issue, and rewrote the viewer sample to include a file upload. Start with /select.html You need to make sure the settings are ok on the Settings node. The bucket name should be unique across all accounts, so choose something unique.