/api/alert endpoints. Deprecated: will soon be migrated to notification APIs. | (ns ^:deprecated metabase.pulse.api.alert
#_{:clj-kondo/ignore [:metabase/modules]}
(:require
[clojure.set :as set]
[metabase.api.common :as api]
[metabase.api.macros :as api.macros]
[metabase.api.notification :as api.notification]
[metabase.config :as config]
[metabase.plugins.classloader :as classloader]
[metabase.util.cron :as u.cron]
[metabase.util.malli.schema :as ms]
[toucan2.core :as t2])) |
(set! *warn-on-reflection* true) | |
(when config/ee-available? (classloader/require 'metabase-enterprise.advanced-permissions.common)) | |
Convert a notification to the legacy pulse structure for backward compatibility. | (defn- notification->pulse
[notification]
(let [subscription (-> notification :subscriptions first)
notification-card (-> notification :payload)
card (->> notification :payload :card_id (t2/select-one :model/Card))]
(merge
(select-keys notification [:id :creator_id :creator :created_at :updated_at])
{:name nil
:alert_condition (if (-> notification-card :send_condition (= :has_result)) "rows" "goal")
:alert_above_goal (if (-> notification-card :send_condition (= :goal_above)) true nil)
:alert_first_only (-> notification :payload :send_once)
:archived (not (:active notification))
:collection_position nil
:collection_id nil
:skip_if_empty true
:parameters []
:dashboard_id nil
:card (merge
(select-keys card [:name :description :collection_id :display])
{:format_rows true
:include_xls false
:include_csv true
:pivot_results false
:dashboard_id nil
:dashboard_card_id nil
:parameter_mappings nil})
:channels (map (fn [handler]
(let [user-recipients (->> handler
:recipients
(filter #(= :notification-recipient/user (:type %)))
(map :user)
(map #(select-keys % [:email :last_name :first_name :id :common_name])))
;; for external emails and slack channel
value-recipients (->> handler
:recipients
(filter #(= :notification-recipient/raw-value (:type %)))
(map :details))]
(merge
(when subscription
(select-keys (u.cron/cron-string->schedule-map (:cron_schedule subscription))
[:schedule_type :schedule_hour :schedule_day :schedule_frame]))
{:id (:id handler)
:recipients (if (= :channel/email (:channel_type handler))
(concat (map #(set/rename-keys % {:value :email}) value-recipients) user-recipients)
[])
:channel_type (name (:channel_type handler))
:channel_id (:channel_id handler)
:enabled (:active handler)
:details (case (:channel_type handler)
:channel/slack
{:channel (-> value-recipients first :value)}
:channel/email
{:emails (map :value value-recipients)}
{})})))
(:handlers notification))}))) |
(api.macros/defendpoint :get "/"
"Fetch alerts which the current user has created or will receive, or all alerts if the user is an admin.
The optional `user_id` will return alerts created by the corresponding user, but is ignored for non-admin users."
[_route-params
{:keys [archived user_id]} :- [:map
[:archived {:default false} [:maybe ms/BooleanValue]]
[:user_id {:optional true} [:maybe ms/PositiveInt]]]]
(let [user-id (if api/*is-superuser?*
user_id
api/*current-user-id*)]
(->> (api.notification/list-notifications
{:payload_type :notification/card
:legacy-user-id user-id
:legacy-active (not archived)})
(map notification->pulse)
(remove nil?)))) | |
(api.macros/defendpoint :get "/:id"
"Fetch an alert by ID"
[{:keys [id]} :- [:map
[:id ms/PositiveInt]]]
(-> (api.notification/get-notification id)
api/read-check
notification->pulse)) | |
(api.macros/defendpoint :delete "/:id/subscription"
"For users to unsubscribe themselves from the given alert."
[{:keys [id]} :- [:map
[:id ms/PositiveInt]]]
(api.notification/unsubscribe-user! id api/*current-user-id*)
api/generic-204-no-content) | |