     (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) <!
+    (->> (gmail-messages {::gmail-query "from:noreply@youtube.com is:unread"}) <!
          (map :id)
          (distinct)
          (map #(assoc options :gmail.message/id %))

     (.setQueryData uri (make-query query))
     (.toString uri))))

(defn gmail-messages [_]
  (go
    (-> (fetch (api-uri "gmail/v1/users/me/messages" [[:includeSpamTrash false]
                                                      [:q "from:noreply@youtube.com is:unread"]]))
        <! :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)]

(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
