Google Docs API client for OCaml
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

OCaml 97.0%
Dune 0.9%
Other 2.1%
17 1 0

Clone this repository

https://tangled.org/gazagnaire.org/ocaml-gdocs https://tangled.org/did:plc:jhift2vwcxhou52p3sewcrpx/ocaml-gdocs
git@git.recoil.org:gazagnaire.org/ocaml-gdocs git@git.recoil.org:did:plc:jhift2vwcxhou52p3sewcrpx/ocaml-gdocs

For self-hosted knots, clone URLs may differ based on your setup.

Download tar.gz
README.md

gdocs#

Google Docs API client for OCaml.

gdocs implements a small, opinionated slice of the Google Docs REST API: fetching documents by ID and extracting their content as plain text or Markdown. Authentication is delegated to gauth; reading requires the .../auth/documents.readonly OAuth scope.

Installation#

Install with opam:

$ opam install gdocs

If opam cannot find the package, it may not yet be released in the public opam-repository. Add the overlay repository, then install it:

$ opam repo add samoht https://tangled.org/gazagnaire.org/opam-overlay.git
$ opam update
$ opam install gdocs

Usage#

The main entry points are Gdocs.get, Document.title, Document.to_text, and Markdown.of_document:

let fetch_markdown http ~token ~document_id =
  match Gdocs.get http ~token document_id with
  | Error (`Msg m) -> Error m
  | Ok doc ->
      let body = Gdocs.Markdown.of_document doc in
      Ok (Gdocs.Document.title doc, body)

Wire that up with gauth and Eio for a full flow:

let run env ~key_path ~document_id =
  Eio.Switch.run @@ fun sw ->
  let http = Requests.v ~sw env in
  let clock = Eio.Stdenv.clock env in
  match Gauth.Service_account.of_file key_path with
  | Error (`Msg m) -> failwith m
  | Ok key ->
      match
        Gauth.Service_account.token http ~clock
          ~scopes:[ Gdocs.scope_readonly ] key
      with
      | Error (`Msg m) -> failwith m
      | Ok token ->
          match Gdocs.get http ~token document_id with
          | Ok doc ->
              Fmt.pr "# %s@.@.%s@."
                (Gdocs.Document.title doc)
                (Gdocs.Markdown.of_document doc)
          | Error (`Msg m) -> Fmt.pr "fetch failed: %s@." m

Plain text#

Document.to_text concatenates every textRun in paragraph order; the API already emits trailing newlines, so the result is paragraph-terminated:

let title_and_text doc =
  Gdocs.Document.title doc, Gdocs.Document.to_text doc

Scopes#

let readonly = Gdocs.scope_readonly
let readwrite = Gdocs.scope_readwrite

HTTP errors surface with the response status in the Msg payload: 401 for an invalid or expired token, 403 for missing scopes or no access, 404 for an unknown document id.

Licence#

MIT