         dragging? (r/atom false)
         error (r/atom nil)
         new-bot (r/atom {})
-        state (r/atom :initial)]
+        state (r/atom :initial)
+        bot-valid? (reaction (and
+                               (and (string? (@new-bot :name))
+                                 (re-matches bot-name-re (@new-bot :name)))
+                               (and (string? (@new-bot :webhook-url))
+                                 (re-matches #"\S+" (@new-bot :webhook-url)))
+                               (some? (@new-bot :avatar))))]
     (fn []
       (when @admin?
         [:div.add-bot

(ns braid.ui.views.pages.bots
  (:require [reagent.core :as r]
            [chat.client.reagent-adapter :refer [subscribe]]
            [braid.ui.views.pills :refer [user-pill-view]]
            [chat.client.dispatcher :refer [dispatch!]]
            [braid.ui.views.upload :refer [avatar-upload-view]]))

(defn bot-view
  [bot]

               [:img {:src avatar}])
             [avatar-upload-view {:on-upload (fn [url] (swap! new-bot assoc :avatar url))
                                  :dragging-change (partial reset! dragging?)}]]
            [:input {:type "submit" :value "Add Bot" :disabled (not @bot-valid?)}]]

           :created
           [:div
