
ãæŠåšåº«ãéè€ãã§ãã¯ã»èªåãã£ã³ã»ã«ã»ã«ã¬ã³ããŒé£æºãŸã§äºçŽç®¡çãå šéšèªååããæ¹æ³ïŒGoogleããŒã«ïŒ
éè€äºçŽã®èªåãã§ãã¯ã»ãã£ã³ã»ã«ãªã³ã¯ã»ã«ã¬ã³ããŒé£æºãŸã§ããã¹ãŠç¡æããŒã«ã§å®è£ ããå®å šã¬ã€ãã§ããã¹ã¯ãªããã¯ã³ããŒïŒããŒã¹ãã§åããŸãã
ã¯ããã«ïŒãããªæ©ã¿ã¯ãããŸãããïŒ
ãæ©æãäŒè°å®€ã®äºçŽç®¡çãçŽãLINEã§ãã£ãŠããŠãäºéäºçŽãèµ·ããã
ãäºçŽç®¡çããŒã«ãå°å
¥ãããããã³ã¹ãããããã®ã§æ¿èªãäžããªãã
ãGoogleãã©ãŒã ã§äºçŽãåãä»ããŠããããéè€ãã§ãã¯ã¯æäœæ¥ã
ãã®ã¬ã€ãã¯ãããªæ¹ã«åããŠããŸããGoogle ãã©ãŒã ãGoogle ã«ã¬ã³ããŒã䜿ã£ãŠã以äžããã¹ãŠç¡æã§å®çŸããŸãã
â
ãã©ãŒã ããã®äºçŽåä»
â
éè€äºçŽã®èªåãã§ãã¯ã»åæ¶
â
äºçŽç¢ºå®ã»ãšã©ãŒã®èªåã¡ãŒã«éç¥
â
Google ã«ã¬ã³ããŒãžã®èªåç»é²
â
ã¡ãŒã«å
ãªã³ã¯ãã¯ãªãã¯ããã ãã®ãã£ã³ã»ã«æ©èœ
â
ã¹ãã¬ããã·ãŒãã«ããå°åž³ç®¡ç
â
æ¥ããŸããäºçŽã«ã察å¿
äŒç€Ÿã®äŒè°å®€ãã¹ããŒãã¯ã©ãã®èšåãNPOã®æ©æãç 究宀ã®è£ 眮ãªã©ããGoogleã¢ã«ãŠã³ããããçµç¹ãã§ããã°ãã®ãŸãŸäœ¿ããŸãã
ã·ã¹ãã å šäœå
å©çšè
管çè
ïŒèªååŠçïŒ
â â
â ãã©ãŒã éä¿¡ â
âââââââââââââââââââââââââââââââââââºâ
â éè€ãã§ãã¯
â âïŒéè€ããïŒè¡åé€ â ãšã©ãŒã¡ãŒã«éä¿¡
â âïŒéè€ãªãïŒ
â ã«ã¬ã³ããŒã«ã€ãã³ãç»é²
â ããŒã¯ã³çæã»å°åž³ã«èšé²
ââââââââââââââââââââââââââââââââââââ€
â äºçŽç¢ºå®ã¡ãŒã«ïŒãã£ã³ã»ã«ãªã³ã¯ä»ãïŒ
â
â ãã£ã³ã»ã«ãªã³ã¯ãã¯ãªãã¯
âââââââââââââââââââââââââââââââââââºâ
â æ¬äººç¢ºèªã»æéãã§ãã¯
â å°åž³ããåæ¶æžã¿ãã«æŽæ°
â ã«ã¬ã³ããŒã€ãã³ãåé€
ââââââââââââââââââââââââââââââââââââ€
â ãã£ã³ã»ã«å®äºã¡ãŒã«äœ¿çšããŒã«ãšè²»çš
| ããŒã« | çšé | è²»çš |
|--------|------|------|
| Google ãã©ãŒã | äºçŽã®åä» | ç¡æ |
| Google ã¹ãã¬ããã·ãŒã | äºçŽå°åž³ | ç¡æ |
| Google Apps Script | èªååŠçïŒéè€ãã§ãã¯ã»ã¡ãŒã«ã»ãã£ã³ã»ã«ïŒ | ç¡æ |
| Google ã«ã¬ã³ã㌠| äºçŽç¶æ³ã®å¯èŠå | ç¡æ |
Apps Script ã®ç¡ææ ã«ã€ããŠ
ã¡ãŒã«éä¿¡ã¯1æ¥100éïŒGoogle Workspace ã¯1,500éïŒãã¹ã¯ãªããå®è¡æéã¯1æ¥90åãäžéã§ããæ°åäººèŠæš¡ã®çµç¹å
å©çšã§ããã°ååã§ãã
STEP 1ïŒGoogle ãã©ãŒã ã®äœæ
ãã©ãŒã ã®æ°èŠäœæ
Google ãã©ã€ããéãïŒdrive.google.comïŒ
ç»é¢å·Šäžã®ãïŒ æ°èŠããã¯ãªãã¯
ããã®ä»ãâãGoogle ãã©ãŒã ããéžæ
ã¿ã€ãã«ãèšå®ïŒäŸïŒæœèšã»æ©æ äºçŽãã©ãŒã ïŒ
質åé ç®ã®èšå®
以äžã®é ç®ããå¿ é ãã§è¿œå ããŸããåé ç®ã®å³äžã«ãããå¿ é ãã®ãã°ã«ããªã³ã«ããŠãã ããã
| 質åé
ç® | ã¿ã€ã | åè |
|----------|--------|------|
| æ°å / ID | èšè¿°åŒ | å©çšè
ã®ç¹å® |
| æ©æã»èšåå | ãã«ããŠã³ or ã©ãžãªãã¿ã³ | 管çããæ©æããã¹ãŠå
¥å |
| å©çšéå§æ¥æ | æ¥ä»ïŒãæå»ãå«ãããONïŒ | |
| å©çšçµäºæ¥æ | æ¥ä»ïŒãæå»ãå«ãããONïŒ | |
| å©çšç®ç | 段èœïŒèšè¿°åŒïŒ | |
ãæå»ãå«ãããã®èšå®æ¹æ³
æ¥ä»ã¿ã€ãã®è³ªåã远å ããããå³äžã®ãã»ã»ã»ãïŒãã®ä»ã®ãªãã·ã§ã³ïŒãã¯ãªãã¯ãããæå»ãå«ãããããªã³ã«ããŠãã ããã
éèŠïŒã»ãã¥ãªãã£èšå®
ãã©ãŒã ã®ãèšå®ãã¿ã âãåçãã»ã¯ã·ã§ã³ âãã¡ãŒã«ã¢ãã¬ã¹ãåéãããã ONïŒç¢ºèªæžã¿ïŒ ã«ããŸãã
ããã«ãã Google ã¢ã«ãŠã³ãã§ã®ãã°ã€ã³ãå¿ é ã«ãªãããªãããŸãäºçŽãã¹ãã ã鲿¢ã§ããŸãã
ãã©ãŒã ã®èª¬ææ¬ã«ã«ã¬ã³ããŒãæ¡å ãã
ãã©ãŒã ã®èª¬ææ¬ã«ãåŸã§äœæããäºçŽã«ã¬ã³ããŒã®å ¬éURLãèšèŒããŠãããŸãïŒSTEP 4 ã§ååŸïŒã
ãäºçŽåã«äžèšã«ã¬ã³ããŒã§ç©ºãç¶æ³ãã確èªãã ããïŒhttps://calendar.google.com/âŠã
STEP 2ïŒäºçŽå°åž³ïŒã¹ãã¬ããã·ãŒãïŒã®æºå
ãã©ãŒã ç·šéç»é¢ã®ãåçãã¿ããã¯ãªãã¯
ç·ã®ã¹ãã¬ããã·ãŒãã¢ã€ã³ã³ïŒãã¹ãã¬ããã·ãŒãã§ç¢ºèªãïŒãã¯ãªãã¯
ãæ°ããã¹ãã¬ããã·ãŒããäœæããéžæããŠé£æº
ãã©ãŒã ã®åçãèªåçã«ã¹ãã¬ããã·ãŒãã«èç©ãããããã«ãªããŸãã
åã®é çªã確èªãã
ãã©ãŒã ã®è³ªåé ç®ãAåïŒã¿ã€ã ã¹ã¿ã³ãïŒããé ã«äžŠã³ãŸããåŸã§èšå®ããã¹ã¯ãªããã® `COL` 宿°ã®çªå·ãšãã®åé ã察å¿ããŠããŸãã
åã®ç¢ºèªæ¹æ³
ã¹ãã¬ããã·ãŒããéãã1è¡ç®ã®é
ç®åã確èªããŠãã ããã
AåïŒã¿ã€ã ã¹ã¿ã³ãïŒèªåïŒ
BåïŒã¡ãŒã«ã¢ãã¬ã¹ïŒèªåïŒ
CåïŒæ°å / ID
DåïŒæ©æã»èšåå
EåïŒå©çšéå§æ¥æ
FåïŒå©çšçµäºæ¥æ
GåïŒå©çšç®ç
ãã©ãŒã ã®è³ªåé ã倿Žããå Žåã¯ãã¹ã¯ãªããã® `COL` ã®å€ãåãããŠå€æŽããŠãã ããã
åŸã®æé ã§HãKåïŒã¹ããŒã¿ã¹ã»ãã£ã³ã»ã«æ å ±ïŒã远å ããŸãã
STEP 3ïŒæ©æäºçŽçš Google ã«ã¬ã³ããŒã®äœæ
Google ã«ã¬ã³ããŒãéãïŒcalendar.google.comïŒ
å·Šãµã€ãããŒã®ãä»ã®ã«ã¬ã³ããŒã暪ã®ãïŒãâãæ°ããã«ã¬ã³ããŒãäœæã
ååãèšå®ïŒäŸïŒæœèšã»æ©æ äºçŽç¶æ³ïŒ
ã¿ã€ã ãŸãŒã³ããæ¥æ¬æéïŒJSTïŒãã«èšå®
äœæåŸãã«ã¬ã³ããŒã®èšå®ç»é¢ãéããã«ã¬ã³ããŒIDããã³ããŒããŠæ§ãã
ã«ã¬ã³ããŒIDã®ç¢ºèªæ¹æ³
ã«ã¬ã³ããŒåã®å³ã«ãããâ®ãâãèšå®ãšå
±æããéããããŒãžäžéšãã«ã¬ã³ããŒã®çµ±åãã»ã¯ã·ã§ã³ã«ã«ã¬ã³ããŒIDã衚瀺ãããŸãã`xxxx@group.calendar.google.com` ãšãã圢åŒã§ãã
STEP 4ïŒã«ã¬ã³ããŒã®å ¬éèšå®
äœæããã«ã¬ã³ããŒã®èšå® âãã«ã¬ã³ããŒã®ã¢ã¯ã»ã¹æš©éããéã
å ¬éç¯å²ãéžæïŒ
çµç¹å ã®ã¿ïŒãïŒçµç¹åïŒã§å©çšã§ããããã«ãããã«ãã§ãã¯ïŒæšå¥šïŒ
äžè¬å ¬éïŒãäžè¬å ¬éããŠèª°ã§ãå©çšã§ããããã«ãããã«ãã§ãã¯
ããã¹ãŠã®äºå®ã®è©³çްããéžæ
ãã«ã¬ã³ããŒã®çµ±åãã»ã¯ã·ã§ã³ã®ãå ¬éURLããæ§ãã
ãã®å ¬éURLã STEP 1 ã®ãã©ãŒã ã®èª¬ææ¬ã«è²Œãä»ããŸãã
å人æ
å ±ã®å
¬éã«ã€ããŠ
ãã®ã·ã¹ãã ã®ã¹ã¯ãªãã㯠`CALENDAR_INFO_LEVEL = 'minimal'` èšå®ïŒããã©ã«ãïŒã«ãããã«ã¬ã³ããŒã«è¡šç€ºãããã®ã¯ãæ©æåãšäºçŽæžã¿ãã®ã¿ã§ããæ°åãå©çšç®çã¯å€éšã«å
¬éãããŸããã
STEP 5ïŒApps Script ãšãã£ã¿ãéã
ãŸããšãã£ã¿ãéãæ¹æ³ã確èªããŸãïŒåå¿è ã®æ¹ã¯å¿ èªïŒ
STEP 2 ã§äœæããäºçŽå°åž³ïŒã¹ãã¬ããã·ãŒãïŒãéã
äžéšã¡ãã¥ãŒã®ãæ¡åŒµæ©èœããã¯ãªãã¯
ãApps Scriptããéžæ
ãã©ãŠã¶ã®å¥ã¿ãã§ Apps Script ãšãã£ã¿ãéããŸããSTEP 5ã9 ã¯ãã¹ãŠãã®ãšãã£ã¿äžã§ã®äœæ¥ã§ãã
STEP 6ïŒã¹ã¯ãªããããããã£ã®èšå®
管çè ã¡ãŒã«ã¢ãã¬ã¹ãšã«ã¬ã³ããŒIDã¯ãã¹ã¯ãªããå ã«çŽæžããããã¹ã¯ãªããããããã£ãã§å®å šã«ç®¡çããŸãã
Apps Script ãšãã£ã¿å·Šã¡ãã¥ãŒã®ããããžã§ã¯ãã®èšå®ãïŒâïž æ¯è»ã¢ã€ã³ã³ïŒãã¯ãªãã¯
ç»é¢ãäžã«ã¹ã¯ããŒã«ããŠãã¹ã¯ãªãã ããããã£ãã»ã¯ã·ã§ã³ãæ¢ã
ãã¹ã¯ãªãã ããããã£ã远å ããã¿ã³ãã¯ãªãã¯
以äžã®2ã€ãç»é²ããïŒ`WEB_APP_URL` 㯠STEP 10 ã®ãããã€åŸã«è¿œå ïŒ
| ããããã£åïŒããŒïŒ | å€ |
|---------------------|-----|
| `ADMIN_EMAIL` | 管çè
ã®ã¡ãŒã«ã¢ãã¬ã¹ |
| `CALENDAR_ID` | STEP 3 ã§æ§ããã«ã¬ã³ããŒID |
å
¥åæ¹æ³
ãããããã£ãæ¬ã«å·Šåã®æåïŒäŸïŒ`ADMIN_EMAIL`ïŒãããå€ãæ¬ã«å³åã®å
容ãå
¥åããŸãã1è¡ãã€ãè¡ã远å ãã§å¢ãããŸããæåŸã«ãã¹ã¯ãªãã ããããã£ãä¿åããã¯ãªãã¯ããŠãã ããã
STEP 7ïŒApps Script ã®èšè¿°
Apps Script ãšãã£ã¿å·Šã¡ãã¥ãŒã®ããšãã£ã¿ãïŒ`< >`ã¢ã€ã³ã³ïŒãã¯ãªãã¯
`ã³ãŒã.gs` ãéã
æåããæžããŠãã `function myFunction() { }` ããã¹ãŠåé€
以äžã®ã¹ã¯ãªããããã®ãŸãŸã³ããŒïŒããŒã¹ã
äžéšã®ããããžã§ã¯ãåãªãããšæžããŠããéšåãã¯ãªãã¯ããŠååãä»ããŠä¿åïŒäŸïŒReservationSystemïŒ
/**
* ================================================================
* æœèšã»æ©æ äºçŽç®¡çã·ã¹ãã â å®å
šçã¹ã¯ãªãã
* ããŒãžã§ã³: 3.2ïŒæ¥ãŸããäºçŽå¯Ÿå¿çïŒ
* ================================================================
*/
// ================================================================
// ãèšå®å¿
é é
ç®ãç°å¢ã«åãããŠå¿
ã倿ŽããŠãã ãã
// ================================================================
/** äºçŽå°åž³ã®ã·ãŒãå */
const SHEET_NAME = 'ãã©ãŒã ã®åç 1';
/** 管çè
ã¡ãŒã«ã¢ãã¬ã¹ïŒã¹ã¯ãªããããããã£ã§ç®¡çïŒ */
const ADMIN_EMAIL =
PropertiesService.getScriptProperties().getProperty('ADMIN_EMAIL')
|| 'admin@example.com';
/** æ©æäºçŽã«ã¬ã³ããŒIDïŒã¹ã¯ãªããããããã£ã§ç®¡çïŒ */
const CALENDAR_ID =
PropertiesService.getScriptProperties().getProperty('CALENDAR_ID')
|| 'ããã«ã«ã¬ã³ããŒIDã貌ãä»ããŸã';
/** Webã¢ããªURLïŒSTEP 10 ã§ãããã€åŸã«èšå®ïŒ */
const WEB_APP_URL =
PropertiesService.getScriptProperties().getProperty('WEB_APP_URL') || '';
/** 1ä»¶ãããã®æå€§å©çšæéïŒæéïŒâ»æ¥ãŸããå©çšã«åãããŠèª¿æŽ */
const MAX_HOURS = 24;
/** äºçŽå¯èœãªéå§æå»ïŒæïŒ */
const OPEN_HOUR = 9;
/** äºçŽå¯èœãªçµäºæå»ïŒæïŒ */
const CLOSE_HOUR = 21;
/** ãã£ã³ã»ã«å¯èœãªæéïŒå©çšéå§ã®äœæéåãŸã§ïŒ */
const CANCEL_DEADLINE_HOURS = 2;
/**
* ã«ã¬ã³ããŒã«å
¬éããæ
å ±ã¬ãã«
* 'minimal' â æ©æåãšäºçŽæžã¿ã®ã¿è¡šç€ºïŒæšå¥šïŒå人æ
å ±ä¿è·ïŒ
* 'standard' â æ°åã衚瀺
*/
const CALENDAR_INFO_LEVEL = 'minimal';
/**
* ã¹ãã¬ããã·ãŒãåã€ã³ããã¯ã¹ïŒ0å§ãŸã: Aå=0ïŒ
* ãã©ãŒã ã®è³ªåé ã»ã¹ãã¬ããã·ãŒãã®åé ã«åãããŠå€æŽããŠãã ãã
*/
const COL = {
TIMESTAMP: 0, // A: ã¿ã€ã ã¹ã¿ã³ãïŒèªåïŒ
USER_EMAIL: 1, // B: ã¡ãŒã«ã¢ãã¬ã¹
USER_NAME: 2, // C: æ°å / ID
MACHINE: 3, // D: æ©æã»èšåå
START_TIME: 4, // E: å©çšéå§æ¥æ
END_TIME: 5, // F: å©çšçµäºæ¥æ
PURPOSE: 6, // G: å©çšç®ç
STATUS: 7, // H: ã¹ããŒã¿ã¹ïŒç¢ºå® / åæ¶æžã¿ïŒ
TOKEN: 8, // I: ãã£ã³ã»ã«ããŒã¯ã³ïŒUUIDïŒ
EVENT_ID: 9, // J: ã«ã¬ã³ããŒã€ãã³ãID
CANCEL_URL: 10, // K: ãã£ã³ã»ã«URLïŒãã€ããŒãªã³ã¯ïŒ
};
// ================================================================
// ãåæèšå®çšãã¹ãã¬ããã·ãŒãã«åã远å ããïŒååã®ã¿å®è¡ïŒ
// ================================================================
function addCancellationColumns() {
const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(SHEET_NAME);
if (!sheet) { Logger.log('ã·ãŒããèŠã€ãããŸãã'); return; }
const lastCol = sheet.getLastColumn();
[
'ã¹ããŒã¿ã¹',
'ãã£ã³ã»ã«ããŒã¯ã³',
'ã«ã¬ã³ããŒã€ãã³ãID',
'ãã£ã³ã»ã«URL',
].forEach((name, i) => {
const col = lastCol + 1 + i;
sheet.getRange(1, col).setValue(name).setFontWeight('bold');
});
Logger.log('4åã远å ããŸãããHãKåã確èªããŠãã ããã');
}
// ================================================================
// ãã¡ã€ã³ããã©ãŒã éä¿¡æã®ãšã³ããªãã€ã³ã
// ================================================================
function checkDuplicateReservation(e) {
// æä»ããã¯ååŸïŒåæéä¿¡ã«ããäºéäºçŽã鲿¢ïŒ
const lock = LockService.getScriptLock();
try {
lock.waitLock(10000);
} catch (_) {
sendMail(
ADMIN_EMAIL,
'ããšã©ãŒãäºçŽåŠçãã¿ã€ã ã¢ãŠãããŸãã',
'åæã¢ã¯ã»ã¹ãéäžããåŠçã§ããŸããã§ããããã©ãŒã ã®éä¿¡ããŒã¿ãæåã§ç¢ºèªããŠãã ããã'
);
return;
}
try {
_processReservation(e);
} finally {
lock.releaseLock();
}
}
function _processReservation(e) {
const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(SHEET_NAME);
if (!sheet) {
const msg = `ã·ãŒãã${SHEET_NAME}ããèŠã€ãããŸããã`;
Logger.log(msg);
sendMail(ADMIN_EMAIL, 'ããšã©ãŒãã¹ã¯ãªãã忢', msg);
return;
}
const newRowIndex = e.range.getRow();
const newValues = e.values;
const tz = Session.getScriptTimeZone();
const startTime = safeParseDate(newValues[COL.START_TIME], tz);
const endTime = safeParseDate(newValues[COL.END_TIME], tz);
const reservation = {
machine: newValues[COL.MACHINE],
startTime,
endTime,
userEmail: newValues[COL.USER_EMAIL],
userName: newValues[COL.USER_NAME],
purpose: newValues[COL.PURPOSE],
};
const missing = validateRequired(reservation);
if (missing.length > 0) {
sheet.deleteRow(newRowIndex);
sendMail(
reservation.userEmail || ADMIN_EMAIL,
'ããšã©ãŒãäºçŽã«å¿
èŠãªé
ç®ãäžè¶³ããŠããŸã',
`以äžã®é
ç®ãæªå
¥åã§ãã:\n${missing.join('\n')}\n\nå床ãã©ãŒã ãããç³ã蟌ã¿ãã ããã`
);
return;
}
const dateError = validateDateTime(startTime, endTime);
if (dateError) {
sheet.deleteRow(newRowIndex);
sendMail(
reservation.userEmail,
'ããšã©ãŒãäºçŽæ¥æãäžæ£ã§ã',
`${dateError}\n\nå床ãã©ãŒã ãããç³ã蟌ã¿ãã ããã`
);
return;
}
const data = sheet.getDataRange().getValues();
const isDuplicate = checkOverlap(data, reservation, newRowIndex, tz);
if (isDuplicate) {
sheet.deleteRow(newRowIndex);
sendMail(
reservation.userEmail,
'ããšã©ãŒãäºçŽãéè€ããŠããŸãïŒäºçŽã¯åãæ¶ãããŸããïŒ',
buildErrorBody(reservation)
);
sendMail(
ADMIN_EMAIL,
'ãéç¥ãéè€äºçŽã®è©Šè¡ããããŸãã',
`${reservation.userEmail} æ§ã«ãã ${reservation.machine} ã®äºçŽã§éè€ãæ€åºãããŸããã`
);
return;
}
const token = Utilities.getUuid();
const eventId = createCalendarEvent(reservation);
const cancelUrl = WEB_APP_URL
? `${WEB_APP_URL}?action=cancel&token=${token}&email=${encodeURIComponent(reservation.userEmail)}`
: '';
sheet.getRange(newRowIndex, COL.STATUS + 1, 1, 4).setValues([[
'確å®',
token,
eventId || '',
cancelUrl,
]]);
if (cancelUrl) {
sheet.getRange(newRowIndex, COL.CANCEL_URL + 1)
.setFormula(`=HYPERLINK("${cancelUrl}","ãã£ã³ã»ã«")`);
}
sendMail(
reservation.userEmail,
'ãäºçŽç¢ºå®ãäºçŽãå®äºããŸãã',
buildConfirmBody(reservation, !!eventId, cancelUrl)
);
}
// ================================================================
// ãããªããŒã·ã§ã³é¢æ°ã
// ================================================================
function safeParseDate(str, tz) {
if (!str) return null;
if (str instanceof Date) return isNaN(str.getTime()) ? null : str;
const formats = [
'yyyy/MM/dd HH:mm:ss',
'yyyy/MM/dd HH:mm',
'MM/dd/yyyy HH:mm:ss',
];
for (const fmt of formats) {
try {
const d = Utilities.parseDate(String(str), tz, fmt);
if (d && !isNaN(d.getTime())) return d;
} catch (_) {}
}
const fallback = new Date(str);
return isNaN(fallback.getTime()) ? null : fallback;
}
function validateRequired(r) {
const missing = [];
if (!r.userEmail) missing.push('ã»ã¡ãŒã«ã¢ãã¬ã¹');
if (!r.userName) missing.push('ã»æ°å / ID');
if (!r.machine) missing.push('ã»æ©æã»èšåå');
if (!r.startTime) missing.push('ã»å©çšéå§æ¥æ');
if (!r.endTime) missing.push('ã»å©çšçµäºæ¥æ');
return missing;
}
function validateDateTime(startTime, endTime) {
if (endTime <= startTime) {
return 'çµäºæ¥æã¯éå§æ¥æããåŸã«èšå®ããŠãã ããã';
}
const hours = (endTime - startTime) / 3600000;
if (hours > MAX_HOURS) {
return `1åã®äºçŽã¯æå€§ ${MAX_HOURS} æéãŸã§ã§ããïŒç³è«: ${hours.toFixed(1)} æéïŒ`;
}
// éå§ã»çµäºãããããã®æ¥ã§ç¬ç«ãã§ãã¯ïŒæ¥ãŸãã察å¿ïŒ
// ååäœã§æ¯èŒïŒgetHours() ã ãšåã»ç§ãç¡èŠãããããïŒ
const startMinutes = startTime.getHours() * 60 + startTime.getMinutes();
const endMinutes = endTime.getHours() * 60 + endTime.getMinutes();
if (startMinutes < OPEN_HOUR * 60) {
return `äºçŽéå§ã¯ ${OPEN_HOUR}:00 以éã«èšå®ããŠãã ããã`;
}
if (endMinutes > CLOSE_HOUR * 60) {
return `äºçŽçµäºã¯ ${CLOSE_HOUR}:00 ãŸã§ã«èšå®ããŠãã ããã`;
}
return null;
}
function checkOverlap(data, newRes, newRowIndex, tz) {
for (let i = 1; i < data.length; i++) {
if (i + 1 === newRowIndex) continue;
const row = data[i];
if (row[COL.STATUS] === 'åæ¶æžã¿') continue;
if (!row[COL.MACHINE] || !row[COL.START_TIME] || !row[COL.END_TIME]) continue;
const exStart = safeParseDate(row[COL.START_TIME], tz);
const exEnd = safeParseDate(row[COL.END_TIME], tz);
if (!exStart || !exEnd) continue;
if (
row[COL.MACHINE] === newRes.machine &&
exStart < newRes.endTime &&
exEnd > newRes.startTime
) return true;
}
return false;
}
// ================================================================
// ãã«ã¬ã³ããŒé£æºã
// ================================================================
function createCalendarEvent(r) {
try {
const cal = CalendarApp.getCalendarById(CALENDAR_ID);
if (!cal) throw new Error('ã«ã¬ã³ããŒIDãç¡å¹ã§ã: ' + CALENDAR_ID);
const title = CALENDAR_INFO_LEVEL === 'minimal'
? `[äºçŽæž] ${r.machine}`
: `[äºçŽæž] ${r.machine} / ${r.userName}`;
const desc = CALENDAR_INFO_LEVEL === 'minimal'
? 'äºçŽæžã¿ïŒè©³çްã¯ç®¡çè
ãžãåãåãããã ããïŒ'
: `å©çšè
: ${r.userName}\nç®ç: ${r.purpose}`;
const event = cal.createEvent(title, r.startTime, r.endTime, {
description: desc,
sendInvites: false,
});
Logger.log('ã«ã¬ã³ããŒç»é²æå: ' + title);
return event.getId();
} catch (err) {
Logger.log('ã«ã¬ã³ããŒç»é²å€±æ: ' + err);
sendMail(ADMIN_EMAIL, 'ããšã©ãŒãã«ã¬ã³ããŒç»é²å€±æ',
`ãšã©ãŒ: ${err}\nã«ã¬ã³ããŒIDã確èªããŠãã ããã`);
return null;
}
}
// ================================================================
// ããã£ã³ã»ã«æ©èœãWebã¢ããªã®ãšã³ããªãã€ã³ã
// ================================================================
function doGet(e) {
const action = e.parameter.action;
const token = e.parameter.token;
const email = e.parameter.email;
if (action === 'cancel') {
return handleCancel(token, email);
}
return buildHtmlPage('ãšã©ãŒ', 'ãã©ã¡ãŒã¿ãäžæ£ã§ãã');
}
function handleCancel(token, email) {
if (!token || !email) {
return buildHtmlPage('ãšã©ãŒ', 'ãªã³ã¯ãäžæ£ã§ããã¡ãŒã«ã®ãªã³ã¯ãå床ã確èªãã ããã');
}
const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(SHEET_NAME);
const data = sheet.getDataRange().getValues();
let targetRow = -1;
for (let i = 1; i < data.length; i++) {
if (data[i][COL.TOKEN] === token) { targetRow = i + 1; break; }
}
if (targetRow === -1) {
return buildHtmlPage('ãšã©ãŒ', 'ãã®äºçŽã¯èŠã€ãããŸããã§ããããã§ã«å逿žã¿ã®å¯èœæ§ããããŸãã');
}
const row = data[targetRow - 1];
const reservedEmail = row[COL.USER_EMAIL];
const isAdmin = (email === ADMIN_EMAIL);
const isOwner = (email === reservedEmail);
if (!isAdmin && !isOwner) {
return buildHtmlPage('ãšã©ãŒ', 'ãã®ãã£ã³ã»ã«ãªã³ã¯ã¯ãäºçŽè
æ¬äººã®ã¿æå¹ã§ãã');
}
if (row[COL.STATUS] === 'åæ¶æžã¿') {
return buildHtmlPage('確èª', 'ãã®äºçŽã¯ãã§ã«ãã£ã³ã»ã«æžã¿ã§ãã');
}
const startTime = new Date(row[COL.START_TIME]);
const deadline = new Date(startTime.getTime() - CANCEL_DEADLINE_HOURS * 3600000);
if (new Date() > deadline) {
const deadlineStr = Utilities.formatDate(deadline, Session.getScriptTimeZone(), 'yyyy/MM/dd HH:mm');
return buildHtmlPage(
'ãã£ã³ã»ã«æéè¶
é',
`ãã£ã³ã»ã«å¯èœæéïŒ${deadlineStr}ïŒãéããŠãããããèªåãã£ã³ã»ã«ã§ããŸããã\n管çè
ã«ãé£çµ¡ãã ããã`
);
}
sheet.getRange(targetRow, COL.STATUS + 1).setValue('åæ¶æžã¿');
const eventId = row[COL.EVENT_ID];
let calOk = false;
if (eventId) {
try {
const cal = CalendarApp.getCalendarById(CALENDAR_ID);
const event = cal.getEventById(eventId);
if (event) { event.deleteEvent(); calOk = true; }
} catch (err) {
Logger.log('ã«ã¬ã³ããŒã€ãã³ãåé€å€±æ: ' + err);
sendMail(ADMIN_EMAIL, 'ããšã©ãŒãã«ã¬ã³ããŒåé€å€±æ',
`ã€ãã³ãID: ${eventId}\nãšã©ãŒ: ${err}\næåã§åé€ããŠãã ããã`);
}
}
const reservation = {
machine: row[COL.MACHINE],
startTime: new Date(row[COL.START_TIME]),
endTime: new Date(row[COL.END_TIME]),
userName: row[COL.USER_NAME],
userEmail: reservedEmail,
};
sendMail(reservedEmail, 'ããã£ã³ã»ã«å®äºãäºçŽããã£ã³ã»ã«ããŸãã', buildCancelBody(reservation));
sendMail(
ADMIN_EMAIL,
'ãéç¥ãäºçŽããã£ã³ã»ã«ãããŸãã',
`${reservation.userName}ïŒ${reservedEmail}ïŒæ§ã® ${reservation.machine} äºçŽããã£ã³ã»ã«ãããŸããã\n` +
`å©çšäºå®: ${fmt(reservation.startTime)} ïœ ${fmt(reservation.endTime)}\n` +
`ã«ã¬ã³ããŒåé€: ${calOk ? 'æå' : '倱æïŒæå察å¿ãå¿
èŠã§ãïŒ'}`
);
return buildHtmlPage(
'ãã£ã³ã»ã«å®äº',
`${reservation.machine} ã®äºçŽ\nïŒ${fmt(reservation.startTime)} ïœ ${fmt(reservation.endTime)}ïŒ\nããã£ã³ã»ã«ããŸããã\nãã£ã³ã»ã«å®äºã¡ãŒã«ããéãããŸããã®ã§ã確èªãã ããã`
);
}
// ================================================================
// ãã¡ãŒã«éä¿¡ã»æ¬æçæã
// ================================================================
function sendMail(to, subject, body) {
if (!to) return;
try {
MailApp.sendEmail(to, subject, body);
} catch (err) {
Logger.log(`ã¡ãŒã«é信倱æ â ${to}: ${err}`);
}
}
function fmt(date) {
return Utilities.formatDate(date, Session.getScriptTimeZone(), 'yyyy/MM/dd HH:mm');
}
function buildConfirmBody(r, calOk, cancelUrl) {
const deadline = new Date(r.startTime.getTime() - CANCEL_DEADLINE_HOURS * 3600000);
const deadlineStr = fmt(deadline);
return [
`${r.userName} æ§`,
'',
'ãã®åºŠã¯ãäºçŽããããšãããããŸãã',
'以äžã®å
容ã§äºçŽã確å®ããŸããã',
'',
`â æ©æã»èšåå : ${r.machine}`,
`â å©çšéå§ : ${fmt(r.startTime)}`,
`â å©çšçµäº : ${fmt(r.endTime)}`,
`â å©çšç®ç : ${r.purpose}`,
'',
calOk
? 'äºçŽç¶æ³ã«ã¬ã³ããŒã«ãç»é²ãããŸããã'
: 'ãæ³šæãã«ã¬ã³ããŒãžã®èªåç»é²ã«å€±æããŸããããäºçŽã¯å°åž³ã«èšé²ãããŠããŸãã',
'',
'ââââââââââââââââââââââââââââââ',
'â ãã£ã³ã»ã«ã«ã€ããŠ',
`ãã£ã³ã»ã«ã¯ ${deadlineStr} ãŸã§åãä»ããŠããŸãã`,
'äžèšã®ãªã³ã¯ãã¯ãªãã¯ãããšãã£ã³ã»ã«æç¶ããå®äºããŸãã',
'ïŒãã®ãªã³ã¯ã¯ãæ¬äººã®ã¿æå¹ã§ãïŒ',
'',
cancelUrl || 'ïŒãã£ã³ã»ã«ã¯ç®¡çè
ã«ãåãåãããã ããïŒ',
'ââââââââââââââââââââââââââââââ',
'',
'â» ãã®ã¡ãŒã«ã¯èªåéä¿¡ãããŠããŸãã',
].join('\n');
}
function buildErrorBody(r) {
return [
`${r.userName} æ§`,
'',
'èª ã«ç³ãèš³ããããŸãããã以äžã®äºçŽã¯ä»ã®å©çšè
ã®äºçŽãšéè€ãããã',
'èªåçã«åãæ¶ãããŸããã',
'',
`â æ©æã»èšåå : ${r.machine}`,
`â å©çšéå§ : ${fmt(r.startTime)}`,
`â å©çšçµäº : ${fmt(r.endTime)}`,
'',
'æãå
¥ããŸãããäºçŽã«ã¬ã³ããŒã§ç©ºãç¶æ³ãã確èªã®ããã',
'å¥ã®æ¥æã§å床ãäºçŽãã ããã',
'',
'â» ãã®ã¡ãŒã«ã¯èªåéä¿¡ãããŠããŸãã',
].join('\n');
}
function buildCancelBody(r) {
return [
`${r.userName} æ§`,
'',
'以äžã®äºçŽããã£ã³ã»ã«ããŸããã',
'',
`â æ©æã»èšåå : ${r.machine}`,
`â å©çšéå§ : ${fmt(r.startTime)}`,
`â å©çšçµäº : ${fmt(r.endTime)}`,
'',
'ãŸãã®ãå©çšããåŸ
ã¡ããŠãããŸãã',
'å床ãäºçŽã®å Žåã¯äºçŽãã©ãŒã ãããç³ã蟌ã¿ãã ããã',
'',
'â» ãã®ã¡ãŒã«ã¯èªåéä¿¡ãããŠããŸãã',
].join('\n');
}
// ================================================================
// ãWebã¢ããªããã£ã³ã»ã«å®äºããŒãžã®HTMLçæ
// ================================================================
function buildHtmlPage(title, message) {
const isError = title.includes('ãšã©ãŒ') || title.includes('è¶
é');
const isCancel = title.includes('ãã£ã³ã»ã«å®äº');
const icon = isError ? 'â' : isCancel ? 'â' : '!';
const color = isError ? '#C00000' : isCancel ? '#375623' : '#C55A11';
const html = `
<!DOCTYPE html>
<html lang="ja"><head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>${title}</title>
<style>
* { box-sizing: border-box; margin: 0; padding: 0; }
body {
font-family: 'Yu Gothic', 'Hiragino Sans', sans-serif;
background: #f5f5f5; min-height: 100vh;
display: flex; align-items: center; justify-content: center;
padding: 20px;
}
.card {
background: #fff; border-radius: 12px;
box-shadow: 0 2px 12px rgba(0,0,0,.08);
max-width: 480px; width: 100%; padding: 40px 36px;
text-align: center;
}
.icon {
width: 64px; height: 64px; border-radius: 50%;
background: ${color}22; display: flex;
align-items: center; justify-content: center;
margin: 0 auto 24px; font-size: 28px; color: ${color};
}
h1 { font-size: 22px; color: ${color}; margin-bottom: 16px; font-weight: 600; }
p { font-size: 14px; color: #555; line-height: 1.8; white-space: pre-wrap; }
.footer { margin-top: 28px; font-size: 12px; color: #aaa; }
</style>
</head><body>
<div class="card">
<div class="icon">${icon}</div>
<h1>${title}</h1>
<p>${message}</p>
<div class="footer">æœèšã»æ©æ äºçŽã·ã¹ãã </div>
</div>
</body></html>`;
return HtmlService.createHtmlOutput(html).setTitle(title);
}STEP 8ïŒã¹ãã¬ããã·ãŒãã«ãã£ã³ã»ã«çšåã远å ãã
ã¹ã¯ãªããå ã® `addCancellationColumns` 颿°ã䜿ã£ãŠãã¹ãã¬ããã·ãŒãã« HãK åãèªå远å ããŸãã
Apps Script ãšãã£ã¿äžéšã®ããããããŠã³ïŒã颿°ãéžæããšè¡šç€ºãããŠããéšåïŒãã¯ãªãã¯
ãaddCancellationColumnsããéžæ
â· å®è¡ãã¿ã³ïŒåçãã¿ã³ïŒãã¯ãªãã¯
â ïž ååå®è¡æïŒæš©éã®æ¿èªãå¿ èŠã§ã
åããŠå®è¡ãããšãæ¿èªãå¿ èŠã§ãããšãããã€ã¢ãã°ã衚瀺ãããŸãã以äžã®æé ã§é²ããŠãã ããã
ãæš©éã確èªããã¯ãªãã¯
Googleã¢ã«ãŠã³ãã®éžæç»é¢ãåºããã䜿çšããã¢ã«ãŠã³ããã¯ãªãã¯
ããã®ã¢ããªã¯Googleã§ç¢ºèªãããŠããŸããããšããèŠåç»é¢ãåºãŸã
âã詳现ããã¯ãªãã¯
âããïŒå®å šã§ã¯ãªãããŒãžïŒã«ç§»åããã¯ãªãã¯
ïŒããã¯èªåã§äœã£ãã¹ã¯ãªããã«ã¯å¿ ã衚瀺ãããèŠåã§ããèªäœã®ã¹ã¯ãªãããªã®ã§å®å šã§ãïŒãèš±å¯ããã¯ãªãã¯
æ¿èªãå®äºãããå床 â· å®è¡ãã¿ã³ãã¯ãªãã¯ããŠãã ããã
ã¹ãã¬ããã·ãŒããéããHãK åïŒã¹ããŒã¿ã¹ã»ãã£ã³ã»ã«ããŒã¯ã³ã»ã«ã¬ã³ããŒã€ãã³ãIDã»ãã£ã³ã»ã«URLïŒã远å ãããŠããããšã確èª
ãã®é¢æ°ã¯åå1åã ãå®è¡ããã° OK ã§ãã
STEP 9ïŒãã©ãŒã éä¿¡ããªã¬ãŒã®èšå®
ãããªã¬ãŒããšã¯ããã©ãŒã ãéä¿¡ããããèªåçã«ã¹ã¯ãªãããå®è¡ããããšãã仿ãã§ãã
Apps Script ãšãã£ã¿å·Šã¡ãã¥ãŒ â æèšã¢ã€ã³ã³ïŒãããªã¬ãŒãïŒãã¯ãªãã¯
ç»é¢å³äžãããªã¬ãŒã远å ããã¯ãªãã¯
以äžã®éãã«èšå®ïŒ
| èšå®é
ç® | èšå®å€ |
|----------|--------|
| å®è¡ãã颿° | `checkDuplicateReservation` |
| å®è¡ããããã〠| Head |
| ã€ãã³ãã®ãœãŒã¹ | ã¹ãã¬ããã·ãŒããã |
| ã€ãã³ãã®çš®é¡ | ãã©ãŒã éä¿¡æ |
ãä¿åããã¯ãªãã¯
æš©éæ¿èªãã€ã¢ãã°ã衚瀺ãããå Žå㯠STEP 8 ãšåæ§ã®æé ã§ãèš±å¯ããã¯ãªãã¯
STEP 10ïŒWebã¢ããªãšããŠãããã€ïŒãã£ã³ã»ã«æ©èœã®æå¹åïŒ
ããããã€ããšã¯ããã£ã³ã»ã«ãªã³ã¯ãã¯ãªãã¯ãããšãã«åãããŒãžãã€ã³ã¿ãŒãããäžã«å ¬éãããäœæ¥ã§ãã
Apps Script ãšãã£ã¿å³äžããããã€ããã¿ã³ãã¯ãªãã¯
ãæ°ãããããã€ããéžæ
å·Šäžã® âïžïŒæ¯è»ïŒã¢ã€ã³ã³ãã¯ãªã㯠âãWebã¢ããªããéžæ
以äžã®éãã«èšå®ïŒ
| èšå®é
ç® | èšå®å€ |
|----------|--------|
| 次ã®ãŠãŒã¶ãŒãšããŠå®è¡ | èªåïŒã¹ã¯ãªãããªãŒããŒïŒ |
| ã¢ã¯ã»ã¹ã§ãããŠãŒã¶ãŒ | å
šå¡ |
ããããã€ããã¯ãªãã¯
æš©éã®æ¿èªãã€ã¢ãã°ã衚瀺ãããã STEP 8 ãšåæ§ã®æé ã§ãèš±å¯ããã¯ãªãã¯
ãWebã¢ã㪠URLãã衚瀺ãããã®ã§ã³ããŒããŠæ§ãã
ã³ããŒããURLãã¹ã¯ãªããããããã£ã«è¿œå ãã
STEP 6 ãšåãæé ã§ã¹ã¯ãªããããããã£ãéãã以äžã远å ããŸãã
| ããããã£å | å€ |
|------------|-----|
| `WEB_APP_URL` | æé 7ã§ã³ããŒããURL |
ã¹ã¯ãªããæŽæ°åŸã¯åãããã€ãå¿ èŠã§ã
ã¹ã¯ãªããã倿Žããå Žåã¯ããããã€ãâãæ¢åã®ãããã€ã管çãâãç·šéãâãæ°ããããŒãžã§ã³ãã§åãããã€ããŠãã ãããWebã¢ããªã®URLã¯å€ãããŸããã
STEP 11ïŒåäœãã¹ã
ãã¹ã 1ïŒæ£åžžãªäºçŽ
ãã©ãŒã ãããã¹ãããŒã¿ãéä¿¡
ã¹ãã¬ããã·ãŒãã«è¡ã远å ãããHãKåã«å€ãå ¥ã£ãŠããããšã確èª
äºçŽç¢ºå®ã¡ãŒã«ã«ãã£ã³ã»ã«ãªã³ã¯ãå«ãŸããããšã確èª
ã«ã¬ã³ããŒã«ã€ãã³ãã远å ãããŠããããšã確èª
ãã¹ã 2ïŒæ¥ãŸããäºçŽ
éå§æ¥æããåœæ¥ 20:00ããçµäºæ¥æããç¿æ¥ 08:00ãã«èšå®ããŠéä¿¡
äºçŽç¢ºå®ã¡ãŒã«ãå±ããã«ã¬ã³ããŒã«æ¥ãŸããã®ã€ãã³ããç»é²ãããããšã確èª
ãã¹ã 3ïŒéè€ãã§ãã¯
ãã¹ã 1 ãšåãæ©æã»åãæé垯ã§å床ãã©ãŒã ãéä¿¡
ã¹ãã¬ããã·ãŒãã®è¡ãåé€ãããããšã確èª
éè€ãšã©ãŒã¡ãŒã«ãå±ãããšã確èª
ãã¹ã 4ïŒãã£ã³ã»ã«ïŒå©çšè ïŒ
ãã¹ã 1 ã®ç¢ºå®ã¡ãŒã«å ã®ãã£ã³ã»ã«ãªã³ã¯ãã¯ãªãã¯
ãã©ãŠã¶ã«ããã£ã³ã»ã«å®äºãããŒãžã衚瀺ãããããšã確èª
ã¹ãã¬ããã·ãŒãã®ã¹ããŒã¿ã¹ããåæ¶æžã¿ãã«ãªã£ãŠããããšã確èª
ã«ã¬ã³ããŒã®ã€ãã³ããåé€ãããŠããããšã確èª
ãã¹ã 5ïŒãã£ã³ã»ã«ïŒç®¡çè ïŒ
ã¹ãã¬ããã·ãŒãã® K åïŒãã£ã³ã»ã«ãªã³ã¯ïŒãã¯ãªãã¯
ãã¹ã 4 ãšåæ§ã®çµæã«ãªãããšã確èª
ã«ã¹ã¿ãã€ãºã®ãã€ã³ã
ã¹ã¯ãªããåé ã®å®æ°ã倿Žããããšã§ãçµç¹ã«åããã調æŽãã§ããŸãã
| 宿°å | åæå€ | 倿ŽäŸ |
|--------|--------|--------|
| `MAX_HOURS` | 24ïŒæéïŒ | æ¥ãŸãããªããªã 8 ã«æ»ããäžæ³å©çšãªã 24 ã®ãŸãŸ |
| `OPEN_HOUR` | 9ïŒæïŒ | æœèšã®éæŸæéã«åãããŠå€æŽ |
| `CLOSE_HOUR` | 21ïŒæïŒ | æœèšã®é宀æéã«åãããŠå€æŽ |
| `CANCEL_DEADLINE_HOURS` | 2ïŒæéåïŒ | 0 ã«ãããšçŽåãŸã§ãã£ã³ã»ã«å¯èœ |
| `CALENDAR_INFO_LEVEL` | `'minimal'` | `'standard'` ã«ãããšæ°åãã«ã¬ã³ããŒã«è¡šç€º |
æ¥ãŸãããèš±å¯ããªãå Žå
`validateDateTime` 颿°ã®æé垯ãã§ãã¯ã®çŽåã«ä»¥äžã®1è¡ã远å ããããšã§ã忥å
ã®ã¿ã®äºçŽã«å¶éã§ããŸãã
if (startTime.toDateString() !== endTime.toDateString()) {
return 'éå§æ¥æãšçµäºæ¥æã¯åãæ¥ã«ããŠãã ãããæ¥ããŸããäºçŽã¯ã§ããŸããã';
}ãããã質å
QïŒGoogleã¢ã«ãŠã³ããæã£ãŠããªãå©çšè
ã¯äœ¿ããŸããïŒ
AïŒSTEP 1 ã§ãã¡ãŒã«ã¢ãã¬ã¹ãåéãããã ON ã«ããå ŽåãGoogleã¢ã«ãŠã³ããžã®ãã°ã€ã³ãå¿
èŠã«ãªããŸããçµç¹å
ã§ã®å©çšãäž»ãªæ³å®ã§ãã
QïŒæ©æã1çš®é¡ãããªãå Žåã§ã䜿ããŸããïŒ
AïŒäœ¿ããŸãããæ©æã1çš®é¡ã»å°äººæ°ã®å Žåã¯ã«ã¬ã³ããŒãç·šéæš©éä»ãã§å
±æããã ãã®ã·ã³ãã«ãªéçšã®æ¹ãæéãããããŸãããäžç¹å®å€æ°ãå©çšããããŸãã¯å°åž³ãå¿
èŠãªå Žåã«ãã®ã·ã¹ãã ã广ãçºæ®ããŸãã
QïŒã¡ãŒã«ãå±ããŸãã
AïŒãŸãã¹ãã ãã©ã«ãã確èªããŠãã ãããããã§ãå±ããªãå Žåã¯ãApps Script ãšãã£ã¿å·Šã¡ãã¥ãŒã®ãå®è¡æ°ããéãããšã©ãŒãåºãŠããªãã確èªããŠãã ãããããªã¬ãŒã®èšå®ïŒSTEP 9ïŒãæ£ããããåãããŠç¢ºèªããŠãã ããã
QïŒã¹ã¯ãªããã倿Žããããã£ã³ã»ã«ãªã³ã¯ãåããªããªããŸãã
AïŒSTEP 10 ã®åãããã€ãå¿
èŠã§ããããããã€ãâãæ¢åã®ãããã€ã管çãâãç·šéãâãæ°ããããŒãžã§ã³ãã§åãããã€ããŠãã ããã
QïŒããã®ã¢ããªã¯Googleã§ç¢ºèªãããŠããŸããããšåºãŠæãã®ã§ãã
AïŒèªåã§äœæããã¹ã¯ãªããã«ã¯å¿
ããã®èŠåã衚瀺ãããŸãã第äžè
ãäœã£ãã¢ããªã§ã¯ãªãèªåã®ã¹ã¯ãªãããªã®ã§ãå®å
šã«ã詳现ãâãç§»åãâãèš±å¯ããšé²ããŠåé¡ãããŸããã
QïŒæéãéããŠããŸã£ããã£ã³ã»ã«ã¯ã©ãããã°ããã§ããïŒ
AïŒç®¡çè
ãã¹ãã¬ããã·ãŒãã® H åïŒã¹ããŒã¿ã¹ïŒãæåã§ãåæ¶æžã¿ãã«å€æŽããã«ã¬ã³ããŒã®ã€ãã³ããæååé€ããŠãã ããã
ãŸãšã
ãã®ã·ã¹ãã ã§å®çŸã§ããããšïŒ
â
å®å
šç¡æïŒGoogle ããŒã«ã®ã¿ïŒ
â
éè€äºçŽã®èªåãã§ãã¯ã»åæ¶ã»éç¥
â
ãã£ã³ã»ã«ãªã³ã¯ä»ãã®äºçŽç¢ºå®ã¡ãŒã«
â
ã«ã¬ã³ããŒãžã®èªåç»é²ã»èªååé€
â
ã¹ãã¬ããã·ãŒãã«ããå°åž³ç®¡ç
â
管çè
ã¯ã¹ãã¬ããã·ãŒãã®ãªã³ã¯1ã¯ãªãã¯ã§ãã£ã³ã»ã«å¯èœ
â
æ¥ããŸããäºçŽã«ã察å¿
ãäºçŽç®¡çããŒã«ãå°å ¥ããã»ã©ã§ã¯ãªãããæäœæ¥ã§ã®ç®¡çã«éçãæããŠããããšããçµç¹ã«ãšã£ãŠãçŸå®çã§è²»çšãããããªãéžæè¢ã§ãã
ãå 責äºé ãã³ãŒãã¯æ å ±æäŸãç®çãšããŠããŸãã䜿çšã«ãã£ãŠçããããŒã¿ã®æå€±ã»æŒæŽ©ã»ãã®ä»ãããªãæå®³ã«ã€ããŠããäœè ã¯è²¬ä»»ãè² ããŸãããæ¥åã§ã®äœ¿çšåã«å¿ ãããã¯ã¢ãããåããåäœç¢ºèªãè¡ã£ãŠãã ããã