質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
SendGrid

SendGridは、米SendGrid社のクラウド型メール配信サービス。アカウントを作成するだけですぐに利用することが可能です。さらに到達率向上のための送信ドメイン認証対応や、柔軟性のあるスケーラビリティなど多くの機能を有します。

Google スプレッドシート

Google スプレッドシートは、フリーで利用できる表計算ソフト。Webアプリのためインターネットに接続することで利用できます。チャートやグラフの作成のほか、シートを他のユーザーと共有したり、同時に作業を進めることも可能です。

Google フォーム

Google フォームは、 Google社が提供しているアンケートフォーム作成および集計ができる無料のツール。Googleアカウントがあれば利用が可能です。集計データは、スプレッドシートに収集され、データ分析もできます。

Google Apps Script

Google Apps ScriptはGoogleの製品と第三者のサービスでタスクを自動化するためのJavaScriptのクラウドのスクリプト言語です。

Q&A

0回答

131閲覧

センドグリッド送信用に、指定のフォルダーに名前を付けて保存したい

10-mo

総合スコア21

SendGrid

SendGridは、米SendGrid社のクラウド型メール配信サービス。アカウントを作成するだけですぐに利用することが可能です。さらに到達率向上のための送信ドメイン認証対応や、柔軟性のあるスケーラビリティなど多くの機能を有します。

Google スプレッドシート

Google スプレッドシートは、フリーで利用できる表計算ソフト。Webアプリのためインターネットに接続することで利用できます。チャートやグラフの作成のほか、シートを他のユーザーと共有したり、同時に作業を進めることも可能です。

Google フォーム

Google フォームは、 Google社が提供しているアンケートフォーム作成および集計ができる無料のツール。Googleアカウントがあれば利用が可能です。集計データは、スプレッドシートに収集され、データ分析もできます。

Google Apps Script

Google Apps ScriptはGoogleの製品と第三者のサービスでタスクを自動化するためのJavaScriptのクラウドのスクリプト言語です。

0グッド

2クリップ

投稿2024/03/15 05:40

実現したいこと

下記で質問をし、回答をいただきましたが、他にも質問事項が発生し、質問タイトルと内容の混乱回避のため新たに質問を作成しました。
https://teratail.com/questions/gpu9080ea6mpht

ここに実現したいことを箇条書きで書いてください。
・スプレッドシート上で作成したQRコード(img)をドライブの指定フォルダーに、個別の名前をつけてQRコードを保存したい。form(e)で氏名を取得しているので、これをファイル名にしたいです。

