より良いエンジニアを目指して

1日1つ。良くなる!上手くなる!

Google Docs APIを使って文章を作成してみる

Google Documentをよく作成しているのですが、いつも文書のタイトルを入力して、本文にもタイトルを入力するようにしています。

地味に同じ文字列を二度入力するのは手間です。

そこからGoogle Document APIを使って、作業効率化できないかなと思って調べてみることにしました。

developers.google.com

まず結論

ここに至る結論が長いので、結論から書きます。私は以下のようなコードにすることにしました。

from __future__ import print_function
import pickle
import os.path
import webbrowser

from googleapiclient.discovery import build
from google_auth_oauthlib.flow import InstalledAppFlow
from google.auth.transport.requests import Request


SCOPES = ['https://www.googleapis.com/auth/documents']

def get_credential():
    creds = None
    # The file token.pickle stores the user's access and refresh tokens, and is
    # created automatically when the authorization flow completes for the first
    # time.
    if os.path.exists('token.pickle'):
        with open('token.pickle', 'rb') as token:
            creds = pickle.load(token)
    # If there are no (valid) credentials available, let the user log in.
    if not creds or not creds.valid:
        if creds and creds.expired and creds.refresh_token:
            creds.refresh(Request())
        else:
            flow = InstalledAppFlow.from_client_secrets_file(
                'credentials.json', SCOPES)
            creds = flow.run_local_server(port=0)
        # Save the credentials for the next run
        with open('token.pickle', 'wb') as token:
            pickle.dump(creds, token)    
    return creds

def main(title, text):
    """Shows basic usage of the Docs API.
    Prints the title of a sample document.
    """
    creds = get_credential()
    service = build('docs', 'v1', credentials=creds)

    body = {
        "title":title
    }
    doc = service.documents().create(body=body).execute()
    requests = [
         {
            'insertText': {
                'location': {
                    'index': 1,
                },
                'text': text
            }
        }
    ]
    document_id = doc.get('documentId')
    url = 'https://docs.google.com/document/d/' + document_id
    service.documents().batchUpdate(documentId=document_id, body={'requests': requests}).execute()
    webbrowser.open(url)

if __name__ == '__main__':
    # 文書のタイトルと本文の内容を指定
    main('ドキュメントタイトル','本文')
  1. credentials.jsonから認証情報を生成
  2. 文書を作成
  3. 文書に文字列を挿入
  4. WebBrowserで生成したドキュメントを開く

という流れです。

f:id:rimever:20191007204837p:plain
いけましたね

補足説明

文書を作成して、さらに文書に文字列を挿入しています。

これは二度手間だと思うのですが、GoogleDocumentの厄介な点として文書構造の複雑さにあります。

末尾で文書情報のjsonサンプルを紹介しますが、文書情報はフォント、フォントサイズ、文字の揃えなど、こちらが考える以上の情報量です。

それを補うだけの情報をAPIで用意されているようです。

が、それっぽい文書情報をjsonで入力してみたのですが本文が空で上手く行きませんでした。

私としては、とりあえず、手軽に作れれば良いやということで、insertTextのAPIを用いて文字列を挿入しています。

SCOPE

SCOPE(文書の参照・編集について)は以下を。

developers.google.com

参考までに文書構造を

