{-# LANGUAGE GADTs #-} {-# LANGUAGE QuasiQuotes #-} {-# LANGUAGE RecordWildCards #-} module Lib.Notifications where import Startlude hiding ( get ) import Data.String.Interpolate.IsString import Data.UUID.V4 import Database.Persist import Database.Persist.Sql import Lib.Error import Lib.Types.Core import Lib.Types.Emver import Model emit :: MonadIO m => AppId -> Version -> AgentNotification -> SqlPersistT m (Entity Notification) emit appId version ty = do uuid <- liftIO nextRandom now <- liftIO getCurrentTime let k = NotificationKey uuid let v = Notification now Nothing appId version (toCode ty) (toTitle ty) (toMessage appId version ty) insertKey k v putStrLn $ toMessage appId version ty pure $ Entity k v archive :: MonadIO m => [Key Notification] -> SqlPersistT m [Entity Notification] archive eventIds = do now <- liftIO getCurrentTime events <- for eventIds $ flip updateGet [NotificationArchivedAt =. Just now] pure $ zipWith Entity eventIds events data AgentNotification = InstallSuccess | InstallFailedGetApp | InstallFailedAppMgrExitCode Int | InstallFailedS9Error S9Error | BackupSucceeded | BackupFailed S9Error | RestoreSucceeded | RestoreFailed S9Error | RestartFailed S9Error | DockerFuckening | CertRenewFailed ExitCode String String | OsUpdateSucceeded | OsUpdateFailed Text -- CODES -- RULES: -- The first digit indicates the call to action and the tone of the error code as follows -- 0: General Information, No Action Required, Neutral Tone -- 1: Success Message, No Action Required, Positive Tone -- 2: Warning, Action Possible but NOT Required, Negative Tone -- 3: Error, Action Required, Negative Tone -- -- The second digit indicates where the error was originated from as follows -- 0: Originates from Agent -- 1: Originates from App (Not presently used) -- 2: Originates from Agent ABOUT THE AGENT -- -- The remaining section of the code may be as long as you want but must be at least one digit -- EXAMPLES: -- 100 -- |||> Code "0" -- ||> Originates from Agent -- |> Success Message -- -- 213 -- |||> Code "3" -- ||> Originates from App -- |> Warning Message -- toCode :: AgentNotification -> Text toCode InstallSuccess = "100" toCode BackupSucceeded = "101" toCode RestoreSucceeded = "102" toCode OsUpdateSucceeded = "103" toCode InstallFailedGetApp = "300" toCode (InstallFailedAppMgrExitCode _) = "301" toCode DockerFuckening = "302" toCode (InstallFailedS9Error _) = "303" toCode (BackupFailed _) = "304" toCode (RestoreFailed _) = "305" toCode (RestartFailed _) = "306" toCode CertRenewFailed{} = "320" toTitle :: AgentNotification -> Text toTitle InstallSuccess = "Install succeeded" toTitle BackupSucceeded = "Backup succeeded" toTitle RestoreSucceeded = "Restore succeeded" toTitle OsUpdateSucceeded = "EmbassyOS Update Succeeded" toTitle InstallFailedGetApp = "Install failed" toTitle (InstallFailedAppMgrExitCode _) = "Install failed" toTitle (InstallFailedS9Error _) = "Install failed" toTitle (BackupFailed _) = "Backup failed" toTitle (RestoreFailed _) = "Restore failed" toTitle (RestartFailed _) = "Restart failed" toTitle DockerFuckening = "App unstoppable" toTitle CertRenewFailed{} = "Embassy Certificate Renewal Failed" toMessage :: AppId -> Version -> AgentNotification -> Text toMessage appId version InstallSuccess = [i|Successfully installed #{appId} at version #{version}|] toMessage appId version n@InstallFailedGetApp = [i|Failed to install #{appId} at version #{version}, this should be impossible, contact support and give them the code #{toCode n}|] toMessage appId version n@(InstallFailedAppMgrExitCode ec) = [i|Failed to install #{appId} at version #{version}, many things could cause this, contact support and give them the code #{toCode n}.#{ec}|] toMessage appId version n@(InstallFailedS9Error e) = [i|Failed to install #{appId} at version #{version}, the dependency reverse index could not be updated, contact support and give them the code #{toCode n}.#{errorCode $ toError e}|] toMessage appId _version DockerFuckening = [i|Despite attempting to stop #{appId}, it is still running. This is a known issue that can only be solved by restarting the server|] toMessage appId _version BackupSucceeded = [i|Successfully backed up #{appId}|] toMessage appId _version RestoreSucceeded = [i|Successfully restored #{appId}|] toMessage appId _version (BackupFailed reason) = [i|Failed to back up #{appId}: #{errorMessage $ toError reason}|] toMessage appId _version (RestoreFailed reason) = [i|Failed to restore #{appId}: #{errorMessage $ toError reason}|] toMessage appId _version (RestartFailed reason) = [i|Failed to restart #{appId}: #{errorMessage $ toError reason}. Please manually restart|] toMessage _ version (CertRenewFailed ec o e) = [i|Failed to renew SSL Certificates for EmbassyOS (#{version}) ExitCode: #{ec} Stdout: #{o} Stderr: #{e} |] toMessage _ version OsUpdateSucceeded = [i|The update to EmbassyOS #{version} succeeded.|]