AWS LambdaとGoogle Drive APIを使用したファイル転送の自動化


# AWS LambdaとGoogle Drive APIを使用したファイル転送の自動化

## はじめに

この記事では、AWS Lambda関数を使ってS3バケットからファイルを取得し、Google Driveにアップロードする方法について説明します。
Pythonを使用し、boto3とGoogle Drive APIを活用することで、ファイルの自動転送を実現します。

クラウドサービスを使用することで、ファイルの自動化された管理が可能となります。
AWS Lambdaはサーバーレスのコンピューティングサービスであり、Google Drive APIを使用することでファイルのアップロードや管理が簡単にできます。
この組み合わせにより、効率的なファイル管理システムを構築することができます。

## フロー

以下のシーケンス図は、AWS Lambdaを使用してAmazon S3からファイルを取得し、Google Driveにアップロードするプロセスを示しています。

1. **Lambda から S3 へ**: ファイルダウンロード要求
2. **S3 から Lambda へ**: ファイルダウンロード完了
3. **Lambda から Google Drive へ**: ファイルアップロード
4. **Google Drive からの応答**: アップロード完了
5. **Lambda 内**: 一時ファイルのクリーンアップ

このプロセスは、Lambdaの自動化により効率的かつスケーラブルです。


![ChatGPT Diagram.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308256/0da05d3b-0899-998b-c289-71f672f4c87e.png)



## `service-account-key.json`ファイルの作成

Google Drive APIを使用するためには、Google Cloud Platformでサービスアカウントを作成し、対応するJSON形式のキーファイル（`service-account-key.json`）を生成する必要があります。
このキーファイルにはAPIへのアクセスに必要な認証情報が含まれています。

### 手順

1. Google Cloud Platformのコンソールにアクセスし、サービスアカウントを作成します
2. 作成したサービスアカウントに対して、必要な権限を付与します
3. サービスアカウントのキーを生成し、JSON形式でダウンロードします

詳しい手順については、Qiitaの記事「[Lambda(Python)でGoogle Driveへファイルアップロード #Python](https://qiita.com/w2or3w/items/b66a4a8e45e6001a9c46)」に記載されています。
この記事は、サービスアカウントの作成からキーファイルの生成までを詳しく説明しています。

## `service-account-key.json`ファイルの配置

生成した`service-account-key.json`ファイルは、Lambda関数の実行ファイルと同じパスに配置する必要があります。
これにより、Lambda関数がGoogle Drive APIを利用する際に、必要な認証情報にアクセスできるようになります。

## ソースコード解説

以下のソースコードは、S3バケットからファイルを取得し、指定されたGoogle Driveのフォルダにアップロードするプロセスを示しています。

```python
import os
import boto3
from googleapiclient.discovery import build 
from googleapiclient.http import MediaFileUpload 
from oauth2client.service_account import ServiceAccountCredentials 

def lambda_handler(event, context):
    try:
        bucket = os.environ.get('S3_BUCKET_NAME', 'default-bucket-name')
        key = event.get('key')
        folder_name = event.get('folder')
        folder_id = os.environ.get('CAMERAS_FOLDER_ID')

        print(f"Received file from S3: Bucket={bucket}, Key={key}, Folder={folder_name}")
        handle_file_processing(bucket, key, folder_id)
    except Exception as e:
        print(f"Error in lambda handler: {e}")
        raise e

def create_s3_client():
    """S3クライアントを作成する"""
    return boto3.client('s3')

def download_file_from_s3(s3, bucket, key, local_path):
    """S3からファイルをダウンロードする"""
    s3.download_file(Bucket=bucket, Key=key, Filename=local_path)

def create_google_drive_service():
    """Google Driveサービスを作成する"""
    scope = ['https://www.googleapis.com/auth/drive.file'] 
    keyFile = 'service-account-key.json'
    credentials = ServiceAccountCredentials.from_json_keyfile_name(keyFile, scopes=scope)
    return build("drive", "v3", credentials=credentials, cache_discovery=False)

def upload_file_to_google_drive(service, file_name, local_file_path, folder_id):
    """Google Driveにファイルをアップロードする"""
    mime_type = get_mime_type(local_file_path)
    file_metadata = {"name": file_name, "mimeType": mime_type, "parents": [folder_id]}
    media = MediaFileUpload(local_file_path, mimetype=mime_type, resumable=True)
    service.files().create(body=file_metadata, media_body=media, fields='id').execute()

def get_mime_type(file_path):
    """ファイルのMIMEタイプを取得する"""
    ext = os.path.splitext(file_path.lower())[1][1:]
    if ext == "jpg":
        ext = "jpeg"
    return "image/" + ext

def handle_file_processing(bucket, key, folder_id):
    """ファイルの処理を行うメインの関数"""
    local_path = "/tmp/" + os.path.basename(key)
    s3_client = create_s3_client()
    google_drive_service = create_google_drive_service()

    try:
        download_file_from_s3(s3_client, bucket, key, local_path)
        upload_file_to_google_drive(google_drive_service, os.path.basename(key), local_path, folder_id)
    finally:
        clean_up_local_file(local_path)

def clean_up_local_file(file_path):
    """ローカルファイルを削除する"""
    if os.path.exists(file_path):
        os.remove(file_path)

```

### メイン関数: `lambda_handler`

- `lambda_handler`はLambda関数のエントリーポイントです
- 環境変数からS3バケット名とGoogle DriveのフォルダIDを取得します
- イベントからファイルのキーとフォルダ名を取得し、適切な処理を行います

### S3クライアントの作成: `create_s3_client`

- `boto3.client`を使用してS3クライアントを作成します

### Google Driveサービスの作成: `create_google_drive_service`

- Google Drive APIを使用するためのサービスを初期化します

### ファイルのアップロード: `upload_file_to_google_drive`

- Google Driveにファイルをアップロードするための関数です
- MIMEタイプを指定し、メタデータと共にファイルをアップロードします

## まとめ

このソースコードを使用することで、S3からGoogle Driveへのファイル転送を自動化することが可能です。
サーバーレスアーキテクチャを活用することで、リソースの管理が容易になり、効率的なファイル処理が実現できます。

## 参考

* [Lambda(Python)でGoogle Driveへファイルアップロード #Python - Qiita](https://qiita.com/w2or3w/items/b66a4a8e45e6001a9c46)
* [LambdaからGoogleDrive内のファイルを読む #AWS - Qiita](https://qiita.com/afukuma/items/f0d8f0d9d97d9e43ed98)

---
### 会社紹介

**株式会社 Mosaica**  
最先端テクノロジーで社会課題を解決し、持続可能な未来を創造する IT カンパニー。
AI ソリューション、クラウド統合、DX 推進、経営コンサルティングなど包括的なサービスでビジネス変革を支援しています。  

詳しくは [公式サイト](https://mosaica.co.jp/) までお気軽にご相談ください。
公式サイト： https://mosaica.co.jp/