Mail

API: Internal/Beta

Internal service for sending e-mails.

Rationale

Currently only one end-point is exposed for sending a single email to one user at a time, and only SERVICE principals is authorized to do so.

Email templates are pre-defined and are not controllable by clients.

Table of Contents

1. Examples
Description
Sending an email
Forwarding a support ticket to Jira
Changing e-mail settings
2. Remote Procedure Calls
Name Description
retrieveEmailSettings Changes an end-user's e-mail preferences
sendSupport Forwards a support ticket into Jira
sendToUser Sends an email to an end-user based on a pre-defined template
toggleEmailSettings Retrieves an end-user's e-mail preferences
3. Data Models
Name Description
EmailSettings No description
EmailSettingsItem No description
Mail No description
Mail.GrantAppAutoApproveToAdminsMail No description
Mail.GrantApplicationApproveMail No description
Mail.GrantApplicationApproveMailToAdmins No description
Mail.GrantApplicationRejectedMail No description
Mail.GrantApplicationStatusChangedToAdmin No description
Mail.GrantApplicationUpdatedMail No description
Mail.GrantApplicationUpdatedMailToAdmins No description
Mail.GrantApplicationWithdrawnMail No description
Mail.LowFundsMail No description
Mail.NewCommentOnApplicationMail No description
Mail.NewGrantApplicationMail No description
Mail.ProjectInviteMail No description
Mail.ResetPasswordMail No description
Mail.StillLowFundsMail No description
Mail.TransferApplicationMail No description
Mail.UserLeftMail No description
Mail.UserRemovedMail No description
Mail.UserRemovedMailToUser No description
Mail.UserRoleChangeMail No description
Mail.VerificationReminderMail No description
RetrieveEmailSettingsRequest No description
SendRequestItem No description
SendSupportEmailRequest No description
RetrieveEmailSettingsResponse No description

Example: Sending an email

Frequency of useCommon
Actors
  • The UCloud/Core service user (ucloud)
Communication Flow: Kotlin
MailDescriptions.sendToUser.call(
    bulkRequestOf(SendRequestItem(
        mail = Mail.LowFundsMail(
            categories = listOf("u1-standard"), 
            projectTitles = listOf("Science Project"), 
            providers = listOf("ucloud"), 
            subject = "Wallets low on resource", 
        ), 
        mandatory = false, 
        receiver = "User#1234", 
        receivingEmail = null, 
        testMail = null, 
    )),
    ucloud
).orThrow()

/*
Unit
*/
Communication Flow: TypeScript
// Authenticated as ucloud
await callAPI(MailApi.sendToUser(
    {
        "items": [
            {
                "receiver": "User#1234",
                "mail": {
                    "type": "lowFunds",
                    "categories": [
                        "u1-standard"
                    ],
                    "providers": [
                        "ucloud"
                    ],
                    "projectTitles": [
                        "Science Project"
                    ],
                    "subject": "Wallets low on resource"
                },
                "mandatory": false,
                "receivingEmail": null,
                "testMail": null
            }
        ]
    }
);

/*
{
}
*/
Communication Flow: Curl
# ------------------------------------------------------------------------------------------------------
# $host is the UCloud instance to contact. Example: 'http://localhost:8080' or 'https://cloud.sdu.dk'
# $accessToken is a valid access-token issued by UCloud
# ------------------------------------------------------------------------------------------------------

# Authenticated as ucloud
curl -XPOST -H "Authorization: Bearer $accessToken" -H "Content-Type: content-type: application/json; charset=utf-8" "$host/api/mail/sendToUser" -d '{
    "items": [
        {
            "receiver": "User#1234",
            "mail": {
                "type": "lowFunds",
                "categories": [
                    "u1-standard"
                ],
                "providers": [
                    "ucloud"
                ],
                "projectTitles": [
                    "Science Project"
                ],
                "subject": "Wallets low on resource"
            },
            "mandatory": false,
            "receivingEmail": null,
            "testMail": null
        }
    ]
}'


# {
# }
Communication Flow: Visual

Example: Forwarding a support ticket to Jira

Frequency of useCommon
Actors
  • The UCloud/Core service user (ucloud)
Communication Flow: Kotlin
MailDescriptions.sendSupport.call(
    SendSupportEmailRequest(
        fromEmail = "foo@bar", 
        message = "Message", 
        subject = "Subject", 
    ),
    ucloud
).orThrow()

/*
Unit
*/
Communication Flow: TypeScript
// Authenticated as ucloud
await callAPI(MailApi.sendSupport(
    {
        "fromEmail": "foo@bar",
        "subject": "Subject",
        "message": "Message"
    }
);

/*
{
}
*/
Communication Flow: Curl
# ------------------------------------------------------------------------------------------------------
# $host is the UCloud instance to contact. Example: 'http://localhost:8080' or 'https://cloud.sdu.dk'
# $accessToken is a valid access-token issued by UCloud
# ------------------------------------------------------------------------------------------------------

# Authenticated as ucloud
curl -XPOST -H "Authorization: Bearer $accessToken" -H "Content-Type: content-type: application/json; charset=utf-8" "$host/api/mail/support" -d '{
    "fromEmail": "foo@bar",
    "subject": "Subject",
    "message": "Message"
}'


# {
# }
Communication Flow: Visual

Example: Changing e-mail settings

Frequency of useCommon
Actors
  • An authenticated user (user)
Communication Flow: Kotlin
MailDescriptions.retrieveEmailSettings.call(
    RetrieveEmailSettingsRequest(
        username = null, 
    ),
    user
).orThrow()

/*
RetrieveEmailSettingsResponse(
    settings = EmailSettings(
        applicationStatusChange = true, 
        applicationTransfer = true, 
        grantApplicationApproved = true, 
        grantApplicationRejected = true, 
        grantApplicationUpdated = true, 
        grantApplicationWithdrawn = true, 
        grantAutoApprove = true, 
        lowFunds = true, 
        newCommentOnApplication = true, 
        newGrantApplication = true, 
        projectUserInvite = true, 
        projectUserRemoved = true, 
        userLeft = true, 
        userRoleChange = true, 
        verificationReminder = true, 
    ), 
)
*/
MailDescriptions.toggleEmailSettings.call(
    bulkRequestOf(EmailSettingsItem(
        settings = EmailSettings(
            applicationStatusChange = true, 
            applicationTransfer = true, 
            grantApplicationApproved = true, 
            grantApplicationRejected = true, 
            grantApplicationUpdated = true, 
            grantApplicationWithdrawn = true, 
            grantAutoApprove = true, 
            lowFunds = true, 
            newCommentOnApplication = true, 
            newGrantApplication = true, 
            projectUserInvite = true, 
            projectUserRemoved = true, 
            userLeft = true, 
            userRoleChange = true, 
            verificationReminder = false, 
        ), 
        username = null, 
    )),
    user
).orThrow()

/*
Unit
*/
MailDescriptions.retrieveEmailSettings.call(
    RetrieveEmailSettingsRequest(
        username = null, 
    ),
    user
).orThrow()

