mirror of
https://github.com/casdoor/casdoor.git
synced 2025-05-24 08:20:31 +08:00
feat: add SendGrid Email provider (#2865)
* feat: add support for email provider send grid * feat: rename send grid to sendgrid * feat: rename send grid to sendgrid * feat: change logo url of send grid
This commit is contained in:
parent
19c4416f10
commit
3354945119
@ -23,6 +23,8 @@ func GetEmailProvider(typ string, clientId string, clientSecret string, host str
|
||||
return NewAzureACSEmailProvider(clientSecret, host)
|
||||
} else if typ == "Custom HTTP Email" {
|
||||
return NewHttpEmailProvider(endpoint, method)
|
||||
} else if typ == "SendGrid" {
|
||||
return NewSendgridEmailProvider(clientSecret)
|
||||
} else {
|
||||
return NewSmtpEmailProvider(clientId, clientSecret, host, port, typ, disableSsl)
|
||||
}
|
||||
|
37
email/sendgrid.go
Normal file
37
email/sendgrid.go
Normal file
@ -0,0 +1,37 @@
|
||||
// Copyright 2024 The Casdoor Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package email
|
||||
|
||||
import (
|
||||
"github.com/sendgrid/sendgrid-go"
|
||||
"github.com/sendgrid/sendgrid-go/helpers/mail"
|
||||
)
|
||||
|
||||
type SendgridEmailProvider struct {
|
||||
ApiKey string
|
||||
}
|
||||
|
||||
func NewSendgridEmailProvider(apiKey string) *SendgridEmailProvider {
|
||||
return &SendgridEmailProvider{ApiKey: apiKey}
|
||||
}
|
||||
|
||||
func (s *SendgridEmailProvider) Send(fromAddress string, fromName, toAddress string, subject string, content string) error {
|
||||
from := mail.NewEmail(fromName, fromAddress)
|
||||
to := mail.NewEmail("", toAddress)
|
||||
message := mail.NewSingleEmail(from, subject, to, "", content)
|
||||
client := sendgrid.NewSendClient(s.ApiKey)
|
||||
_, err := client.Send(message)
|
||||
return err
|
||||
}
|
1
go.mod
1
go.mod
@ -45,6 +45,7 @@ require (
|
||||
github.com/robfig/cron/v3 v3.0.1
|
||||
github.com/russellhaering/gosaml2 v0.9.0
|
||||
github.com/russellhaering/goxmldsig v1.2.0
|
||||
github.com/sendgrid/sendgrid-go v3.14.0+incompatible // indirect
|
||||
github.com/shiena/ansicolor v0.0.0-20200904210342-c7312218db18 // indirect
|
||||
github.com/shirou/gopsutil v3.21.11+incompatible
|
||||
github.com/siddontang/go-log v0.0.0-20190221022429-1e957dd83bed
|
||||
|
3
go.sum
3
go.sum
@ -1907,8 +1907,11 @@ github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdh
|
||||
github.com/scim2/filter-parser/v2 v2.2.0 h1:QGadEcsmypxg8gYChRSM2j1edLyE/2j72j+hdmI4BJM=
|
||||
github.com/scim2/filter-parser/v2 v2.2.0/go.mod h1:jWnkDToqX/Y0ugz0P5VvpVEUKcWcyHHj+X+je9ce5JA=
|
||||
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
|
||||
github.com/sendgrid/rest v2.6.9+incompatible h1:1EyIcsNdn9KIisLW50MKwmSRSK+ekueiEMJ7NEoxJo0=
|
||||
github.com/sendgrid/rest v2.6.9+incompatible/go.mod h1:kXX7q3jZtJXK5c5qK83bSGMdV6tsOE70KbHoqJls4lE=
|
||||
github.com/sendgrid/sendgrid-go v3.13.0+incompatible/go.mod h1:QRQt+LX/NmgVEvmdRw0VT/QgUn499+iza2FnDca9fg8=
|
||||
github.com/sendgrid/sendgrid-go v3.14.0+incompatible h1:KDSasSTktAqMJCYClHVE94Fcif2i7P7wzISv1sU6DUA=
|
||||
github.com/sendgrid/sendgrid-go v3.14.0+incompatible/go.mod h1:QRQt+LX/NmgVEvmdRw0VT/QgUn499+iza2FnDca9fg8=
|
||||
github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0=
|
||||
github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=
|
||||
github.com/shiena/ansicolor v0.0.0-20151119151921-a422bbe96644/go.mod h1:nkxAfR/5quYxwPZhyDxgasBMnRtBZd0FCEpawpjMUFg=
|
||||
|
@ -244,7 +244,7 @@ class ProviderEditPage extends React.Component {
|
||||
return Setting.getLabel(i18next.t("provider:Client secret"), i18next.t("provider:Client secret - Tooltip"));
|
||||
}
|
||||
case "Email":
|
||||
if (provider.type === "Azure ACS") {
|
||||
if (provider.type === "Azure ACS" || provider.type === "SendGrid") {
|
||||
return Setting.getLabel(i18next.t("provider:Secret key"), i18next.t("provider:Secret key - Tooltip"));
|
||||
} else {
|
||||
return Setting.getLabel(i18next.t("general:Password"), i18next.t("general:Password - Tooltip"));
|
||||
@ -729,7 +729,7 @@ class ProviderEditPage extends React.Component {
|
||||
<React.Fragment>
|
||||
{
|
||||
(this.state.provider.category === "Storage" && this.state.provider.type === "Google Cloud Storage") ||
|
||||
(this.state.provider.category === "Email" && this.state.provider.type === "Azure ACS") ||
|
||||
(this.state.provider.category === "Email" && (this.state.provider.type === "Azure ACS" || this.state.provider.type === "SendGrid")) ||
|
||||
(this.state.provider.category === "Notification" && (this.state.provider.type === "Line" || this.state.provider.type === "Telegram" || this.state.provider.type === "Bark" || this.state.provider.type === "Discord" || this.state.provider.type === "Slack" || this.state.provider.type === "Pushbullet" || this.state.provider.type === "Pushover" || this.state.provider.type === "Lark" || this.state.provider.type === "Microsoft Teams")) ? null : (
|
||||
<Row style={{marginTop: "20px"}} >
|
||||
<Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 22 : 2}>
|
||||
@ -770,7 +770,7 @@ class ProviderEditPage extends React.Component {
|
||||
</Col>
|
||||
</Row>
|
||||
{
|
||||
(this.state.provider.type === "WeChat Pay") || (this.state.provider.category === "Email" && this.state.provider.type === "Azure ACS") ? null : (
|
||||
(this.state.provider.type === "WeChat Pay") || (this.state.provider.category === "Email" && (this.state.provider.type === "Azure ACS" || this.state.provider.type === "SendGrid")) ? null : (
|
||||
<Row style={{marginTop: "20px"}} >
|
||||
<Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 22 : 2}>
|
||||
{this.getClientSecret2Label(this.state.provider)} :
|
||||
@ -985,17 +985,19 @@ class ProviderEditPage extends React.Component {
|
||||
</React.Fragment>
|
||||
) : this.state.provider.category === "Email" ? (
|
||||
<React.Fragment>
|
||||
<Row style={{marginTop: "20px"}} >
|
||||
<Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 22 : 2}>
|
||||
{Setting.getLabel(i18next.t("provider:Host"), i18next.t("provider:Host - Tooltip"))} :
|
||||
</Col>
|
||||
<Col span={22} >
|
||||
<Input prefix={<LinkOutlined />} value={this.state.provider.host} onChange={e => {
|
||||
this.updateProviderField("host", e.target.value);
|
||||
}} />
|
||||
</Col>
|
||||
</Row>
|
||||
{["Azure ACS"].includes(this.state.provider.type) ? null : (
|
||||
{["SendGrid"].includes(this.state.provider.type) ? null : (
|
||||
<Row style={{marginTop: "20px"}} >
|
||||
<Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 22 : 2}>
|
||||
{Setting.getLabel(i18next.t("provider:Host"), i18next.t("provider:Host - Tooltip"))} :
|
||||
</Col>
|
||||
<Col span={22} >
|
||||
<Input prefix={<LinkOutlined />} value={this.state.provider.host} onChange={e => {
|
||||
this.updateProviderField("host", e.target.value);
|
||||
}} />
|
||||
</Col>
|
||||
</Row>
|
||||
)}
|
||||
{["Azure ACS", "SendGrid"].includes(this.state.provider.type) ? null : (
|
||||
<Row style={{marginTop: "20px"}} >
|
||||
<Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 22 : 2}>
|
||||
{Setting.getLabel(i18next.t("provider:Port"), i18next.t("provider:Port - Tooltip"))} :
|
||||
@ -1007,7 +1009,7 @@ class ProviderEditPage extends React.Component {
|
||||
</Col>
|
||||
</Row>
|
||||
)}
|
||||
{["Azure ACS"].includes(this.state.provider.type) ? null : (
|
||||
{["Azure ACS", "SendGrid"].includes(this.state.provider.type) ? null : (
|
||||
<Row style={{marginTop: "20px"}} >
|
||||
<Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 22 : 2}>
|
||||
{Setting.getLabel(i18next.t("provider:Disable SSL"), i18next.t("provider:Disable SSL - Tooltip"))} :
|
||||
@ -1073,7 +1075,7 @@ class ProviderEditPage extends React.Component {
|
||||
this.updateProviderField("receiver", e.target.value);
|
||||
}} />
|
||||
</Col>
|
||||
{["Azure ACS"].includes(this.state.provider.type) ? null : (
|
||||
{["Azure ACS", "SendGrid"].includes(this.state.provider.type) ? null : (
|
||||
<Button style={{marginLeft: "10px", marginBottom: "5px"}} onClick={() => ProviderEditTestEmail.connectSmtpServer(this.state.provider)} >
|
||||
{i18next.t("provider:Test SMTP Connection")}
|
||||
</Button>
|
||||
|
@ -181,6 +181,10 @@ export const OtherProviderInfo = {
|
||||
logo: `${StaticBaseUrl}/img/social_azure.png`,
|
||||
url: "https://learn.microsoft.com/zh-cn/azure/communication-services",
|
||||
},
|
||||
"SendGrid": {
|
||||
logo: `${StaticBaseUrl}/img/email_sendgrid.png`,
|
||||
url: "https://sendgrid.com/",
|
||||
},
|
||||
"Custom HTTP Email": {
|
||||
logo: `${StaticBaseUrl}/img/social_default.png`,
|
||||
url: "https://casdoor.org/docs/provider/email/overview",
|
||||
@ -1015,6 +1019,7 @@ export function getProviderTypeOptions(category) {
|
||||
{id: "SUBMAIL", name: "SUBMAIL"},
|
||||
{id: "Mailtrap", name: "Mailtrap"},
|
||||
{id: "Azure ACS", name: "Azure ACS"},
|
||||
{id: "SendGrid", name: "SendGrid"},
|
||||
{id: "Custom HTTP Email", name: "Custom HTTP Email"},
|
||||
]
|
||||
);
|
||||
|
Loading…
x
Reference in New Issue
Block a user