Google Apps Scriptで繰り返し作業を自動化した話2 -BIM360との連携
こちらのスクリプト部分を説明していきます。
Google Apps Scriptでは簡単に外部のWebAPIにアクセスすることができるUrlFetchApp
を提供しています。
こちらを用いてForgeのAPIへアクセスしていきます。共通の設定として以下のものを使用しています。
const base_url = 'https://developer.api.autodesk.com/';
1 Authenticate
1.1 TwoLeggedAccessTokenの取得
今回作成したコードでは別途config
にてアプリの設定を行なっている。そのため、必要なものはそちらから取得している。
APIのドキュメントはこちら
Responseのstatus codeを取得することで、適切に処理が行われているのかを確認します。
ただ、設定をしないとcodeを取得することができません。必ずoption
にmuteHttpExceptions: true
を追加してください。
それによりcodeを取得することが出来る様になります。
function getTwoLeggedToken() {
var scriptProperties = PropertiesService.getScriptProperties();
var client_id = scriptProperties.getProperty('clientId');
var client_secret = scriptProperties.getProperty('clientSecret');
var scope = scriptProperties.getProperty('scope');
var body = {
'client_id' : client_id,
'client_secret' : client_secret,
'grant_type' : 'client_credentials',
'scope' : scope
}
var options = {
'method': 'post',
'contentType': 'application/x-www-form-urlencoded',
'payload' : body,
muteHttpExceptions: true
}
var res = UrlFetchApp.fetch(base_url + 'authentication/v1/authenticate', options);
if (res.getResponseCode() == 200) return res;
else throw("Failed to get Two Legged Access Token.");
}
1.2 Tokenの取得
Two-Leggedのレスポンスにはaccess_token
とexpires_in
が含まれます。一定時間が過ぎるとTokenを再取得する必要があります。
また、時間内であれば再度取得しなくて良いように保存しておくよう設定をしています。
function getToken() {
config();
var scriptProperties = PropertiesService.getScriptProperties();
var expiredDate = new Date(scriptProperties.getProperty('twoLeggedExpiresIn'));
if ( expiredDate == undefined || expiredDate.getTime() < new Date().getTime())
{
var res = getTwoLeggedToken();
if (res != undefined)
{
var token = JSON.parse(getTwoLeggedToken());
var auth = token.token_type + ' ' + token.access_token;
scriptProperties.setProperty('twoLeggedToken', auth);
expiresIn(token.expires_in);
}
}
return scriptProperties.getProperty('twoLeggedToken');
}
function expiresIn(time) {
var scriptProperties = PropertiesService.getScriptProperties();
var date = new Date();
var expiredDate = new Date();
expiredDate.setSeconds(expiredDate.getSeconds() + time)
if (expiredDate > date){
scriptProperties.setProperty('twoLeggedExpiresIn', expiredDate);
}
}
2 Projectの取得
Projectの取得にはData Management API
を用いる方法とBIM360 API
を用いる方法がありますが、今回は2Leggedで取得可能なBIM360 API
を使用していきます。
こちらには取得できるプロジェクト数に制限があり、100個までとなっています。そのため、どこから100個取得するのかをoffset
で指定しています。
また、offsetを設定しない場合にはdefault
値である0
になるようになっています。
function getProjects(offset) {
config();
var token = getToken();
var scriptProperties = PropertiesService.getScriptProperties();
var accountId = ScriptProperties.getProperty('accountId');
var headers = {
Authorization:token
}
var url = base_url + 'hq/v1/accounts/' + accountId + '/projects?limit=100';
var options = {
'method' : 'get',
'headers' : headers,
muteHttpExceptions: true
}
if (offset != undefined) {
url += '&offset=' + offset;
}
var res = UrlFetchApp.fetch(url, options);
if (res.getResponseCode() == 200) {
return res;
} else {
throw("Failed to get Projects.");
}
}
3 Account Userの取得
Userの取得にもProject同様のAPIが用意されています。ただ、問題はProject
に比べてUser
は登録人数が膨大になっている可能性があります。そのため、users/serch
を使っていく方法を取りました。
Project同様のやり方は以下のとおりです。
function getUsers(offset) {
config();
var token = getToken();
var scriptProperties = PropertiesService.getScriptProperties();
var accountId = ScriptProperties.getProperty('accountId');
var headers = {
Authorization:token
}
var url = base_url + 'hq/v1/accounts/' + accountId + '/users?limit=100';
var options = {
'method' : 'get',
'headers' : headers,
muteHttpExceptions: true
}
if (offset != undefined) {
url += '&offset=' + offset;
}
var res = UrlFetchApp.fetch(url, options);
if (res.getResponseCode() == 200) {
return res;
}
return;
}
一方で、emailを利用した取得の方法がこちらです。こちらのAPIではname
, email
, company_name
を単体または複数(AND/OR)の条件で検索することができます。
function getIserByEmail(email) {
var emailUrl = email.replace('@', '%40');
config();
var token = getToken();
var scriptProperties = PropertiesService.getScriptProperties();
var accountId = ScriptProperties.getProperty('accountId');
var headers = {
Authorization:token
}
var options = {
'method' : 'get',
'headers' : headers,
muteHttpExceptions: true
}
var res = UrlFetchApp.fetch(base_url + 'hq/v1/accounts/' + accountId + '/users/search?email=' + emailUrl, option);
if (res.getResponseCode() == 200) {
return res;
} else {
throw Error("Can't get user by Email");
}
}
4 Projectへの登録
ここまで来たら登録したいプロジェクトにユーザーを登録するだけです。使用するのはPOST projects/:project_id/users/import
となります。複数名を一括で登録することも可能ですので、コードを少々変更していただければと思います。
function posetUserToProject(userId, projectId) {
var myUserId = 'PUT YOUR USER ID HERE';
config();
var token = getToken();
var scriptProperties = PropertiesService.getScriptProperties();
var accountId = ScriptProperties.getProperty('accountId');
var headers = {
Authorization:token,
'x-user-id' : myUserId
}
var body = [{
'user_id' : userId,
'servicies' : {
'project_administration' : {
'access_level' : 'admin'
},
'document_management' : {
'access_level' : 'admin'
}
}
}]
//OR
/*
var body = [{
'user_id' : userId,
'servicies' : {
'document_management' : {
'access_level' : 'user'
}
}
}]
*/
var options = {
'method': 'post',
'contentType': 'application/json',
'payload' : JSON.stringify(body),
muteHttpExceptions: true
}
var res = UrlFetchApp.fetch(base_url + 'hq/v2/accounts/' + accountId + '/projects/' + projectId + '/users/import',options);
if (res.getResponseCode() == 200) {
return res;
} else {
throw Error("Can't post user to Project");
}
}
5 まとめ
Google Sheetと合わせて使うと非常に便利です。
メールアドレスを使って一括登録はBIM360 Teamではできたのですが、BIM360 Docs以降はできなくなってしまいました。少しでもめんどくさい作業がなくなれば良いなと思います。千人単位の登録とかメンドすぎます…
おまけ
config()
を勝手に使ってますが、こんな感じにしてあります。
毎度毎度やる必要はないかと思いますが、どのようなプロセスが踏まれるかわからないので、念の為入れてありますが、必要なければ削除することも可能です。
function config() {
var scriptProperties = PropertiesService.getScriptProperties();
scriptProperties.setProperties({
'clientId': 'YOUR CLIENT ID HERE',
'clientSecret': 'YOUR CLIENT SECRET HERE',
'scope' : 'account:read account:write',
'accountId' : 'YOUR ACCOUNT ID HERE'
})
Discussion