はじめに
kintoneでシステムを開発したのですが、同システムのゲストユーザーアカウントを希望する人(メールでアカウント申請した人)に自動発行したいと思い立ちました。
開発したシステム: https://qiita.com/Lastonemile/items/65b9102c868e09b3248e
そこで、GAS(Google Apps Script)とAWSを組み合わせて、自動発行することにしました。
出来たこと
指定した条件の受信メールを自動取得し、同内容をAWSへ送信しAWSでその内容に沿ってゲストユーザー登録を自動化しました。
GASの設定
これまで全く利用したことはありませんが、GASの設定はググりながらで比較的すんなり行えました。(ベースはjavascriptのようです)
// 初期設定
const HOOK_URL = 'https://xxxxxxxxxxxx'; //AWS(api gateway)エンドポイント
function main() {
let after = parseInt(((new Date()).getTime() - 5 * 60 * 1000) / 1000); //5分前の時刻をUNIX時間で取得
let searchTarget = 'in:inbox subject:"アカウント申請" is:unread after:' + after; //検索条件を指定(after以降で件名「アカウント申請」含む)
GmailApp
.search(searchTarget)
.forEach(function (thread) {
let resp;
let mark = false;
thread.getMessages().forEach(function (message) {
let subject = message.getSubject();
resp = send(message);
resp = JSON.parse(resp)
mark = true;
Logger.log(resp);
});
if(mark){
thread.markRead(); //既読に変更
MailApp.sendEmail({ //AWSの処理結果をメール送信
to:resp.body.from,
subject:resp.body.subject,
body:resp.body.body
});
}
});
}
function send(message) {
let sendText = {
"title":message.getSubject(),
"detail":message.getPlainBody()
}
let jsonData = {
"username" : message.getFrom(),
"text" : sendText
}
let options = {
"method" : "POST",
"contentType" : "application/json",
"payload" : JSON.stringify(jsonData)
};
let resp = UrlFetchApp.fetch(HOOK_URL, options); //受信内容をAWSへ
return resp;
}
#AWSの設定(kintoneゲストユーザー追加)
大まかな処理の流れとしては、①ゲストユーザーを追加、②現在スペースに紐づけられているゲストユーザーを取得、③追加したゲストユーザーおよび現ゲストユーザーをスペースに紐づけ 以上になります。
*②については、apiで取得する方法がないようなので、別アプリに登録することで対応しました。
const request = require('/opt/aws-layer/node_modules/request');
exports.handler = async (event) => {
// TODO implement
const code = extract(event.username,"<",">");
const reg_mail = /^[A-Za-z0-9]{1}[A-Za-z0-9_.-]*@{1}[A-Za-z0-9_.-]{1,}\.[A-Za-z0-9]{1,}$/;//メールアドレス判定
if(reg_mail.test(code)){
const DOMAIN = "kintoneドメイン";
const headers = {'X-Cybozu-Authorization': 'kintoneのid:pass(base64)','Content-Type': 'application/json','X-Requested-With':'XMLHttpRequest'};
const pass = pass_create();
let resp = await requestPromise(kintone_guest(headers,DOMAIN,code,pass));
let message = resp.message;
let result;
if(!message){
let resp_guest_new = await requestPromise(guest_newuser(headers,DOMAIN,code,pass));
let resp_guest_get = await requestPromise(guest_get(headers,DOMAIN));
let member = [];
for( let i = 0; i < resp_guest_get.records.length; i++ ){
member.push(resp_guest_get.records[i].MAIL.value);
}
let resp_guest_put = await requestPromise(guest_put(headers,DOMAIN,member));
}
if(!message){
message = remessage(code,pass);
}
result = {
from:event.username,
subject:"ご連絡ありがとうございます",
body:message
};
const response = {
statusCode: 200,
body: result,
};
return response;
}
};
//request promise
function requestPromise(param){
return new Promise((resolve, reject)=>{
request(param, function (error, response, body) {
if(error){
reject("ページを取得できませんでした");
}else{
resolve(body);
}
})
})
}
//kintoneゲスト追加
const kintone_guest = function(headers,DOMAIN,code,pass){
let body = {
'guests': [
{
'code': code,
'password': pass,
'timezone': 'Asia/Tokyo',
'locale': 'ja',
'name': extract(code,"","@")
}
]
};
let BASE_URL = "https://" + DOMAIN + "/k/v1/guests.json";
let options_postguest = {
url: BASE_URL,
method: 'POST',
headers: headers,
body: body,
json: true
};
return options_postguest;
}
//ゲスト情報別記
function guest_newuser(headers,DOMAIN,code,pass){
let url = "https://" + DOMAIN + "/k/v1/record.json";
let body = {
'app': "アプリid",
'record': {
'名前':{
'value': extract(code,"","@")
},
'MAIL':{
'value': code
},
'初期PASS':{
'value': pass
},
'vision_累計': {
'value': 0
},
'vision_月間': {
'value': 0
}
}
};
let options_postrecords = {
url: url,
method: 'POST',
headers: headers,
'Content-Type': 'application/json',
json: true,
body:body
};
return options_postrecords;
}
//メンバー取得
function guest_get(headers,DOMAIN){
let url = "https://" + DOMAIN + "/k/v1/records.json";
let body = {"app": アプリid};
let options_guestget = {
url: url,
method: 'GET',
headers: headers,
json: true,
body: body
};
return options_guestget;
}
//メンバー更新
function guest_put(headers,DOMAIN,member){
let url = "https://" + DOMAIN + "/k/guest/スペースID/v1/space/guests.json";
let body = {"id": スペースid};
body.guests = member;
let options_guestput = {
url: url,
method: 'PUT',
headers: headers,
json: true,
body: body
};
return options_guestput;
}
//メールアドレス抜き出し
function extract(str,before,after){
const beforeIdx = str.indexOf(before);
const afterIdx = str.lastIndexOf(after);
let result;
if (beforeIdx >= 0 && afterIdx >= 0) {
result = str.substring(beforeIdx + before.length, afterIdx);
}else if(!before && afterIdx >= 0){
result = str.substring(0, afterIdx);
}
return result;
}
//パスワード生成
function pass_create(){
let letters = 'abcdefghijklmnopqrstuvwxyz';
let numbers = '0123456789';
let string = letters + letters.toUpperCase() + numbers;
let len = 8; //8文字
let password=''; //文字列が空っぽという定義をする
for (let i = 0; i < len; i++) {
password += string.charAt(Math.floor(Math.random() * string.length));
}
password = password;
return password;
}
//返信メッセージ作成
function remessage(code,pass){
let result = "ご連絡ありがとうございます、下記の通りGuest ID を取得しました。" +
"\nURL: URL\nID(E-mail): " + code + "\nPassWord: " + pass;
return result;
}
筆者の紹介
群馬県の渋川市・高崎市を中心に群馬県内でkintoneを利用したDX化支援を行っています。ご興味ある方はぜひご連絡ください。
https://ks-kiki.hp.peraichi.com/