I am building a website using the autodesk forge viewer and fusion360. Currently I have an app where users can log in, and view models in a fusion360 folder. However, currently I have to log in to my autodesk account in order to view those models. Obviously, users won't have access to that data to log-in. Therefore I was following this tutorial which allows users to view all the models in a fusion360 folder without having to sign into autodesk. Below is my js code for my forge functions:
//Function to get the part name from __MachineAssembly.php
var ext = '';
var dim = '';
var assemblyname = '';
function getAssemblyName(){
assemblyname = sessionStorage.getItem("assemblyName");
//var ext = partname.substr(partname.lastIndexOf('.'));
var checkIam = assemblyname.includes(".iam");
console.log(checkIam);
if (checkIam == true){
ext = assemblyname.replace(".iam", "").replace(".dwf", "");}
var checkIpt = assemblyname.includes(".ipt");
if (checkIpt == true){
ext = assemblyname.replace(".ipt", "").replace(".dwf", "");
}
//console.log(ext);
dim = ext + ":1";
console.log(dim);
//ext = assemblyname.split('.');
//dim = ext[0] + ':1';
//dim = ext[0];
//console.log(assemblyname);
//console.log(dim);
if (dim !== ''){
isolateSelected();
}
}
//function to get part name from __MachineParts.php
var partname = '';
var extension = '';
var namewithoutextension = '';
//var partname123 = '';
function getPartName(){
partname = sessionStorage.getItem("partName");
var checkPartIam = partname.includes(".iam");
//var ext = partname.substr(partname.lastIndexOf('.'));
//extension = partname.split('.');
//namewithoutextension = extension[0] + ':1'
if (checkPartIam == true){
extension = partname.replace(".iam","").replace(".dwf","");}
var checkPartIpt = partname.includes(".ipt")
if (checkPartIpt == true){
extension = partname.replace(".ipt","").replace(".dwf","");}
// partname123 = extension.split(" ");
namewithoutextension = extension + ":1";
//namewithoutextension = partname123[0];
//console.log(partname);
console.log(namewithoutextension);
if (namewithoutextension !== ''){
isolateSelectedPart();
}
}
/*******************************************************************************
*
* AUTODESK FORGE VIEWER CODE (HTTP REQUESTS)
*
*******************************************************************************/
//VARIABLE DECLARATION
var code = '';
var access_token = '';
var refreshToken = '';
const hub = 'xxxxxxxxxxxxxxxxxxxxx';
const project ='xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx';
const folder='xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx';
const item = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx';
var itemid = '';
var urn = '';
var urn2 = '';
//allow the program to view data from autodesk
function authorize(){
window.location.href = "https://developer.api.autodesk.com/authentication/v1/authorize?response_type=code&client_id=dm2VLfnwJ6rYHKPAg7dG6l9yVbBQPGlH&redirect_uri=http%3A%2F%2Fteam%2F__MachineViewerMV.php&scope=data:read data:write viewables:read";
}
//grab the code from the url
function getCode(){
const querystring = window.location.search;
// console.log(querystring);
const urlParams = new URLSearchParams(querystring);
code = urlParams.get('code');
// console.log(code);
}
//call the function to get the code right away, and obtain a token
getCode();
getToken();
//function to obtain access token
function getToken(){
$.ajax({
method: 'POST',
url: 'https://developer.api.autodesk.com/authentication/v1/gettoken',
headers: {
'Content-Type':'application/x-www-form-urlencoded'
},
data:'client_id=xxxxxxxxxxxxxxxxxH&client_secret=xxxxxxxxxxxx&grant_type=authorization_code&code=' + code + '&redirect_uri=http://team/__MachineViewerMV.php',
success:function(response){
// console.log(response);
access_token = response.access_token;
console.log(access_token);
console.log(response);
refreshToken = response.refresh_token;
}
})
}
function useRefresh(){
$.ajax({
method:'POST',
url: 'https://developer.api.autodesk.com/authentication/v1/refreshtoken',
headers: {
'Content-Type':'application/x-www-form-urlencoded'
},
data:'client_id=xxxxxxxxxxxxxxxxx&client_secret=xxxxxxxxxxxxxx&grant_type=refresh_token&refresh_token='+refreshToken+'&scope=viewables:read',
success:function(response){
console.log(response);
refreshToken = response.refreshToken;
}
})
}
//Grab desired file id from project folder
function getItem(){
if(viewer !== null){destroyViewer();}
$.ajax({
method:'GET',
url: 'https://developer.api.autodesk.com/data/v1/projects/' + project + '/folders/' + item + '/contents',
headers:{
Authorization:'Bearer ' + access_token
},
/* beforeSend:function(before){
if(access_token !== '' && viewer !==''){
destroyViewer();}
},*/
success:function(response){
//console.log(response);
// folder = response.data[0].id;
// console.log(folder);
// itemid = response.data[0].id;
//console.log(itemid);
console.log(response);
for (var i = 0; i<response.data.length; i++){
//console.log(response.data[i].attributes.displayName);
if(response.data[i].attributes.displayName == fileName){
//console.log('hooray');
itemid = response.data[i].id;
console.log(itemid);
getVersion();
break;
}
else if (response.data[i].attributes.displayName !== fileName){
itemid = '';
}
}
},
error:function(error){
authorize();
}
})
}
function getItem2(){
$.ajax({
method:'GET',
url: 'https://developer.api.autodesk.com/data/v1/projects/' + project + '/folders/' + item + '/contents',
headers:{
Authorization:'Bearer ' + access_token
},
/* beforeSend:function(before){
if(access_token !== '' && viewer !==''){
destroyViewer();}
},*/
success:function(response){
//console.log(response);
// folder = response.data[0].id;
// console.log(folder);
// itemid = response.data[0].id;
//console.log(itemid);
console.log(response);
for (var i = 0; i<response.data.length; i++){
//console.log(response.data[i].attributes.displayName);
if(response.data[i].attributes.displayName == fileName2){
//console.log('hooray');
itemid = response.data[i].id;
console.log(itemid);
getVersion();
break;
}
else if (response.data[i].attributes.displayName !== fileName2){
itemid = '';
}
}
},
error:function(error){
authorize();
}
})
}
function get2dItem(){
if(viewer !== null){destroyViewer();}
$.ajax({
method:'GET',
url: 'https://developer.api.autodesk.com/data/v1/projects/' + project + '/folders/' + item + '/contents',
headers:{
Authorization:'Bearer ' + access_token
},
/*beforeSend:function(before){
if(access_token !== '' && viewer !== ''){
destroyViewer();}
},*/
success:function(response){
//console.log(response);
// folder = response.data[0].id;
// console.log(folder);
// itemid = response.data[0].id;
//console.log(itemid);
console.log(response);
for (var i = 0; i<response.data.length; i++){
//console.log(response.data[i].attributes.displayName);
if(response.data[i].attributes.displayName == fileName2d){
//console.log('hooray');
itemid = response.data[i].id;
console.log(itemid);
getVersion();
break;
}
else if (response.data[i].attributes.displayName !== fileName2d){
itemid = '';
}
}
},
error:function(error){
authorize();
}
})
}
//get version of the file using its id
function getVersion(){
$.ajax({
method:'GET',
url: 'https://developer.api.autodesk.com/data/v1/projects/' + project + '/items/' + itemid + '/versions',
headers:{
Authorization:'Bearer ' + access_token
},
success:function(response){
//console.log(response);
urn = btoa(response.data[0].relationships.storage.data.id);
console.log(urn);
translateToSVF();
}
})
}
function translateToSVF(){
$.ajax({
method: 'POST',
url:"https://developer.api.autodesk.com/modelderivative/v2/designdata/job",
headers:{
"content-type": "application/json",
Authorization: "Bearer " + access_token
},
data:JSON.stringify({
"input":{ "urn":urn
},
"output": {
"formats": [
{
"type": "svf",
"views": [
"2d",
"3d"
]
}
]
}
}),
success:function(response){
// console.log(response);
urn2 = response.urn;
console.log(urn2);
checkStatus();
}
})
}
function checkStatus(){
$.ajax({
method: 'GET',
url: "https://developer.api.autodesk.com/modelderivative/v2/designdata/" + urn2 + "/manifest",
headers:{
Authorization: "Bearer " + access_token
},
success: function(response){
console.log(response);
if (response.progress == 'complete'){
displayViewer();
}
else if (response.progress !== 'complete'){
alert('File Still Uploading, Press the Display Button Again!');
}
}
})
}
//function to get list of viewables\
var guid = '';
function getViewable(){
$.ajax({
method:'GET',
headers:{
Authorization: "Bearer " + access_token
},
url: 'https://developer.api.autodesk.com/modelderivative/v2/designdata/' + urn2 + '/metadata',
success:function(response){
console.log(response);
guid = response.data.metadata[0].guid;
console.log(guid);
}
})
}
//funciton to get the list of items within a model
function getTree(){
$.ajax({
method: 'GET',
headers:{
Authorization: "Bearer " + access_token
},
url:'https://developer.api.autodesk.com/modelderivative/v2/designdata/' + urn2 + '/metadata/' + guid + '/properties',
success:function(response){
console.log(response);
}
})
}
/*
var isSelected = '';
function eventCheck(){
viewer.addEventListener(
Autodesk.Viewing.ISOLATE_EVENT,
(event) => {
isSelected = 'Part Isolated';
console.log(isSelected);
// highlight('fox');
isSelected = 1;
}
)
}*/
var dbIdSel = '';
function eventCheck(){
// viewer2 = new Autodesk.Viewing.Model;
viewer.addEventListener(Autodesk.Viewing.SELECTION_CHANGED_EVENT, onSelectionChanged)
function onSelectionChanged(dbids){
console.log(dbids)
dbIdSel1 = dbids.dbIdArray;
if (dbIdSel1.length > 1){
dbIdSel = dbids.dbIdArray[1];
}
else{
dbIdSel = dbids.dbIdArray[0];
}
// console.log(dbIdSel);
getPropVal();
/*
if (dbIdSel == undefined){
dbIdSel = dbids.dbIdArray[1];
}*/
}}
var selectedProp = '';
function getPropVal(){
viewer.getProperties(dbIdSel, props => {
// props.properties.forEach(prop => {
// any custom action with data?
///console.log(props.properties[2]);
selectedProp1 = props.properties[2].displayValue.split(" ");
selectedProp5 = selectedProp1[0];
if (selectedProp5.includes('_')){
selectedProp = selectedProp5.replace("_","/");
}
else{
var selectedProp3 = selectedProp5.split("-");
console.log(selectedProp3);
if (selectedProp3.length == 2){
selectedProp = selectedProp3[0] + '-' + selectedProp3[1];
console.log(selectedProp);}
if (selectedProp3.length == 3){
selectedProp = selectedProp3[0] + '-' + selectedProp3[1] + '/' + selectedProp3[2];
console.log(selectedProp);}}
sessionStorage.setItem("selectedProperty", selectedProp);
//console.log(selectedProp.split("-"[0][1]))
// console.log(prop.displayValue);
// selectedProp = prop.displayValue;
// console.log(selectedProp.split(" "));
// console.log(selectedProp);
//prop.displayCategory
// etc
// });
});
}
/*
function highlight(text) {
var inputText = document.getElementById("Assemblies1");
var innerHTML = inputText.innerHTML;
var index = innerHTML.indexOf(text);
if (index >= 0) {
innerHTML = innerHTML.substring(0,index) + "<span class='highlight'>" + innerHTML.substring(index,index+text.length) + "</span>" + innerHTML.substring(index + text.length);
inputText.innerHTML = innerHTML;
}
}*/
var propertyValue = '';
function onPropertyClick(property, event) {
// console.log(property.value);
propertyValue = property.value;
console.log(propertyValue);
}
function scrollToAssembly(){
var elmnt = document.getElementById("AssemblyDetails");
elmnt.scrollIntoView();
}
function scrollToPart(){
var elmnt = document.getElementById("PartDetails");
elmnt.scrollIntoView();
}
/**********************************************************************************
*
* FUNCTION TO DISPLAY THE VIEWER IN THE HTML PAGE
*
**********************************************************************************/
//CODE FOR FUSION360 INTERNAL VIEWER
var viewer = null;
function displayViewer(){
//var viewer;
var options = {
env: 'AutodeskProduction',
api: 'derivativeV2', // for models uploaded to EMEA change this option to 'derivativeV2_EU'
getAccessToken: function(onTokenReady) {
var token = access_token;
console.log(token);
var timeInSeconds = 3600; // Use value provided by Forge Authentication (OAuth) API
onTokenReady(token, timeInSeconds);
}
};
Autodesk.Viewing.Initializer(options, function() {
viewer = new Autodesk.Viewing.Private.GuiViewer3D(document.getElementById('forgeViewer'),{extensions:['HandleSelectionExtension', 'ModelSummaryExtension']});
//var htmlDiv = document.getElementById('forgeViewer');
// viewer = new Autodesk.Viewing.Private.GuiViewer3D(htmlDiv);
Autodesk.Viewing.UI.PropertyPanel.prototype.onPropertyClick = onPropertyClick;
var startedCode = viewer.start();
// sessionStorage.setItem("viewer", viewer);
if (startedCode > 0) {
console.error('Failed to create a Viewer: WebGL not supported.');
return;
}
console.log('Initialization complete, loading a model next...');
});
var documentId = 'urn:'+urn2;
Autodesk.Viewing.Document.load(documentId, onDocumentLoadSuccess, onDocumentLoadFailure);
function onDocumentLoadSuccess(viewerDocument) {
var defaultModel = viewerDocument.getRoot().getDefaultGeometry();
viewer.loadDocumentNode(viewerDocument, defaultModel);
console.log(viewer);
viewer.setSelectionColor(new THREE.Color(0xFFAB33));
eventCheck();
// viewer.openPropertiesOnSelect = true;
}
function onDocumentLoadFailure() {
console.error('Failed fetching Forge manifest');
}
}
//function to hide the viewer
function destroyViewer(){
console.log(viewer);
console.log(viewer.contextMenu);
viewer.finish();
viewer = null;
Autodesk.Viewing.shutdown();
console.log(viewer);
}
function checkview(){
console.log(viewer);
}
/*****************************************************************************
* FUNCTIONS TO MODIFY THE VIEWER TO ZOOM INTO THE CORRECT PART/ASSEMBLY
*/
var genAssName = '';
function isolateSelected(){
console.log(dim);
console.log(viewer);
/* if (viewer == null){
getItem();
}*/
viewer.search(dim, function(dbIds) {
// viewer.search('"' + 'M-109408 FOLDING PLOUGH:2' + '"', function(dbIds) {
console.log(dbIds.length);
/*if (dbIds.length == 0){
getItem();
}*/
if (dbIds.length == 0){
dim = ext + ':2';
isolateSelected2();
}
getSubset(dbIds, 'label', dim, function(dbIds) {
// getSubset(dbIds, 'label', 'M-109408 FOLDING PLOUGH:2', function(dbIds) {
// getSubset(dbIds, property.name, 'M-54439 POST TUBING:1', function(dbIds) {
//getSubset(dbIds, property.name, property.value, function(dbIds){
var it = viewer.model.getData().instanceTree;
//console.log(it);
for (i = 0; i<dbIds.length; i++){
var namepart = it.getNodeName(dbIds[i]);
if (namepart !== undefined){
console.log(dbIds);
console.log(namepart);
genAssName = namepart.split(" ")[0];
console.log(genAssName);
sessionStorage.setItem("highlightedAssName",genAssName);
}}
/* for (i = 121; i<381;i++){
var dbId = i;
var it = NOP_VIEWER.model.getData().instanceTree;
var name = it.getNodeName(dbId);
console.log(name);}*/
// viewer.setBackgroundColor(255,0,0,255,0,0);
// viewer.setSelectionColor(new THREE.Color(1,1,1));
// viewer.setSelectionColor(new THREE.Color(0xFFAB33));
viewer.setSelectionColor(new THREE.Color(0xFFC000));
viewer.setBackgroundOpacity(1.0);
viewer.isolate(dbIds)
viewer.select(dbIds);
viewer.utilities.fitToView();
$(window).scrollTop(600);
})
}, function(error) {})
}
function isolateSelected2(){
console.log(dim);
console.log(viewer);
/* if (viewer == null){
getItem();
}*/
viewer.search(dim, function(dbIds) {
// viewer.search('"' + 'M-109408 FOLDING PLOUGH:2' + '"', function(dbIds) {
console.log(dbIds.length);
/*if (dbIds.length == 0){
getItem();
}*/
if (dbIds.length == 0){
alert("Error Isolating Assembly. Search for it inside the viewer.");
}
getSubset(dbIds, 'label', dim, function(dbIds) {
// getSubset(dbIds, 'label', 'M-109408 FOLDING PLOUGH:2', function(dbIds) {
// getSubset(dbIds, property.name, 'M-54439 POST TUBING:1', function(dbIds) {
//getSubset(dbIds, property.name, property.value, function(dbIds){
var it = viewer.model.getData().instanceTree;
//console.log(it);
for (i = 0; i<dbIds.length; i++){
var namepart = it.getNodeName(dbIds[i]);
if (namepart !== undefined){
console.log(dbIds);
console.log(namepart);}}
/* for (i = 121; i<381;i++){
var dbId = i;
var it = NOP_VIEWER.model.getData().instanceTree;
var name = it.getNodeName(dbId);
console.log(name);}*/
// viewer.setBackgroundColor(255,0,0,255,0,0);
// viewer.setSelectionColor(new THREE.Color(1,1,1));
// viewer.setSelectionColor(new THREE.Color(0xFFAB33));
viewer.setSelectionColor(new THREE.Color(0xFFC000));
viewer.setBackgroundOpacity(1.0);
viewer.isolate(dbIds)
viewer.select(dbIds);
viewer.utilities.fitToView();
$(window).scrollTop(600);
})
}, function(error) {})
}
function isolateSelectedPart(){
console.log(namewithoutextension);
if (viewer == null){
getItem();
}
viewer.search(namewithoutextension, function(dbIds) {
// viewer.search('"' + 'M-109408 FOLDING PLOUGH:2' + '"', function(dbIds) {
console.log(dbIds.length);
if (dbIds.length == 0){
// getItem();
alert("Error Isolating Part. Search for it inside the viewer.");
}
getSubset(dbIds, 'label', namewithoutextension, function(dbIds) {
// getSubset(dbIds, 'label', 'M-109408 FOLDING PLOUGH:2', function(dbIds) {
// getSubset(dbIds, property.name, 'M-54439 POST TUBING:1', function(dbIds) {
//getSubset(dbIds, property.name, property.value, function(dbIds){
var it = viewer.model.getData().instanceTree;
//console.log(it);
for (i = 0; i<dbIds.length; i++){
var namepart = it.getNodeName(dbIds[i]);
if (namepart !== undefined){
console.log(dbIds);
console.log(namepart);}}
/* for (i = 121; i<381;i++){
var dbId = i;
var it = NOP_VIEWER.model.getData().instanceTree;
var name = it.getNodeName(dbId);
console.log(name);}*/
viewer.setSelectionColor(new THREE.Color(0xFFAB33));
viewer.setBackgroundOpacity(1.0);
/********************************************************************
* DECIDE IF YOU WANT TO ISOLATE ALL OF THE SAME PART OR ONLY ONE
*********************************************************************/
//isolate one of the parts
// viewer.isolate(dbIds[1])
// viewer.select(dbIds[1]);
//isolate all of the same part
viewer.isolate(dbIds);
viewer.select(dbIds);
viewer.utilities.fitToView();
$(window).scrollTop(600);
})
}, function(error) {})
}
//function to find the dbid of the part/assembly
function getSubset(dbIds, name, value, callback) {
console.log("getSubset, dbIds.length before = " + dbIds.length)
viewer.model.getBulkProperties(dbIds, {
propFilter: [name],
ignoreHidden: true
}, function(data) {
var newDbIds = []
for (var key in data) {
var item = data[key]
// console.log(item.properties);
if (item.properties[0].displayValue === value) {
newDbIds.push(item.dbId)
}
}
console.log("getSubset, dbIds.length after = " + newDbIds.length)
callback(newDbIds)
}, function(error) {})
}
/********************************************************
* VIEWER EXTENSION CODE FOR ISOLATE PART BUTTON
*********************************************************/
class HandleSelectionExtension extends Autodesk.Viewing.Extension {
constructor(viewer, options) {
super(viewer, options);
this._group = null;
this._button = null;
}
load() {
console.log('HandleSelectionExtension has been loaded');
return true;
}
unload() {
// Clean our UI elements if we added any
if (this._group) {
this._group.removeControl(this._button);
if (this._group.getNumberOfControls() === 0) {
this.viewer.toolbar.removeControl(this._group);
}
}
console.log('HandleSelectionExtension has been unloaded');
return true;
}
onToolbarCreated() {
// Create a new toolbar group if it doesn't exist
this._group = this.viewer.toolbar.getControl('allMyAwesomeExtensionsToolbar');
if (!this._group) {
this._group = new Autodesk.Viewing.UI.ControlGroup('allMyAwesomeExtensionsToolbar');
this.viewer.toolbar.addControl(this._group);
}
// Add a new button to the toolbar group
this._button = new Autodesk.Viewing.UI.Button('handleSelectionExtensionButton');
this._button.onClick = (ev) => {
const selection = this.viewer.getSelection();
this.viewer.clearSelection();
// Anything selected?
if (selection.length > 0) {
let isolated = [];
// Iterate through the list of selected dbIds
selection.forEach((dbId) => {
// Get properties of each dbId
this.viewer.getProperties(dbId, (props) => {
// Output properties to console
console.log(props);
console.log(props.name);
// Ask if want to isolate
// if (confirm(`Isolate ${props.name} (${props.externalId})?`)) {
isolated.push(dbId);
this.viewer.isolate(isolated);
//window.open('mailto:[email protected]?subject=subject&body='+props.name);
//}
});
});
} else {
// If nothing selected, restore
this.viewer.isolate(0);
}
};
this._button.setToolTip('Isolate Part');
this._button.addClass('handleSelectionExtensionIcon');
this._group.addControl(this._button);
}
}
Autodesk.Viewing.theExtensionManager.registerExtension('HandleSelectionExtension', HandleSelectionExtension);
//CODE FOR BUTTON TO ORDER A SPARE PART
class ModelSummaryExtension extends Autodesk.Viewing.Extension {
constructor(viewer, options) {
super(viewer, options);
this._group = null;
this._button = null;
}
load() {
console.log('ModelSummaryExtension has been loaded');
return true;
}
unload() {
// Clean our UI elements if we added any
if (this._group) {
this._group.removeControl(this._button);
if (this._group.getNumberOfControls() === 0) {
this.viewer.toolbar.removeControl(this._group);
}
}
console.log('ModelSummaryExtension has been unloaded');
return true;
}
onToolbarCreated() {
// Create a new toolbar group if it doesn't exist
this._group = this.viewer.toolbar.getControl('allMyAwesomeExtensionsToolbar');
if (!this._group) {
this._group = new Autodesk.Viewing.UI.ControlGroup('allMyAwesomeExtensionsToolbar');
this.viewer.toolbar.addControl(this._group);
}
// Add a new button to the toolbar group
this._button = new Autodesk.Viewing.UI.Button('ModelSummaryExtensionButton');
this._button.onClick = (ev) => {
// Execute an action here
// Get current selection
const selection = this.viewer.getSelection();
this.viewer.clearSelection();
// Anything selected?
if (selection.length > 0) {
let isolated = [];
// Iterate through the list of selected dbIds
selection.forEach((dbId) => {
// Get properties of each dbId
this.viewer.getProperties(dbId, (props) => {
// Output properties to console
console.log(props);
var partname1 = props.name.split(' ');
var partname2 = partname1[0];
// Ask if want to isolate
if (confirm(`Would you like to order a spare of ${partname2} ?`)) {
// isolated.push(dbId);
// this.viewer.isolate(isolated);
var quant = prompt('How many would you like to order?','1');
var isNum = parseInt(quant);
if(Number.isInteger(isNum) == false){
quant = prompt('Please enter a number. How many would you like to order?','1');
window.open('mailto:[email protected]?subject=Spare Part Order of ' + partname2 + '&body=We need a quantity of ' + quant + ' '+partname2);
}
else{
window.open('mailto:[email protected]?subject=Spare Part Order of ' + partname2 + '&body=We need a quantity of ' + quant + ' '+partname2);
}}
});
});
} else {
// If nothing selected, restore
this.viewer.isolate(0);
alert("Please Select a Part to Order")
}
};
this._button.setToolTip('Order this Part');
this._button.addClass('modelSummaryExtensionIcon');
this._group.addControl(this._button);
}
}
Autodesk.Viewing.theExtensionManager.registerExtension('ModelSummaryExtension', ModelSummaryExtension);
How can I modify this code so that users do not need to sign into my autodesk account in order to view my models inside a particular folder. I know that using a refreshToken will help. However my function named useRefresh() will only work once before getting an error. How can I change the above code so that the authentication is skipped and users can view all models inside a fusion360 folder. Thanks for all the help! Cheers!
If I understand correctly, you are trying to do exactly the same as described in the article you referenced, right? The source code for it is here: https://github.com/adamenagy/models-website
That means that only you need to log in to Forge (and only once) in order to enable your website to get access to your files. Other users could not log in to have access to your files. Once you logged in, your server side code would need to take care of storing the access_token (which provides access to your files) and the refresh_token. You can use the latter to get new access tokens when needed.
An access token usually expires within an hour. You also have to get a new access_token and refresh_token within 2 weeks even if nobody visited your site within that time period. Otherwise the refresh_token expires, and you will have to log in again to get a new access_token and refresh_token that your server side code could use.
Some more info on this topic: Landing your Forge OAuth authentication workflow
Also, it's not mentioned in the article yet, but it would be better to not provide an access token to the client (i.e. client side javascript code) at all, but make the Viewer pass its requests through your server: Securing your Forge Viewer token behind a proxy In that case we could make sure that only models inside the specific folder can be viewed.
If you're trying to make multiple Fusion Team users' folder public, then they would each have to log in once, and your server side code would need to keep track of the access_token and refresh_token for each account.