f:id:rimever:20191006215748p:plain

    body = {
        "title": "ドキュメントタイトル",
        "body": {
            "content": [
                {
                    "endIndex": 1,
                    "sectionBreak": {
                        "sectionStyle": {
                            "columnSeparatorStyle": "NONE",
                            "contentDirection": "LEFT_TO_RIGHT"
                        }
                    }
                },
                {
                    "startIndex": 1,
                    "endIndex": 6,
                    "paragraph": {
                        "elements": [
                            {
                                "startIndex": 1,
                                "endIndex": 6,
                                "textRun": {
                                    "content": "タイトル\n",
                                    "textStyle": {}
                                }
                            }
                        ],
                        "paragraphStyle": {
                            "headingId": "h.er2w7sbutfor",
                            "namedStyleType": "TITLE",
                            "direction": "LEFT_TO_RIGHT"
                        }
                    }
                },
                {
                    "startIndex": 6,
                    "endIndex": 13,
                    "paragraph": {
                        "elements": [
                            {
                                "startIndex": 6,
                                "endIndex": 13,
                                "textRun": {
                                    "content": "サブタイトル\n",
                                    "textStyle": {}
                                }
                            }
                        ],
                        "paragraphStyle": {
                            "headingId": "h.6imx0s8syx4j",
                            "namedStyleType": "SUBTITLE",
                            "direction": "LEFT_TO_RIGHT"
                        }
                    }
                },
                {
                    "startIndex": 13,
                    "endIndex": 18,
                    "paragraph": {
                        "elements": [
                            {
                                "startIndex": 13,
                                "endIndex": 18,
                                "textRun": {
                                    "content": "見出し1\n",
                                    "textStyle": {}
                                }
                            }
                        ],
                        "paragraphStyle": {
                            "headingId": "h.95f0tp522tw7",
                            "namedStyleType": "HEADING_1",
                            "direction": "LEFT_TO_RIGHT"
                        }
                    }
                },
                {
                    "startIndex": 18,
                    "endIndex": 23,
                    "paragraph": {
                        "elements": [
                            {
                                "startIndex": 18,
                                "endIndex": 23,
                                "textRun": {
                                    "content": "見出し2\n",
                                    "textStyle": {}
                                }
                            }
                        ],
                        "paragraphStyle": {
                            "headingId": "h.ygndpctymssk",
                            "namedStyleType": "HEADING_2",
                            "direction": "LEFT_TO_RIGHT"
                        }
                    }
                },
                {
                    "startIndex": 23,
                    "endIndex": 28,
                    "paragraph": {
                        "elements": [
                            {
                                "startIndex": 23,
                                "endIndex": 28,
                                "textRun": {
                                    "content": "見出し3\n",
                                    "textStyle": {}
                                }
                            }
                        ],
                        "paragraphStyle": {
                            "headingId": "h.bkjlj5ejudzk",
                            "namedStyleType": "HEADING_3",
                            "direction": "LEFT_TO_RIGHT"
                        }
                    }
                }
            ]
        },
        "documentStyle": {
            "background": {
                "color": {}
            },
            "pageNumberStart": 1,
            "marginTop": {
                "magnitude": 72,
                "unit": "PT"
            },
            "marginBottom": {
                "magnitude": 72,
                "unit": "PT"
            },
            "marginRight": {
                "magnitude": 72,
                "unit": "PT"
            },
            "marginLeft": {
                "magnitude": 72,
                "unit": "PT"
            },
            "pageSize": {
                "height": {
                    "magnitude": 841.8897637795277,
                    "unit": "PT"
                },
                "width": {
                    "magnitude": 595.2755905511812,
                    "unit": "PT"
                }
            }
        },
        "namedStyles": {
            "styles": [
                {
                    "namedStyleType": "NORMAL_TEXT",
                    "textStyle": {
                        "bold": False,
                        "italic": False,
                        "underline": False,
                        "strikethrough": False,
                        "smallCaps": False,
                        "backgroundColor": {},
                        "foregroundColor": {
                            "color": {
                                "rgbColor": {}
                            }
                        },
                        "fontSize": {
                            "magnitude": 11,
                            "unit": "PT"
                        },
                        "weightedFontFamily": {
                            "fontFamily": "Arial",
                            "weight": 400
                        },
                        "baselineOffset": "NONE"
                    },
                    "paragraphStyle": {
                        "namedStyleType": "NORMAL_TEXT",
                        "alignment": "START",
                        "lineSpacing": 115,
                        "direction": "LEFT_TO_RIGHT",
                        "spacingMode": "COLLAPSE_LISTS",
                        "spaceAbove": {
                            "unit": "PT"
                        },
                        "spaceBelow": {
                            "unit": "PT"
                        },
                        "borderBetween": {
                            "color": {},
                            "width": {
                                "unit": "PT"
                            },
                            "padding": {
                                "unit": "PT"
                            },
                            "dashStyle": "SOLID"
                        },
                        "borderTop": {
                            "color": {},
                            "width": {
                                "unit": "PT"
                            },
                            "padding": {
                                "unit": "PT"
                            },
                            "dashStyle": "SOLID"
                        },
                        "borderBottom": {
                            "color": {},
                            "width": {
                                "unit": "PT"
                            },
                            "padding": {
                                "unit": "PT"
                            },
                            "dashStyle": "SOLID"
                        },
                        "borderLeft": {
                            "color": {},
                            "width": {
                                "unit": "PT"
                            },
                            "padding": {
                                "unit": "PT"
                            },
                            "dashStyle": "SOLID"
                        },
                        "borderRight": {
                            "color": {},
                            "width": {
                                "unit": "PT"
                            },
                            "padding": {
                                "unit": "PT"
                            },
                            "dashStyle": "SOLID"
                        },
                        "indentFirstLine": {
                            "unit": "PT"
                        },
                        "indentStart": {
                            "unit": "PT"
                        },
                        "indentEnd": {
                            "unit": "PT"
                        },
                        "keepLinesTogether": False,
                        "keepWithNext": False,
                        "avoidWidowAndOrphan": True,
                        "shading": {
                            "backgroundColor": {}
                        }
                    }
                },
                {
                    "namedStyleType": "HEADING_1",
                    "textStyle": {
                        "fontSize": {
                            "magnitude": 20,
                            "unit": "PT"
                        }
                    },
                    "paragraphStyle": {
                        "namedStyleType": "NORMAL_TEXT",
                        "direction": "LEFT_TO_RIGHT",
                        "spaceAbove": {
                            "magnitude": 20,
                            "unit": "PT"
                        },
                        "spaceBelow": {
                            "magnitude": 6,
                            "unit": "PT"
                        },
                        "keepLinesTogether": True,
                        "keepWithNext": True
                    }
                },
                {
                    "namedStyleType": "HEADING_2",
                    "textStyle": {
                        "bold": False,
                        "fontSize": {
                            "magnitude": 16,
                            "unit": "PT"
                        }
                    },
                    "paragraphStyle": {
                        "namedStyleType": "NORMAL_TEXT",
                        "direction": "LEFT_TO_RIGHT",
                        "spaceAbove": {
                            "magnitude": 18,
                            "unit": "PT"
                        },
                        "spaceBelow": {
                            "magnitude": 6,
                            "unit": "PT"
                        },
                        "keepLinesTogether": True,
                        "keepWithNext": True
                    }
                },
                {
                    "namedStyleType": "HEADING_3",
                    "textStyle": {
                        "bold": False,
                        "foregroundColor": {
                            "color": {
                                "rgbColor": {
                                    "red": 0.2627451,
                                    "green": 0.2627451,
                                    "blue": 0.2627451
                                }
                            }
                        },
                        "fontSize": {
                            "magnitude": 14,
                            "unit": "PT"
                        }
                    },
                    "paragraphStyle": {
                        "namedStyleType": "NORMAL_TEXT",
                        "direction": "LEFT_TO_RIGHT",
                        "spaceAbove": {
                            "magnitude": 16,
                            "unit": "PT"
                        },
                        "spaceBelow": {
                            "magnitude": 4,
                            "unit": "PT"
                        },
                        "keepLinesTogether": True,
                        "keepWithNext": True
                    }
                },
                {
                    "namedStyleType": "HEADING_4",
                    "textStyle": {
                        "foregroundColor": {
                            "color": {
                                "rgbColor": {
                                    "red": 0.4,
                                    "green": 0.4,
                                    "blue": 0.4
                                }
                            }
                        },
                        "fontSize": {
                            "magnitude": 12,
                            "unit": "PT"
                        }
                    },
                    "paragraphStyle": {
                        "namedStyleType": "NORMAL_TEXT",
                        "direction": "LEFT_TO_RIGHT",
                        "spaceAbove": {
                            "magnitude": 14,
                            "unit": "PT"
                        },
                        "spaceBelow": {
                            "magnitude": 4,
                            "unit": "PT"
                        },
                        "keepLinesTogether": True,
                        "keepWithNext": True
                    }
                },
                {
                    "namedStyleType": "HEADING_5",
                    "textStyle": {
                        "foregroundColor": {
                            "color": {
                                "rgbColor": {
                                    "red": 0.4,
                                    "green": 0.4,
                                    "blue": 0.4
                                }
                            }
                        },
                        "fontSize": {
                            "magnitude": 11,
                            "unit": "PT"
                        }
                    },
                    "paragraphStyle": {
                        "namedStyleType": "NORMAL_TEXT",
                        "direction": "LEFT_TO_RIGHT",
                        "spaceAbove": {
                            "magnitude": 12,
                            "unit": "PT"
                        },
                        "spaceBelow": {
                            "magnitude": 4,
                            "unit": "PT"
                        },
                        "keepLinesTogether": True,
                        "keepWithNext": True
                    }
                },
                {
                    "namedStyleType": "HEADING_6",
                    "textStyle": {
                        "italic": True,
                        "foregroundColor": {
                            "color": {
                                "rgbColor": {
                                    "red": 0.4,
                                    "green": 0.4,
                                    "blue": 0.4
                                }
                            }
                        },
                        "fontSize": {
                            "magnitude": 11,
                            "unit": "PT"
                        }
                    },
                    "paragraphStyle": {
                        "namedStyleType": "NORMAL_TEXT",
                        "direction": "LEFT_TO_RIGHT",
                        "spaceAbove": {
                            "magnitude": 12,
                            "unit": "PT"
                        },
                        "spaceBelow": {
                            "magnitude": 4,
                            "unit": "PT"
                        },
                        "keepLinesTogether": True,
                        "keepWithNext": True
                    }
                },
                {
                    "namedStyleType": "TITLE",
                    "textStyle": {
                        "fontSize": {
                            "magnitude": 26,
                            "unit": "PT"
                        }
                    },
                    "paragraphStyle": {
                        "namedStyleType": "NORMAL_TEXT",
                        "direction": "LEFT_TO_RIGHT",
                        "spaceAbove": {
                            "unit": "PT"
                        },
                        "spaceBelow": {
                            "magnitude": 3,
                            "unit": "PT"
                        },
                        "keepLinesTogether": True,
                        "keepWithNext": True
                    }
                },
                {
                    "namedStyleType": "SUBTITLE",
                    "textStyle": {
                        "italic": False,
                        "foregroundColor": {
                            "color": {
                                "rgbColor": {
                                    "red": 0.4,
                                    "green": 0.4,
                                    "blue": 0.4
                                }
                            }
                        },
                        "fontSize": {
                            "magnitude": 15,
                            "unit": "PT"
                        },
                        "weightedFontFamily": {
                            "fontFamily": "Arial",
                            "weight": 400
                        }
                    },
                    "paragraphStyle": {
                        "namedStyleType": "NORMAL_TEXT",
                        "direction": "LEFT_TO_RIGHT",
                        "spaceAbove": {
                            "unit": "PT"
                        },
                        "spaceBelow": {
                            "magnitude": 16,
                            "unit": "PT"
                        },
                        "keepLinesTogether": True,
                        "keepWithNext": True
                    }
                }
            ]
        },
    "revisionId": "AOV_f4-TiMb57reetZjj3ZBaNwuyf0eVOuiRuDL83726nz5RagiKs47V08duz0X5Bn-qVSCg_qYk1KG3vtnfj3Q",
    "suggestionsViewMode": "SUGGESTIONS_INLINE",
    "documentId": "15zjqYL9PAJ40tFYqb3PwzMyl-QmvtR58M_W6NXtZn7E"
    }

長いです。

参考サイト

www.ka-net.org