ここ確認したいです
・申し込み者ごとに送信可能か否か
⇨スクリプト下部のfunction sendTest() { ~
このコードで申込者ごとに個別のメールを送れるのでしょうか?どれも固定しないといけないようで、Aさんが申込⇨Aさん宛てに、Bさん申込⇨Bさん宛てとしたいのですが、可能なのでしょうか?
メール内容は、タイトル・本文(時間によって内容分岐)・QRコード(エンコードが必須)※添付ファイルは1つだけ

前提

ここに質問の内容を詳しく書いてください。
・イベントの申し込みのためのコードを作成しています。素人作成で、勉強して理解できてきているところと、そうではないところがあります。GASの制限に抵触する可能性があるため、メール送信をセンドグリッドというメール配信サービスと連携することにしました。この連携のためのコードを、このteratail内でご教示いただきながら進めてきましたが、混乱をきたし始め、残すためにも新たに質問ページを作成させていただきました。

発生している問題・エラーメッセージ

ReferenceError: response is not defined at encodeImage(無題 2:271:15) レスポンスの場所が悪いのでしょうか?

該当のソースコード

function form(e) {//メイン関数
var values = e.values;//フォームの回答を取得
//var stamp = values[0];//タイムスタンプを取得
var mail = values[1];//アドレス
var date = values[2];//日付
var name = values[3];//氏名
var total = values[4]+values[5]+values[6]+values[7]+values[8];//人数←「シンプルに+で足すでOK」
var way = values[9];//イベントをどのように知ったか
var up = 'FALSE';
var brank = '';
var ss = SpreadsheetApp.getActiveSpreadsheet();//スプレッドシートを有効にする
var sht = ss.getSheetByName("13日 来場者");
sht.appendRow([brank, mail, name, way, total, up, date]);
console.log(sht);

var today = Utilities.formatDate(new Date(), "JST", "yyyy/MM/dd");
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sht = ss.getSheetByName("13日 来場者");
var lastrow = sht.getLastRow(); // 最終行を取得
var lastcol = sht.getLastColumn(); // 最終列を取得
var range = sht.getRange(1, 1, lastrow, lastcol);
var values = range.getValues(); // 情報をオンメモリに保持

/*来場者シートのデータを全部取得し、1行ずつチェック。
A列が空欄の場合はランダムな文字列を記入。
I列にQRコードの数式を設定
*/
for (var i = 1; i < lastrow; i++) {
data = values[i][0];
if (data == "") {
values[i][0] = getRndStr();
}
values[i][8] = false;
var qrc1 = '=image("https://chart.apis.google.com/chart?chs=250x250&cht=qr&chl=\"&A' + (i + 1) + ')';
values[i][7] = qrc1;
}
range.setValues(values); //スプレッドシートに書き戻し

/回答の名前と一致する行の1列目をidとして取得する/
for (let row = 1; row <= lastrow; row++) {
if (sht.getRange(row, 3).getValue() == name) {
var id = sht.getRange(row, 1).getValue();
}
}

// 日程シートから該当日のデータを取得
// フォームの送信内容を取得
// const reserveDate = items[2].getResponse(); // 下のように修正
const reserveDate = date; // dateをそのまま使う
//console.log(reserveDate);//5月5日(日) 10:00←日付が取得できてる

// 予約処理
const reservationCount = parseInt(total); // 予約人数
//console.log(reservationCount);
const result = updateDatesSheet(reserveDate, reservationCount ); // 予約人数も渡す。←ここがエラー
//console.log(reservationCount);//予約総数を取得◯
//console.log(result);//
// 追加:reserveSheet変数の定義
const reserveSheet = ss.getSheetByName("13日 予約");
console.log(reserveSheet);

if (result === "success") {
reserveSheet.appendRow([mail, reserveDate]); // 予約シートに追記
updateForm(); // フォームの「空き状況」を更新
}

// 追加。メール送信時にid, name, totalを渡す。
sendEmail(mail, date, result, id, name, total);
//createDraft(mail, date, result, id, name, total);
}

/**

  • 引数に指定した予約日の予約人数が、定員オーバーでないか確認する。
  • オーバーしていなければ、日程シートの現在の予約数に予約人数を加算し、文字列"success"を返す。
  • オーバーしている場合は、文字列"error"を返す。
  • 引数:reserveDate フォームに入力された予約日
  • reservationCount フォームの回答から計算した予約人数

*/
function updateDatesSheet(reserveDate, reservationCount ) { // 修正:予約人数を受け取る。
const ss1 = SpreadsheetApp.openById("スプレッドシートID");
const datesSheet = ss1.getSheetByName("13日 日程");
const table = datesSheet.getDataRange().getValues();
const index = table.findIndex(row => row[0] === reserveDate);
console.log(table);

// 追加:フォームで回答された日付がスプレッドシート中になかった場合の処理。
if (index === -1) return "error";

const target = {
rowNum: index + 1,
date: table[index][0],//日にち
cap: table[index][1],//定員
reserved: table[index][3], // 予約済人数:日程シートのD列
}

// 定員超過しなければ「予約済」に加算する
// [更新前予約人数+フォームで回答された予約人数]と定員とを比較する。+ reservationCount
if (target.reserved <= target.cap) { //予約数<=定員
// 更新後予約済人数を日程シートの予約済(C列)に書き込む。+ reservationCount
datesSheet.getRange(target.rowNum, 3).setValue(target.reserved );
return "success"
} else {
return "error"
}
}

function sendEmail(mail, preferredDate, result, id, name, total) { // id,name,totalを受け取るように修正
//function createDraft(mail, preferredDate, result, id, name, total) {
const mailTitle = "イベント予約結果について";
const imageurl = 'https://chart.apis.google.com/chart?chs=250x250&cht=qr&chl=' + id;
const response = UrlFetchApp.fetch(imageurl); // option削除
const blob = response.getBlob().getAs(MimeType.JPEG);
var folder = DriveApp.getFolderById("ドライブのID");
var file = folder.createFile(blob);
file.setName("テスト.jpeg"); //これを上記form(e)内の氏名を名前にしたい
//var fileId = file.getId(); //新規ファイルのIDを取得する

if (result === "success" && preferredDate === "2024年5月13日(月) 11:00") {
//var emailFrom = ".com";
// QRコード付きのメール
var mailBody = "この度はお申込みをいただきありがとうございます。下記の内容でご予約を承りました。\n 当日、このメールに添付されているQRコードを受付でご提示ください。 \n\n"

  • 【予約日】:${preferredDate}\n

  • '【氏 名】:' + name + '様\n'

  • '【来場者ID】:' + id + '\n'

  • '【お申込み人数】:' + total + '名\n'

  • "-------------------------------\n"

  • "-------------------------------\n"

var option = {
method: "get",
"attachments": blob,
'name': 'イベント事務局'
}
}
//11時以外
else if(result === "success") {
// QRコード付きのメール
var mailBody = "この度はお申込みをいただきありがとうございます。下記の内容でご予約を承りました。\n 当日、このメールに添付されているQRコードを受付でご提示ください。 \n\n"

  • 【予約日】:${preferredDate}\n
  • '【氏 名】:' + name + '様\n'
  • '【来場者ID】:' + id + '\n'
  • '【お申込み人数】:' + total + '名\n'

//+ "【イベント】\n"

  • "-------------------------------\n"

  • "-------------------------------\n"

var option = {
method: "get",
"attachments": blob,
'from': "com",
'name': 'イベント事務局'
}

}
else {
// QRコードなしのメール
var mailBody = "下記のご希望の日程は満席のため予約できませんでした。下記のフォームから再度申請してください。\n"

  • 【予約日】:${preferredDate}は満席です。\n
  • '【氏 名】' + name + '\n'
  • "-------------------------------\n"
  • "【予約お申込み】\n"
  • "https://forms.gle/~~~~~~~~~ \n" //このURLをHPのURLへ変更して

var option = {
'name': 'イベント事務局'
}
}
//GmailApp.createDraft(mail, mailTitle, mailBody, option);

sendGridEmail( mail, mailTitle, mailBody, option);
//GmailApp.sendEmail( mail, mailTitle, mailBody, option);
}

function getRndStr() {
var str = "abcdefghijklmnopqrstuvwxyz0123456789";
var len = 8;
var result = "";
for (var i = 0; i < len; i++) {
result += str.charAt(Math.floor(Math.random() * str.length));
}
return result;
}

function encodeImage(){
// イメージを取得
const image = response.getBlob();
//BlobオブジェクトからByteを取得してBase64にエンコード
// これで得られたものをattachmentsの部分へセット
const baseImage = Utilities.base64Encode(image.getBytes());
//Base64エンコードした結果を戻り値とする
return baseImage;
}

function updateForm() {
console.log("ダミーのupdateForm()が呼ばれました。")
}

//--------------------------------------------------------------------//

//--------------センドグリッド---------------------------------------------------------
function sendTest() {
sendGridEmail('送信先メールアドレス','メールタイトル','送信テスト\n改行テスト','送信元メールアドレス','テスト送信者')
}

function sendGridEmail(mail, mailTitle, mailBody, fromEmailAddress, fromName){

// SendGrid V3 Mail Send API を使って、メールを送信する ---
var SEND_GRID_ENDPOINT = 'https://api.sendgrid.com/v3/mail/send';
var SEND_GRID_API_KEY = 'ここにキーを入力しています';

// メール送信用スクリプト ---------------------------------
var img = encodeImage();

var body = {
personalizations: [
{
to: [
{
email: mail,
},
],

subject: mailTitle, }, ], from: { email: fromEmailAddress, name: fromName, }, content: [ { // text/plain で指定しないと \n で改行されない type: "text/plain", value: mailBody, }, ], attachments: [{ content: img, type: 'image/jpeg', filename: 'お名前.JPEG'//'添付ファイルのファイル名', }]

};

// メール送信に必要な記述
var payload = JSON.stringify(body);
UrlFetchApp.fetch(SEND_GRID_ENDPOINT, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': ' Bearer ' + SEND_GRID_API_KEY,
},
payload: payload,
});
}

function encodeImage(){
// イメージを取得
const image = response.getBlob();
//BlobオブジェクトからByteを取得してBase64にエンコード
// これで得られたものをattachmentsの部分へセット
const baseImage = Utilities.base64Encode(image.getBytes());
//Base64エンコードした結果を戻り値とする
return baseImage;
}

試したこと

var folder = DriveApp.getFolderById("ドライブのID");
var file = folder.createFile(blob);
file.setName("テスト.jpeg"); //これを上記form(e)内の氏名を名前にしたい
//var fileId = file.getId(); //新規ファイルのIDを取得する

for (var i = 1; i < lastrow; i++){
response = UrlFetchApp.fetch("http://chart.apis.google.com/chart?cht=qr&chs=150x150&chl=" + values[i][7]); // H列にQRがある
image = response.getBlob().setName(values[i][2] + ".jpeg"); // C列が人名なので、これをファイル名
SpreadsheetApp.createFile(image);
}
を書いてみたのですが、挿入箇所がわかりませんでした。。。。。

補足情報(FW/ツールのバージョンなど)

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

YellowGreen

2024/03/15 06:52 編集

・変数の宣言とスコープについて ・関数の引数について お調べになってますか。 (なぜか2つある)encodeImage()という関数の中で responseという変数の宣言がなされていないというエラーです。
10-mo

2024/03/15 23:56

コメントいただきありがとうございます。 冷静になってみると、分かりました! ありがとうございます!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだ回答がついていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問