Skip to content

Commit 2f435b4

Browse files
authored
Merge pull request #427 from smalruby/feature/google-drive-loader
Add Google Drive file loading functionality
2 parents 09535a9 + 8bd2f1e commit 2f435b4

File tree

11 files changed

+886
-2
lines changed

11 files changed

+886
-2
lines changed

.env.example

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
# Google Drive API Configuration
2+
# See docs/google-drive-setup.md for setup instructions
3+
4+
# Google OAuth 2.0 Client ID (Web Application)
5+
# Example: 123456789012-abcdefghijklmnopqrstuvwxyz123456.apps.googleusercontent.com
6+
GOOGLE_CLIENT_ID=your-client-id-here.apps.googleusercontent.com
7+
8+
# Google API Key (for Picker API)
9+
# Example: AIzaSyAbCdEfGhIjKlMnOpQrStUvWxYz1234567
10+
GOOGLE_API_KEY=your-api-key-here

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,4 +27,7 @@ npm-*
2727
# for act
2828
.secrets
2929

30+
# Environment variables (contains sensitive API keys)
31+
.env
32+
3033
/tmp

cspell.json

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
{
2+
"version": "0.2",
3+
"language": "en",
4+
"words": [
5+
"gapi",
6+
"googleusercontent"
7+
],
8+
"ignorePaths": [
9+
"node_modules",
10+
"build",
11+
"dist",
12+
"coverage",
13+
".nyc_output"
14+
]
15+
}

docs/google-drive-setup.md

