Googleフォト容量無制限終了に備えて非root化なPixelをGoogleフォト アップロードサーバーにしてみる

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/207109/5725e5af-d0d8-686f-0805-981e6e421771.png)

# はじめに

2020年11月に[Googleアカウントのストレージポリシー変更](https://japan.googleblog.com/2020/11/storage-policies-update.html)のアナウンスがあり、2021年6月1日よりGoogleフォトの容量も無制限ではなくなることになりました。
しかし以下の記載のように2021年5月現在発売中のPixel端末からアップロードされた写真は、引き続き高画質であれば容量無制限となります。

> また、Google Pixel 3 〜 5 の端末をご利用の場合、対象デバイスから高画質でアップロードされた写真と動画は、今回の変更の対象外です。つまり 2021 年 6 月 1 日以降も写真と動画についてはストレージに計上されず引き続き無制限でお使いいただけます。

※`Google Pixel 3 〜 5`とありますが、[こちら](https://support.google.com/photos/answer/6220791?co=GENIE.Platform%3DAndroid&hl=ja#zippy=%2Cpixel%2Cpixel-apixel)の記述では廉価版のaシリーズ含むPixel 2 ～ 5まで高画質であれば容量無制限のままのようです（初代Pixelは`元の画質で保存され、無料、容量無制限です`との記載あり）

私は今までスマホの写真はGoogleフォトアプリ、一眼レフの写真はWindows PCで「Googleのバックアップと同期」アプリでGoogleフォトへ自動バックアップしていました。
今回上記のGoogleフォト ポリシー変更を名目に今まで使っていたPixel 3aからPixel 5への買い替えの家庭内承認が下りたので、Pixel 3aをGoogleフォト アップロードサーバーに仕立ててみました。

※Amazonプライムフォト等、他のサービスへの変更も検討しましたが「[Google Nest HubはフォトフレームのUX革命だ！](https://note.com/miso_develop/n/n9b644541adad)」という記事に書いたように、Googleフォト自体の機能、そしてNest Hubといったデバイス連携によるフォトUXが大変すばらしいため、Googleフォトを使い続ける選択肢を選びました



# Googleフォト アップロードサーバーの要件

アップロードサーバーとしての要件は以下を満たせばよいと考えました。

* スマホの写真をPixelへ日次なり定期で自動アップロードできる
* アップロードから1週間ほど経った写真は削除する
	* 1週間もあればどこかしらのタイミングでGoogleフォトへの写真アップロードは行われているはず
* 端末の残容量をチェックして一定値を下回ったら通知

以上の要件のもとPixelの非root化を前提として実現した構成が以下の図になります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/207109/5725e5af-d0d8-686f-0805-981e6e421771.png)

## スマホからPixelへ写真をアップロード

ここはPixelにてSFTPサーバーを立ち上げ、スマホ（Android）からは「FolderSync」というバックアップアプリを使用して写真をアップロードします。

FolderSync (Google Play)
https://play.google.com/store/apps/details?id=dk.tacit.android.foldersync.lite

* FolderSyncとは
	* さまざまなプロトコルでバックアップ/ミラーリングが行える
	* スケジューリング実行できる
	* 過去にコピー済みのファイルをスキップできる（重要）
	* Android版しかない🥺

> ※iOSではFolderSyncの代替となるアプリがぱっと見つからなかったです…😢何かしらのファイル転送プロトコルをスケジュール実行できる良いアプリがあったらご教示ください…
> ※もしご自宅のNASにバックアップする仕組みがあるようでしたら「[NASにバックアップを行っているケース](#nasにバックアップを行っているケース)」をご覧ください

またSFTPサーバーは「SSH/SFTP Server」というアプリを使用しました。
ここはSFTPではなくともFolderSyncが対応しているプロトコルであればなんでも大丈夫です。

## 残りの仕様はTermux上のNode.jsにてスクリプト実行

一定期間を過ぎたファイルの削除や残容量監視・通知は適したアプリが見つからなかったため、「Termux」というアプリとNode.jsで実装しました。
これをPixel端末上で実行させます。
また通知はLINE NotifyでのPush通知を使用しました。

* Termuxとは
	* ターミナルエミュレーターアプリ
	* 非rootでもわりと色々いける
	* GitやNode.jsも普通に使える

ここにNode.jsをインストールしスクリプト実行します。
Node.jsスクリプトでは以下の処理を実装し、cronにて定期実行します。

* アップロードから1週間経った写真は削除
* 端末容量のしきい値をチェックして下回っていたら通知（LINE Notify）
* 写真アップロードディレクトリ内のサブディレクトリにアップロードされた写真を、写真アップロードディレクトリ直下に移動する
	* Googleフォトアプリのアップロードフォルダ指定簡易化のため

Node.jsスクリプトはGitHubにて公開しています。
（下記の構築手順にて`git clone`しています）

**[google-photos-upload-server (GitHub)](https://github.com/miso-develop/google-photos-upload-server)**



# 具体的な構築手順

それではGoogleフォト アップロードサーバーの構築手順を記載していきます。
Pixel端末にて以下の手順を実施してください。

## Termuxの環境構築

### Termuxを~~Google Playより~~インストール、起動

~~Termux (Google Play)
https://play.google.com/store/apps/details?id=com.termux~~

【2022/1/7 追記（@abetaaaa さん、編集リクエストありがとうございます！）】
現在Google Playで配布されているTermuxでは、`pkg update`が実行できず後に行うパッケージのインストールができません。 
（どうやらリポジトリの参照先が閉鎖されていることが原因のようです…）

F-Droidというサイトで配布されているTermuxが最新版になります。
こちらのほうでは問題なく動作しますので、下記URLからapkファイルをDLしてインストールしてください。
（Google Play版は技術的背景の問題で更新停止しており、最新版はF-Droidにてリリースされていくようです。Termux公式としてもF-DroidからのDL、インストールを推奨しているとのことです）

https://f-droid.org/packages/com.termux/

問題の詳細は下記の記事を参照。

https://qiita.com/jan_pali_1212/items/8658cab554b619a32371

### Scrcpyの導入（任意）

ここから先はTermux上にてコマンドを打ち込んでいきますが、Scrcpyを使ってPCからPixelを操作すると楽です。

* Scrcpyとは
	* Android端末の画面をPC上に表示・操作できるPC向けアプリ（Linux、Windows、macOS対応）
	* キーボード、マウス、クリップボードを共有できる
	* GitHub: https://github.com/Genymobile/scrcpy
		* 導入方法は[Get the app](https://github.com/Genymobile/scrcpy#get-the-app)参照（さくっとできます）

### Termuxのセットアップ

Termux上で以下のコマンドを順次実行しセットアップしていきます。

```
# パッケージインストール（途中適宜'y'を入力）
pkg update -y
pkg install -y git nodejs cronie termux-services

# ストレージアクセス有効可（このとき出てくるウインドウにて許可を選択）
termux-setup-storage
cd /storage/emulated/0/

# Node.jsスクリプトclone
git clone https://github.com/miso-develop/google-photos-upload-server
cd google-photos-upload-server/app
npm i

# スクリプトのテスト実行（このとき出てくるウインドウにて許可を選択）
sh index.sh

# 一旦閉じる
exit
```

そして再度Termuxを起動し、Node.jsスクリプトをcronにて日次実行するよう設定します。

```
# cron登録
crontab -e
```

以下のcorn式を書き込み保存します。

```
# 毎日AM6:00にNode.jsスクリプト実行
0 6 * * * sh /storage/emulated/0/google-photos-upload-server/app/index.sh
```

デフォルトだとnanoでファイルが開かれます。
nanoで保存を行うには「ctrl + o -> enter -> ctrl + x」と入力していきます。
このときCtrlキーはPC側キーボードでは効かないため、Androidのソフトキーボードの上に表示される`CTRL`をタップしてください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/207109/85485427-86cf-afa8-8113-b8d45ae8e010.png)

最後にTermux起動時にcrondを自動実行するようサービス登録を行います。

```
# Termux起動時にcrondを自動起動化
sv-enable crond
```

Termuxのセットアップは以上になります。

### 自動起動について
Pixelを再起動したとき、Termuxを手動で起動しないとcronにてNode.jsスクリプトが自動実行されません。
端末起動時のTermuxの自動起動については「[Termux: Boot](https://play.google.com/store/apps/details?id=com.termux.boot)」という自動起動プラグイン（有料：230円）があるようです。
Pixelを完全放置サーバーとしたいならこれを試してみる価値はありそうです。

※個人的にはPixelを家用のSpotifyやYouTube Musicのコントローラーとしても使っているため、自動起動でなくとも問題ないのでTermux: Bootは試していません



## LINE Notifyの有効化

> この手順は不要な方はスキップしてしまって大丈夫です。

続いてLINE NotifyによるLINE通知を有効化します。
ざっくり手順を説明すると、LINEのWebコンソールからトークンを発行し、Node.jsスクリプトのconfigファイルにトークンを書き込むだけです。

まずはLINE Notifyのトークン発行を行います。
[LINE NotifyのWebコンソール](https://notify-bot.line.me/ja/)にアクセスし、通知を送りたいLINEのIDでログインします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/207109/5960df89-dc2f-e2e1-ea3b-1f517189364f.png)

ログイン後、名前をクリックするとメニューが表示されるので「マイページ」を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/207109/01fc8f30-9e15-2e24-7c5e-d50122f9b469.png)

「アクセストークンの発行（開発者向け）」という項目より「トークンを発行する」ボタンを押します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/207109/232a5bca-1b2b-9f91-c364-1ba87e571dc3.png)

トークン名を適当に入力し、通知を送信するトークルームに「1:1でLINE Notifyから通知を受け取る」を選択します。
※ここは表示されるトークルームから任意のものを選択してもOKです
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/207109/3865708d-4fe6-2bb9-910b-a3d6525e47a7.png)

トークンが発行されるのでメモります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/207109/8a512423-597a-b37f-d722-65c2a899af92.png)

Webコンソールによるトークン発行は以上となります。

続いてNode.jsスクリプトのconfig.jsに発行したトークンを書き込みます。
以下のコマンドを実行しconfig.jsを開きます。

```
# config.jsを開く
cd /storage/emulated/0/google-photos-upload-server/app
nano config.js
```

内容は以下のようになっているので、2行目の`exports.lineNotifyToken = ""`の値にトークンを書き込み保存します。

```js:config.js
exports.photosDir = "../photos"					// アップロード対象写真ディレクトリ
exports.lineNotifyToken = ""					// LINE Notifyトークン
exports.minFreeSize = 5 * 1024 * 1024 * 1024	// 通知を送る残容量しきい値
exports.periodDay = 7							// 削除までの保持日数
```

そして`notify-test.js`を実行するとLINE Notifyでの通知テストが行えます。

```
# LINE Notifyのテスト実行
node notify-test.js
```

LINEへ以下のような通知が飛んでいれば成功です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/207109/71894ede-a619-3c08-f8a7-a9b8eab4fd98.png)



## SFTP Serverの有効化

続いてPixelにてSFTPサーバーを起動します。
SFTPサーバーの起動には「SSH/SFTP Server - Terminal」というアプリを使用します。
画面を見れば設定方法は一目瞭然かと思いますので、簡潔にやることを列挙してみます。

SSH/SFTP Server - Terminal (Google Play)
https://play.google.com/store/apps/details?id=net.xnano.android.sshserver

* Google Playよりインストール、起動
* Usersタブよりユーザー作成
	* 任意の「Name」「Username」「Password」を入力
	* 「Add new」をタップして「Path」に「`/storage/emulated/0/`」を指定
* Homeタブの「Automation settings」よりサーバー自動起動設定
* Homeタブ内右上のボタンよりサーバー起動

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/207109/fe3fb56a-c9ad-238b-a5ff-ec171f9541bf.png)

