Google Docs, Sheets, Slides上でのJavascript実行方法

## 動機

~~ネタです。~~
ある日、Googleのドキュメント、スプレッドシート、スライドで
Javascriptを実行したくなる時が、来るかもしれないので（来るか？）、記事を書いておきます。
未来は、予測不可能ですので。ネタ元は[こちら](https://www.labnol.org/javascript-code-in-google-docs-220922)。

スライドとかで、コード見せて実行してみるとか、
もしかしたら少しは需要あるかも。

:::note warn
警告
本記事で`eval()`を使用しています。
しかし`eval()`は、危険な関数として知られています。
この記事では、引用元のコードを変更せず利用しています。
実際に使われる際には、`Function`など代替手段も、ご検討ください。
以下の記事が参考になります。
[eval() - JavaScript | MDN](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/eval#eval_%E3%82%92%E4%BD%BF%E3%82%8F%E3%81%AA%E3%81%84%E3%81%A7%E3%81%8F%E3%81%A0%E3%81%95%E3%81%84!)
:::

---

## Google Docs

ドキュメントの場合は、[ネタ元](https://www.labnol.org/javascript-code-in-google-docs-220922)と同じです。
以下の手順で、実行が可能です。

- ドキュメント作成
- メニューバーの拡張機能から、Apps Scriptを選択
- エディターが開くので、下記スクリプトを貼り付け&保存
- ドキュメントを開きなおすと、メニューバーにCode Runnerが追加される
- ドキュメントに、Javascriptを記述
- メニューバーのCode Runner > 🦄 Run JavaScript（1回目は、アクセスを許可する必要があります）

```javascript:main.gs
/**
* @OnlyCurrentDoc
* ネタ元
* https://www.labnol.org/javascript-code-in-google-docs-220922
*/

function codeRunner() {
  const doc = DocumentApp.getActiveDocument();
  const text = doc.getBody().getText();
  const response = eval(text);
  DocumentApp.getUi().alert(response);
}

function onOpen() {
  const ui = DocumentApp.getUi();
  const menu = ui.createMenu('Code Runner');
  menu.addItem('🦄 Run JavaScript ', 'codeRunner');
  menu.addToUi();
}
```

ドキュメントの方は、なんでもいいです。
例として、下記のようなスクリプトを書いて動かしてみます。

```javascript:Google Docuemnt
/*
* Calculate the days left until next Christmas
* ネタ元
* https://www.labnol.org/javascript-code-in-google-docs-220922
*/

function daysUntilChristmas() {
  const now = new Date();
  const christmas = new Date(now.getFullYear(), 11, 25);
  if ( now.getMonth() == 11 && now.getDate() > 25) {
    christmas.setFullYear(christmas.getFullYear() + 1);
  }
  const one_day = 1000 * 60 * 60 * 24;
  const days_left = Math.ceil((christmas.getTime() - now.getTime()) / (one_day));
  return `クリスマスまで残り${days_left}日！ 🎅`;
}

daysUntilChristmas();
```

画像のようになれば成功です！

![Document](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2888091/3321d50c-3c1d-2a29-cac1-c84d638fdb51.jpeg)

---

## Google Sheets

スプレッドシートも、似たような手順です。

今回のスクリプトでは、アクティブセルを実行するようにしています。`getActiveRange`で取得しているので、変えたい時は、ここを変えてみてください。

スプレッドシートは図形とかに、スクリプト埋め込めたりできます。
なので、トリガーの設置はメニューバー以外にもできるので試してみてください。

以下の手順で、実行が可能です。

- スプレッドシート作成
- メニューバーの拡張機能から、Apps Scriptを選択
- エディターが開くので、下記スクリプトを貼り付け&保存
- スプレッドシートを開きなおすと、メニューバーにCode Runnerが追加される
- スプレッドシートに、Javascriptを記述
- メニューバーのCode Runner > 🦄 Run JavaScript（1回目は、アクセスを許可する必要があります）

```javascript:main.gs
/**
 * @OnlyCurrentSheet
 */

function codeRunner() {
  const text = SpreadsheetApp.getActiveRange().getValue();
  const response = eval(text);
  SpreadsheetApp.getUi().alert(response);
}

function onOpen() {
  const ui = SpreadsheetApp.getUi();
  const menu = ui.createMenu('Code Runner');
  menu.addItem('🦄 Run JavaScript ', 'codeRunner');
  menu.addToUi();
}
```

スプレッドシートでも、同じコードを動かしてみます。

```javascript:GoogleSheet
/*
* Calculate the days left until next Christmas
* ネタ元
* https://www.labnol.org/javascript-code-in-google-docs-220922
*/

function daysUntilChristmas() {
  const now = new Date();
  const christmas = new Date(now.getFullYear(), 11, 25);
  if ( now.getMonth() == 11 && now.getDate() > 25) {
    christmas.setFullYear(christmas.getFullYear() + 1);
  }
  const one_day = 1000 * 60 * 60 * 24;
  const days_left = Math.ceil((christmas.getTime() - now.getTime()) / (one_day));
  return `クリスマスまで残り${days_left}日！ 🎅`;
}

daysUntilChristmas();
```

画像のようになれば成功です。

![Sheet](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2888091/cdbf0b00-f0f4-6ebd-3446-2d63fe48019e.jpeg)

出力は、アラートで出していますが、
隣のセルに書き出す、とかすればもっと見やすいかと思います。

---

## Google Slides

スライドも似たような感じです。
スライドに、スクリプトを書いたオブジェクト以外のものがあるとめんどいので、今回はコードを書いたオブジェクトのみを、スライドに置いています。

アクティブスライドを取得しに行くので、任意のスライドで実行できます。

以下の手順で、実行が可能です。

- スライド作成
- メニューバーのツールから、スクリプトエディタを選択
- エディターが開くので、下記スクリプトを貼り付け&保存
- スライドを開きなおすと、メニューバーにCode Runnerが追加される
- スライドに、Javascriptを記述
- メニューバーのCode Runner > 🦄 Run JavaScript（1回目は、アクセスを許可する必要があります）

```javascript:main.gs
/**
 * @OnlyCurrentSlide
 */

function codeRunner() {
  const presentation = SlidesApp.getActivePresentation();
  const page = presentation.getSelection().getCurrentPage();
  // 要素を取得（今回は1個しかオブジェクトがないので決め打ち）
  // 複数ある場合はgetPageElementById(id)などで指定してあげるとよい
  const element = page.getPageElements()[0];
  const text = element.asShape().getText().asString();
  const response = eval(text);
  SlidesApp.getUi().alert(response);

}

function onOpen() {
  const ui = SlidesApp.getUi();
  const menu = ui.createMenu('Code Runner');
  menu.addItem('🦄 Run JavaScript ', 'codeRunner');
  menu.addToUi();
}
```

スライドでも、同じコードを動かしてみます。

```javascript:GoogleSheet
/*
* Calculate the days left until next Christmas
* ネタ元
* https://www.labnol.org/javascript-code-in-google-docs-220922
*/

function daysUntilChristmas() {
  const now = new Date();
  const christmas = new Date(now.getFullYear(), 11, 25);
  if ( now.getMonth() == 11 && now.getDate() > 25) {
    christmas.setFullYear(christmas.getFullYear() + 1);
  }
  const one_day = 1000 * 60 * 60 * 24;
  const days_left = Math.ceil((christmas.getTime() - now.getTime()) / (one_day));
  return `クリスマスまで残り${days_left}日！ 🎅`;
}

daysUntilChristmas();
```

画像のようになれば成功です。

![Slide](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2888091/5cdfa301-adb5-821e-e112-42512df8f4d7.jpeg)

スライドは、
プレゼン中に実行結果を見せたりできるので、~~そんな奴いるか？~~
 多少は使い道あるかもしれないですね。

---

## 最後に

GAS(Google Apps Script)は、Googleのサービス（やそれ以外のもの）に対して、簡単にいろいろなことを実現できるので非常に便利です。
しかも、基本javascriptで動くので、大体の人が触れるからよいですね。

面白いと思ったら、「いいね」してくれると励みになります。
ではまた。

---

## 参考資料

[How to Use Google Docs as a Code Runner](https://www.labnol.org/javascript-code-in-google-docs-220922)

[Document Service](https://developers.google.com/apps-script/reference/document)

[Spreadsheet Service](https://developers.google.com/apps-script/reference/spreadsheet)

[Slides Service](https://developers.google.com/apps-script/reference/slides)