LANG SELRCT

Apps Script Reference  (Create: Create new Spreadsheet | Create new Apps Script

Sunday, December 18, 2022

JIRA API でOAuth2.0を利用してみる(add "offline_access" to get refresh token)


この記事では、JIRA APIのOAuth2.0における
  • アクセストークンの取得方法と使い方
  • リフレッシュトークンの取得方法と使い方
について手元で実行した手順を書いていきます。

この記事では、コールバックURLにGoogle Apps Scriptを利用します。

今回refresh tokenを取得する際に使う offline_access をどう追加するかにちょっと時間がかかりました。
offline_accessの記述例については、STEP16以降に書きました。
おそらく同じところでつまづく人もいると思うので、お役に立てると幸いです。



JIRAでOAuth 2.0を利用する方法については、

OAuth 2.0 (3LO) apps

に書かれています。

その中にある Enabling OAuth 2.0 (3LO)  のステップを手元で進めながら書いていこうと思います。



STEP1
まずは、developer console を開きます。

Before you can implement OAuth 2.0 (3LO) for your app, you need to enable it for your app using the developer console. 

From any page on developer.atlassian.com, select your profile icon in the top-right corner, and from the dropdown, select Developer console.

STEP2
「Create」の中の「OAuth 2.0 integration」をクリックします。


STEP3
任意の名前を入れて「Create」をクリックします。


STEP4
「Permissions」を開きます。
Note, if you haven't already added an API to your app, you should do this now:

Select Permissions in the left menu.
Next to the API you want to add, select Add.


STEP5
Jira APIの「Add」をクリックすると「Configure」となるので、再度クリックします。


STEP6
「Edit Scopes」をクリックします。


STEP7
APIでやりたいことに合わせて、必要なスコープを選択して「Save」します。


STEP8
「Authorization」を選択して、「Add」をクリックします。


STEP9
「Callback URL」の入力欄があるので、ここではApps ScriptでWebアプリを作り、デプロイしたアプリのURLを貼り付けて「Save changes」をクリックします。


Apps ScriptのWebアプリ側はこんなコードにしてデプロイしました↓


コード.gs
function doGet(e) {
  return ContentService.createTextOutput(JSON.stringify(e));
}

manifest.json
{
  "timeZone": "Asia/Tokyo",
  "dependencies": {},
  "exceptionLogging": "STACKDRIVER",
  "runtimeVersion": "V8",
  "webapp": {
    "executeAs": "USER_DEPLOYING",
    "access": "MYSELF"
  }
}

デプロイの手順





STEP10
Save changeしたあと、authorization URLが表示されるので、別のタブで開きます。
(これが後にrefresh tokenの取得プロセスでキーポイントになるauthorization URL)


STEP11
「Accept」をクリックします。

すると、このような形でauthorization codeが返ってきます。


{"queryString":
  "code=ここにauthorization codeが入っている&state=%24%7BYOUR_USER_BOUND_VALUE%7D",
  "contextPath":"",
  "contentLength":-1,
  "parameter":{
    "code":"ここにauthorization codeが入っている",
    "state":"${YOUR_USER_BOUND_VALUE}"
  },
  "parameters":{
    "code":["ここにauthorization codeが入っている"],
    "state":["${YOUR_USER_BOUND_VALUE}"]
    }
}



STEP12
そのcodeの値を使って、アクセストークンを取得します。
その際に必要な「client_id」「client_secret」はSettingsからコピーできます。


STEP13
curlで --data '{〜}'内にあるこれらの値を代入して以下のrequestを実行します。
YOUR_CLIENT_ID
YOUR_CLIENT_SECRET
YOUR_AUTHORIZATION_CODE
YOUR_APP_CALLBACK_URL


curl --request POST \
  --url 'https://auth.atlassian.com/oauth/token' \
  --header 'Content-Type: application/json' \
  --data '{"grant_type": "authorization_code","client_id": "YOUR_CLIENT_ID","client_secret": "YOUR_CLIENT_SECRET","code": "YOUR_AUTHORIZATION_CODE","redirect_uri": "YOUR_APP_CALLBACK_URL"}'


するとこのような形でアクセストークンが返ってきます。

{
  "access_token":"アクセストークン",
  "scope":"write:jira-work read:jira-work read:jira-user",
  "expires_in":3600,
  "token_type":"Bearer"
}%



STEP14
そのアクセストークンを使って以下のrequestを送ります。

curl --request GET \
  --url https://api.atlassian.com/oauth/token/accessible-resources \
  --header 'Authorization: Bearer ACCESS_TOKEN' \
  --header 'Accept: application/json'



すると、このような結果が返ってきます。

[
  {
    "id":"CLOUD_ID",
    "url":"https://SITE_NAME.atlassian.net",
    "name":"SITE_NAME",
    "scopes":[
      "write:jira-work",
      "read:jira-work",
      "read:jira-user"
    ],
  "avatarUrl":"https://site-admin-avatar-cdn.prod.public.atl-paas.net/avatars/240/star.png"
  }
]%




STEP15
そのCLOUD_IDを使って以下のrequestを実行すると、プロジェクトのデータが返ってきます。

curl --request GET \
  --url https://api.atlassian.com/ex/jira/CLOUD_ID/rest/api/2/project \
  --header 'Authorization: Bearer ACCESS_TOKEN' \
  --header 'Accept: application/json'



STEP16
offline_accessを追加して、リフレッシュトークンを取得してみる。

ここがちょっと情報少なくて時間かかりました。

この記事を書いている時点では、公式ドキュメントにはこう書かれていました。
To get a refresh token in your initial authorization flow, add offline_access to the scope parameter of the authorization URL. 
authorization URLのscopeのパラメータにoffline_accessを追加するとのことですが、さて、どのように追加しようか。
…というのがわからず、ググったり試行錯誤する時間を経て、refresh tokenを返すことができたやり方を書きます。

ここからはSTEP10〜13とかぶる部分もあります。

STEP17
STEP10でも触れたAuthorizationページの下部に書かれているauthorization URLのscope=に「offline_access%20」を追加してブラウザの別タブで開きます。
実際どのように追加するかというと

もともと書かれているscopeの中身を見ると
read%3Ajira-work%20read%3Ajira-user%20write%3Ajira-work
となっており、これらはSTEP7のスコープ設定画面でチェックを入れて選択したものです。
そこに「offline_access」を追加して、半角スペース(%20)で以下のようにつなげます。

「offline_access%20」を追加したURLの例
https://auth.atlassian.com/authorize?audience=api.atlassian.com&client_id=CLIENT_ID&scope=offline_access%20read%3Ajira-work%20read%3Ajira-user%20write%3Ajira-work&redirect_uri=CALLBACK_URL&state=${YOUR_USER_BOUND_VALUE}&response_type=code&prompt=consent

上記URLをブラウザの別タブで開きます。

STEP18
STEP11と同じく「Accept」をクリックします。
すると、このような形で、authorization codeが返ってきます。


{
  "parameter":
    {
      "state":"${YOUR_USER_BOUND_VALUE}",
      "code":"ここにauthorization codeが入っている"
}, "contextPath":"", "contentLength":-1, "queryString":"code=ここにauthorization codeが入っている&state=%24%7BYOUR_USER_BOUND_VALUE%7D",
"parameters":{ "state":["${YOUR_USER_BOUND_VALUE}"], "code":["ここにauthorization codeが入っている"] } }



STEP19
STEP12と同じく、そのcodeの値を使って、アクセストークンを取得します。
その際に必要な「client_id」「client_secret」はSettingsからコピーできます。


STEP20
STEP13と同じく
curlで --data '{〜}'内にあるこれらの値を代入して実行します。
YOUR_CLIENT_ID
YOUR_CLIENT_SECRET
YOUR_AUTHORIZATION_CODE
YOUR_APP_CALLBACK_URL


curl --request POST \
  --url 'https://auth.atlassian.com/oauth/token' \
  --header 'Content-Type: application/json' \
  --data '{"grant_type": "authorization_code","client_id": "YOUR_CLIENT_ID","client_secret": "YOUR_CLIENT_SECRET","code": "YOUR_AUTHORIZATION_CODE","redirect_uri": "YOUR_APP_CALLBACK_URL"}'


するとこのような形でアクセストークンとリフレッシュトークンが返ってきます。

{
  "access_token":"アクセストークン",
  "refresh_token":"リフレッシュトークン",
  "scope":"write:jira-work read:jira-work read:jira-user offline_access",
  "expires_in":3600,
  "token_type":"Bearer"
}%

STEP13ではアクセストークンだけでしたが、今回はリフレッシュトークンも返ってきました。


STEP21
リフレッシュトークンを使ってアクセストークンを更新してみる。

curlで --data '{〜}'内にあるこれらの値を代入して実行します。
CLIENT_ID
CLIENT_SECRET
REFRESH_TOKEN


curl --request POST \
  --url 'https://auth.atlassian.com/oauth/token' \
 --header 'Content-Type: application/json' \
 --data '{ "grant_type": "refresh_token", "client_id": "CLIENT_ID", "client_secret": "CLIENT_SECRET", "refresh_token": "REFRESH_TOKEN" }'


すると、STEP20の結果と同じくこのように値が返ってきます。

{
  "access_token":"アクセストークン",
  "refresh_token":"リフレッシュトークン",
  "scope":"write:jira-work read:jira-work read:jira-user offline_access",
  "expires_in":3600,
  "token_type":"Bearer"
}%


STEP22
JQLの結果を取得してみる

特定のPROJECT_KEYにある課題を取得したい場合

JQLはこう書くと思います
project=PROJECT_KEY

それをAPIでこのように渡すために
search?jql=project=PROJECT_KEY

パラメータ内で使えない?や=の文字をエンコードしてこのように表現します。
search%3Fjql%3Dproject%3DPROJECT_KEY


そしてrequestの中にあるこれらの値を代入して実行すると、PROJECT_KEYの中にある課題情報が返ってきます。
CLOUD_ID
PROJECT_KEY
ACCESS_TOKEN



curl --request GET \
  --url https://api.atlassian.com/ex/jira/CLOUD_ID/rest/api/2/search%3Fjql%3Dproject%3DPROJECT_KEY \
  --header 'Authorization: Bearer ACCESS_TOKEN' \
  --header 'Accept: application/json'



この記事ではJIRA APIのOAuth2.0における
  • アクセストークンの取得方法と使い方
  • リフレッシュトークンの取得方法と使い方
について手元で実行した手順を書いてきました。

仕様やドキュメントは将来変わっていくものだと思うので、ここに書いた方法がいつまで有効かわかりませんが、この記事が同じところでつまずいている開発者のお役に立てれば幸いです。


おまけ:認可コード取得→アクセストークン取得をGoogle Apps Script側でやってみる

Webアプリとして利用するApps Scriptのコード.gsを以下のように書いて、STEP9同様にデプロイし、そのURLを使います。(JIRAのAuthorizationのCallback URLと、Apps Scriptのredirect_uriに入れるURL)

STEP 10, 11同様、authorization URLを別のタブで開いて Accept をクリックすると、Apps Script側ではauthorization codeを e['parameter']['code'] で取得して、一気にアクセストークンを返してくれます。




Webアプリとしてデプロイするコードは以下の通り

コード.gs
var client_id = 'CLIENT_ID';
var client_secret = 'CLIENT_SECRET';

var redirect_uri = "WebアプリとしてデプロイしたURL";

function doGet(e) {// Web認証用URLを開いたときに動く処理
  var response = getAccessToken(e);
  return ContentService.createTextOutput(response);// ブラウザに表示する
}

var token_url = 'https://auth.atlassian.com/oauth/token';

function getAccessToken(e) {// 認可コードを利用してトークン情報を取得して返す
  var code = e['parameter']['code'];
  var payload = {
    'grant_type': 'authorization_code',
    'client_id': client_id,
    'client_secret': client_secret,
    'code': code,
    'redirect_uri': redirect_uri
  }
  
  var options = {
    'method': 'post',
    'header': {'Content-Type': 'application/json'},
    'payload': payload
  };
  var response = UrlFetchApp.fetch(token_url, options);
  Logger.log(response);
  return response;
}


manifest.json
{
  "timeZone": "Asia/Tokyo",
  "dependencies": {},
  "exceptionLogging": "STACKDRIVER",
  "runtimeVersion": "V8",
  "webapp": {
    "executeAs": "USER_DEPLOYING",
    "access": "MYSELF"
  }
}


参考

Basic auth for REST APIs


Thursday, November 3, 2022

Googleドキュメントのテキストの色を一括で変えたい


下記コード.gsの ID を変えて myFunction() を実行すると、ドキュメントのテキストの色を #d3d3d3 に変更できました。



コード.gs
function myFunction() {
  var url = "https://docs.google.com/document/d/ID/edit";
  var doc = DocumentApp.openByUrl(url);
  doc.editAsText().setForegroundColor('#d3d3d3');
}


参考

editAsText()

setForegroundColor(foregroundColor)

Monday, August 15, 2022

Google SpreadsheetのnotesをDocumentに書き出したい


Google SpreadsheetのnotesをまとめてDocumentに書き出したくて書いたコードです。

実行プロセス
  1. getSheetNotes():noteを取得したいシートの範囲を指定して取得します
  2. notes.join("\n"):取得したデータ(配列)を改行でつないで文字列にします
  3. createSingleSentence(str):一文ごとに分けます
    • str.replace(/(?<![a-zA-Z0-9!?])[\s ](?![a-zA-Z0-9!?])/g, ""):英数以外の不要な半角スペースを削除(もとの文章に不要な半角がなければ省略)
    • .replace(/。/g, "。\n\n"):すべての「。」のあとに改行2つ追加
  4. addTextToDocument(singleSentences):指定したドキュメントに書き出します



コード.gs
function writeNotesToDocument() {
  const notes = getSheetNotes();
  const str = notes.join("\n");
  const singleSentences = createSingleSentence(str);
  addTextToDocument(singleSentences);
}

function getSheetNotes() {
  const ssUrl = "SPREADSHEET_URL";
  const ss = SpreadsheetApp.openByUrl(ssUrl);
  const sh = ss.getSheets()[0];
  const col = "E";
  const startRow = 2;
  const endRow = 378;
  const range = sh.getRange(col + startRow + ":" + col + endRow);
  const notes = range.getNotes();
  Logger.log(notes);
  return notes;
}

function createSingleSentence(str) {
  const sigleSentence = str.replace(/(?<![a-zA-Z0-9!?])[\s ](?![a-zA-Z0-9!?])/g, "").replace(/。/g, "。\n\n");
  return sigleSentence;
}

function addTextToDocument(text) {
  const url = "DOCUMENT_URL";
  const doc = DocumentApp.openByUrl(url);
  const body = doc.getBody();
  body.appendParagraph(text);
}


参考

スプレッドシートのノートを取得する

Googleドキュメントにテキストを追加したい

正規表現で英数以外のテキストの間にある半角スペースを削除したい

Google Driveで特定フォルダ内にあるファイルの説明をDocumentに書き出したい


Google Driveの特定フォルダ内にあるファイルの説明をすべて取得してドキュメントに書き出したくて書いたコードです。

書き出す順番はファイル名を昇順で並べ替えています。

実行プロセスの概要
  1. getFileDescriptionsInFolder() :フォルダを指定してファイルをすべて取得します
  2. fileObjArray.sort(asc):ファイル名の昇順で並べ替えます
  3. createDescriptionArray(sortedArray) :説明だけの配列を作ります
  4. descriptionsArray.join("\n") :配列を改行でつなげた文字列にします
  5. addTextToDocument(str) :指定したDocumentに書き出します



コード.gs
function addFileDescriptionsToDocument() {
  const fileObjArray = getFileDescriptionsInFolder();
  const sortedArray = fileObjArray.sort(asc);
  Logger.log(sortedArray);
  const descriptionsArray = createDescriptionArray(sortedArray);
  const str = descriptionsArray.join("\n");
  addTextToDocument(str);
}

function getFileDescriptionsInFolder() {
  const folderId = "FOLDER_ID";
  const folder = DriveApp.getFolderById(folderId);
  const files = folder.getFiles();
  let array = [];
  while(files.hasNext()) {
    const file = files.next();
    const obj = {};
    obj["name"] = file.getName();
    obj["url"] = file.getUrl();
    obj["description"] = file.getDescription();
    array.push(obj);
  }
  return array;
}

function asc(a, b){
  const targetA = a.name;
  const targetB = b.name;
  if(targetA > targetB){
    return 1;
  }else if(targetA < targetB ){
    return -1;
  }else{
   return 0;
  }
}

function createDescriptionArray(sortedArray) {
  const array = [];
  const target = "description";
  for(let i = 0; i < sortedArray.length; i++){
    const description = sortedArray[i][target];
    array.push(description);
  }
  return array;
}

function addTextToDocument(description) {
  const url = "DOCUMENT_URL";
  const doc = DocumentApp.openByUrl(url);
  const body = doc.getBody();
  body.appendParagraph(description);
}



参考

Google Driveのファイルの説明をフォルダ単位で取得したい

Google Driveのファイルの説明をフォルダ単位で取得したい


ファイル単位で説明を取得する方法は
で書きました。

ここではフォルダ単位でファイルの説明を取得してみます。



コード.gs
function getFileDescriptionsInFolder() {
  const folderId = "FOLDER_ID";
  const folder = DriveApp.getFolderById(folderId);
  const files = folder.getFiles();
  let array = [];
  while(files.hasNext()) {
    const file = files.next();
    const obj = {};
    obj["name"] = file.getName();
    obj["url"] = file.getUrl();
    obj["description"] = file.getDescription();
    array.push(obj);
  }
  Logger.log(array);
}


実行すると以下のようなログが出力されます

[
  {
    name=ファイル名, 
    description=説明, 
    url=ファイルのURL
  }, 
  {
    name=ファイル名, 
    description=説明, 
    url=ファイルのURL
  }, 
]


参考

Google Driveにあるファイルの説明を読み書きしたい 

Google Driveにあるファイルの説明を読み書きしたい


ここで言うGoogle Driveにあるファイルの説明とは

ファイルの詳細にある「説明を追加」項目です。
詳細の表示・非表示は右上の「i」アイコンで切り替えられます。



説明を追加する



コード.gs
function updateFileDescription() {
  const fileId = "FILE_ID;
  const text = "テキスト入力\n次の行";
  const file = DriveApp.getFileById(fileId);
  file.setDescription(text);
}



実行結果





説明を取得する



コード.gs
function getFileDescription() {
  const fileId = "FILE_ID";
  const file = DriveApp.getFileById(fileId);
  const description = file.getDescription();
  Logger.log(description);
}



実行結果



参考

getDescription() 

setDescription(description)

Sunday, May 8, 2022

Google Apps Scriptでドキュメントに画像を配置したい(フォルダ内の複数画像)


Google Apps Scriptでドキュメントに画像を配置したい では、ひとつの画像をドキュメントに配置しました。

今回は、特定のフォルダ内にある画像を一気に配置したくて書いたコードです。

画像が大きく見えるように画像サイズは1.2倍にしました。



コード.gs
const docUrl = "https://docs.google.com/document/d/ID/edit";

const FOLDER_ID = "Google Drive FOLDER ID";

function insertImages() {
  const doc = DocumentApp.openByUrl(docUrl);
  const docBody = doc.getBody();
  const docWidth = docBody.getPageWidth();
  const docHeight = docBody.getPageHeight();
  const fileIds = getFileIds();
  for(let i = 0; i < fileIds.length; i++) {
    const image = DriveApp.getFileById(fileIds[i]);
    docBody.getParagraphs()[0].insertInlineImage(0, image)
                              .setWidth(docWidth*1.2)
                              .setHeight(docHeight*1.2);
  }
}

function getFileIds() {
  let fileIds = [];
  const folder = DriveApp.getFolderById(FOLDER_ID);
  const files = folder.getFiles();
  while(files.hasNext()) {
    const file = files.next();
    const id = file.getId();
    fileIds.push(id);
  }
  return fileIds;
}



関連記事

Google Apps Scriptでドキュメントに画像を配置したい

Saturday, May 7, 2022

Google Apps Scriptでドキュメントに画像を配置したい


Googleドライブにある画像ファイルをドキュメントに配置したくて書いたコードです。

画像の大きさがドキュメントのページ範囲に収まるように、getPageWidth, getPageHeightを使いました。



コード.gs
const docUrl = "https://docs.google.com/document/d/ID/edit";

const imageUrl = "https://drive.google.com/file/d/ID/view?usp=sharing";

const imageId = imageUrl.split("/d/")[1].split("/view?")[0]

const image = DriveApp.getFileById(imageId);

function myFunction() {
  const doc = DocumentApp.openByUrl(docUrl);
  const docBody = doc.getBody();
  const docWidth = docBody.getPageWidth();
  const docHeight = docBody.getPageHeight();
  docBody.getParagraphs()[0].insertInlineImage(0, image).setWidth(docWidth).setHeight(docHeight);
}


参考

insertInlineImage(childIndex, image)

Class InlineImage

Class Body

Saturday, April 16, 2022

Googleスライドで文字色を一気に変更したい


スライドに配置されている図形内の文字色を#434343に一括変更したくて書いたコードです。


前提条件
SLIDE_IDで指定されたスライドのページには一つの図形があり、その図形にはテキストが入力されている



コード.gs
function changeFontColor() {
  const slideUrl = 'https://docs.google.com/presentation/d/SLIDE_ID/edit#slide=id.p';
  const slide = SlidesApp.openByUrl(slideUrl);
  const slides = slide.getSlides();

  const textColor = "#434343";
  const startPage = 0;
  const endpage =  slides.length


  for(let i = startPage; i < endpage; i++) {
    const element = slides[i].getShapes()[0];
    element.getText().getTextStyle().setForegroundColor(textColor);
  }
}



Googleスライドでテキストサイズを一気に変更したい


スライドに配置されている図形内のテキストサイズを24に一括変更したくて書いたコードです。


前提条件
SLIDE_IDで指定されたスライドのページには一つの図形があり、その図形にはテキストが入力されている



コード.gs
function changeFontSize() {
  const slideUrl = 'https://docs.google.com/presentation/d/SLIDE_ID/edit#slide=id.p';
  const slide = SlidesApp.openByUrl(slideUrl);
  const slides = slide.getSlides();

  const fontSize = 24;
  const startPage = 0;
  const endPage = slides.length;

 
  for(let i = startPage; i < endPage; i++) {
    const element = slides[i].getShapes()[0];
    element.getText().getTextStyle().setFontSize(fontSize)
  }
}



Googleスライドにページを追加してテキストの上下左右を中央に揃えたい


Googleスライドのページを自動作成したくて書いたコードです。

こういう二次元の配列があって
 [["はれ", "晴れ", "hare"],["あめ", "雨", "ame"]];


一つの配列をもとに一つのページを作りたい。

やりたいこと
  1. 高さを3等分した図形を配置してその中にテキストを入れたい
  2. ページの背景は白、枠線なし
  3. テキストは中央に揃えたい
  4. 一番上のテキストは下揃えにしたい
  5. 真ん中のテキストは上下も中央に揃えたい
  6. 一番下のテキストは上揃えにしたい
  7. 上中下それぞれのテキストの色とサイズを指定したい



コード.gs
const slideUrl = "https://docs.google.com/presentation/d/SLIDE_ID/edit#slide=id.p";
const textColor = ["#b7b7b7", "#000000", "#b7b7b7"];
const contentAlignment = SlidesApp.ContentAlignment
const fontSize = 60;
const valuesArray = [["はれ", "晴れ", "hare"],["あめ", "雨", "ame"]];

function insertNewPage() {
  const slide = SlidesApp.openByUrl(slideUrl);
  const pageWidth = slide.getPageWidth();
  const pageHight = slide.getPageHeight();
  const height = [0, pageHight/3, (pageHight/3)*2];

   for(let i = 0; i < valuesArray.length; i++) {
     const values = valuesArray[i];
     createPage(slide, pageWidth,pageHight, height, textColor, contentAlignment, values);
  }
}

function createPage(slide, pageWidth, pageHight, height, textColor, contentAlignment, values) {
  const slides = slide.getSlides();
  const newPage = slide.insertSlide(slides.length)
  const position = [contentAlignment.BOTTOM, contentAlignment.MIDDLE, contentAlignment.TOP];

  for(let i = 0; i < values.length; i++) {
    const rect = newPage.insertShape(SlidesApp.ShapeType.RECTANGLE)
    .setWidth(pageWidth)
    .setHeight(pageHight/3)
    .setTop(height[i])
    .setLeft(0);

    rect.getText().setText(values[i])
    .getTextStyle().setFontSize(fontSize).setForegroundColor(textColor[i]);

    rect.getFill().setSolidFill("#FFFFFF");
    rect.getBorder().setTransparent();
    rect.getText().getParagraphStyle().setParagraphAlignment(SlidesApp.ParagraphAlignment.CENTER);
    rect.setContentAlignment(position[i]);
  }
}



参考

Editing and styling text

setContentAlignment(contentAlignment)

Enum ContentAlignment 

Enum ParagraphAlignment


Sunday, February 6, 2022

Google Apps ScriptでOAuthのScopeを設定したい


スクリプトに与えるOAuth Scopeの話です。

明示的に変更しなくてもある程度は自動判定してくれますが、手動でさらに絞りたいときにはマニフェストファイル(appsscript.json)で変更できるようです。

公式ドキュメントに記載されている以下について、2022/02/06現在のエディタUIで試してみました。


スプレッドシートのファイル名を「Hello」に変更するコード.gsを例に書いていきます。



コード.gs
function myFunction() {
  var ss = SpreadsheetApp.openById("ファイルID");
  ss.rename("Hello");
}


ファイルIDを指定して実行すると、指定したファイル名が「Hello」になります。



現在のOAuthスコープを見てみる


概要を開きます。


プロジェクトのOAuthスコープが表示されます。

https://www.googleapis.com/auth/spreadsheets
Googleドライブでスプレッドシートを表示、編集、作成、削除できるため、ファイル名を「Hello」に変更できました。



マニフェストファイル(appsscript.json)を表示してみる


「プロジェクトの設定」を開きます。


マニフェストファイルをエディタで表示するをチェックします。



エディタにappsscript.jsonが表示されて、中身を確認できるようになります。



appsscript.jsonでOAuthスコープを設定してみる

以下のようにoauthScopesを追加して、スプレッドシートを表示するだけの権限に変更してみます。

appsscript.json
{
  "timeZone": "America/New_York",
  "dependencies": {
  },
  "exceptionLogging": "STACKDRIVER",
  "runtimeVersion": "V8",
  "oauthScopes": [
    "https://www.googleapis.com/auth/spreadsheets.readonly"
    ]
}


https://www.googleapis.com/auth/spreadsheets.readonly
Googleスプレッドシートを表示するだけで、それ以外の編集・作成・削除はできなくなります。



もう一度プロジェクトのOAuthスコープを見てみる



https://www.googleapis.com/auth/spreadsheets
だったのが
https://www.googleapis.com/auth/spreadsheets.readonly
に変更されて、表示するだけしかできなくなりました。


この状態でコードを実行すると、編集権限がないため、以下のようなエラーが出ます。


Required permissions: https://www.googleapis.com/auth/spreadsheets
と出ているので、OAuthスコープにそれを追加してやるとエラーが解消されます。

Monday, January 3, 2022

GASでAPIを作ってPOSTでpayloadを渡したい


MISSION
Google Apps ScriptのWebアプリにpayloadでデータを渡したい


KEY
eventObject.postData.contents


PROCESS 
Google Apps Scriptでpayloadを受け取るWebアプリを作る(api.gs)

そのWebアプリにpayloadを渡すコードを書く(コード.gs)


STEPS

STEP1
Apps Scriptの新規プロジェクトを作成します


STEP2
api.gsをコピーして貼り付けます


STEP3
const FOLDER_ID = "フォルダID" の右辺に、出力先となるGoogleドライブのフォルダIDを入れます


STEP4
Webアプリケーションとして導入します


STEP5
もう一つ新規でApps Scriptのプロジェクトを作成します


STEP6
コード.gsをコピーして貼り付けます


STEP7
const url = 'api.gsのWebアプリURL' の右辺に、STEP4で導入したWebアプリのURLを入れます


STEP8
createData()を実行します


Googleドライブの指定したフォルダにpayloadで渡したデータが保存されます。
ログにsuccessと保存したデータが表示されます。

Latest post

スプレッドシートA列にある複数のテキストをスライドに追加したい(Google Apps Script)

今回Google Apps Scriptでやりたいこと GoogleスプレッドシートA列にある複数の値を取得して Googleスライドに渡して 図形オブジェクトのテキストとして追加したい ① スプレッドシートのA列に値を入れておく ② Code.gsのinsertNewShape...