      (.setQueryData uri (make-query query))
      (.toString uri))))
 
-(defn gmail-messages [_]
+(defn gmail-messages [{::keys [gmail-query]}]
   (go
     (-> (fetch (api-uri "gmail/v1/users/me/messages" [[:includeSpamTrash false]
-                                                      [:q "from:noreply@youtube.com is:unread"]]))
+                                                      [:q gmail-query]]))
         <! :messages)))
-
-(defn gmail-thread [{:gmail.thread/keys [id]}]
-  (fetch (api-uri (str "gmail/v1/users/me/threads/" id) [])))
-
-(s/fdef gmail-thread
-  :args (s/cat :request (s/keys :req [:gmail.thread/id])))
 
 (defn gmail-message [{:gmail.message/keys [id]}]
   (fetch (api-uri (str "gmail/v1/users/me/messages/" id) [])))
 
 (s/fdef gmail-message
   :args (s/cat :request (s/keys :req [:gmail.message/id])))
-
-(defn gmail-filters []
-  (go
-    (->> (fetch (api-uri (str "gmail/v1/users/me/settings/filters") []))
-         <! :filter
-         (map (partial map->flatten-ns "gmail.filter")))))
-
-(s/fdef gmail-filters
-  :ret map?)
-
-(defn gmail-labels []
-  (go
-    (->> (fetch (api-uri (str "gmail/v1/users/me/labels") []))
-         <! :labels
-         (map (partial map->flatten-ns "gmail.label")))))
-
-(s/def :gmail.label/api-entity
-  (s/keys :req [:gmail.label/id :gmail.label/name :gmail.label/type]
-          :opt [:gmail.label/label-list-visibility :gmail.label/message-list-visibility]))
-
-(s/fdef gmail-labels
-  :ret (s/coll-of :gmail.label/api-entity))
-
-(defn gmail-create-label [{:gmail.label/keys [name label-list-visibility message-list-visibility]
-                           :or               {label-list-visibility   "labelShow"
-                                              message-list-visibility "show"}}]
-  (go
-    (->> (fetch (api-uri "gmail/v1/users/me/labels")
-                {:method  "post"
-                 :headers {"Content-Type" "application/json"}
-                 :body    (js/JSON.stringify #js {:name                  name
-                                                  :labelListVisibility   label-list-visibility
-                                                  :messageListVisibility message-list-visibility})})
-         <! (map->flatten-ns "gmail.label"))))
-
-(s/fdef gmail-create-label
-  :args (s/cat :label (s/keys :req [:gmail.label/name]
-                              :opt [:gmail.label/label-list-visibility :gmail.label/message-list-visibility]))
-  :ret :gmail.label/api-entity)
 
 (defn extract-youtube-id [msg]
   (if-let [[_ id] (re-find #"youtube\.com/watch\?v=([^&]+)" msg)]

    (swap! video-id->message-id assoc youtube-id id)
    youtube-id))

(s/def :common-specs.internet/email (s/and string? #(re-find #"\w+@\w+\.\w+" %)))

(s/def :common-specs.auth/password (s/and string? (comp #(-> % (>= 8)) count)))
(s/def :common-specs.auth/password-confirmation :common-specs.auth/password)

(s/def :common-specs.auth/password+confirmation
  (s/and (s/keys :req [:common-specs.auth/password :common-specs.auth/password-confirmation])
         (fn [{:common-specs.auth/keys [password password-confirmation]}]
           (= password password-confirmation))))

(s/def ::new-user
  (s/merge (s/keys :req [:common-specs.internet/email])
           :common-specs.auth/password+confirmation))

(defn youtube-queue-ids [options]
  (go
    (->> (gmail-messages options) <!
         (map :id)
         (distinct)
         (map #(assoc options :gmail.message/id %))

(s/def :youtube.video/dislike-count nat-int?)
(s/def :youtube.video/comment-count nat-int?)

(s/def ::gmail-query string?)

(defn map->flatten-ns [ns m]
  (reduce
