在Google Apps脚本中从用户名获取名称和姓氏 问题:工作流程:代码示例:注意:流量:示例脚本:

问题描述

我使用脚本自动插入日期和用户名以填写字符串。桌子上有几个人。如何修改脚本,以便插入名字和姓氏而不是用户名

function onEdit(e) {
  var sheet = e.source.getActiveSheet();
  var idCol = e.range.getColumn();
  var idRow = e.range.getRow();
  
  if ( idCol == 4 && sheet.getName() =='LIST1' ) {
    var Value = e.range.offset(0,-2).getValues();
    if ( Value == "" ) {
      var vartoday = getDate();  //Gets the current date//
      sheet.getRange(idRow,2).setValue( vartoday ); //Inserts into column 2 of the current row//
      var u = Session.getEffectiveUser().getUsername();  //Gets the username of the editor//
      sheet.getRange(idRow,7).setValue(u); //Inserts into column 7 of the current row//
    }
  }
  function getDate() {
    var today = new Date();
    today.setDate(today.getDate());
    return Utilities.formatDate(today,'GMT+03:00','dd/MM/yy');
  }
}

解决方法

好像您将用户名存储在此处-

var u = Session.getEffectiveUser().getUsername();  //Gets the username of the editor//

然后在此处插入用户名-

sheet.getRange(idRow,7).setValue(u); //Inserts into column 7 of the current row//

在存储名称之前,您需要先拆分名称。像这样-

var first_name = // Split by your delimeter here and store first name 
var last_name = // Split by your delimeter here and store last name 
sheet.getRange(idRow,7).setValue(first_name); //Inserts into column 7 of the current row//
sheet.getRange(idRow,8).setValue(last_name); //Inserts into column 8 of the current row//
,

问题:

getUsername()仅提供不带域部分的电子邮件地址(即@之前的内容)。假设并非每个电子邮件地址都按照其他答案(例如name.surname中的建议)以可区分的方式设置格式,则它不会提供有关名称或姓氏的信息。

如果要访问用户的实际姓名和姓氏,则需要从Users resource访问Directory API。最简单的方法是在脚本上使用高级Admin SDK Directory Service

重要说明:这要求使用Admin SDK,该方法只能由Google Workspace(以前称为G Suite)帐户使用。如果您不是Workspace用户,则无法检索此信息

工作流程:

  • 通过单击Resources > Advanced Google Services...在脚本上启用高级目录服务,将directory_v1设置为on,然后单击OKsee example
  • 由于访问此API需要授权,并且简单触发器无法访问需要授权的服务(请参见Restrictions),因此您必须安装onEdit(e)触发器。首先,更改函数的名称,使其不称为onEdit。这是保留的函数名称,用于简单的触发器(在下面的代码示例中,我将其称为fireOnEdit)。
  • 安装触发器,manually(请参见example settings)或programmatically
  • 在已安装的触发器中,effective user是安装触发器的用户,而不是其编辑触发了脚本的用户。因此,您将需要使用getActiveUser()或事件对象(属性e.user)。
  • 使用高级服务,通过调用Users: get来检索活动的用户属性。
  • 从API响应中检索两个所需的字段:名字(User.name.givenName)和姓氏(User.name.familyName)。

代码示例:

function fireOnEdit(e) {
  var sheet = e.source.getActiveSheet();
  var idCol = e.range.getColumn();
  var idRow = e.range.getRow();  
  if ( idCol == 4 && sheet.getName() =='LIST1' ) {
    var Value = e.range.offset(0,-2).getValues();
    if ( Value == "" ) {
      var vartoday = getDate();  //Gets the current date//
      sheet.getRange(idRow,2).setValue( vartoday ); //Inserts into column 2 of the current row//
      var email = e.user.getEmail();
      var user = AdminDirectory.Users.get(email);
      var name = user.name.givenName;
      var surname = user.name.familyName;
      //sheet.getRange(idRow,7).setValue(name + " " + surname); // Name and surname copied to the same cell in G
      sheet.getRange(idRow,7,1,2).setValues([[name,surname]]); // Name and surname copied to G and H
    }
  }
  function getDate() {
    var today = new Date();
    today.setDate(today.getDate());
    return Utilities.formatDate(today,'GMT+03:00','dd/MM/yy');
  }
}

注意:

  • 关于活动用户的信息可能并不总是可用(例如,如果创建触发器的用户和导致脚本运行的用户不属于同一域)。例如,请参见this answer
  • 您需要使用可以通过Directory API访问Users资源的帐户安装触发器。
  • 我不确定您是否要在同一单元格中同时连接名字和姓氏,还是将一个添加到列G中,另一个添加到列H中。我在代码示例中添加了两种可能性,请根据您的喜好注释/取消注释相应的行。
,

如果您是Gsuite / Google工作区的客户,则可以使用Directory API as mentioned in this answer

如果没有,您也许可以利用ScriptApp提供的 identity token

★您需要获得每个编辑器的显式权限才能获得其名称。未经明确许可,您将无法以编程方式记录其编辑。内置功能“编辑历史记录”仍会记录下来。

流量:

  • 从“文件”>“项目属性”>“作用域”中获取当前脚本作用域
  • 将显式openidprofileemail范围添加到上述范围,并将它们添加到manifest。例如,以下示例脚本需要以下作用域:
  "oauthScopes":["openid","profile","email","https://www.googleapis.com/auth/script.scriptapp","https://www.googleapis.com/auth/spreadsheets.currentonly","https://www.googleapis.com/auth/script.container.ui"
                ],
  • 请编辑者通过单击菜单按钮进行注册,以将其添加到编辑日志中

  • 单击菜单按钮,为他们创建一个已安装的Edit触发器。

  • 使用可安装的编辑触发器获取identity token。解析令牌以获得名字和姓氏。

示例脚本:

function getNameOfCurrentEditor() {
  const idToken = ScriptApp.getIdentityToken();
  const body = idToken.split('.')[1];
  const decoded = Utilities.newBlob(
    Utilities.base64Decode(body)
  ).getDataAsString();
  const { given_name: firstName,family_name: lastName } = JSON.parse(decoded);
  return { firstName,lastName };
}

/**
 * @param{GoogleAppsScript.Events.SheetsOnEdit} e
 */
function installedEditTrigger(e) {
  const eUser = e.user.getEmail();
  if (eUser === '') return; //no permission=> exit
  const { firstName,lastName } = getNameOfCurrentEditor();
  e.range.setNote(
    `${e.range.getNote()}\n${e.value} added by ${firstName}_${lastName}`
  );
}

function onOpen() {
  SpreadsheetApp.getUi()
    .createMenu('Edit Logger')
    .addItem('Sign me up!','createEditTrigger')
    .addToUi();
}

function createEditTrigger() {
  ScriptApp.newTrigger('installedEditTrigger')
    .forSpreadsheet(SpreadsheetApp.getActive())
    .onEdit()
    .create();
}

注意:注册的所有编辑者的多个编辑触发器将自动运行,但是只有实际进行编辑的编辑者才能通过此条件:if (eUser === '')。之所以可行,是因为每个编辑者都无法获得其他编辑者的电子邮件地址。在这种情况下,仅返回一个空字符串。

,

说明:

假设用户名的格式为{{1},那么您可以使用split(),通过使用{{,将名称姓氏分开1}}和name.surname

如果用户名的格式不同,则可以相应地更改参数。例如,如果您有u.split('.')[0],则使用u.split('.')[1]name-surname


解决方案:

u.split('-')[0]