(ns metabase.notification.payload.impl.card (:require [metabase.channel.render.core :as channel.render] [metabase.events :as events] [metabase.notification.payload.core :as notification.payload] [metabase.notification.payload.execute :as notification.execute] [metabase.notification.send :as notification.send] [metabase.util.malli :as mu] [metabase.util.ui-logic :as ui-logic] [toucan2.core :as t2])) | |
(mu/defmethod notification.payload/payload :notification/card [{:keys [creator_id payload subscriptions] :as _notification-info} :- ::notification.payload/Notification] (let [card_id (:card_id payload)] {:card_part (notification.execute/execute-card creator_id card_id ;; for query_execution's context purposes ;; TODO: check whether we can remove this or rename it? :pulse-id (:id payload)) :card (t2/select-one :model/Card card_id) :style {:color_text_dark channel.render/color-text-dark :color_text_light channel.render/color-text-light :color_text_medium channel.render/color-text-medium} :notification_card payload :subscriptions subscriptions})) | |
(defn- goal-met? [{:keys [send_condition], :as notification_card} card_part] (let [goal-comparison (if (= :goal_above (keyword send_condition)) >= <) goal-val (ui-logic/find-goal-value card_part) comparison-col-rowfn (ui-logic/make-goal-comparison-rowfn (:card card_part) (get-in card_part [:result :data]))] (when-not (and goal-val comparison-col-rowfn) (throw (ex-info "Unable to compare results to goal for notificationt_card" {:notification_card notification_card :result card_part}))) (boolean (some (fn [row] (goal-comparison (comparison-col-rowfn row) goal-val)) (get-in card_part [:result :data :rows]))))) | |
(mu/defmethod notification.payload/should-send-notification? :notification/card [{:keys [payload]}] (let [{:keys [notification_card card_part]} payload send-condition (:send_condition notification_card)] (cond (= :has_result send-condition) (not (notification.execute/is-card-empty? card_part)) (#{:goal_above :goal_below} send-condition) (goal-met? notification_card card_part) :else (let [^String error-text (format "Unrecognized alert with condition '%s'" send-condition)] (throw (IllegalArgumentException. error-text)))))) | |
(defmethod notification.send/do-after-notification-sent :notification/card [{:keys [id creator_id handlers] :as notification-info} _notification-payload] (when (-> notification-info :payload :send_once) (t2/update! :model/Notification (:id notification-info) {:active false})) (events/publish-event! :event/alert-send {:id id :user-id creator_id :object {:recipients (->> handlers (mapcat :recipients) (map #(or (:user %) (:email %)))) :filters (-> notification-info :alert :parameters)}})) | |