またアプリ設定とは別途、ルーターかPixel自体のWi-Fi設定にてIPアドレスを固定しておきます。



## Googleフォトアプリ設定

最後にGoogleフォトアプリの設定です。

Google フォト (Google Play)
https://play.google.com/store/apps/details?id=com.google.android.apps.photos

* Google Playよりインストール、起動
* Googleフォトアプリにて右上のアカウントアイコンをタップ
* 「アカウントの保存容量」をタップ
* 「アップロード サイズ」を「高画質」に設定
* 「デバイスのフォルダのバックアップ」にて「photos」を指定
	* 画面上パスが確認できませんが`/storage/emulated/0/google-photos-upload-server/photos`が指定されるように

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/207109/f9dc49cb-d6ef-5932-1935-1faf640e56b8.png)



## アップロード元端末でのFolderSync設定

続いて**Pixelへ写真をアップロードする端末側**のセットアップです。
FolderSyncをインストール、起動し以下の設定を行います。

FolderSync (Google Play)
https://play.google.com/store/apps/details?id=dk.tacit.android.foldersync.lite

まずはアカウントタブにてアカウントを追加します。

* アカウント追加ボタンをタップ
* アカウントの種類にてSFTPを選択
* ログイン名、パスワードにてSFTP Serverで設定したuser/passwordを入力
* サーバーアドレス、ポートにてIP固定したPixelのIPアドレスとSFTP Serverで設定したポート番号を入力

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/207109/578fd3e3-74fd-20ee-c6e7-570268aae1d4.png)

