HTTPリクエストを送信したい(UrlFetchApp)
1UrlFetchApp.fetch("URL", オプション);
UrlFetchApp.fetchで指定したURLに対してHTTPリクエスト(GET、POSTなど)できます。
コンテンツタイプやHTTPヘッダーなどは、第2引数のオプション(Object)で設定します。
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}
指定した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.stringify(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(webhookUrl, 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 Logger.log(`Error: ${data.error}`);
27 return [];
28 }
29
30 return data.members.map(member => ({
31 "id": member.id,
32 "name": member.name,
33 "real_name": member.real_name,
34 "email": member.profile.email || "no_mail",
35 "is_bot": member.is_bot
36 }));
37}
38
39function writeToSheet() {
40 // 指定したスプレッドシートを取得
41 const sheetId = "シートID";
42 const book = SpreadsheetApp.openById(sheetId);
43
44 // メンバー数を記録するシート
45 let sheetCounter = book.getSheetByName("slackCounter");
46 if (!sheetCounter) {
47 sheetCounter = book.insertSheet("slackCounter");
48 sheetCounter.appendRow(["更新日", "メンバー数"]);
49 }
50
51 // メンバー情報を記録するシート
52 let sheetRoster = book.getSheetByName("slackRoster");
53 if (!sheetRoster) {
54 sheetRoster = book.insertSheet("slackRoster");
55 }
56
57 // Slackの情報を取得
58 const members = getSlackMembers();
59 if (!members || members.length === 0) {
60 Logger.log("メンバー情報の取得に失敗");
61 return;
62 }
63
64 // 見出し行を取得
65 const headers = Object.keys(members[0]);
66
67 // メンバー情報を2次元配列に変換
68 const data = members.map(member => headers.map(header => member[header] || ""));
69
70 // 1. 既存のシートにメンバー数を追記する
71 // 実行した時刻を最終更新日とする
72 const now = new Date();
73 const lastUpdated = Utilities.formatDate(now, "JST", "yyyy-MM-dd HH:mm:ssZ");
74 sheetCounter.appendRow([lastUpdated, members.length]);
75
76 // 2. 現在のメンバー情報をシートに書き出す
77 // 既存のシートをクリア
78 sheetRoster.clear();
79 sheetRoster.appendRow(headers);
80 const nrows = data.length;
81 const ncols = headers.length;
82 const range = sheetRoster.getRange(2, 1, nrows, ncols);
83 range.setValues(data);
84}
Slack APIトークンのスコープは以下を設定します。
users:readusers:read.email(メールアドレスを取得する場合)
取得できるユーザー情報のサンプル
idnamereal_nameis_adminis_owneris_primary_owneris_botupdatedprofile.emailprofile.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 "PRIVATE-TOKEN": 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 const projectId = "GitLabのプロジェクトID";
3 const token = "GitLabのPAT";
4 const data = "コミットしたい内容";
5 const title = "マージリクエストのタイトル";
6 const description = "マージリクエストの説明";
7
8 // 実行時のタイムスタンプを使ってユニークなブランチ名を作成
9 // シートの入力されたタイムスタンプでもいいかも
10 const branchName = "update-from-google-sheet-" + new Date().getTime();
11
12 const exists = checkBranchExists(projectId, branchName, token);
13 if (!exists) {
14 createNewBranch(projectId, branchName, "main", token);
15 }
16 commitToBranch(projectId, branchName, "data.csv", data, token);
17 createMergeRequest(projectId, branchName, "main", title, description, token);
18}
19
20function createNewBranch(projectId, newBranchName, baseBranchName, token) {
21 const url = `https://gitlab.com/api/v4/projects/${projectId}/repository/branches`;
22
23 const payload = {
24 branch: newBranchName,
25 ref: baseBranchName
26 };
27
28 const options = {
29 method: "post",
30 headers: {
31 "PRIVATE-TOKEN": token,
32 "Content-Type": "application/json"
33 },
34 payload: JSON.stringify(payload)
35 };
36
37 const response = UrlFetchApp.fetch(url, options);
38 const status = response.getResponseCode();
39 const body = response.getContentText();
40 Logger.log(`createNewBranch: ${status}: ${body}`);
41}
42
43function commitToBranch(projectId, branchName, filePath, fileContent, token) {
44 const url = `https://gitlab.com/api/v4/projects/${projectId}/repository/files/${encodeURIComponent(filePath)}`;
45
46 const payload = {
47 branch: branchName,
48 commit_message: "Googleシートのデータを追加",
49 content: Utilities.base64Encode(fileContent),
50 encoding: "base64"
51 };
52
53 const options = {
54 method: "put",
55 headers: {
56 "PRIVATE-TOKEN": token,
57 "Content-Type": "application/json"
58 },
59 payload: JSON.stringify(payload)
60 };
61
62 const response = UrlFetchApp.fetch(url, options);
63 const status = response.getResponseCode();
64 const body = response.getContentText();
65 Logger.log(`commitToBranch: ${status}: ${body}`);
66}
67
68function createMergeRequest(projectId, sourceBranchName, targetBranchName, title, description, token) {
69 const url = `https://gitlab.com/api/v4/projects/${projectId}/merge_requests`;
70 const payload = {
71 source_branch: sourceBranchName,
72 target_branch: targetBranchName,
73 title: title,
74 description: description,
75 remove_source_branch: true
76 };
77
78 const options = {
79 method: "post",
80 headers: {
81 "PRIVATE-TOKEN": token,
82 "Content-Type": "application/json"
83 },
84 payload: JSON.stringify(payload)
85 };
86
87 const response = UrlFetchApp.fetch(url, options);
88 const status = response.getResponseCode();
89 const body = response.getContentText();
90 Logger.log(`createMergeRequest: ${status}: ${body}`);
91}
92
93function checkBranchExists(projectId, branchName, token) {
94 const url = `https://gitlab.com/api/v4/projects/${projectId}/repository/branches/${encodeURIComponent(branchName)}`;
95 const options = {
96 method: "get",
97 headers: {
98 "PRIVATE-TOKEN": token
99 },
100 muteHttpExceptions: true
101 };
102
103 const response = UrlFetchApp.fetch(url, options);
104 const status = response.getResponseCode();
105 const body = response.getContentText();
106 Logger.log(`checkBranchExists: ${status}: ${body}`);
107
108 // ブランチが存在する場合はtrue、存在しない場合はfalse
109 return status === 200;
110}
GoogleシートのデータをGitLabに追加することを想定したサンプルです。
mainブランチに直接コミットするのではなく、マージリクエストを作成しています。
mainブランチから新規ブランチを作成する作成したブランチにコミットする
マージリクエストを作成する