実現したいこと
ここに実現したいことを箇条書きで書いてください。
・スプレッドシートのコンテナバインドから、センドグリッドを介してメールを自動送信したい
・できるだけ現状のコード改変は避けたい
前提
◯ここに質問の内容を詳しく書いてください。◯
イベントの申し込みフォームを作成しています。Googleフォームで申込受付⇨スプレッドシートに集約⇨QRコードを生成し申込者にメール送信という流れです。
申込者が想定よりも多くなりそうで、GASでの返信だと制限に引っかかる可能性が出てきたため、センドグリッドを利用して自動返信したいと思っています。
下記サイトを参考にしながら作成を試みるも、エラー表示ばかりで一向に解決できないため、こちらに質問させていただきました。
https://teratail.com/questions/eab8j0pf72wzkk
https://www.safetyrabbit.net/techinfo/google-apps-script-%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0-5-sendgrid-web-api-v3%E3%82%92%E4%BD%BF%E3%81%A3%E3%81%A6%E3%83%A1%E3%83%BC%E3%83%AB%E3%82%92%E9%80%81%E3%82%8B/
スクリプトの作成も動画やサイトを見ながら作りましたが、センドグリッドとの連携については情報量が少なく、上記サイトを参考にしても解決できず、ご質問させていただきました。よろしくお願いいたします。
発生している問題・エラーメッセージ
①Exception: Request failed for https://api.sendgrid.com returned code 400. Truncated server response: {"errors":[{"message":"The to email parameter is required.","field":"personalizations.0.to.0.email","help":"http://sendgrid.com/docs/API_Reference/... (use muteHttpExceptions option to examine full response) at sendEmail(無題:24:28) ※どの時に表示されたのかコードの記録がありません… **⇨表示されなくなりました** ②Exception: Request failed for https://api.sendgrid.com returned code 400. Truncated server response: {"errors":[{"message":"Additional property mail is not allowed.","field":"personalizations.0.mail","help":null},{"message":"Invalid type. Expected:... (use muteHttpExceptions option to examine full response) at sendmail(センドグリッド送信:44:15) at sendEmail(コード:226:3) at form(コード:69:3) ※再度表示されるようになりました 手を加えながらのため、ここにあげたコードと行数が一致しないかもしれません。。。
③コメントいただき修正後、再度スクリプト実行したところ「完了」と表示されました。しかし、実際はメールが送信されておりませんでした。私のテストメールアドレスに受信メールがありません
※20240307 8:45現在
※function sendGridEmail~は別のスクリプトに記入しました。
該当のソースコード
1 2function form(e) {//メイン関数 3 var values = e.values;//フォームの回答を取得 4 //var stamp = values[0];//タイムスタンプを取得 5 var mail = values[1];//アドレス 6 var date = values[2];//日付 7 var name = values[3];//氏名 8 var total = values[4]+values[5]+values[6]+values[7]+values[8];//人数←「シンプルに+で足すでOK」 9 var way = values[9];//イベントをどのように知ったか 10 var up = 'FALSE'; 11 var brank = ''; 12 var ss = SpreadsheetApp.getActiveSpreadsheet();//スプレッドシートを有効にする 13 var sht = ss.getSheetByName("来場者"); 14 sht.appendRow([brank, mail, name, way, total, up, date]); 15 console.log(sht); 16 17 var today = Utilities.formatDate(new Date(), "JST", "yyyy/MM/dd"); 18 var ss = SpreadsheetApp.getActiveSpreadsheet(); 19 var sht = ss.getSheetByName("来場者"); 20 var lastrow = sht.getLastRow(); // 最終行を取得 21 var lastcol = sht.getLastColumn(); // 最終列を取得 22 var range = sht.getRange(1, 1, lastrow, lastcol); 23 var values = range.getValues(); // 情報をオンメモリに保持 24 25 /*来場者シートのデータを全部取得し、1行ずつチェック。 26 A列が空欄の場合はランダムな文字列を記入。 27 I列にQRコードの数式を設定 28 */ 29 for (var i = 1; i < lastrow; i++) { 30 data = values[i][0]; 31 if (data == "") { 32 values[i][0] = getRndStr(); 33 } 34 values[i][8] = false; 35 var qrc1 = '=image(\"https://chart.apis.google.com/chart?chs=250x250&cht=qr&chl=\"&A' + (i + 1) + ')'; 36 values[i][7] = qrc1; 37 } 38 range.setValues(values); //スプレッドシートに書き戻し 39 40 /*回答の名前と一致する行の1列目をidとして取得する*/ 41 for (let row = 1; row <= lastrow; row++) { 42 if (sht.getRange(row, 3).getValue() == name) { 43 var id = sht.getRange(row, 1).getValue(); 44 } 45 } 46 //------------------上まではOK(フォームのセクションが消えると、動作不良になるので注意------------------------ 47 //------------------------------------------ 48 // 日程シートから該当日のデータを取得 49 // フォームの送信内容を取得 50 // const reserveDate = items[2].getResponse(); // 下のように修正 51 const reserveDate = date; // dateをそのまま使う 52 //console.log(reserveDate);//5月5日(日) 10:00←日付が取得できてる 53 54 // 予約処理 55 const reservationCount = parseInt(total); // 予約人数 56 //console.log(reservationCount); 57 const result = updateDatesSheet(reserveDate, reservationCount ); // 予約人数も渡す。←ここがエラー 58 //console.log(reservationCount);//予約総数を取得◯ 59 //console.log(result);// 60 // 追加:reserveSheet変数の定義 61 const reserveSheet = ss.getSheetByName("予約"); 62 console.log(reserveSheet); 63 64 if (result === "success") { 65 reserveSheet.appendRow([mail, reserveDate]); // 予約シートに追記 66 updateForm(); // フォームの「空き状況」を更新 67 } 68 69 // 追加。メール送信時にid, name, totalを渡す。 70 sendEmail(mail, date, result, id, name, total); 71 //createDraft(mail, date, result, id, name, total); 72} 73 74/** 75 * 引数に指定した予約日の予約人数が、定員オーバーでないか確認する。 76 * オーバーしていなければ、日程シートの現在の予約数に予約人数を加算し、文字列"success"を返す。 77 * オーバーしている場合は、文字列"error"を返す。 78 * 引数:reserveDate フォームに入力された予約日 79 * reservationCount フォームの回答から計算した予約人数 80*/ 81function updateDatesSheet(reserveDate, reservationCount ) { // 修正:予約人数を受け取る。 82 const ss1 = SpreadsheetApp.openById("ここにスプレッドシートID"); 83 const datesSheet = ss1.getSheetByName("日程"); 84 const table = datesSheet.getDataRange().getValues(); 85 const index = table.findIndex(row => row[0] === reserveDate); 86 console.log(table); 87 88 // 追加:フォームで回答された日付がスプレッドシート中になかった場合の処理。 89 if (index === -1) return "error"; 90 91 const target = { 92 rowNum: index + 1, 93 date: table[index][0],//日にち 94 cap: table[index][1],//定員 95 reserved: table[index][3], // 予約済人数:日程シートのD列 96 } 97 98 // 定員超過しなければ「予約済」に加算する 99 // [更新前予約人数+フォームで回答された予約人数]と定員とを比較する。+ reservationCount 100 if (target.reserved <= target.cap) { //予約数<=定員 101 // 更新後予約済人数を日程シートの予約済(C列)に書き込む。+ reservationCount 102 datesSheet.getRange(target.rowNum, 3).setValue(target.reserved ); 103 return "success" 104 } else { 105 return "error" 106 } 107} 108 109function sendEmail(mail, preferredDate, result, id, name, total) { // id,name,totalを受け取るように修正 110//function createDraft(mail, preferredDate, result, id, name, total) { 111 const mailTitle = "イベント予約結果について"; 112 const imageurl = 'https://chart.apis.google.com/chart?chs=250x250&cht=qr&chl=' + id; 113 const response = UrlFetchApp.fetch(imageurl); // option削除 114 const blob = response.getBlob().getAs(MimeType.JPEG); 115 116if (result === "success" && preferredDate === "2024年5月5日(日) 11:00") { 117 //var emailFrom = ".com"; 118 // QRコード付きのメール 119 var mailBody = "この度はお申込みをいただきありがとうございます。下記の内容でご予約を承りました。\n 当日、このメールに添付されているQRコードを受付でご提示ください。 \n\n" 120 + `【予約日】:${preferredDate}\n` 121 + '【氏 名】:' + name + '様\n' 122 + '【来場者ID】:' + id + '\n' 123 + '【お申込み人数】:' + total + '名\n' 124 + "-------------------------------\n" 125 126 127 128 + "-------------------------------\n" 129 130 var option = { 131 method: "get", 132 "attachments": blob, 133 'name': イベント事務局' 134 } 135} 136//11時以外 137 else if(result === "success") { 138 // QRコード付きのメール 139 var mailBody = "この度はお申込みをいただきありがとうございます。下記の内容でご予約を承りました。\n 当日、このメールに添付されているQRコードを受付でご提示ください。 \n\n" 140 + `【予約日】:${preferredDate}\n` 141 + '【氏 名】:' + name + '様\n' 142 + '【来場者ID】:' + id + '\n' 143 + '【お申込み人数】:' + total + '名\n' 144 145 //+ "【イベント】\n" 146 + "-------------------------------\n" 147 148 149 + "-------------------------------\n" 150 151 var option = { 152 method: "get", 153 "attachments": blob, 154 'from': "com", 155 'name': 'イベント事務局' 156 } 157 158 } 159 else { 160 // QRコードなしのメール 161 var mailBody = "下記のご希望の日程は満席のため予約できませんでした。下記のフォームから再度申請してください。\n" 162 + `【予約日】:${preferredDate}は満席です。\n` 163 + '【氏 名】' + name + '\n' 164 + "-------------------------------\n" 165 + "【予約お申込み】\n" 166 + "https://forms.gle/~~~~~~~~~ \n" //このURLをHPのURLへ変更して 167 168 var option = { 169 'name': 'イベント事務局' 170 } 171} 172 //GmailApp.createDraft(mail, mailTitle, mailBody, option); 173 174**//ここ変更しました** 175 sendGridEmail( mail, mailTitle, mailBody, option); 176 //GmailApp.sendEmail( mail, mailTitle, mailBody, option); 177} 178 179function getRndStr() { 180 var str = "abcdefghijklmnopqrstuvwxyz0123456789"; 181 var len = 8; 182 var result = ""; 183 for (var i = 0; i < len; i++) { 184 result += str.charAt(Math.floor(Math.random() * str.length)); 185 } 186 return result; 187} 188 189 190function updateForm() { 191 console.log("ダミーのupdateForm()が呼ばれました。") 192} 193 194**---------ここからセンドグリッドAPI連携---------** 195**//ここ変更しました** 196**上記とは違う別のスクリプト内に書きました。** 197function sendGridEmail(mail, mailTitle, mailBody, option){ 198 199// SendGrid V3 Mail Send API を使って、メールを送信する --- 200// スクリプトプロパティは、「プロジェクトの設定」->「スクリプトプロパティの追加」を行なう 201var scriptProperties = PropertiesService.getScriptProperties(); 202var SEND_GRID_ENDPOINT = scriptProperties.getProperty('SEND_GRID_ENDPOINT'); 203var SEND_GRID_API_KEY = scriptProperties.getProperty('SEND_GRID_API_KEY'); 204 205 206// メール送信用スクリプト --------------------------------- 207 208 209 var body = { 210 personalizations: [ 211 { 212 to: [ 213 { 214 email: mail, 215 }, 216 ], 217 218 subject: mailTitle, 219 }, 220 ], 221 from: { 222 //email: emailFrom, 223 name: option, 224 }, 225 content: [ 226 { 227 // text/plain で指定しないと \n で改行されない 228 type: "text/plain", 229 value: mailBody, 230 }, 231 ], 232 }; 233 234 235 // メール送信に必要な記述 236 var payload = JSON.stringify(body); 237 UrlFetchApp.fetch(SEND_GRID_ENDPOINT, { 238 method: 'POST', 239 headers: { 240 'Content-Type': 'application/json', 241 'Authorization': ' Bearer ' + SEND_GRID_API_KEY, 242 }, 243 payload: payload, 244 }); 245} 246**//sendEmailBySendGrid( mail, mailTitle, mailBody, option);** 247 248 249 250
試したこと
・GmailApp ⇨ sendEmailBySendGridやsendEmailに変更してみた
・APIキーをスクリプト内に入れてみた
補足情報(FW/ツールのバージョンなど)
プロジェクトの設定から、APIキーやエンドポイントをスクリプトプロパティに入れています。
回答1件
あなたの回答
tips
プレビュー