次に同期フォルダータブにてアップロードしたい写真フォルダーを同期フォルダーとして登録していきます。

* 同期フォルダーを作成ボタンをタップ
* SFTPアカウントを選択
* 適当に名前をつける
* 各項目を以下のように設定
	* 同期タイプ: Upload
	* リモートフォルダー: /google-photos-upload-server/photos/
	* ローカルフォルダー: /storage/emulated/0/DCIM/
	* スケジュール
		* スケジュールされた同期を使用: オン
			* カスタムスケジュール
			* 同期する曜日: すべて選択
			* 同期する時刻: 任意の時間帯（Node.jsスクリプトのcron実行時間前を推奨）
	* 高度な設定
		* 変更したソースファイルのみを再同期（一度同期されたターゲットの削除を無視）: オン
	* フィルター
		* 必要に応じて（Googleフォトに既にバックアップ済みの写真を日付でフィルタリングする等）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/207109/2e670bef-4f78-0c34-14b7-d743bb7d8245.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/207109/2264be20-7c1e-f751-5c1d-47908b8a0648.png)

スクリーンショット等も含めたい場合は、上記設定のうちローカルフォルダーに「/Pictures/Screenshot/」を指定した同期フォルダーを作成します。
ほかにもバックアップしたいフォルダがあればそれぞれローカルフォルダーのパスを変えて同期フォルダーを作成していきます。



