(ns ^{:added "0.51.0"} metabase.models.channel (:require [malli.core :as mc] [metabase.models.audit-log :as audit-log] [metabase.models.interface :as mi] [metabase.models.permissions :as perms] [metabase.models.serialization :as serdes] [metabase.util :as u] [metabase.util.malli :as mu] [metabase.util.malli.schema :as ms] [methodical.core :as methodical] [toucan2.core :as t2])) | |
(set! *warn-on-reflection* true) | |
(methodical/defmethod t2/table-name :model/Channel [_model] :channel) (methodical/defmethod t2/table-name :model/ChannelTemplate [_model] :channel_template) | |
(doto :model/Channel (derive :metabase/model) (derive :hook/timestamped?)) | |
(doto :model/ChannelTemplate (derive :metabase/model) (derive :hook/timestamped?)) | |
------------------------------------------------------------------------------------------------;; :model/Channel ;; ------------------------------------------------------------------------------------------------;; | |
(t2/deftransforms :model/Channel {:type (mi/transform-validator mi/transform-keyword (partial mi/assert-namespaced "channel")) :details mi/transform-encrypted-json}) | |
(defmethod mi/can-write? :model/Channel [& _] (or (mi/superuser?) (perms/current-user-has-application-permissions? :setting))) | |
(t2/define-before-update :model/Channel [instance] (let [deactivation? (false? (:active (t2/changes instance)))] (when deactivation? (t2/delete! :model/PulseChannel :channel_id (:id instance))) (cond-> instance deactivation? ;; Channel.name has an unique constraint and it's a useful property for serialization ;; We rename deactivated channels so that new channels can reuse the name ;; Limit to 254 characters to avoid hitting character limit (assoc :name (u/truncate (format "DEACTIVATED_%d %s" (:id instance) (:name instance)) 254))))) | |
(defmethod audit-log/model-details :model/Channel [channel _event-type] (select-keys channel [:id :name :description :type :active])) | |
(defmethod serdes/entity-id "Channel" [_ {:keys [name]}] name) | |
(defmethod serdes/hash-fields :model/Channel [_instance] [:name :type]) | |
(defmethod serdes/make-spec "Channel" [_model-name _opts] {:copy [:name :description :type :details :active] :transform {:created_at (serdes/date)}}) | |
------------------------------------------------------------------------------------------------;; :model/ChannelTemplate ;; ------------------------------------------------------------------------------------------------;; | |
(t2/deftransforms :model/ChannelTemplate {:channel_type (mi/transform-validator mi/transform-keyword (partial mi/assert-namespaced "channel")) :details mi/transform-json}) | |
(def ^:private channel-template-details-type #{:email/handlebars-text :email/handlebars-resource}) | |
(def ^:private ChannelTemplateEmailDetails [:merge [:map [:type (apply ms/enum-keywords-and-strings channel-template-details-type)] [:subject string?] [:recipient-type {:optional true} (ms/enum-keywords-and-strings :cc :bcc)]] [:multi {:dispatch (comp keyword :type)} [:email/handlebars-resource [:map [:path string?]]] [:email/handlebars-text [:map [:body string?]]]]]) | |
Channel Template schema. | (def ChannelTemplate [:merge [:map [:channel_type [:fn #(= "channel" (-> % keyword namespace))]]] [:multi {:dispatch :channel_type} [:channel/email [:map [:details ChannelTemplateEmailDetails]]] [::mc/default :any]]]) |
(defn- check-valid-channel-template [channel-template] (mu/validate-throw ChannelTemplate channel-template)) | |
(t2/define-before-insert :model/ChannelTemplate [instance] (check-valid-channel-template instance) instance) | |
(t2/define-before-update :model/ChannelTemplate [instance] (check-valid-channel-template instance) instance) | |
(defmethod mi/can-write? :model/ChannelTemplate [& _] (or (mi/superuser?) (perms/current-user-has-application-permissions? :setting))) | |