LoginSignup
0
2

More than 1 year has passed since last update.

【GAS x AWS】kintoneのゲストユーザーを自動追加したい~GASとAWSを連携してメールを自動処理する~【kintone】

Last updated at Posted at 2021-02-24

はじめに

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/

0
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
2