## Node.jsスクリプト実行ログについて

以上で2021年6月1日以降もGoogleフォトへ容量無制限に写真をアップロードするしくみが整いました。

なおNode.jsスクリプト実行時に同ディレクトリの`log.txt`というファイルにログを出力しています。
このログファイルにスクリプト実行日時、削除したファイルパス、ストレージ空き容量を出力するようにしています。
Googleフォト アップロードサーバーを構築してしばらくはこのログと、ちゃんとGoogleフォトに写真がアップされているかチェックしてみてください。

またログが不要な場合は`index.sh`よりログファイルへのリダイレクトを削除してください。

```sh:index.sh
#!/bin/bash
cd $(cd $(dirname $0);pwd)

date >> ./log.txt				# この行を削除 or コメントアウト

termux-wake-lock
node ./index.js >> ./log.txt	# ここの`>> ./log.txt`を削除する
termux-wake-unlock
```



# NASにバックアップを行っているケース

NASへバックアップを行っている場合はPixelにSFTP Server等を起動する必要はなく、PixelにFolderSyncをインストールしNASからファイルをPullする方法で十分です。
この方法であれば普段写真を撮っているメインスマホ側へは特段変更を行う必要はありません。

## 我が家の現状のバックアップ構成

例えば我が家の現状のバックアップ構成は下図のようになっています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/207109/45b98717-93c6-3c1e-0ee6-1bb4adb9febd.png)

* 各スマホからPCとNAS（ラズパイ&外付けHDD）へ日次バックアップ
* PCの「Google バックアップと同期」アプリにてバックアップされた写真をGoogleフォトへ自動バックアップ
	* **ここをPixel経由に変更する！**

## Pixelを経由したバックアップ構成

現状バックアップ構成をPixelを経由する形にすると下図のようになります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/207109/ef99519e-6dac-68ad-972b-bcd76a5dc5df.png)

