github.com/kubevela/workflow@v0.6.0/pkg/providers/email/send.go (about) 1 /* 2 Copyright 2022 The KubeVela Authors. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package email 18 19 import ( 20 "fmt" 21 "sync" 22 23 "gopkg.in/gomail.v2" 24 25 monitorContext "github.com/kubevela/pkg/monitor/context" 26 27 wfContext "github.com/kubevela/workflow/pkg/context" 28 "github.com/kubevela/workflow/pkg/cue/model/value" 29 "github.com/kubevela/workflow/pkg/types" 30 ) 31 32 const ( 33 // ProviderName is provider name for install. 34 ProviderName = "email" 35 ) 36 37 type provider struct { 38 } 39 40 type sender struct { 41 Address string `json:"address"` 42 Alias string `json:"alias,omitempty"` 43 Password string `json:"password"` 44 Host string `json:"host"` 45 Port int `json:"port"` 46 } 47 48 type content struct { 49 Subject string `json:"subject"` 50 Body string `json:"body"` 51 } 52 53 var emailRoutine sync.Map 54 55 // Send sends email 56 func (h *provider) Send(ctx monitorContext.Context, wfCtx wfContext.Context, v *value.Value, act types.Action) error { 57 stepID, err := v.LookupValue("stepID") 58 if err != nil { 59 return err 60 } 61 id, err := stepID.String() 62 if err != nil { 63 return err 64 } 65 routine, ok := emailRoutine.Load(id) 66 if ok { 67 switch routine { 68 case "success": 69 emailRoutine.Delete(id) 70 return nil 71 case "initializing", "sending": 72 act.Wait("wait for the email") 73 return nil 74 default: 75 emailRoutine.Delete(id) 76 return fmt.Errorf("failed to send email: %v", routine) 77 } 78 } else { 79 emailRoutine.Store(id, "initializing") 80 } 81 82 s, err := v.LookupValue("from") 83 if err != nil { 84 return err 85 } 86 87 senderValue := &sender{} 88 if err := s.UnmarshalTo(senderValue); err != nil { 89 return err 90 } 91 92 r, err := v.LookupValue("to") 93 if err != nil { 94 return err 95 } 96 receiverValue := &[]string{} 97 if err := r.UnmarshalTo(receiverValue); err != nil { 98 return err 99 } 100 101 c, err := v.LookupValue("content") 102 if err != nil { 103 return err 104 } 105 contentValue := &content{} 106 if err := c.UnmarshalTo(contentValue); err != nil { 107 return err 108 } 109 110 m := gomail.NewMessage() 111 m.SetAddressHeader("From", senderValue.Address, senderValue.Alias) 112 m.SetHeader("To", *receiverValue...) 113 m.SetHeader("Subject", contentValue.Subject) 114 m.SetBody("text/html", contentValue.Body) 115 116 dial := gomail.NewDialer(senderValue.Host, senderValue.Port, senderValue.Address, senderValue.Password) 117 go func() { 118 if routine, ok := emailRoutine.Load(id); ok && routine == "initializing" { 119 emailRoutine.Store(id, "sending") 120 if err := dial.DialAndSend(m); err != nil { 121 emailRoutine.Store(id, err.Error()) 122 return 123 } 124 emailRoutine.Store(id, "success") 125 } 126 }() 127 act.Wait("wait for the email") 128 return nil 129 } 130 131 // Install register handlers to provider discover. 132 func Install(p types.Providers) { 133 prd := &provider{} 134 p.Register(ProviderName, map[string]types.Handler{ 135 "send": prd.Send, 136 }) 137 }