Comment passer un paramètre au format html?

J'ai un script qui utilise le sélecteur de fichiers, mais j'ai besoin de passer un paramètre spécifique qui est appelé nom d'utilisateur et est conservé comme une variable globale dans le script d'appel. Que les appels sont asynchrones, il semble que je ne peut pas accéder à ce paramètre. Est-il loin pour accéder à ce paramètre dans le fichier html ou de passer ce paramètre à la page html?

J'ai peut-être un mélange basé sur un modèle html et non basé sur un modèle (c'est à dire https://developers.google.com/apps-script/guides/html/templates et https://developers.google.com/apps-script/guides/html/) mais j'ai besoin de résoudre ce problème.

Reconnaissant de toute aide.

Voici le code appelant (initié par l'intermédiaire d'un élément de menu dans une feuille de calcul):

function syncStudentsFile(userId, ss) {
  scriptUser_(userId);  //save userId
  Logger.log('SRSConnect : syncStudentsFile : userId:'+userId);  //userId is correct here
  var ss = SpreadsheetApp.getActiveSpreadsheet();  
  var html = HtmlService.createHtmlOutputFromFile('PickerSync.html')
    .setWidth(600).setHeight(425);
  SpreadsheetApp.getUi().showModalDialog(html, 'Select a file');
}

function scriptUser_(userId) {
  if (userId !== undefined)
    sUserId = userId; //Global variable
  try { return sUserId; } catch (e) { return undefined; }
}

function getOAuthToken() {  //used by Picker
  DriveApp.getRootFolder();
  return ScriptApp.getOAuthToken();
}

Voici le code html du sélecteur de fichier:

<link rel="stylesheet" href="https://ssl.gstatic.com/docs/script/css/add-ons.css">
<script type="text/javascript">
var DEVELOPER_KEY = '..............';
var DIALOG_DIMENSIONS = {width: 600, height: 425};
var pickerApiLoaded = false;
/**
* Loads the Google Picker API.
*/
gapi.load('picker', {'callback': function() {
pickerApiLoaded = true;
}});
/**
* Gets the user's access token from the server-side script so that
* it can be passed to Picker. This technique keeps Picker from needing to
* show its own authorization dialog, but is only possible if the OAuth scope
* that Picker needs is available in Apps Script. Otherwise, your Picker code
* will need to declare its own OAuth scopes.
*/
function getOAuthToken() {
google.script.run.withSuccessHandler(createPicker)
.withFailureHandler(showError).getOAuthToken();
}
/**
* Creates a Picker that can access the user's spreadsheets. This function
* uses advanced options to hide the Picker's left navigation panel and
* default title bar.
*
* @param {string} token An OAuth 2.0 access token that lets Picker access the
*     file type specified in the addView call.
*/
function createPicker(token) {
if (pickerApiLoaded && token) {
var uploadView = new google.picker.DocsUploadView();
var picker = new google.picker.PickerBuilder()
//Instruct Picker to display only spreadsheets in Drive. For other
//views, see https://developers.google.com/picker/docs/#otherviews
.addView(google.picker.ViewId.DOCS)
.addView(google.picker.ViewId.RECENTLY_PICKED)
.addView(uploadView)
.hideTitleBar()
.setOAuthToken(token)
.setDeveloperKey(DEVELOPER_KEY)
.setCallback(pickerCallback)
//Instruct Picker to fill the dialog, minus 2 pixels for the border.
.setSize(DIALOG_DIMENSIONS.width - 2,
DIALOG_DIMENSIONS.height - 2)
.build();
picker.setVisible(true);
} else {
showError('Unable to load the file picker.');
}
}
/**
* A callback function that extracts the chosen document's metadata from the
* response object. For details on the response object, see
* https://developers.google.com/picker/docs/result
*
* @param {object} data The response object.
*/
function pickerCallback(data) {
var action = data[google.picker.Response.ACTION];
if (action == google.picker.Action.PICKED) {
var doc = data[google.picker.Response.DOCUMENTS][0];
var id = doc[google.picker.Document.ID];
google.script.host.close();
//--------------> user global parameter sUserId set earlier
google.script.run.PickerSyncFile(sUserId, id);
} else if (action == google.picker.Action.CANCEL) {
google.script.host.close();
}
}
/**
* Displays an error message within the #result element.
*
* @param {string} message The error message to display.
*/
function showError(message) {
document.getElementById('result').innerHTML = 'Error: ' + message;
}
</script>
<div>
<script>getOAuthToken()</script>
<p id='result'></p>
<input type="button" value="Close" onclick="google.script.host.close()" />
</div>

Voici le sélecteur de code:

function pickerSyncFile(userId, id) {
Logger.log('userId:'+userId);  //BUG: it is null
Logger.log('id:'+id);  //id returned well from picker
//rest of code here but userId was is incorrect
}