Skip to content

Commit

Permalink
Merge 642bb15 into 8e16fb5
Browse files Browse the repository at this point in the history
  • Loading branch information
alilestera authored Jul 26, 2023
2 parents 8e16fb5 + 642bb15 commit 0a411a7
Show file tree
Hide file tree
Showing 11 changed files with 468 additions and 1 deletion.
9 changes: 9 additions & 0 deletions cmd/layotto/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ import (

"mosn.io/layotto/components/cryption"

"mosn.io/layotto/components/email"

"mosn.io/layotto/pkg/grpc/lifecycle"

"mosn.io/layotto/components/oss"
Expand All @@ -43,6 +45,8 @@ import (
aws_cryption "mosn.io/layotto/components/cryption/aws"
aliyun_file "mosn.io/layotto/components/file/aliyun"

aliyun_email "mosn.io/layotto/components/email/aliyun"

"github.com/dapr/components-contrib/secretstores"
"github.com/dapr/components-contrib/secretstores/aws/parameterstore"
"github.com/dapr/components-contrib/secretstores/aws/secretmanager"
Expand Down Expand Up @@ -311,6 +315,11 @@ func NewRuntimeGrpcServer(data json.RawMessage, opts ...grpc.ServerOption) (mgrp
cryption.NewFactory("aliyun.kms", aliyun_cryption.NewCryption),
cryption.NewFactory("aws.kms", aws_cryption.NewCryption),
),

// Email
runtime.WithEmailServiceFactory(
email.NewFactory("aliyun.email", aliyun_email.NewAliyunEmail),
),
// PubSub
runtime.WithPubSubFactory(
pubsub.NewFactory("redis", func() dapr_comp_pubsub.PubSub {
Expand Down
146 changes: 146 additions & 0 deletions components/email/aliyun/email.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
/*
* Copyright 2021 Layotto Authors
*
* 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 aliyun

import (
"context"
"strings"

openapi "github.com/alibabacloud-go/darabonba-openapi/v2/client"
dm20151123 "github.com/alibabacloud-go/dm-20151123/v2/client"
"github.com/alibabacloud-go/tea/tea"

"mosn.io/layotto/components/email"
)

type AliyunEmail struct {
client *dm20151123.Client
}

func NewAliyunEmail() email.EmailService {
return &AliyunEmail{}

Check warning on line 35 in components/email/aliyun/email.go

View check run for this annotation

Codecov / codecov/patch

components/email/aliyun/email.go#L34-L35

Added lines #L34 - L35 were not covered by tests
}

var _ email.EmailService = (*AliyunEmail)(nil)

func (a *AliyunEmail) Init(ctx context.Context, conf *email.Config) error {
accessKeyID := conf.Metadata[email.ClientKey]
accessKeySecret := conf.Metadata[email.ClientSecret]
endpoint := conf.Metadata[email.Endpoint]
config := &openapi.Config{
// accessKey ID
AccessKeyId: tea.String(accessKeyID),
// accessKey Secret
AccessKeySecret: tea.String(accessKeySecret),
// endpoint, ref https://api.aliyun.com/product/Dm
Endpoint: tea.String(endpoint),
}

client, err := dm20151123.NewClient(config)
if err != nil {
return err

Check warning on line 55 in components/email/aliyun/email.go

View check run for this annotation

Codecov / codecov/patch

components/email/aliyun/email.go#L55

Added line #L55 was not covered by tests
}
a.client = client
return nil
}

// SendEmail .
func (a *AliyunEmail) SendEmail(ctx context.Context, req *email.SendEmailRequest) (*email.SendEmailResponse, error) {
if !a.checkSendRequest(req) {
return nil, email.ErrInvalid

Check warning on line 64 in components/email/aliyun/email.go

View check run for this annotation

Codecov / codecov/patch

components/email/aliyun/email.go#L64

Added line #L64 was not covered by tests
}

// AccountName is the email send from
accountName := req.Address.From
// ToAddress is target addresses the email send to
toAddress := strings.Join(req.Address.To, ",")

sendMailRequest := &dm20151123.SingleSendMailRequest{}
sendMailRequest.
SetAccountName(accountName).
// AddressType = 1: use the email send from
// ref https://help.aliyun.com/document_detail/29444.html
SetAddressType(1).
// ReplyToAddress = false: the email no need to reply
// ref https://help.aliyun.com/document_detail/29444.html
SetReplyToAddress(false).
SetSubject(req.Subject).
SetToAddress(toAddress).
SetTextBody(req.Content.Text)

resp, err := a.client.SingleSendMail(sendMailRequest)
if err != nil {
return nil, err
}
return &email.SendEmailResponse{
RequestId: *resp.Body.RequestId,
}, nil

Check warning on line 91 in components/email/aliyun/email.go

View check run for this annotation

Codecov / codecov/patch

components/email/aliyun/email.go#L89-L91

Added lines #L89 - L91 were not covered by tests
}

func (a *AliyunEmail) checkSendRequest(r *email.SendEmailRequest) bool {
// make sure content not empty
if r.Content == nil || r.Content.Text == "" {
return false

Check warning on line 97 in components/email/aliyun/email.go

View check run for this annotation

Codecov / codecov/patch

components/email/aliyun/email.go#L97

Added line #L97 was not covered by tests
}
if info := r.Address; info == nil || info.From == "" || len(info.To) == 0 {
return false

Check warning on line 100 in components/email/aliyun/email.go

View check run for this annotation

Codecov / codecov/patch

components/email/aliyun/email.go#L100

Added line #L100 was not covered by tests
}
return true
}

// SendEmailWithTemplate .
// template must have been applied in aliyun console, and there need the template name
// receivers must have been filled in aliyun console, and there need the receivers list name
func (a *AliyunEmail) SendEmailWithTemplate(ctx context.Context, req *email.SendEmailWithTemplateRequest) (*email.SendEmailWithTemplateResponse, error) {
if !a.checkSendWithTemplateRequest(req) {
return nil, email.ErrInvalid

Check warning on line 110 in components/email/aliyun/email.go

View check run for this annotation

Codecov / codecov/patch

components/email/aliyun/email.go#L110

Added line #L110 was not covered by tests
}

// AccountName is the email send from
accountName := req.Address.From
// ReceiversName is the name of the recipient list that is created in advance and uploaded with recipients.
// Only take the element with index zero
receiversName := req.Address.To[0]

sendMailWithTemplateRequest := &dm20151123.BatchSendMailRequest{}
sendMailWithTemplateRequest.
SetAccountName(accountName).
// AddressType = 1: use the email send from
// ref https://help.aliyun.com/document_detail/29444.html
SetAddressType(1).
SetReceiversName(receiversName).
SetTemplateName(req.Template.TemplateId)

resp, err := a.client.BatchSendMail(sendMailWithTemplateRequest)
if err != nil {
return nil, err
}
return &email.SendEmailWithTemplateResponse{
RequestId: *resp.Body.RequestId,
}, nil

Check warning on line 134 in components/email/aliyun/email.go

View check run for this annotation

Codecov / codecov/patch

components/email/aliyun/email.go#L132-L134

Added lines #L132 - L134 were not covered by tests
}

func (a *AliyunEmail) checkSendWithTemplateRequest(r *email.SendEmailWithTemplateRequest) bool {
// make sure template exist
if r.Template == nil || r.Template.TemplateId == "" {
return false

Check warning on line 140 in components/email/aliyun/email.go

View check run for this annotation

Codecov / codecov/patch

components/email/aliyun/email.go#L140

Added line #L140 was not covered by tests
}
if info := r.Address; info == nil || info.From == "" || len(info.To) == 0 {
return false

Check warning on line 143 in components/email/aliyun/email.go

View check run for this annotation

Codecov / codecov/patch

components/email/aliyun/email.go#L143

Added line #L143 was not covered by tests
}
return true
}
88 changes: 88 additions & 0 deletions components/email/aliyun/email_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
/*
* Copyright 2021 Layotto Authors
*
* 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 aliyun

import (
"context"
"testing"

"github.com/stretchr/testify/assert"

"mosn.io/layotto/components/email"
)

func TestInit(t *testing.T) {
a := &AliyunEmail{}
conf := &email.Config{
Metadata: map[string]string{
email.ClientKey: "aki",
email.ClientSecret: "aks",
email.Endpoint: "endpoint",
},
}
err := a.Init(context.TODO(), conf)
assert.Nil(t, err)
}

func TestSendEmail(t *testing.T) {
a := &AliyunEmail{}
conf := &email.Config{
Metadata: map[string]string{
email.ClientKey: "aki",
email.ClientSecret: "aks",
email.Endpoint: "endpoint",
},
}
err := a.Init(context.TODO(), conf)
assert.Nil(t, err)

request := &email.SendEmailRequest{
Subject: "a_subject",
Address: &email.EmailAddress{
From: "email_send_from",
To: []string{"email_send_to"},
},
Content: &email.Content{Text: "some words"},
}
_, err = a.SendEmail(context.TODO(), request)
assert.Error(t, err)
}

func TestSendEmailWithTemplate(t *testing.T) {
a := &AliyunEmail{}
conf := &email.Config{
Metadata: map[string]string{
email.ClientKey: "aki",
email.ClientSecret: "aks",
email.Endpoint: "endpoint",
},
}
err := a.Init(context.TODO(), conf)
assert.NoError(t, err)

request := &email.SendEmailWithTemplateRequest{
Template: &email.EmailTemplate{
TemplateId: "a_template",
},
Address: &email.EmailAddress{
From: "email_send_from",
To: []string{"receivers_name"},
},
}
_, err = a.SendEmailWithTemplate(context.TODO(), request)
assert.Error(t, err)
}
23 changes: 23 additions & 0 deletions components/email/errors.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/*
* Copyright 2021 Layotto Authors
*
* 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 "errors"

var (
ErrInvalid = errors.New("invalid argument")
)
23 changes: 23 additions & 0 deletions components/email/meta.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/*
* Copyright 2021 Layotto Authors
*
* 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

const (
ClientKey = "accessKeyID"
ClientSecret = "accessKeySecret"
Endpoint = "endpoint"
)
1 change: 1 addition & 0 deletions components/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ go 1.18
require (
github.com/DATA-DOG/go-sqlmock v1.5.0
github.com/alibabacloud-go/darabonba-openapi/v2 v2.0.4
github.com/alibabacloud-go/dm-20151123/v2 v2.0.1
github.com/alibabacloud-go/kms-20160120/v3 v3.0.2
github.com/alibabacloud-go/tea v1.1.19
github.com/alicebob/miniredis/v2 v2.16.0
Expand Down
3 changes: 3 additions & 0 deletions components/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -141,11 +141,14 @@ github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk5
github.com/alibaba/sentinel-golang v1.0.3/go.mod h1:Lag5rIYyJiPOylK8Kku2P+a23gdKMMqzQS7wTnjWEpk=
github.com/alibabacloud-go/alibabacloud-gateway-spi v0.0.4 h1:iC9YFYKDGEy3n/FtqJnOkZsene9olVspKmkX5A2YBEo=
github.com/alibabacloud-go/alibabacloud-gateway-spi v0.0.4/go.mod h1:sCavSAvdzOjul4cEqeVtvlSaSScfNsTQ+46HwlTL1hc=
github.com/alibabacloud-go/darabonba-openapi/v2 v2.0.0/go.mod h1:5JHVmnHvGzR2wNdgaW1zDLQG8kOC4Uec8ubkMogW7OQ=
github.com/alibabacloud-go/darabonba-openapi/v2 v2.0.2/go.mod h1:5JHVmnHvGzR2wNdgaW1zDLQG8kOC4Uec8ubkMogW7OQ=
github.com/alibabacloud-go/darabonba-openapi/v2 v2.0.4 h1:7Q2FEyqxeZeIkwYMwRC3uphxV4i7O2eV4ETe21d6lS4=
github.com/alibabacloud-go/darabonba-openapi/v2 v2.0.4/go.mod h1:5JHVmnHvGzR2wNdgaW1zDLQG8kOC4Uec8ubkMogW7OQ=
github.com/alibabacloud-go/debug v0.0.0-20190504072949-9472017b5c68 h1:NqugFkGxx1TXSh/pBcU00Y6bljgDPaFdh5MUSeJ7e50=
github.com/alibabacloud-go/debug v0.0.0-20190504072949-9472017b5c68/go.mod h1:6pb/Qy8c+lqua8cFpEy7g39NRRqOWc3rOwAy8m5Y2BY=
github.com/alibabacloud-go/dm-20151123/v2 v2.0.1 h1:wEIEI4vvk7vtiJmXEUnom+ylEBfy107WQjaPNyQc7E4=
github.com/alibabacloud-go/dm-20151123/v2 v2.0.1/go.mod h1:q9cd++SgWfT9U5kdBbRRlvzrr0HOKayLxfe9s0NVZhQ=
github.com/alibabacloud-go/endpoint-util v1.1.0 h1:r/4D3VSw888XGaeNpP994zDUaxdgTSHBbVfZlzf6b5Q=
github.com/alibabacloud-go/endpoint-util v1.1.0/go.mod h1:O5FuCALmCKs2Ff7JFJMudHs0I5EBgecXXxZRyswlEjE=
github.com/alibabacloud-go/kms-20160120/v3 v3.0.2 h1:kxtotOKKdQuO2UlOrOsevBioZfdfV4MYGu1jJ0Rctlk=
Expand Down
Loading

0 comments on commit 0a411a7

Please sign in to comment.