-
-
Save coldnew/f4a44390c04c6595f9ed0df5057b6ae1 to your computer and use it in GitHub Desktop.
Clojure example of accessing google APIs directly
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(ns example.api.google | |
(:require [cemerick.url :as url] | |
[cheshire.core :as json] | |
[clj-jwt.core :as jwt] | |
[clj-jwt.key :as key] | |
[clj-time.core :as time] | |
[clj-http.client :as http] | |
[clojure.string :as str]) | |
(:import java.io.StringReader)) | |
;;; Example code for calling Google apis using a service account. | |
(defn load-creds | |
"Takes a path to a service account .json credentials file" | |
[secrets-json-path] | |
(-> secrets-json-path slurp (json/parse-string keyword))) | |
;; list of API scopes requested, e.g. https://developers.google.com/admin-sdk/directory/v1/guides/authorizing | |
(def scopes ["https://www.googleapis.com/auth/admin.directory.user" | |
"https://www.googleapis.com/auth/admin.directory.group"]) | |
(defn create-claim [creds & [{:keys [sub] :as opts}]] | |
(let [claim (merge {:iss (:client_email creds) | |
:scope (str/join " " scopes) | |
:aud "https://www.googleapis.com/oauth2/v4/token" | |
:exp (-> 1 time/hours time/from-now) | |
:iat (time/now)} | |
(when sub | |
;; when using the Admin API, delegating access, :sub may be needed | |
{:sub sub}))] | |
(-> claim jwt/jwt (jwt/sign :RS256 (-> creds :private_key (#(StringReader. %)) (#(key/pem->private-key % nil)))) (jwt/to-str)))) | |
(defn request-token [creds & [{:keys [sub] :as opts}]] | |
(let [claim (create-claim creds opts) | |
resp (http/post "https://www.googleapis.com/oauth2/v4/token" {:form-params {:grant_type "urn:ietf:params:oauth:grant-type:jwt-bearer" | |
:assertion claim} | |
:as :json})] | |
(when (= 200 (-> resp :status)) | |
(-> resp :body :access_token)))) | |
;; Call request-token to make an API call to google to create a new access token, using creds. Access-tokens are valid for 1 hour after creating. Pass the received token to API calls. | |
(defn api-req [{:keys [] :as request} token] | |
(http/request (-> request | |
(assoc-in [:headers "Authorization"] (str "Bearer " token)) | |
(assoc :as :json)))) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment