Handle Discord announcements

Also add some documentation on Slack/Discord web hooks
This commit is contained in:
Filip Gralinski 2021-08-21 10:48:34 +02:00
parent 5f4af21006
commit 9c4a751bf2
5 changed files with 26 additions and 5 deletions

View File

@ -209,6 +209,13 @@ for evaluation (e.g. `expected.tsv` files for the challenge or
given when a challenge is created or a submission is done and the given when a challenge is created or a submission is done and the
Gonito server must have access to such a special remote. Gonito server must have access to such a special remote.
Integration with Slack/Discord
------------------------------
Gonito can send announcements to Slack or Discord via web hooks, e.g.
when new best result is achieved. Simply set the `ANNOUNCEMENT_HOOK`
environment variable to a Slack/Discord webhook.
Authors Authors
------- -------

View File

@ -16,19 +16,24 @@ import Prelude
import Data.Aeson import Data.Aeson
import Data.Default import Data.Default
data AnnouncementHook = SlackWebHook Text data AnnouncementHook = SlackWebHook Text | DiscordWebHook Text
toAnnouncementHook :: Text -> AnnouncementHook toAnnouncementHook :: Text -> AnnouncementHook
toAnnouncementHook url toAnnouncementHook url
| ".slack." `isInfixOf` url = SlackWebHook url | ".slack." `isInfixOf` url = SlackWebHook url
| otherwise = error $ "unknown hook type" | "discord.com" `isInfixOf` url = DiscordWebHook url
| otherwise = error $ unpack $ "unknown hook type '" <> url <> "'"
sendAnnouncement :: AnnouncementHook -> Text -> IO () sendAnnouncement :: AnnouncementHook -> Text -> IO ()
sendAnnouncement (SlackWebHook hook) message = do sendAnnouncement (SlackWebHook hook) message = sendAnnouncementViaJson hook "text" message
sendAnnouncement (DiscordWebHook hook) message = sendAnnouncementViaJson hook "content" message
sendAnnouncementViaJson :: Text -> Text -> Text -> IO ()
sendAnnouncementViaJson hook fieldName message = do
let (Just (hookUrl, _)) = parseUrlHttps $ DTE.encodeUtf8 hook let (Just (hookUrl, _)) = parseUrlHttps $ DTE.encodeUtf8 hook
R.runReq def $ do R.runReq def $ do
let payload = object [ "text" .= message ] let payload = object [ fieldName .= message ]
(_ :: IgnoreResponse) <- R.req R.POST (_ :: IgnoreResponse) <- R.req R.POST
hookUrl hookUrl
(R.ReqBodyJson payload) (R.ReqBodyJson payload)
@ -38,4 +43,8 @@ sendAnnouncement (SlackWebHook hook) message = do
formatLink :: Maybe AnnouncementHook -> Text -> Text -> Text formatLink :: Maybe AnnouncementHook -> Text -> Text -> Text
formatLink (Just (SlackWebHook _)) url title = "<" <> url <> "|" <> title <> ">" formatLink (Just (SlackWebHook _)) url title = "<" <> url <> "|" <> title <> ">"
formatLink Nothing url title = title <> "<" <> url <> ">" formatLink (Just (DiscordWebHook _)) url title = formatLinkWithAngleBrackets url title
formatLink Nothing url title = formatLinkWithAngleBrackets url title
formatLinkWithAngleBrackets :: Text -> Text -> Text
formatLinkWithAngleBrackets url title = title <> " <" <> url <> ">"

View File

@ -16,6 +16,7 @@ services:
- AUTO_OPENING=${GONITO_AUTO_OPENING:-false} - AUTO_OPENING=${GONITO_AUTO_OPENING:-false}
- IS_PUBLIC=${GONITO_IS_PUBLIC:-true} - IS_PUBLIC=${GONITO_IS_PUBLIC:-true}
- JSON_WEB_KEY=${JSON_WEB_KEY} - JSON_WEB_KEY=${JSON_WEB_KEY}
- ANNOUNCEMENT_HOOK=${GONITO_ANNOUNCEMENT_HOOK}
ports: ports:
- 3000:3000 - 3000:3000
volumes: volumes:

View File

@ -29,6 +29,7 @@ services:
- VIEWING_PROGRESS_STYLE=${GONITO_VIEWING_PROGRESS_STYLE:-with-web-sockets} - VIEWING_PROGRESS_STYLE=${GONITO_VIEWING_PROGRESS_STYLE:-with-web-sockets}
- AUTO_TEAM=${GONITO_AUTO_TEAM:-false} - AUTO_TEAM=${GONITO_AUTO_TEAM:-false}
- TEAM_FIELD=$GONITO_TEAM_FIELD - TEAM_FIELD=$GONITO_TEAM_FIELD
- ANNOUNCEMENT_HOOK=${GONITO_ANNOUNCEMENT_HOOK}
expose: expose:
- "3000" - "3000"
volumes: volumes:

View File

@ -26,3 +26,6 @@ GONITO_TEAM_FIELD=given_name
# #
# Note: at the moment, only RS256 is handled. # Note: at the moment, only RS256 is handled.
JSON_WEB_KEY={"kty":"RSA", "alg":"RS256", "use":"sig", "kid":"h01jmt_bD-1Di8i_GYbEV2a4NxhptzySHO-R8VuNHVA", "e":"AQAB", "n": "qG1elE6KPW3BYMxNpgK73MoksvbrUSfpRY4z9hU5iMsJREyD5Ar6XpjM1xAr6G7xglnOoumPC9o6FqhDHihm6QdJ5s5MA9ZyGkbi--kvy9Qc2d_VIGU-UR4vwyk3hAwXOFLhoknpQrJBJmMQvGFdas1Yr-m9EIWwT1zN7neHZkRUYZSVyQw_XghtMIWAUsLnhr6mM7nstHLafgxe5Qamzuc4K5EC_qipFXu4ugYkMDnaknlhkT43m7tcduVDnv5GV_4dBesF7FRII8tgUQWyw3Ty_FIoq43SInUPU_9cxA-qPGQz5C50th2aJl1z1snpLWS_1Zfsa8lnFsMj8_oh6w"} JSON_WEB_KEY={"kty":"RSA", "alg":"RS256", "use":"sig", "kid":"h01jmt_bD-1Di8i_GYbEV2a4NxhptzySHO-R8VuNHVA", "e":"AQAB", "n": "qG1elE6KPW3BYMxNpgK73MoksvbrUSfpRY4z9hU5iMsJREyD5Ar6XpjM1xAr6G7xglnOoumPC9o6FqhDHihm6QdJ5s5MA9ZyGkbi--kvy9Qc2d_VIGU-UR4vwyk3hAwXOFLhoknpQrJBJmMQvGFdas1Yr-m9EIWwT1zN7neHZkRUYZSVyQw_XghtMIWAUsLnhr6mM7nstHLafgxe5Qamzuc4K5EC_qipFXu4ugYkMDnaknlhkT43m7tcduVDnv5GV_4dBesF7FRII8tgUQWyw3Ty_FIoq43SInUPU_9cxA-qPGQz5C50th2aJl1z1snpLWS_1Zfsa8lnFsMj8_oh6w"}
# Announcements can be sent to Slack or Discord via a given web hook
GONITO_ANNOUNCEMENT_HOOK=https://discord.com/api/webhooks/123456789/abcdefghijklmnopqrstuvwxz123456789