「PC→Googleフォト」とつながっていた部分を「NAS（ラズパイ）→Pixel→Googleフォト」という流れに変更します。



## 具体的な構築手順（NASにバックアップを行っているケース）

[Termuxの環境構築](#termuxの環境構築)、[LINE Notifyの有効化](#line-notifyの有効化)、[Googleフォトアプリ設定](#googleフォトアプリ設定)は上記手順と同様に行います。

[SFTP Serverの有効化](#sftp-serverの有効化)、[アップロード元端末でのFolderSync設定](#アップロード元端末でのFolderSync設定)の手順は不要となり、代わりにPixel端末にてFolderSyncの設定を行います。

### FolderSyncの設定（NASにバックアップを行っているケース）

まずはアカウントタブにてアカウントを追加します。

* アカウント追加ボタンをタップ
* アカウントの種類にて、NASへアクセス可能なプロトコル（SMB等）を選択
* ログイン名、パスワード等、NASへのアクセスに必要な情報を入力

次に同期フォルダータブにてアップロードしたい写真フォルダーを同期フォルダーとして登録していきます。

* 同期フォルダーを作成ボタンをタップ
* 上記手順で作成したアカウントを選択
* 適当に名前をつける
* 各項目を以下のように設定
	* **同期タイプ: Download**
	* **リモートフォルダー: バックアップしている写真フォルダーのパス**
	* **ローカルフォルダー: /storage/emulated/0/google-photos-upload-server/photos/**
	* スケジュール
		* スケジュールされた同期を使用: オン
			* カスタムスケジュール
			* 同期する曜日: すべて選択
			* 同期する時刻: 任意の時間帯（Node.jsスクリプトのcron実行時間前を推奨）
	* 高度な設定
		* 変更したソースファイルのみを再同期（一度同期されたターゲットの削除を無視）: オン
	* フィルター
		* 必要に応じて

他にもバックアップしたいフォルダがあればそれぞれリモートフォルダーのパスを変えて同期フォルダーを作成していきます。



# さいごに
以上で2021年6月1日以降も引き続き容量無制限でGoogleフォトへ写真をバックアップし続けるようになり一安心です。最後に冒頭に書いた

> ※Amazonプライムフォト等、他のサービスへの変更も検討しましたが「[Google Nest HubはフォトフレームのUX革命だ！](https://note.com/miso_develop/n/n9b644541adad)」という記事に書いたように、Googleフォト自体の機能、そしてNest Hubといったデバイス連携によるフォトUXが大変すばらしいため、Googleフォトを使い続ける選択肢を選びました

についてもう少し詳しく書いておこうと思います。
上記のリンク先記事で書いていることをざっくり言うとGoogleフォトとGoogle Nest Hubを連携することで

* **「撮った写真を取り込む（バックアップ）」**
* **「撮った写真を精査する（ブレてる写真とかを消す）」**
* **「撮った写真を能動的に見る」**

という写真に纏わる三大面倒事が解消されるのです。
写真を撮ったらその後私は本当に何もせずとも、いい感じに撮れた写真がGoogle Nest Hubに表示されます。
これは現状本当に最高のフォトUXだと思っています。

AmazonプライムフォトもAmazon Echo Showシリーズで同等の機能がありますが、Googleフォトの方が機能・顔認識率とも頭ひとつ抜きん出ていると思います。（Amazonプライムフォトでも並行してバックアップ、Amazon Echo Showでの写真表示は使っていますが…）

またGoogleフォトの容量無制限化のために新たにPixelを購入するかは環境によるところかと思いますが、200GBを超える可能性があるかがひとつのラインかと思います。
Googleドライブ（Google One）の次の課金プランが[2TBで年額13,000円](https://one.google.com/about/plans?hl=ja)となり、Pixel 3aの中古端末は現在[約15,000円～25,000円ほどです](https://iosys.co.jp/items?q=Pixel+3a&sort=h)。

200GBを超える可能性があるなら中古Pixel端末をGoogleフォトアップロードサーバーにする選択肢は大いにアリ寄りのアリでしょう。（現行Pixel端末の容量無制限サポートもそのうちまたポリシー変更で…なんてこともなくはなさそうですが…）

P.S. 誰か本記事のNode.jsスクリプト部分をアプリ化してください😣