BLOGサブスレッドの日常
2025.10.29
(Python + PowerAutomate)GoogleDocsの権限を自動的に変更したい
torikai
サブスレッドでは、毎週全社ミーティングが行われるのですが、そのアジェンダはGoogleDocsで全社員に共有されております。
そして、ミーティングが行われる日の10:00に、アジェンダの権限を「閲覧者(コメント可)」変更するルールとなっております。
毎週忘れずに手ずから権限変更をする…
数年間はそのように運用されていましたが、鳥飼がとうとう我慢出来なくなってきました。
Googleのことなので、GASで…と思いましたが、得意なPythonで対応することにしました。
Google の OAuth クライアントID を取得する
まず、https://console.cloud.google.com/apis/credentials からOAuth2.0のクライアントIDを発行しましょう。
アプリケーションの種類は「デスクトップアプリ」、名前は適当に「GoogleDocsの権限更新」とでもしておきます。

「作成」ボタンを押すと、OAuthクライアントが作成され、その情報が入ったJSONファイルがダウンロードできるようになります。忘れずダウンロードしておきましょう。

Pythonスクリプトを用意
いつものように poetry で仮想環境を作りまして。Python のバージョンは、現時点で最新の 3.13.9 としました。
パッケージとして、google-api-python-client google-auth-httplib2 google-auth-oauthlib が必要なので、適宜追加します。
Googleクライアントの認証クラスを、Copilotに手伝ってもらいながら用意しました。
import os
import pickle
from pathlib import Path
from google.auth.transport.requests import Request
from google_auth_oauthlib.flow import InstalledAppFlow
from googleapiclient.discovery import build
class GoogleClient:
BASE_DIR = BASE_DIR = Path(__file__).resolve().parent.parent
# スコープ設定(Driveのフルアクセス)
SCOPES = ["https://www.googleapis.com/auth/drive"]
# クレデンシャルファイル
CREDENTIALS_FILE = BASE_DIR / "oauth_credentials.json"
# トークン保存ファイル
TOKEN_PICKLE = BASE_DIR / "token.pickle"
def __init__(self, *args, **kwargs):
self.creds = self.authorization()
# クライアント初期化
self.drive_service = build("drive", "v3", credentials=self.creds, num_retries=3)
def authorization(self):
# 認証処理
_creds = None
# 認証済のトークンが存在する場合は、ファイルから認証情報を取得
if os.path.exists(self.TOKEN_PICKLE):
with open(self.TOKEN_PICKLE, "rb") as token:
_creds = pickle.load(token)
# 認証情報がない、または期限切れの場合
if not _creds or not _creds.valid:
if _creds and _creds.expired and _creds.refresh_token:
# トークンをリフレッシュ
_creds.refresh(Request())
else:
# ブラウザを開いて手動認証(OAuth)
flow = InstalledAppFlow.from_client_secrets_file(
self.CREDENTIALS_FILE, self.SCOPES
)
_creds = flow.run_local_server(port=0)
# 新しいトークンを保存
with open(self.TOKEN_PICKLE, "wb") as token:
pickle.dump(_creds, token)
return _creds
さて、全社ミーティングのアジェンダは、Googleドライブの特定のフォルダに 全社ミーティング_251028 のようなファイル名で保存されています。
そして全社ミーティングは特定の曜日に開催されますが、その曜日が祝日などで休みの場合、別の日に開催されることになります。
という事情から、「毎日10:00にスクリプトを起動して、その日の日付のアジェンダがあれば権限を "閲覧者(コメント可)" に変更する」という仕様で作成します。
処理の内容は割愛します。
ついでに PowerAutomate で通知
サブスレッドは Microsoft365 を使って社内でやり取りしています。
せっかくなので、「権限を変更したよ」という通知を、社内のチャネルに投稿するようにしましょう。
チャネルに対してメールを送信してもいいんですが、今回は「Teams Webhook 要求を受信したとき」のトリガーを使います。
PowerAutomate の「作成」より「インスタント クラウド フロー」を選択し、トリガーには「Teams Webhook 要求を受信したとき」を選択します。

Webhook URL は、フローを保存した時に生成されるのですが、フローを保存するには少なくとも1つのアクションを配置する必要があるので、「チャットまたはチャネルでメッセージを投稿する」を配置しつつ、投稿先を適宜設定します。
Message には、Webhook URL にリクエストされた内容を表示したいので、「式を挿入する」から triggerBody().description を入力して設定します。

せっかくなのでタイトルもほしいですね。「詳細パラメーター」より「Subject」を選択して、これも同様に「式を挿入する」から triggerBody().subject を入力して設定します。
ようやくフローを保存できる状態になりますので、保存しましょう。
すると Webhook URL が生成されます🎉

このURLにリクエストする処理を書きましょう!
today = datetime.now().astimezone()
weekday = ["月", "火", "水", "木", "金", "土", "日"][today.weekday()]
body = f"[{self.file['name']}](https://docs.google.com/document/d/{self.file['id']}) の権限を更新しました。\n"
requests.post(
"(先程生成した Webhook URL)",
json={
"subject": f"{today:%Y年%m月%d日({weekday})}",
"description": markdown.markdown(body),
},
)

アジェンダの権限も無事「閲覧者(コメント可)」に変更され、Teamsのチャネルにも通知されました。
めでたしめでたし。
この記事を書いた人
torikai
