2017年7月23日日曜日

久しぶりにGoogle Cloudを触ってはまる、の巻

プログラマの皆さん、こんにちは。

自分が趣味で開発しているスマフォアプリの宣伝ブログを立ち上げようとしているのですが、記事を書くのが面倒なのでデータ収集→HTML編集→Blogger投稿を自動化しようと考えました。

Googleのサービスを触らなくなって久しいのですが

  • ID/Passwordによる認証はもはやサポートされてない(Oauthを使う必要あり)
  • Oauth用アカウントには二種類あって
    • Webブラウザやスマフォアプリに人間がID/Passwordを入れてOauth認証
    • 鍵/秘密鍵をJWTで送り付けて認証する(サービスアカウント)
というところまでは割とすんなり理解しました。

で、今回はBlogger投稿の完全自動化を目指しているのでサービスアカウント一択となります。以下のような簡単なコードを書いてみました。

from oauth2client.service_account import ServiceAccountCredentials
from httplib2 import Http
from googleapiclient.discovery import build


def get_blogger_service():
    scopes = ['https://www.googleapis.com/auth/blogger']
    credentials = ServiceAccountCredentials.from_json_keyfile_name(
        'credentials.json', scopes=scopes
    )
    http_auth = credentials.authorize(Http())
    return build('blogger', 'v3', http=http_auth)

def create_public_post(blogger_service, blog_id, content):
    request = blogger_service.posts().insert(
        blogId=blog_id,
        body=content
    )
    response = request.execute()
    return response

if __name__ == '__main__':
    service = get_blogger_service()
    content = {
        "kind": "blogger#post",
        "id": '俺様のblog id',
        "title": "posted via python",
        "content": "
hello world test
" } print create_public_post(service, '俺様のblog id', content)


上記コードを実行すると例外が発生し



googleapiclient.errors.HttpError: httperror 403="" access="" alt="json" blogger="" blogs="" but="" don="" e="" have="" https:="" permission="" posts="" re="" requesting="" resource.="" returned="" sorry="" t="" this="" to="" v3="" when="" www.googleapis.com="" you=""

というエラーが返っていることがわかります。最初はサービスアカウントに持たせた権限が足らないのかなと思いましたが、Owner権限(ほぼなんでもできる)に設定しても症状は変わりません。

悩むこと数日。

こんなやり取りを見つけました。

  • Paulという人がBlogger API v3で(自分と同様に)自動化された投稿を試みるも、403で跳ねられる。何がおかしいのかを質問。
  • BrettというおそらくはGoogleの中の人が「Service Accountからの投稿は許可してないよ」と一行回答。
  • Peterが「なんでじゃい?」と食い下がる。
  • Brettの回答「Blogger投稿には利用規約への同意が必要。自動化されたサービスアカウントには同意ができない。だからダメ」
  • Johnという別人が議論に参戦。「おかしいだろそれ。Blogger API v3のドキュメントではService Accountについて言及してるし、Google ConsoleからBlogger APIを選ぶと、紐づけアカウントでService Account選べるようになってるぞ」と反論。
  • Brettは頑なに「利用規約に同意しないとBloggerへの投稿はできない」というだけ。

ドキュメントが誤解を招くものなのも問題だし、利用規約への同意がないと投稿ができないっていうのもYes/Noの選択だけなんだからプログラムにやらせてもいいと思うんだけど。

まあGoogleもでかい会社だし、こういうお役人みたいな対応する社員がいてもおかしくはないかな、と。

ということでブラウザ経由で認証する仕組みに実装を変えます。で、Headless Browserをスクリプトで制御すればなんとかなるでしょ...

0 件のコメント:

コメントを投稿