Lines changed: 197 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,197 @@
1+
# Google Drive連携機能のセットアップ手順
2+
3+
このドキュメントでは、Smalruby3-GUIでGoogle Driveからファイルを読み込むための機能を有効にするために必要なGoogle Cloud Platform (GCP)の設定手順を説明します。
4+
5+
## 前提条件
6+
7+
- Googleアカウントを持っていること
8+
- Google Cloud Platformへのアクセス権限があること
9+
10+
## 1. Google Cloud Platformプロジェクトの作成
11+
12+
1. [Google Cloud Console](https://console.cloud.google.com/)にアクセス
13+
2. 画面上部の「プロジェクトを選択」をクリック
14+
3. 「新しいプロジェクト」をクリック
15+
4. プロジェクト名を入力(例: `smalruby3-gui`
16+
5. 「作成」をクリック
17+
18+
## 2. 必要なAPIの有効化
19+
20+
### Google Drive APIを有効化
21+
22+
1. Google Cloud Consoleで作成したプロジェクトを選択
23+
2. 左側のメニューから「APIとサービス」→「ライブラリ」を選択
24+
3. 検索ボックスに「Google Drive API」と入力
25+
4. 「Google Drive API」を選択
26+
5. 「有効にする」をクリック
27+
28+
### Google Picker APIを有効化
29+
30+
1. 同じく「ライブラリ」画面で検索ボックスに「Google Picker API」と入力
31+
2. 「Google Picker API」を選択
32+
3. 「有効にする」をクリック
33+
34+
## 3. OAuth 2.0 認証情報の作成
35+
36+
### OAuth同意画面の設定
37+
38+
1. 左側のメニューから「APIとサービス」→「OAuth同意画面」を選択
39+
2. ユーザータイプで「外部」を選択(テスト用途の場合)
40+
3. 「作成」をクリック
41+
4. アプリ情報を入力:
42+
- **アプリ名**: `Smalruby3 GUI`
43+
- **ユーザーサポートメール**: あなたのメールアドレス
44+
- **デベロッパーの連絡先情報**: あなたのメールアドレス
45+
5. 「保存して次へ」をクリック
46+
6. 「スコープ」画面で「スコープを追加または削除」をクリック
47+
7. 以下のスコープを追加:
48+
- `https://www.googleapis.com/auth/drive.file`**推奨**: ファイルの読み込みとアップロードの両方に対応)
49+
8. 「更新」→「保存して次へ」をクリック
50+
9. テストユーザー画面で「保存して次へ」をクリック
51+
10. 確認画面で「ダッシュボードに戻る」をクリック
52+
53+
### OAuth 2.0 クライアントIDの作成
54+
55+
1. 左側のメニューから「APIとサービス」→「認証情報」を選択
56+
2. 画面上部の「認証情報を作成」→「OAuth クライアント ID」をクリック
57+
3. アプリケーションの種類で「ウェブアプリケーション」を選択
58+
4. 名前を入力(例: `Smalruby3 GUI Web Client`
59+
5. 「承認済みのJavaScript生成元」に以下を追加:
60+
- `http://localhost:8601` (開発環境)
61+
- 本番環境のURL(例: `https://smalruby.github.io`
62+
6. 「承認済みのリダイレクトURI」は空欄でOK(Picker APIでは不要)
63+
7. 「作成」をクリック
64+
8. 表示されたダイアログで「クライアントID」をコピーして保存
65+
66+
**重要**: クライアントシークレットは今回の実装では使用しません(フロントエンドのみの実装のため)
67+
68+
## 4. APIキーの作成(Picker API用)
69+
70+
1. 「認証情報」画面で「認証情報を作成」→「APIキー」をクリック
71+
2. APIキーが作成されるので、コピーして保存
72+
3. (推奨)「キーを制限」をクリック
73+
4. 「アプリケーションの制限」で「HTTPリファラー(ウェブサイト)」を選択
74+
5. 「ウェブサイトの制限」に以下を追加:
75+
- `http://localhost:8601/*`
76+
- 本番環境のURL(例: `https://smalruby.github.io/*`
77+
6. 「APIの制限」で「キーを制限」を選択
78+
7. 「Google Picker API」を選択
79+
8. 「保存」をクリック
80+
81+
## 5. 環境変数の設定
82+
83+
### 開発環境(Docker使用時)
84+
85+
**重要**: このプロジェクトはDockerを使用しているため、プロジェクトルート(`smalruby3-develop/`)に `.env` ファイルを作成します。
86+
87+
1. プロジェクトルートに `.env` ファイルを作成:
88+
89+
```bash
90+
# Google Drive API設定
91+
GOOGLE_CLIENT_ID=your-client-id.apps.googleusercontent.com
92+
GOOGLE_API_KEY=your-api-key
93+
```
94+
95+
2. **注意事項**:
96+
- `.env` ファイルは `.gitignore` に含まれているため、Gitにコミットされません
97+
- `docker-compose.yml` がこの `.env` ファイルを自動的に読み込みます
98+
- 環境変数を変更した場合は、`docker compose restart gui` でサービスを再起動してください
99+
100+
3. サービスの再起動:
101+
102+
```bash
103+
# 環境変数を反映させるため再起動
104+
docker compose restart gui
105+
```
106+
107+
### 開発環境(Dockerを使用しない場合)
108+
109+
Dockerを使用せず、直接npmコマンドを実行する場合:
110+
111+
```bash
112+
# gui/smalruby3-gui/ ディレクトリに .env ファイルを作成
113+
cd gui/smalruby3-gui
114+
cat > .env << 'EOF'
115+
GOOGLE_CLIENT_ID=your-client-id.apps.googleusercontent.com
116+
GOOGLE_API_KEY=your-api-key
117+
EOF
118+
119+
# 開発サーバー起動
120+
npm start
121+
```
122+
123+
### 本番環境
124+
125+
本番環境では、ビルド時に環境変数を設定します:
126+
127+
```bash
128+
GOOGLE_CLIENT_ID=your-client-id.apps.googleusercontent.com \
129+
GOOGLE_API_KEY=your-api-key \
130+
npm run build
131+
```
132+
133+
または、GitHub ActionsなどのCI/CD環境では、シークレット変数として設定します。
134+
135+
## 6. セキュリティに関する注意事項
136+
137+
### クライアントIDとAPIキーの管理
138+
139+
- **クライアントID**: 公開しても問題ありませんが、承認済みのJavaScript生成元で制限することを推奨
140+
- **APIキー**: HTTPリファラーで制限し、API制限を有効にすることを強く推奨
141+
- **クライアントシークレット**: フロントエンドでは使用しないこと(セキュリティリスク)
142+
143+
### OAuth 2.0 スコープの選択
144+
145+
このアプリケーションでは以下のスコープを使用します:
146+
147+
- `drive.file` (**推奨・使用中**):
148+
- アプリが作成したファイルの読み書き
149+
- ユーザーがGoogle Pickerで選択したファイルへのアクセス
150+
- ファイルのアップロード機能に必要
151+
- 完全なDriveアクセスより制限されているため安全
152+
153+
**注意**: `drive.readonly`(読み取り専用)では、Google Pickerのアップロードタブが機能しません。
154+
155+
## 7. 動作確認
156+
157+
1. 開発サーバーを起動:
158+
```bash
159+
docker compose up gui
160+
```
161+
162+
2. ブラウザで `http://localhost:8601` を開く
163+
164+
3. ファイルメニューから「Google ドライブから読み込む」を選択
165+
166+
4. Google認証画面が表示されることを確認
167+
168+
5. 認証後、Google Driveのファイル選択画面が表示されることを確認
169+
170+
## トラブルシューティング
171+
172+
### "Access blocked: This app's request is invalid"
173+
174+
- OAuth同意画面の設定が完了していない可能性があります
175+
- テストユーザーに自分のアカウントが追加されているか確認してください
176+
177+
### "API key not valid. Please pass a valid API key."
178+
179+
- APIキーが正しく設定されていない可能性があります
180+
- APIキーの制限設定を確認してください
181+
- Picker APIが有効になっているか確認してください
182+
183+
### "The origin http://localhost:8601 is not allowed"
184+
185+
- OAuth クライアントIDの「承認済みのJavaScript生成元」に `http://localhost:8601` が追加されているか確認してください
186+
187+
### 動的スクリプトのロードエラー
188+
189+
- ブラウザのコンソールでエラー内容を確認してください
190+
- Content Security Policy (CSP) の設定を確認してください
191+
192+
## 参考リンク
193+
194+
- [Google Cloud Console](https://console.cloud.google.com/)
195+
- [Google Picker API Documentation](https://developers.google.com/picker/api)
196+
- [Google Identity Services](https://developers.google.com/identity/gsi/web/guides/overview)
197+
- [Google Drive API v3](https://developers.google.com/drive/api/v3/about-sdk)

src/components/gui/gui.jsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,7 @@ const GUIComponent = props => {
140140
vm,
141141
// Exclude Redux-related props from being passed to DOM
142142
setSelectedBlocks: _setSelectedBlocks,
143+
openUrlLoaderModal: _openUrlLoaderModal,
143144
...componentProps
144145
} = omit(props, 'dispatch');
145146
if (children) {

src/components/menu-bar/menu-bar.jsx

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ import SB3Downloader from '../../containers/sb3-downloader.jsx';
2727
import DeletionRestorer from '../../containers/deletion-restorer.jsx';
2828
import TurboMode from '../../containers/turbo-mode.jsx';
2929
import MenuBarHOC from '../../containers/menu-bar-hoc.jsx';
30+
import GoogleDriveLoaderHOC from '../../containers/google-drive-loader-hoc.jsx';
3031
import SettingsMenu from './settings-menu.jsx';
3132

3233
import {openTipsLibrary, openDebugModal} from '../../reducers/modals';
@@ -519,6 +520,15 @@ class MenuBar extends React.Component {
519520
id="gui.menuBar.loadFromUrl"
520521
/>
521522
</MenuItem>
523+
<MenuItem
524+
onClick={this.props.onStartSelectingGoogleDrive}
525+
>
526+
<FormattedMessage
527+
defaultMessage="Load from Google Drive"
528+
description="Menu bar item for loading from Google Drive"
529+
id="gui.menuBar.loadFromGoogleDrive"
530+
/>
531+
</MenuItem>
522532
</MenuSection>
523533
</MenuBarMenu>
524534
</div>
@@ -946,6 +956,7 @@ MenuBar.propTypes = {
946956
onSetTimeTravelMode: PropTypes.func,
947957
onShare: PropTypes.func,
948958
onStartSelectingFileUpload: PropTypes.func,
959+
onStartSelectingGoogleDrive: PropTypes.func,
949960
onStartSelectingUrlLoad: PropTypes.func,
950961
onToggleLoginOpen: PropTypes.func,
951962
projectTitle: PropTypes.string,
@@ -1026,6 +1037,7 @@ const mapDispatchToProps = dispatch => ({
10261037
export default compose(
10271038
injectIntl,
10281039
MenuBarHOC,
1040+
GoogleDriveLoaderHOC,
10291041
connect(
10301042
mapStateToProps,
10311043
mapDispatchToProps

0 commit comments

Comments
 (0)