/*
RetrieveEmailSettingsResponse(
    settings = EmailSettings(
        applicationStatusChange = true, 
        applicationTransfer = true, 
        grantApplicationApproved = true, 
        grantApplicationRejected = true, 
        grantApplicationUpdated = true, 
        grantApplicationWithdrawn = true, 
        grantAutoApprove = true, 
        lowFunds = true, 
        newCommentOnApplication = true, 
        newGrantApplication = true, 
        projectUserInvite = true, 
        projectUserRemoved = true, 
        userLeft = true, 
        userRoleChange = true, 
        verificationReminder = false, 
    ), 
)
*/
Communication Flow: TypeScript
// Authenticated as user
await callAPI(MailApi.retrieveEmailSettings(
    {
        "username": null
    }
);

/*
{
    "settings": {
        "newGrantApplication": true,
        "grantAutoApprove": true,
        "grantApplicationUpdated": true,
        "grantApplicationApproved": true,
        "grantApplicationRejected": true,
        "grantApplicationWithdrawn": true,
        "newCommentOnApplication": true,
        "applicationTransfer": true,
        "applicationStatusChange": true,
        "projectUserInvite": true,
        "projectUserRemoved": true,
        "verificationReminder": true,
        "userRoleChange": true,
        "userLeft": true,
        "lowFunds": true
    }
}
*/
await callAPI(MailApi.toggleEmailSettings(
    {
        "items": [
            {
                "username": null,
                "settings": {
                    "newGrantApplication": true,
                    "grantAutoApprove": true,
                    "grantApplicationUpdated": true,
                    "grantApplicationApproved": true,
                    "grantApplicationRejected": true,
                    "grantApplicationWithdrawn": true,
                    "newCommentOnApplication": true,
                    "applicationTransfer": true,
                    "applicationStatusChange": true,
                    "projectUserInvite": true,
                    "projectUserRemoved": true,
                    "verificationReminder": false,
                    "userRoleChange": true,
                    "userLeft": true,
                    "lowFunds": true
                }
            }
        ]
    }
);

/*
{
}
*/
await callAPI(MailApi.retrieveEmailSettings(
    {
        "username": null
    }
);

/*
{
    "settings": {
        "newGrantApplication": true,
        "grantAutoApprove": true,
        "grantApplicationUpdated": true,
        "grantApplicationApproved": true,
        "grantApplicationRejected": true,
        "grantApplicationWithdrawn": true,
        "newCommentOnApplication": true,
        "applicationTransfer": true,
        "applicationStatusChange": true,
        "projectUserInvite": true,
        "projectUserRemoved": true,
        "verificationReminder": false,
        "userRoleChange": true,
        "userLeft": true,
        "lowFunds": true
    }
}
*/
Communication Flow: Curl
# ------------------------------------------------------------------------------------------------------
# $host is the UCloud instance to contact. Example: 'http://localhost:8080' or 'https://cloud.sdu.dk'
# $accessToken is a valid access-token issued by UCloud
# ------------------------------------------------------------------------------------------------------

# Authenticated as user
curl -XGET -H "Authorization: Bearer $accessToken" "$host/api/mail/retrieveEmailSettings?" 

# {
#     "settings": {
#         "newGrantApplication": true,
#         "grantAutoApprove": true,
#         "grantApplicationUpdated": true,
#         "grantApplicationApproved": true,
#         "grantApplicationRejected": true,
#         "grantApplicationWithdrawn": true,
#         "newCommentOnApplication": true,
#         "applicationTransfer": true,
#         "applicationStatusChange": true,
#         "projectUserInvite": true,
#         "projectUserRemoved": true,
#         "verificationReminder": true,
#         "userRoleChange": true,
#         "userLeft": true,
#         "lowFunds": true
#     }
# }

curl -XPOST -H "Authorization: Bearer $accessToken" -H "Content-Type: content-type: application/json; charset=utf-8" "$host/api/mail/toggleEmailSettings" -d '{
    "items": [
        {
            "username": null,
            "settings": {
                "newGrantApplication": true,
                "grantAutoApprove": true,
                "grantApplicationUpdated": true,
                "grantApplicationApproved": true,
                "grantApplicationRejected": true,
                "grantApplicationWithdrawn": true,
                "newCommentOnApplication": true,
                "applicationTransfer": true,
                "applicationStatusChange": true,
                "projectUserInvite": true,
                "projectUserRemoved": true,
                "verificationReminder": false,
                "userRoleChange": true,
                "userLeft": true,
                "lowFunds": true
            }
        }
    ]
}'


# {
# }

curl -XGET -H "Authorization: Bearer $accessToken" "$host/api/mail/retrieveEmailSettings?" 

# {
#     "settings": {
#         "newGrantApplication": true,
#         "grantAutoApprove": true,
#         "grantApplicationUpdated": true,
#         "grantApplicationApproved": true,
#         "grantApplicationRejected": true,
#         "grantApplicationWithdrawn": true,
#         "newCommentOnApplication": true,
#         "applicationTransfer": true,
#         "applicationStatusChange": true,
#         "projectUserInvite": true,
#         "projectUserRemoved": true,
#         "verificationReminder": false,
#         "userRoleChange": true,
#         "userLeft": true,
#         "lowFunds": true
#     }
# }
Communication Flow: Visual

Remote Procedure Calls

retrieveEmailSettings

API: Internal/Beta Auth: Users

Changes an end-user’s e-mail preferences

Request Response Error
RetrieveEmailSettingsRequest RetrieveEmailSettingsResponse CommonErrorMessage

sendSupport

API: Internal/Beta Auth: Services

Forwards a support ticket into Jira

Request Response Error
SendSupportEmailRequest Unit CommonErrorMessage

NOTE: This endpoint is meant only for use by SDU and might not work well with other deployments.

sendToUser

API: Internal/Beta Auth: Services

Sends an email to an end-user based on a pre-defined template

Request Response Error
BulkRequest<SendRequestItem> Unit CommonErrorMessage

toggleEmailSettings

API: Internal/Beta Auth: Users

Retrieves an end-user’s e-mail preferences

Request Response Error
BulkRequest<EmailSettingsItem> Unit CommonErrorMessage

Data Models

EmailSettings

API: Internal/Beta

data class EmailSettings(
    val newGrantApplication: Boolean?,
    val grantAutoApprove: Boolean?,
    val grantApplicationUpdated: Boolean?,
    val grantApplicationApproved: Boolean?,
    val grantApplicationRejected: Boolean?,
    val grantApplicationWithdrawn: Boolean?,
    val newCommentOnApplication: Boolean?,
    val applicationTransfer: Boolean?,
    val applicationStatusChange: Boolean?,
    val projectUserInvite: Boolean?,
    val projectUserRemoved: Boolean?,
    val verificationReminder: Boolean?,
    val userRoleChange: Boolean?,
    val userLeft: Boolean?,
    val lowFunds: Boolean?,
)
Properties
newGrantApplication: Boolean?
grantAutoApprove: Boolean?
grantApplicationUpdated: Boolean?
grantApplicationApproved: Boolean?
grantApplicationRejected: Boolean?
grantApplicationWithdrawn: Boolean?
newCommentOnApplication: Boolean?
applicationTransfer: Boolean?
applicationStatusChange: Boolean?
projectUserInvite: Boolean?
projectUserRemoved: Boolean?
verificationReminder: Boolean?
userRoleChange: Boolean?
userLeft: Boolean?
lowFunds: Boolean?

EmailSettingsItem

API: Internal/Beta

data class EmailSettingsItem(
    val username: String?,
    val settings: EmailSettings,
)
Properties
username: String?
settings: EmailSettings

Mail

API: Internal/Beta

sealed class Mail {
    abstract val subject: String

    class GrantAppAutoApproveToAdminsMail : Mail()
    class GrantApplicationApproveMail : Mail()
    class GrantApplicationApproveMailToAdmins : Mail()
    class GrantApplicationRejectedMail : Mail()
    class GrantApplicationStatusChangedToAdmin : Mail()
    class GrantApplicationUpdatedMail : Mail()
    class GrantApplicationUpdatedMailToAdmins : Mail()
    class GrantApplicationWithdrawnMail : Mail()
    class LowFundsMail : Mail()
    class NewCommentOnApplicationMail : Mail()
    class NewGrantApplicationMail : Mail()
    class ProjectInviteMail : Mail()
    class ResetPasswordMail : Mail()
    class StillLowFundsMail : Mail()
    class TransferApplicationMail : Mail()
    class UserLeftMail : Mail()
    class UserRemovedMail : Mail()
    class UserRemovedMailToUser : Mail()
    class UserRoleChangeMail : Mail()
    class VerificationReminderMail : Mail()
}
Properties
subject: String

Mail.GrantAppAutoApproveToAdminsMail

API: Internal/Beta

data class GrantAppAutoApproveToAdminsMail(
    val sender: String,
    val projectTitle: String,
    val subject: String?,
    val type: String /* "autoApproveGrant" */,
)
Properties
sender: String
projectTitle: String
subject: String?
type: String /* "autoApproveGrant" */ The type discriminator

API: Stable


Mail.GrantApplicationApproveMail

API: Internal/Beta

data class GrantApplicationApproveMail(
    val projectTitle: String,
    val subject: String?,
    val type: String /* "applicationApproved" */,
)
Properties
projectTitle: String
subject: String?
type: String /* "applicationApproved" */ The type discriminator

API: Stable


Mail.GrantApplicationApproveMailToAdmins

API: Internal/Beta

data class GrantApplicationApproveMailToAdmins(
    val sender: String,
    val projectTitle: String,
    val subject: String?,
    val type: String /* "applicationApprovedToAdmins" */,
)
Properties
sender: String
projectTitle: String
subject: String?
type: String /* "applicationApprovedToAdmins" */ The type discriminator

API: Stable


Mail.GrantApplicationRejectedMail

API: Internal/Beta

data class GrantApplicationRejectedMail(
    val projectTitle: String,
    val subject: String?,
    val type: String /* "applicationRejected" */,
)
Properties
projectTitle: String
subject: String?
type: String /* "applicationRejected" */ The type discriminator

API: Stable


Mail.GrantApplicationStatusChangedToAdmin

API: Internal/Beta

data class GrantApplicationStatusChangedToAdmin(
    val status: String,
    val projectTitle: String,
    val sender: String,
    val receivingProjectTitle: String,
    val subject: String?,
    val type: String /* "applicationStatusChangedToAdmins" */,
)
Properties
status: String
projectTitle: String
sender: String
receivingProjectTitle: String
subject: String?
type: String /* "applicationStatusChangedToAdmins" */ The type discriminator

API: Stable


Mail.GrantApplicationUpdatedMail

API: Internal/Beta

data class GrantApplicationUpdatedMail(
    val projectTitle: String,
    val sender: String,
    val subject: String?,
    val type: String /* "applicationUpdated" */,
)
Properties
projectTitle: String
sender: String
subject: String?
type: String /* "applicationUpdated" */ The type discriminator

API: Stable


Mail.GrantApplicationUpdatedMailToAdmins

API: Internal/Beta

data class GrantApplicationUpdatedMailToAdmins(
    val projectTitle: String,
    val sender: String,
    val receivingProjectTitle: String,
    val subject: String?,
    val type: String /* "applicationUpdatedToAdmins" */,
)
Properties
projectTitle: String
sender: String
receivingProjectTitle: String
subject: String?
type: String /* "applicationUpdatedToAdmins" */ The type discriminator

API: Stable


Mail.GrantApplicationWithdrawnMail

API: Internal/Beta

data class GrantApplicationWithdrawnMail(
    val projectTitle: String,
    val sender: String,
    val subject: String?,
    val type: String /* "applicationWithdrawn" */,
)
Properties
projectTitle: String
sender: String
subject: String?
type: String /* "applicationWithdrawn" */ The type discriminator

API: Stable


Mail.LowFundsMail

API: Internal/Beta

data class LowFundsMail(
    val categories: List<String>,
    val providers: List<String>,
    val projectTitles: List<String>,
    val subject: String?,
    val type: String /* "lowFunds" */,
)
Properties
categories: List<String>
providers: List<String>
projectTitles: List<String>
subject: String?
type: String /* "lowFunds" */ The type discriminator

API: Stable


Mail.NewCommentOnApplicationMail

API: Internal/Beta

data class NewCommentOnApplicationMail(
    val sender: String,
    val projectTitle: String,
    val receivingProjectTitle: String,
    val subject: String?,
    val type: String /* "newComment" */,
)
Properties
sender: String
projectTitle: String
receivingProjectTitle: String
subject: String?
type: String /* "newComment" */ The type discriminator

API: Stable


Mail.NewGrantApplicationMail

API: Internal/Beta

data class NewGrantApplicationMail(
    val sender: String,
    val projectTitle: String,
    val subject: String?,
    val type: String /* "newGrantApplication" */,
)
Properties
sender: String
projectTitle: String
subject: String?
type: String /* "newGrantApplication" */ The type discriminator

API: Stable


Mail.ProjectInviteMail

API: Internal/Beta

data class ProjectInviteMail(
    val projectTitle: String,
    val subject: String?,
    val type: String /* "invitedToProject" */,
)
Properties
projectTitle: String
subject: String?
type: String /* "invitedToProject" */ The type discriminator

API: Stable


Mail.ResetPasswordMail

API: Internal/Beta

data class ResetPasswordMail(
    val token: String,
    val subject: String?,
    val type: String /* "resetPassword" */,
)
Properties
token: String
subject: String?
type: String /* "resetPassword" */ The type discriminator

API: Stable


Mail.StillLowFundsMail

API: Internal/Beta

data class StillLowFundsMail(
    val category: String,
    val provider: String,
    val projectTitle: String,
    val subject: String?,
    val type: String /* "stillLowFunds" */,
)
Properties
category: String
provider: String
projectTitle: String
subject: String?
type: String /* "stillLowFunds" */ The type discriminator

API: Stable


Mail.TransferApplicationMail

API: Internal/Beta

data class TransferApplicationMail(
    val senderProject: String,
    val receiverProject: String,
    val applicationProjectTitle: String,
    val subject: String?,
    val type: String /* "transferApplication" */,
)
Properties
senderProject: String
receiverProject: String
applicationProjectTitle: String
subject: String?
type: String /* "transferApplication" */ The type discriminator

API: Stable


Mail.UserLeftMail

API: Internal/Beta

data class UserLeftMail(
    val leavingUser: String,
    val projectTitle: String,
    val subject: String?,
    val type: String /* "userLeft" */,
)
Properties
leavingUser: String
projectTitle: String
subject: String?
type: String /* "userLeft" */ The type discriminator

API: Stable


Mail.UserRemovedMail

API: Internal/Beta

data class UserRemovedMail(
    val leavingUser: String,
    val projectTitle: String,
    val subject: String?,
    val type: String /* "userRemoved" */,
)
Properties
leavingUser: String
projectTitle: String
subject: String?
type: String /* "userRemoved" */ The type discriminator

API: Stable


Mail.UserRemovedMailToUser

API: Internal/Beta

data class UserRemovedMailToUser(
    val projectTitle: String,
    val subject: String?,
    val type: String /* "userRemovedToUser" */,
)
Properties
projectTitle: String
subject: String?
type: String /* "userRemovedToUser" */ The type discriminator

API: Stable


Mail.UserRoleChangeMail

API: Internal/Beta

data class UserRoleChangeMail(
    val subjectToChange: String,
    val roleChange: String,
    val projectTitle: String,
    val subject: String?,
    val type: String /* "userRoleChange" */,
)
Properties
subjectToChange: String
roleChange: String
projectTitle: String
subject: String?
type: String /* "userRoleChange" */ The type discriminator

API: Stable


Mail.VerificationReminderMail

API: Internal/Beta

data class VerificationReminderMail(
    val projectTitle: String,
    val role: String,
    val subject: String?,
    val type: String /* "verificationReminder" */,
)
Properties
projectTitle: String
role: String
subject: String?
type: String /* "verificationReminder" */ The type discriminator

API: Stable


RetrieveEmailSettingsRequest

API: Internal/Beta

data class RetrieveEmailSettingsRequest(
    val username: String?,
)
Properties
username: String?

SendRequestItem

API: Internal/Beta

data class SendRequestItem(
    val receiver: String,
    val mail: Mail,
    val mandatory: Boolean?,
    val receivingEmail: String?,
    val testMail: Boolean?,
)
Properties
receiver: String
mail: Mail
mandatory: Boolean?
receivingEmail: String?
testMail: Boolean?

SendSupportEmailRequest

API: Internal/Beta

data class SendSupportEmailRequest(
    val fromEmail: String,
    val subject: String,
    val message: String,
)
Properties
fromEmail: String
subject: String
message: String

RetrieveEmailSettingsResponse

API: Internal/Beta

data class RetrieveEmailSettingsResponse(
    val settings: EmailSettings,
)
Properties
settings: EmailSettings