# [メタ情報]
# 識別子: マイライブラリ_dropboxAPI_Mac_GASデータ交換_exe
# システム名: マイライブラリ_dropboxAPI_Mac_GASデータ交換
# 技術種別: Misc
# 機能名: Misc
# 使用言語: Python
# 状態: 公開用
# [/メタ情報]
# [/メタ情報]
要約:DropboxのOAuth認証設定、リンク自動取得、GASとの通信を行う3本のPythonスクリプト群。
①dropbox_auth_setup.pyはローカルHTTPサーバで認証コードを受け取り、Dropboxのアクセストークンとリフレッシュトークンを取得する。
②get_dropbox_link.pyはリフレッシュトークンを用いてDropbox APIに接続し、指定ローカルファイルの共有リンクを取得または生成し、dl=0をraw=1に変換して出力する。
③send_request.pyはAppleScriptから受け取ったDropboxリンクやファイル情報をGASのエンドポイントへJSON形式で送信し、更新処理を実行する。
M2Mac
▫️DropboxのAPIからトークン取得
Python
<任意のフォルダパス>/dropbox_auth_setup.py
dropbox_auth_setup.py
```
import os
import webbrowser
import http.server
import socketserver
import urllib.parse
import requests
from dotenv import load_dotenv
# .envファイルのロード
env_path = "<任意のフォルダパス>"
load_dotenv(env_path)
APP_KEY = os.environ.get("APP_KEY")
APP_SECRET = os.environ.get("APP_SECRET")
REDIRECT_URI = "http://localhost:8080"
AUTH_URL = "https://www.dropbox.com/oauth2/authorize"
TOKEN_URL = "https://api.dropboxapi.com/oauth2/token"
# 📡 Step 1: 認証コードを取得する
params = {
"response_type": "code",
"client_id": APP_KEY,
"redirect_uri": REDIRECT_URI,
"token_access_type": "offline"
}
url = f"{AUTH_URL}?{urllib.parse.urlencode(params)}"
print("🌐 ブラウザで認証を開始します...")
webbrowser.open(url)
# 🔁 Step 2: ローカルでcodeを受け取る
class OAuthHandler(http.server.SimpleHTTPRequestHandler):
def do_GET(self):
query = urllib.parse.urlparse(self.path).query
code = urllib.parse.parse_qs(query).get("code", [None])[0]
self.send_response(200)
self.send_header("Content-type", "text/html")
self.end_headers()
self.wfile.write("
認証完了。ターミナルに戻ってください。
".encode("utf-8"))
self.server.auth_code = code
with socketserver.TCPServer(("localhost", 8080), OAuthHandler) as httpd:
httpd.handle_request()
code = httpd.auth_code
# 🎫 Step 3: アクセストークン+リフレッシュトークン取得
print("🔐 トークンを取得しています...")
res = requests.post(TOKEN_URL, data={
"code": code,
"grant_type": "authorization_code",
"client_id": APP_KEY,
"client_secret": APP_SECRET,
"redirect_uri": REDIRECT_URI
})
if res.status_code != 200:
print("❌ 認証に失敗しました:", res.text)
exit(1)
tokens = res.json()
print("✅ ACCESS_TOKEN:", tokens["access_token"])
print("🔄 REFRESH_TOKEN:", tokens["refresh_token"])
```
get_dropbox_link.py
<任意のフォルダパス>/get_dropbox_link.py
<任意のフォルダパス>/get_dropbox_link.py
◆M2 Mac M1 Mac共用
```
# get_dropbox_link.py — リフレッシュトークン対応版
import sys
import os
import json
import re
import dropbox
from dotenv import load_dotenv
# .envファイルのロード
env_path = "<任意のフォルダパス>"
load_dotenv(env_path)
# ✅ あなたのDropboxアプリ情報をここに記入
APP_KEY = os.environ.get("APP_KEY")
APP_SECRET = os.environ.get("APP_SECRET")
REFRESH_TOKEN = os.environ.get("REFRESH_TOKEN")
# 🔁 Dropboxオブジェクトを取得(リフレッシュ対応)
def get_dbx():
return dropbox.Dropbox(
oauth2_refresh_token=<個別のトークン文字列>,
app_key=APP_KEY,
app_secret=APP_SECRET
)
# 🔧 Dropbox内の相対パスを取得
def get_dropbox_path(local_path):
possible_roots = [
"<任意のフォルダパス>",
"/Volumes/NO3_SSD/Dropbox/dropbox_1"
]
for root in possible_roots:
if local_path.startswith(root):
relative_path = local_path[len(root):]
return "/dropbox_1" + relative_path
print(f"ERROR: ファイルがDropboxフォルダ内にありません\nlocal_path: {local_path}", file=sys.stderr)
sys.exit(1)
# 🔗 共有リンクを取得または作成
def get_shared_link(dbx, dbx_path):
try:
links = dbx.sharing_list_shared_links(path=dbx_path, direct_only=True).links
if links:
return convert_to_raw_url(links[0].url)
except Exception:
pass
# なければ新規作成
try:
link = dbx.sharing_create_shared_link_with_settings(dbx_path)
return convert_to_raw_url(link.url)
except Exception as e:
print("❌ Dropbox APIで共有リンクを作成できませんでした:", file=sys.stderr)
print(e, file=sys.stderr)
sys.exit(1)
# 🔄 dl=0 → raw=1 変換
def convert_to_raw_url(url):
return re.sub(r'dl=0', 'raw=1', url)
# 🏁 実行エントリポイント
if __name__ == "__main__":
if len(sys.argv) < 2:
print("Usage: get_dropbox_link.py ", file=sys.stderr)
sys.exit(1)
local_path = sys.argv[1]
dbx_path = get_dropbox_path(local_path)
print(f"📂 Dropbox API 送信パス = {dbx_path}", file=sys.stderr)
dbx = get_dbx()
link = get_shared_link(dbx, dbx_path)
print(link)
```
▫️macとspreadsheetのデータ交換
Python
send_request.py
<任意のフォルダパス>/send_request.py
<任意のフォルダパス>/send_request.py
◆M1 Mac、M2 Mac共通
```
import sys
import os
import json
import requests
from dotenv import load_dotenv
# .envファイルのロード
env_path = "<任意のフォルダパス>"
load_dotenv(env_path)
# Google Apps Script API エンドポイント
GAS_URL = os.environ.get("GAS_URL")
# 🔍 受け取った引数を確認
print("📥 受信引数:", sys.argv)
# コマンドライン引数を取得
if len(sys.argv) < 5:
print("❌ 引数が不足しています")
sys.exit(1)
dropbox_link, file_path, file_name, extn = sys.argv[1], sys.argv[2], sys.argv[3], sys.argv[4]
# 🔍 受け取ったデータをログに記録
print("📥 受信データ from AppleScript:")
print(f" dropboxLink: {dropbox_link}")
print(f" filePath: {file_path}")
print(f" fileName: {file_name}")
print(f" extn: {extn}")
# 送信データ
data = {
"dropboxLink": dropbox_link,
"filePath": file_path,
"fileName": file_name,
"updateFlag": "ADD"
}
# 🔍 送信データを確認
print("📤 送信データ:", json.dumps(data, indent=2, ensure_ascii=False))
# GAS にデータを送信
try:
response = requests.post(GAS_URL, json=data)
response.raise_for_status()
gas_response = response.json()
print("📥 GAS レスポンス:", json.dumps(gas_response, indent=2, ensure_ascii=False))
if gas_response.get("status") == "success":
print("✅ GAS にデータが正常に送信されました!")
print("success")
else:
print(f"❌ GAS でエラー発生: {gas_response.get('message')}")
print("error")
except requests.exceptions.RequestException as e:
print(f"❌ GAS 送信エラー: {e}")
print("error")
```