HTTPリクエストしたい(UrlFetchApp
)
1UrlFetchApp.fetch("URL", "オプション");
UrlFetchApp.fetch
で指定したURLに対してHTTPリクエスト(GET
、POST
など)できます。
コンテンツタイプやHTTPヘッダーなどはオプションできます。
GETリクエストしたい
1function fetchData() {
2 // URLを指定する
3 const url = "https://httpbin.org/get";
4
5 // GETリクエストを送信する
6 const response = UrlFetchApp.fetch(url);
7
8 // レスポンスの内容を取得する
9 const content = response.getContentText();
10 Logger.log(`content: ${content}`)
11}
指定したURLに対してGETリクエストを送信し、レスポンスを取得するサンプルです。
POSTリクエストしたい
1function postData() {
2 // URLを指定する
3 const url = "https://httpbin.org/post";
4 // オプションを設定する
5 const options = {
6 "method": "post",
7 "payload": {
8 "key1": "value1",
9 "key2": "value2"
10 }
11 };
12
13 // POSTリクエストを送信する
14 const response = UrlFetchApp.fetch(url, options);
15
16 // レスポンスの内容を取得する
17 const content = response.getContentText();
18
19 Logger.log(`content: ${content}`)
20
21}
指定したURLに対してPOSTリクエストを送信し、レスポンスを取得するサンプルです。 オプションで、ペイロード(=送信するデータ)を設定できます。
ヘッダーしたい
1function fetchWithHeaders() {
2 // URLを指定する
3 const url = "https://httpbin.org/get";
4
5 // オプションでヘッダーを設定する
6 const options = {
7 "method": "get",
8 "headers": {
9 "Authorization": "Bearer ACCESS_TOKEN",
10 "Accept": "application/json"
11 }
12 };
13
14 // リクエストを送信
15 const response = UrlFetchApp.fetch(url, options);
16
17 // レスポンスの内容を取得する
18 const content = response.getContentText();
19 Logger.log(`content: ${content}`)
20
21 const json = JSON.parse(content);
22 Logger.log(`json: ${json}`)
23}
Bearer
トークンを使った認証のサンプルです。
その他のオプションは以下のとおりです。
1const options = {
2 "method": "get", // "post", "put", "delete"
3 "headers": {},
4 "payload": {},
5 "muteHttpExceptions": false,
6 "followRedirects": true,
7 "timeoutMs": 5000, // 5 [sec]
8 "validateHttpsCertificates": true
9 "contentType": "application/x-www-form-urlencoded",
10 "escaping": true,
11}
Slackに通知したい
1function sendToSlack() {
2 // Incoming Webhooksを有効にする
3 const webhookUrl = "https://hooks.slack.com/services/トークン";
4
5 // 通知する内容
6 const message = {
7 "channel" : "チャンネル名",
8 "username": "通知ボットの名前",
9 "attachments":[{
10 //データ一式
11 }],
12 "icon_emoji": "絵文字コード",
13 };
14
15 // 通知内容をJSON形式に変換
16 const payload = JSON.stringify(message);
17
18 // リクエストのオプション
19 // POST で payloadを追加
20 const options = {
21 "method" : "POST",
22 "contentType": "application/json",
23 "payload": payload,
24 "muteHttpExceptions": true
25 }
26 // データをSlackにPOSTする
27 const response = UrlFetchApp.fetch(url, options);
28
29 // レスポンスの内容で成功/失敗をチェックする
30 const status = response.getResponseCode();
31 Logger.log(`status: ${status}`); // => 200 / 404
32 const content = response.getContentText();
33 Logger.log(`content: ${content}`); // => ok / No service
34}
SlackのIncoming Webhooks
アプリを使って、外部サービスからSlackに通知できるようになります。
基本となる手順は以下の通りです。
通知する内容を作成する
JSON形式に変換する
POSTメソッドでリクエストを送信する
Incoming WebhooksのURLの作り方や、
message
に追加できる値については、
それぞれ適切なドキュメントを参照してください。
Slackのメンバー数を取得したい
1function getSlackMembers() {
2 // Slack API Tokenをあらかじめ取得する
3 // 以下のスコープが必要
4 // - users:read
5 // - users.read.email (アドレスを取得する場合)
6 const token = "SlackのAPIトークン";
7
8 // APIのエンドポイント -> JSON形式のデータが返ってくる
9 const url = "https://slack.com/api/users.list";
10
11 // リクエストのオプション
12 // ヘッダーに認証情報を追加する
13 const options = {
14 "method": "get",
15 "headers": {
16 "Authorization": "Bearer " + token,
17 }
18 };
19
20 // リクエスト
21 const response = UrlFetchApp.fetch(url, options);
22 const content = response.getContentText();
23 const data = JSON.parse(content);
24
25 if (data.ok) {
26 const members = data.members.map(function(member) {
27 const item = {
28 "id": member.id,
29 "name": member.name,
30 "real_name": member.real_name,
31 "email": member.profile.email || "no_mail",
32 "is_bot": member.is_bot
33 };
34 return item;
35 }
36 );
37 return members;
38
39 // 次の forループ に相当
40 // const members = [];
41 // for (let i = 0; i < data.members.length; i++) {
42 // const member = data.members[i];
43 // const item = {
44 // "id": member.id,
45 // "name": member.name,
46 // "real_name": member.real_name,
47 // "email": member.profile.email || "no_mail",
48 // };
49 // members.push(item);
50 // };
51 // return members;
52 } else {
53 Logger.log(`Error: ${data.error}`);
54 };
55};
56
57function writeToSheet() {
58 // 指定したスプレッドシートを取得
59 const sheetId = "シートID"
60 const book = SpreadsheetApp.openById(sheetId);
61
62 // メンバー数を記録するシート
63 let sheet_counter = book.getSheetByName("slackCounter");
64 if (!sheet_counter){
65 sheet_counter = book.insertSheet("slackCounter");
66 sheet_counter.appendRow(["更新日", "メンバー数"])
67 }
68
69 // メンバー情報を記録するシート
70 let sheet_roster = book.getSheetByName("slackRoster");
71 if (!sheet_roster) {
72 sheet_roster = book.insertSheet("slackRoster");
73 }
74
75 // Slackの情報を取得
76 const members = getSlackMembers();
77 if (!members || members.length === 0) {
78 Logger.log("メンバー情報の取得に失敗");
79 return;
80 }
81
82 // 見出し行を取得
83 const headers = Object.keys(members[0]);
84
85 // メンバー情報を2次元配列に変換
86 const data = members.map(member => headers.map(header => member[header] || ""));
87 //
88 // 次のforループに相当
89 // const data = [];
90 // for (let i = 0; i < members.length; i++) {
91 // const member = members[i];
92 // const row = [];
93 // for (let j = 0; j < headers.length; j++) {
94 // const header = headers[j]
95 // const item = member[header] || ""
96 // row.push(item);
97 // }
98 // data.push(row);
99 // }
100
101 // データを出力する
102
103 // 1. 既存のシートにメンバー数を追記する
104 // 実行した時刻を最終更新日とする
105 const now = new Date();
106 const lastUpdated = Utilities.formatDate(now, "JST", "yyyy-MM-dd HH:mm:ssZ");
107 sheet_counter.appendRow([lastUpdated, members.length]);
108
109 // 2. 現在のメンバー情報をシートに書き出す
110 // 既存のシートをクリア
111 sheet_roster.clear();
112 sheet_roster.appendRow(headers);
113 const nrows = data.length;
114 const ncols = headers.length;
115 const range = sheet_roster.getRange(2, 1, nrows, ncols);
116 range.setValues(data);
117}
Slack APIトークンのスコープは以下を設定します。
users:read
users:read.email
(メールアドレスを取得する場合
取得できるユーザー情報のサンプル
id
name
real_name
is_admin
is_owner
is_primary_owner
is_bot
updated
profile.email
profile.real_name
(=real_name
)profile.display_name
data
の構造
{
"ok": true,
"members": [
{
"id": "ユーザーID",
"team_id": "ワークスペースID",
"name": "ユーザー名",
...
"profile": {
"email": "メールアドレス",
...
},
"is_bot": false,
...
},
{
"id": "次のユーザーID",
...
}
// 他のメンバーの情報
]
}
GitLabにコミットしたい
1function commitToGitLab(data) {
2 // data: コミットしたい内容
3
4 // GitLabのAPIエンドポイント
5 const projectId = "プロジェクトID"
6 const filePath = "ファイルパス"
7 const url = `https://gitlab.com/api/v4/${projectId}/repository/files/${filePath}`;
8
9 // GitLabのPersonal API Token (PAT)
10 const token = "GitLabのPAT"
11
12 const content = {
13 branch: "main",
14 commit_message: "Update from Google Sheets",
15 content: data,
16 encoding: "base64",
17 };
18 const payload = JSON.stringify(content);
19
20 const options = {
21 method: "put,
22 headers: {
23 "PRIVATETOKEN": token,
24 "Content-Type": "application/json"
25 },
26 payload: payload,
27 };
28
29 const response = UrlFetchApp.fetch(url, options);
30 const status = response.getResponseCode();
31 Logger.log(`status: ${status}`);
32}
GitLabにマージリクエストしたい
1function pushDataToGitLabWithMR() {
2
3 const projectId = "GitLabのプロジェクトID";
4 const token = "GitLabのPAT";
5
6 // 実行時のタイムスタンプを使ってユニークなブランチ名を作成
7 // シートの入力されたタイムスタンプでもいいかも
8 const branchName = "update-from-google-sheet-" + new Date().getTime();
9
10 const check = checkBranchExists(projectId, branchName);
11 if ( !check ) {
12 createNewBranch(projectId, branchName, "main", token);
13 };
14 commitToBranch(projectId, branchName, "data.csv", content, token);
15 createMergeRequest(projectId, branchName, "main", title, description, token);
16}
17
18function createNewBranch(
19 projectId,
20 newBranchName,
21 baseBranchName,
22 token
23 ) {
24 const url = `https://gitlab.com/api/v4/projects/${projectId}/repository/branches`;
25
26 const payload = {
27 branch: newBranchName,
28 ref: baseBranchName
29 };
30
31 const options = {
32 method: "post",
33 headers: {
34 "PRIVATE-TOKEN": token,
35 "Content-Type": "application/json"
36 },
37 payload: JSON.stringify(payload)
38 };
39
40 const response = UrlFetchApp.fetch(url, options);
41 const status = response.getResponseCode();
42 const body = response.getContentText();
43 Logger.log(`createNewBranch: ${status}: ${body}`);
44 };
45
46function commitToBranch(
47 projectId,
48 branchName,
49 filePath,
50 fileContent,
51 token
52 ) {
53 const url = `https://gitlab.com/api/v4/projects/${projectId}/repository/files/${encodeURIComponent(filePath)}`;
54
55 const payload = {
56 branch: branchName,
57 commit_message: "Googleシートのデータを追加",
58 content: Utilities.base64Encode(fileContent),
59 encoding: "base64"
60 };
61
62 const options = {
63 method: "put",
64 headers: {
65 "PRIVATE-TOKEN": token,
66 "Content-Type": "application/json"
67 },
68 payload: JSON.stringify(payload)
69 };
70
71 const response = UrlFetch(url, options);
72 const status = response.getResponseCode();
73 const body = response.getContentText();
74 Logger.log(`commitToBranch: ${status}: ${body}`)
75
76 };
77
78function createMergeRequest(
79 projectId,
80 sourceBranchName,
81 targetBranchName,
82 title,
83 description,
84 token
85 ) {
86 const url = `https://gitlab.com/api/v4/projects/${projectId}/merge_requests`;
87 const payload = {
88 source_branch: sourceBranchName,
89 target_branch: targetBranchName,
90 title: title,
91 description: description,
92 remove_source_branch: true
93 };
94
95 const options = {
96 method: "post",
97 headers: {
98 "PRIVATE-TOKEN": token,
99 "Content-Type": "application/json"
100 },
101 payload: JSON.stringify(payload)
102 };
103
104 const response = UrlFetchApp.fetch(url, options);
105 const status = response.getResponseCode();
106 const body = response.getContentText();
107 Logger.Log(`createMergeRequest: ${status}: ${body}`);
108 }
109
110function checkBranchExists(
111 projectId,
112 branchName,
113 token
114 ) {
115 const url = `https://gitlab.com/api/v4/projects/${projectId}/repository/branches/${encodeURIComponent(branchName)}`;
116 const options = {
117 method: "get",
118 headers: {
119 "PRIVATE-TOKEN": token
120 }
121 };
122
123 const response = UrlFetchApp.fetch(url, options);
124 const status = response.getResponseCode();
125 const body = response.getContentText();
126 Logger.log(`checkBranchExists: ${status}: ${body}`);
127
128 if (status === 200) {
129 // ブランチが存在する場合
130 return true;
131 } else {
132 // ブランチが存在しない場合
133 return false;
134 };
135 };
GoogleシートのデータをGitLabに追加することを想定したサンプルです。
main
ブランチに直接コミットするのではなく、マージリクエストを作成しています。
main
ブランチから新規ブランチを作成する作成したブランチにコミットする
マージリクエストを作成する