From 78a1e5c7d83542bea260fb3cc5c401c81f98f1d1 Mon Sep 17 00:00:00 2001 From: Ludovico Russo Date: Sat, 20 Apr 2024 12:25:07 +0200 Subject: [PATCH] feat: add attachments to kannon (#211) --- .proto/kannon/mailer/apiv1/mailerapiv1.proto | 7 + ...40420090612_add-attachments-to-message.sql | 6 + db/schema.sql | 8 +- internal/db/attachment.go | 45 +++ internal/db/attachment_test.go | 52 ++++ internal/db/models.go | 1 + internal/db/pool.sql | 7 +- internal/db/pool.sql.go | 12 +- internal/mailbuilder/attachments.go | 5 + internal/mailbuilder/mailbuilder.go | 18 +- internal/mailbuilder/mailbuilder_test.go | 53 ++++ internal/pool/pool.go | 5 +- pkg/api/mailapi/mailer.go | 8 +- proto/kannon/mailer/apiv1/mailerapiv1.pb.go | 289 ++++++++++++------ sqlc.yaml | 3 + 15 files changed, 408 insertions(+), 111 deletions(-) create mode 100644 db/migrations/20240420090612_add-attachments-to-message.sql create mode 100644 internal/db/attachment.go create mode 100644 internal/db/attachment_test.go create mode 100644 internal/mailbuilder/attachments.go diff --git a/.proto/kannon/mailer/apiv1/mailerapiv1.proto b/.proto/kannon/mailer/apiv1/mailerapiv1.proto index 89916e3..38a0134 100644 --- a/.proto/kannon/mailer/apiv1/mailerapiv1.proto +++ b/.proto/kannon/mailer/apiv1/mailerapiv1.proto @@ -11,12 +11,18 @@ service Mailer { rpc SendTemplate(SendTemplateReq) returns (SendRes) {} } +message Attachment { + string filename = 1; + bytes content = 2; +} + message SendHTMLReq { pkg.kannon.mailer.types.Sender sender = 1; string subject = 3; string html = 4; optional google.protobuf.Timestamp scheduled_time = 5; repeated pkg.kannon.mailer.types.Recipient recipients = 6; + repeated Attachment attachments = 7; } message SendTemplateReq { @@ -25,6 +31,7 @@ message SendTemplateReq { string template_id = 4; optional google.protobuf.Timestamp scheduled_time = 5; repeated pkg.kannon.mailer.types.Recipient recipients = 6; + repeated Attachment attachments = 7; } message SendRes { diff --git a/db/migrations/20240420090612_add-attachments-to-message.sql b/db/migrations/20240420090612_add-attachments-to-message.sql new file mode 100644 index 0000000..2987f92 --- /dev/null +++ b/db/migrations/20240420090612_add-attachments-to-message.sql @@ -0,0 +1,6 @@ +-- migrate:up +ALTER TABLE messages ADD COLUMN attachments JSONB; + +-- migrate:down + +ALTER TABLE messages DROP COLUMN attachments; \ No newline at end of file diff --git a/db/schema.sql b/db/schema.sql index 8000e12..8693be6 100644 --- a/db/schema.sql +++ b/db/schema.sql @@ -67,7 +67,8 @@ CREATE TABLE public.messages ( sender_email character varying(320) NOT NULL, sender_alias character varying(100) NOT NULL, template_id character varying(50) NOT NULL, - domain character varying(254) NOT NULL + domain character varying(254) NOT NULL, + attachments jsonb ); @@ -76,7 +77,7 @@ CREATE TABLE public.messages ( -- CREATE TABLE public.schema_migrations ( - version character varying(255) NOT NULL + version character varying(128) NOT NULL ); @@ -323,4 +324,5 @@ INSERT INTO public.schema_migrations (version) VALUES ('20220806075424'), ('20220809092503'), ('20220830073617'), - ('20220904111715'); + ('20220904111715'), + ('20240420090612'); diff --git a/internal/db/attachment.go b/internal/db/attachment.go new file mode 100644 index 0000000..d33633c --- /dev/null +++ b/internal/db/attachment.go @@ -0,0 +1,45 @@ +package sqlc + +import ( + "database/sql/driver" + "encoding/json" + "fmt" +) + +var ErrInvalidAttachment = fmt.Errorf("invalid attachment") + +type Attachments map[string][]byte + +// implement Vauler interface +func (a Attachments) Value() (driver.Value, error) { + return json.Marshal(a) +} + +// implement Scanner interface +func (a *Attachments) Scan(src interface{}) (err error) { + defer func() { + if err != nil { + err = fmt.Errorf("%w: %w", ErrInvalidAttachment, err) + } + }() + + if src == nil { + *a = nil + return nil + } + + var byteSrc []byte + + switch s := src.(type) { + case []byte: + byteSrc = s + case string: + byteSrc = []byte(s) + default: + return fmt.Errorf("unsupported scan type for TemplateType: %T", src) + } + + err = json.Unmarshal(byteSrc, a) + + return +} diff --git a/internal/db/attachment_test.go b/internal/db/attachment_test.go new file mode 100644 index 0000000..9934437 --- /dev/null +++ b/internal/db/attachment_test.go @@ -0,0 +1,52 @@ +package sqlc_test + +import ( + "reflect" + "testing" + + sqlc "github.com/ludusrusso/kannon/internal/db" +) + +func TestReadWriteAttachment(t *testing.T) { + var testData = []struct { + name string + data sqlc.Attachments + }{ + { + name: "empty attachment", + data: sqlc.Attachments{}, + }, + { + name: "single file attachment", + data: sqlc.Attachments{ + "file1.txt": []byte("this is a file"), + }, + }, + { + name: "nil attachment", + data: nil, + }, + } + + for _, tt := range testData { + t.Run(tt.name, func(t *testing.T) { + // Marshal the attachment + value, err := tt.data.Value() + if err != nil { + t.Fatalf("error marshaling attachment: %v", err) + } + + // Unmarshal the attachment + var att sqlc.Attachments + err = att.Scan(value) + if err != nil { + t.Fatalf("error unmarshaling attachment: %v", err) + } + + // Check if the attachments are the same + if !reflect.DeepEqual(tt.data, att) { + t.Fatalf("attachments are not equal: %v != %v", tt.data, att) + } + }) + } +} diff --git a/internal/db/models.go b/internal/db/models.go index c05c1df..fb2b13f 100644 --- a/internal/db/models.go +++ b/internal/db/models.go @@ -68,6 +68,7 @@ type Message struct { SenderAlias string TemplateID string Domain string + Attachments Attachments } type SendingPoolEmail struct { diff --git a/internal/db/pool.sql b/internal/db/pool.sql index b581c6a..17c8cd0 100644 --- a/internal/db/pool.sql +++ b/internal/db/pool.sql @@ -45,8 +45,8 @@ SELECT * FROM sending_pool_emails WHERE message_id = $1 LIMIT $2 OFFSET $3; -- name: CreateMessage :one INSERT INTO messages - (message_id, subject, sender_email, sender_alias, template_id, domain) VALUES - ($1, $2, $3, $4, $5, $6) RETURNING *; + (message_id, subject, sender_email, sender_alias, template_id, domain, attachments) VALUES + ($1, $2, $3, $4, $5, $6, $7) RETURNING *; -- name: CreatePool :exec INSERT INTO sending_pool_emails (email, status, scheduled_time, original_scheduled_time, message_id, fields, domain) VALUES @@ -61,7 +61,8 @@ SELECT m.subject, m.message_id, m.sender_email, - m.sender_alias + m.sender_alias, + m.attachments FROM messages as m JOIN templates as t ON t.template_id = m.template_id JOIN domains as d ON d.domain = m.domain diff --git a/internal/db/pool.sql.go b/internal/db/pool.sql.go index ac8cf62..f842e9f 100644 --- a/internal/db/pool.sql.go +++ b/internal/db/pool.sql.go @@ -27,8 +27,8 @@ func (q *Queries) CleanPool(ctx context.Context, arg CleanPoolParams) error { const createMessage = `-- name: CreateMessage :one INSERT INTO messages - (message_id, subject, sender_email, sender_alias, template_id, domain) VALUES - ($1, $2, $3, $4, $5, $6) RETURNING message_id, subject, sender_email, sender_alias, template_id, domain + (message_id, subject, sender_email, sender_alias, template_id, domain, attachments) VALUES + ($1, $2, $3, $4, $5, $6, $7) RETURNING message_id, subject, sender_email, sender_alias, template_id, domain, attachments ` type CreateMessageParams struct { @@ -38,6 +38,7 @@ type CreateMessageParams struct { SenderAlias string TemplateID string Domain string + Attachments Attachments } func (q *Queries) CreateMessage(ctx context.Context, arg CreateMessageParams) (Message, error) { @@ -48,6 +49,7 @@ func (q *Queries) CreateMessage(ctx context.Context, arg CreateMessageParams) (M arg.SenderAlias, arg.TemplateID, arg.Domain, + arg.Attachments, ) var i Message err := row.Scan( @@ -57,6 +59,7 @@ func (q *Queries) CreateMessage(ctx context.Context, arg CreateMessageParams) (M &i.SenderAlias, &i.TemplateID, &i.Domain, + &i.Attachments, ) return i, err } @@ -122,7 +125,8 @@ SELECT m.subject, m.message_id, m.sender_email, - m.sender_alias + m.sender_alias, + m.attachments FROM messages as m JOIN templates as t ON t.template_id = m.template_id JOIN domains as d ON d.domain = m.domain @@ -138,6 +142,7 @@ type GetSendingDataRow struct { MessageID string SenderEmail string SenderAlias string + Attachments Attachments } func (q *Queries) GetSendingData(ctx context.Context, messageID string) (GetSendingDataRow, error) { @@ -152,6 +157,7 @@ func (q *Queries) GetSendingData(ctx context.Context, messageID string) (GetSend &i.MessageID, &i.SenderEmail, &i.SenderAlias, + &i.Attachments, ) return i, err } diff --git a/internal/mailbuilder/attachments.go b/internal/mailbuilder/attachments.go new file mode 100644 index 0000000..a772dfe --- /dev/null +++ b/internal/mailbuilder/attachments.go @@ -0,0 +1,5 @@ +package mailbuilder + +import "io" + +type Attachments map[string]io.Reader diff --git a/internal/mailbuilder/mailbuilder.go b/internal/mailbuilder/mailbuilder.go index 8ffd77c..51e8632 100644 --- a/internal/mailbuilder/mailbuilder.go +++ b/internal/mailbuilder/mailbuilder.go @@ -51,8 +51,15 @@ func (m *mailBuilder) BuildEmail(ctx context.Context, email sqlc.SendingPoolEmai Alias: emailData.SenderAlias, } + logrus.Infof("📧 Building attachmes for %+v\n", emailData.Attachments) + + attachments := make(Attachments) + for name, r := range emailData.Attachments { + attachments[name] = bytes.NewReader(r) + } + returnPath := buildReturnPath(email.Email, emailData.MessageID) - msg, err := m.prepareMessage(ctx, sender, emailData.Subject, email.Email, emailData.Domain, emailData.MessageID, emailData.Html, m.headers, email.Fields) + msg, err := m.prepareMessage(ctx, sender, emailData.Subject, email.Email, emailData.Domain, emailData.MessageID, emailData.Html, m.headers, email.Fields, attachments) if err != nil { return nil, err } @@ -72,7 +79,7 @@ func (m *mailBuilder) BuildEmail(ctx context.Context, email sqlc.SendingPoolEmai }, nil } -func (m *mailBuilder) prepareMessage(ctx context.Context, sender pool.Sender, subject string, to string, domain string, messageID string, html string, baseHeaders headers, fields map[string]string) ([]byte, error) { +func (m *mailBuilder) prepareMessage(ctx context.Context, sender pool.Sender, subject string, to string, domain string, messageID string, html string, baseHeaders headers, fields map[string]string, attachments Attachments) ([]byte, error) { emailMessageID := buildEmailID(to, messageID) html, err := m.preparedHTML(ctx, html, to, domain, messageID, fields) if err != nil { @@ -83,7 +90,7 @@ func (m *mailBuilder) prepareMessage(ctx context.Context, sender pool.Sender, su return nil, err } h := buildHeaders(subject, sender, to, messageID, emailMessageID, baseHeaders) - return renderMsg(html, h) + return renderMsg(html, h, attachments) } func signMessage(domain string, dkimPrivateKey string, msg []byte) ([]byte, error) { @@ -136,7 +143,7 @@ func (m *mailBuilder) addTrackPixel(ctx context.Context, html string, email stri } // renderMsg render a MsgPayload to an SMTP message -func renderMsg(html string, headers headers) ([]byte, error) { +func renderMsg(html string, headers headers, attachments Attachments) ([]byte, error) { msg := mail.NewMessage() for key, value := range headers { @@ -144,6 +151,9 @@ func renderMsg(html string, headers headers) ([]byte, error) { } msg.SetDateHeader("Date", time.Now()) msg.SetBody("text/html", html) + for name, r := range attachments { + msg.AttachReader(name, r) + } var buff bytes.Buffer if _, err := msg.WriteTo(&buff); err != nil { diff --git a/internal/mailbuilder/mailbuilder_test.go b/internal/mailbuilder/mailbuilder_test.go index a7c26d0..ac510d5 100644 --- a/internal/mailbuilder/mailbuilder_test.go +++ b/internal/mailbuilder/mailbuilder_test.go @@ -8,6 +8,7 @@ import ( "io" "net/mail" "os" + "strings" "testing" schema "github.com/ludusrusso/kannon/db" @@ -115,3 +116,55 @@ func TestPrepareMail(t *testing.T) { assert.Equal(t, "test Test", string(html)) } + +func TestPrepareMailWithAttachments(t *testing.T) { + d, err := adminAPI.CreateDomain(context.Background(), &adminapiv1.CreateDomainRequest{ + Domain: "test2.com", + }) + assert.Nil(t, err) + + token := base64.StdEncoding.EncodeToString([]byte(d.Domain + ":" + d.Key)) + ctx := metadata.NewIncomingContext(context.Background(), metadata.Pairs("authorization", "Basic "+token)) + + res, err := ma.SendHTML(ctx, &mailerapiv1.SendHTMLReq{ + Sender: &pb.Sender{ + Email: "test@test.com", + Alias: "Test", + }, + Subject: "Test {{ name }}", + Html: "test {{name }}", + ScheduledTime: timestamppb.Now(), + Recipients: []*pb.Recipient{ + { + Email: "test@emailtest.com", + Fields: map[string]string{ + "name": "Test", + }, + }, + }, + Attachments: []*mailerapiv1.Attachment{ + { + Filename: "test.txt", + Content: []byte("test"), + }, + }, + }) + assert.Nil(t, err) + + err = pm.SetScheduled(ctx, res.MessageId, "test@emailtest.com") + assert.Nil(t, err) + + emails, err := pm.PrepareForSend(context.Background(), 1) + assert.Nil(t, err) + assert.Equal(t, 1, len(emails)) + + m, err := mb.BuildEmail(context.Background(), emails[0]) + assert.Nil(t, err) + parsed, err := mail.ReadMessage(bytes.NewReader(m.Body)) + assert.Nil(t, err) + + assert.Nil(t, err) + assert.Equal(t, "test@emailtest.com", parsed.Header.Get("To")) + assert.Equal(t, "Test ", parsed.Header.Get("From")) + assert.Equal(t, "multipart/mixed", strings.Split(parsed.Header.Get("Content-Type"), ";")[0]) +} diff --git a/internal/pool/pool.go b/internal/pool/pool.go index 9e38e94..bd9253f 100644 --- a/internal/pool/pool.go +++ b/internal/pool/pool.go @@ -17,7 +17,7 @@ type Sender struct { // SendingPoolManager is a manger for sending pool type SendingPoolManager interface { - AddRecipientsPool(ctx context.Context, template sqlc.Template, recipents []*pb.Recipient, from Sender, scheduled time.Time, subject string, domain string) (sqlc.Message, error) + AddRecipientsPool(ctx context.Context, template sqlc.Template, recipents []*pb.Recipient, from Sender, scheduled time.Time, subject string, domain string, attachments sqlc.Attachments) (sqlc.Message, error) PrepareForSend(ctx context.Context, max uint) ([]sqlc.SendingPoolEmail, error) PrepareForValidate(ctx context.Context, max uint) ([]sqlc.SendingPoolEmail, error) SetScheduled(ctx context.Context, messageID string, email string) error @@ -30,7 +30,7 @@ type sendingPoolManager struct { } // AddPool starts a new schedule in the pool -func (m *sendingPoolManager) AddRecipientsPool(ctx context.Context, template sqlc.Template, recipents []*pb.Recipient, from Sender, scheduled time.Time, subject string, domain string) (sqlc.Message, error) { +func (m *sendingPoolManager) AddRecipientsPool(ctx context.Context, template sqlc.Template, recipents []*pb.Recipient, from Sender, scheduled time.Time, subject string, domain string, attachments sqlc.Attachments) (sqlc.Message, error) { msg, err := m.db.CreateMessage(ctx, sqlc.CreateMessageParams{ TemplateID: template.TemplateID, Domain: domain, @@ -38,6 +38,7 @@ func (m *sendingPoolManager) AddRecipientsPool(ctx context.Context, template sql SenderEmail: from.Email, SenderAlias: from.Alias, MessageID: utils.CreateMessageID(domain), + Attachments: attachments, }) if err != nil { return sqlc.Message{}, err diff --git a/pkg/api/mailapi/mailer.go b/pkg/api/mailapi/mailer.go index c7a4b78..1afd692 100644 --- a/pkg/api/mailapi/mailer.go +++ b/pkg/api/mailapi/mailer.go @@ -43,6 +43,7 @@ func (s mailAPIService) SendHTML(ctx context.Context, req *pb.SendHTMLReq) (*pb. TemplateId: template.TemplateID, ScheduledTime: req.ScheduledTime, Recipients: req.Recipients, + Attachments: req.Attachments, }) } @@ -67,7 +68,12 @@ func (s mailAPIService) SendTemplate(ctx context.Context, req *pb.SendTemplateRe scheduled = req.ScheduledTime.AsTime() } - pool, err := s.sendingPoll.AddRecipientsPool(ctx, template, req.Recipients, sender, scheduled, req.Subject, domain.Domain) + attachments := make(sqlc.Attachments) + for _, r := range req.Attachments { + attachments[r.Filename] = r.Content + } + + pool, err := s.sendingPoll.AddRecipientsPool(ctx, template, req.Recipients, sender, scheduled, req.Subject, domain.Domain, attachments) if err != nil { logrus.Errorf("cannot create pool %v\n", err) diff --git a/proto/kannon/mailer/apiv1/mailerapiv1.pb.go b/proto/kannon/mailer/apiv1/mailerapiv1.pb.go index 34234ba..ab2a7b3 100644 --- a/proto/kannon/mailer/apiv1/mailerapiv1.pb.go +++ b/proto/kannon/mailer/apiv1/mailerapiv1.pb.go @@ -22,6 +22,61 @@ const ( _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) ) +type Attachment struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Filename string `protobuf:"bytes,1,opt,name=filename,proto3" json:"filename,omitempty"` + Content []byte `protobuf:"bytes,2,opt,name=content,proto3" json:"content,omitempty"` +} + +func (x *Attachment) Reset() { + *x = Attachment{} + if protoimpl.UnsafeEnabled { + mi := &file_kannon_mailer_apiv1_mailerapiv1_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Attachment) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Attachment) ProtoMessage() {} + +func (x *Attachment) ProtoReflect() protoreflect.Message { + mi := &file_kannon_mailer_apiv1_mailerapiv1_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Attachment.ProtoReflect.Descriptor instead. +func (*Attachment) Descriptor() ([]byte, []int) { + return file_kannon_mailer_apiv1_mailerapiv1_proto_rawDescGZIP(), []int{0} +} + +func (x *Attachment) GetFilename() string { + if x != nil { + return x.Filename + } + return "" +} + +func (x *Attachment) GetContent() []byte { + if x != nil { + return x.Content + } + return nil +} + type SendHTMLReq struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -32,12 +87,13 @@ type SendHTMLReq struct { Html string `protobuf:"bytes,4,opt,name=html,proto3" json:"html,omitempty"` ScheduledTime *timestamppb.Timestamp `protobuf:"bytes,5,opt,name=scheduled_time,json=scheduledTime,proto3,oneof" json:"scheduled_time,omitempty"` Recipients []*types.Recipient `protobuf:"bytes,6,rep,name=recipients,proto3" json:"recipients,omitempty"` + Attachments []*Attachment `protobuf:"bytes,7,rep,name=attachments,proto3" json:"attachments,omitempty"` } func (x *SendHTMLReq) Reset() { *x = SendHTMLReq{} if protoimpl.UnsafeEnabled { - mi := &file_kannon_mailer_apiv1_mailerapiv1_proto_msgTypes[0] + mi := &file_kannon_mailer_apiv1_mailerapiv1_proto_msgTypes[1] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -50,7 +106,7 @@ func (x *SendHTMLReq) String() string { func (*SendHTMLReq) ProtoMessage() {} func (x *SendHTMLReq) ProtoReflect() protoreflect.Message { - mi := &file_kannon_mailer_apiv1_mailerapiv1_proto_msgTypes[0] + mi := &file_kannon_mailer_apiv1_mailerapiv1_proto_msgTypes[1] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -63,7 +119,7 @@ func (x *SendHTMLReq) ProtoReflect() protoreflect.Message { // Deprecated: Use SendHTMLReq.ProtoReflect.Descriptor instead. func (*SendHTMLReq) Descriptor() ([]byte, []int) { - return file_kannon_mailer_apiv1_mailerapiv1_proto_rawDescGZIP(), []int{0} + return file_kannon_mailer_apiv1_mailerapiv1_proto_rawDescGZIP(), []int{1} } func (x *SendHTMLReq) GetSender() *types.Sender { @@ -101,6 +157,13 @@ func (x *SendHTMLReq) GetRecipients() []*types.Recipient { return nil } +func (x *SendHTMLReq) GetAttachments() []*Attachment { + if x != nil { + return x.Attachments + } + return nil +} + type SendTemplateReq struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -111,12 +174,13 @@ type SendTemplateReq struct { TemplateId string `protobuf:"bytes,4,opt,name=template_id,json=templateId,proto3" json:"template_id,omitempty"` ScheduledTime *timestamppb.Timestamp `protobuf:"bytes,5,opt,name=scheduled_time,json=scheduledTime,proto3,oneof" json:"scheduled_time,omitempty"` Recipients []*types.Recipient `protobuf:"bytes,6,rep,name=recipients,proto3" json:"recipients,omitempty"` + Attachments []*Attachment `protobuf:"bytes,7,rep,name=attachments,proto3" json:"attachments,omitempty"` } func (x *SendTemplateReq) Reset() { *x = SendTemplateReq{} if protoimpl.UnsafeEnabled { - mi := &file_kannon_mailer_apiv1_mailerapiv1_proto_msgTypes[1] + mi := &file_kannon_mailer_apiv1_mailerapiv1_proto_msgTypes[2] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -129,7 +193,7 @@ func (x *SendTemplateReq) String() string { func (*SendTemplateReq) ProtoMessage() {} func (x *SendTemplateReq) ProtoReflect() protoreflect.Message { - mi := &file_kannon_mailer_apiv1_mailerapiv1_proto_msgTypes[1] + mi := &file_kannon_mailer_apiv1_mailerapiv1_proto_msgTypes[2] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -142,7 +206,7 @@ func (x *SendTemplateReq) ProtoReflect() protoreflect.Message { // Deprecated: Use SendTemplateReq.ProtoReflect.Descriptor instead. func (*SendTemplateReq) Descriptor() ([]byte, []int) { - return file_kannon_mailer_apiv1_mailerapiv1_proto_rawDescGZIP(), []int{1} + return file_kannon_mailer_apiv1_mailerapiv1_proto_rawDescGZIP(), []int{2} } func (x *SendTemplateReq) GetSender() *types.Sender { @@ -180,6 +244,13 @@ func (x *SendTemplateReq) GetRecipients() []*types.Recipient { return nil } +func (x *SendTemplateReq) GetAttachments() []*Attachment { + if x != nil { + return x.Attachments + } + return nil +} + type SendRes struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -193,7 +264,7 @@ type SendRes struct { func (x *SendRes) Reset() { *x = SendRes{} if protoimpl.UnsafeEnabled { - mi := &file_kannon_mailer_apiv1_mailerapiv1_proto_msgTypes[2] + mi := &file_kannon_mailer_apiv1_mailerapiv1_proto_msgTypes[3] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -206,7 +277,7 @@ func (x *SendRes) String() string { func (*SendRes) ProtoMessage() {} func (x *SendRes) ProtoReflect() protoreflect.Message { - mi := &file_kannon_mailer_apiv1_mailerapiv1_proto_msgTypes[2] + mi := &file_kannon_mailer_apiv1_mailerapiv1_proto_msgTypes[3] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -219,7 +290,7 @@ func (x *SendRes) ProtoReflect() protoreflect.Message { // Deprecated: Use SendRes.ProtoReflect.Descriptor instead. func (*SendRes) Descriptor() ([]byte, []int) { - return file_kannon_mailer_apiv1_mailerapiv1_proto_rawDescGZIP(), []int{2} + return file_kannon_mailer_apiv1_mailerapiv1_proto_rawDescGZIP(), []int{3} } func (x *SendRes) GetMessageId() string { @@ -254,67 +325,80 @@ var file_kannon_mailer_apiv1_mailerapiv1_proto_rawDesc = []byte{ 0x66, 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1e, 0x6b, 0x61, 0x6e, 0x6e, 0x6f, 0x6e, 0x2f, 0x6d, 0x61, 0x69, 0x6c, 0x65, 0x72, 0x2f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2f, 0x73, 0x65, 0x6e, 0x64, 0x2e, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x22, 0x93, 0x02, 0x0a, 0x0b, 0x53, 0x65, 0x6e, 0x64, 0x48, 0x54, 0x4d, 0x4c, 0x52, 0x65, - 0x71, 0x12, 0x37, 0x0a, 0x06, 0x73, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x1f, 0x2e, 0x70, 0x6b, 0x67, 0x2e, 0x6b, 0x61, 0x6e, 0x6e, 0x6f, 0x6e, 0x2e, 0x6d, - 0x61, 0x69, 0x6c, 0x65, 0x72, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x53, 0x65, 0x6e, 0x64, - 0x65, 0x72, 0x52, 0x06, 0x73, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x75, - 0x62, 0x6a, 0x65, 0x63, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x73, 0x75, 0x62, - 0x6a, 0x65, 0x63, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x68, 0x74, 0x6d, 0x6c, 0x18, 0x04, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x04, 0x68, 0x74, 0x6d, 0x6c, 0x12, 0x46, 0x0a, 0x0e, 0x73, 0x63, 0x68, 0x65, - 0x64, 0x75, 0x6c, 0x65, 0x64, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, - 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x48, 0x00, 0x52, 0x0d, - 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x64, 0x54, 0x69, 0x6d, 0x65, 0x88, 0x01, 0x01, - 0x12, 0x42, 0x0a, 0x0a, 0x72, 0x65, 0x63, 0x69, 0x70, 0x69, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x06, - 0x20, 0x03, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x70, 0x6b, 0x67, 0x2e, 0x6b, 0x61, 0x6e, 0x6e, 0x6f, - 0x6e, 0x2e, 0x6d, 0x61, 0x69, 0x6c, 0x65, 0x72, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x52, - 0x65, 0x63, 0x69, 0x70, 0x69, 0x65, 0x6e, 0x74, 0x52, 0x0a, 0x72, 0x65, 0x63, 0x69, 0x70, 0x69, - 0x65, 0x6e, 0x74, 0x73, 0x42, 0x11, 0x0a, 0x0f, 0x5f, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, - 0x65, 0x64, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x22, 0xa4, 0x02, 0x0a, 0x0f, 0x53, 0x65, 0x6e, 0x64, - 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x12, 0x37, 0x0a, 0x06, 0x73, - 0x65, 0x6e, 0x64, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x70, 0x6b, - 0x67, 0x2e, 0x6b, 0x61, 0x6e, 0x6e, 0x6f, 0x6e, 0x2e, 0x6d, 0x61, 0x69, 0x6c, 0x65, 0x72, 0x2e, - 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x53, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x52, 0x06, 0x73, 0x65, - 0x6e, 0x64, 0x65, 0x72, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x18, - 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x1f, - 0x0a, 0x0b, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x04, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x0a, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x49, 0x64, 0x12, - 0x46, 0x0a, 0x0e, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x64, 0x5f, 0x74, 0x69, 0x6d, - 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, - 0x61, 0x6d, 0x70, 0x48, 0x00, 0x52, 0x0d, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x64, - 0x54, 0x69, 0x6d, 0x65, 0x88, 0x01, 0x01, 0x12, 0x42, 0x0a, 0x0a, 0x72, 0x65, 0x63, 0x69, 0x70, - 0x69, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x70, 0x6b, - 0x67, 0x2e, 0x6b, 0x61, 0x6e, 0x6e, 0x6f, 0x6e, 0x2e, 0x6d, 0x61, 0x69, 0x6c, 0x65, 0x72, 0x2e, - 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x52, 0x65, 0x63, 0x69, 0x70, 0x69, 0x65, 0x6e, 0x74, 0x52, - 0x0a, 0x72, 0x65, 0x63, 0x69, 0x70, 0x69, 0x65, 0x6e, 0x74, 0x73, 0x42, 0x11, 0x0a, 0x0f, 0x5f, - 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x64, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x22, 0x8c, - 0x01, 0x0a, 0x07, 0x53, 0x65, 0x6e, 0x64, 0x52, 0x65, 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x6d, 0x65, - 0x73, 0x73, 0x61, 0x67, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, - 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x49, 0x64, 0x12, 0x1f, 0x0a, 0x0b, 0x74, 0x65, 0x6d, - 0x70, 0x6c, 0x61, 0x74, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, - 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x49, 0x64, 0x12, 0x41, 0x0a, 0x0e, 0x73, 0x63, - 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x64, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, + 0x6f, 0x22, 0x42, 0x0a, 0x0a, 0x41, 0x74, 0x74, 0x61, 0x63, 0x68, 0x6d, 0x65, 0x6e, 0x74, 0x12, + 0x1a, 0x0a, 0x08, 0x66, 0x69, 0x6c, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x08, 0x66, 0x69, 0x6c, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x63, + 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x6f, + 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x22, 0xda, 0x02, 0x0a, 0x0b, 0x53, 0x65, 0x6e, 0x64, 0x48, 0x54, + 0x4d, 0x4c, 0x52, 0x65, 0x71, 0x12, 0x37, 0x0a, 0x06, 0x73, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x70, 0x6b, 0x67, 0x2e, 0x6b, 0x61, 0x6e, 0x6e, + 0x6f, 0x6e, 0x2e, 0x6d, 0x61, 0x69, 0x6c, 0x65, 0x72, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, + 0x53, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x52, 0x06, 0x73, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x12, 0x18, + 0x0a, 0x07, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x07, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x68, 0x74, 0x6d, 0x6c, + 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x68, 0x74, 0x6d, 0x6c, 0x12, 0x46, 0x0a, 0x0e, + 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x64, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x05, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, + 0x48, 0x00, 0x52, 0x0d, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x64, 0x54, 0x69, 0x6d, + 0x65, 0x88, 0x01, 0x01, 0x12, 0x42, 0x0a, 0x0a, 0x72, 0x65, 0x63, 0x69, 0x70, 0x69, 0x65, 0x6e, + 0x74, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x70, 0x6b, 0x67, 0x2e, 0x6b, + 0x61, 0x6e, 0x6e, 0x6f, 0x6e, 0x2e, 0x6d, 0x61, 0x69, 0x6c, 0x65, 0x72, 0x2e, 0x74, 0x79, 0x70, + 0x65, 0x73, 0x2e, 0x52, 0x65, 0x63, 0x69, 0x70, 0x69, 0x65, 0x6e, 0x74, 0x52, 0x0a, 0x72, 0x65, + 0x63, 0x69, 0x70, 0x69, 0x65, 0x6e, 0x74, 0x73, 0x12, 0x45, 0x0a, 0x0b, 0x61, 0x74, 0x74, 0x61, + 0x63, 0x68, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x07, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x23, 0x2e, + 0x70, 0x6b, 0x67, 0x2e, 0x6b, 0x61, 0x6e, 0x6e, 0x6f, 0x6e, 0x2e, 0x6d, 0x61, 0x69, 0x6c, 0x65, + 0x72, 0x2e, 0x61, 0x70, 0x69, 0x76, 0x31, 0x2e, 0x41, 0x74, 0x74, 0x61, 0x63, 0x68, 0x6d, 0x65, + 0x6e, 0x74, 0x52, 0x0b, 0x61, 0x74, 0x74, 0x61, 0x63, 0x68, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x42, + 0x11, 0x0a, 0x0f, 0x5f, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x64, 0x5f, 0x74, 0x69, + 0x6d, 0x65, 0x22, 0xeb, 0x02, 0x0a, 0x0f, 0x53, 0x65, 0x6e, 0x64, 0x54, 0x65, 0x6d, 0x70, 0x6c, + 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x12, 0x37, 0x0a, 0x06, 0x73, 0x65, 0x6e, 0x64, 0x65, 0x72, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x70, 0x6b, 0x67, 0x2e, 0x6b, 0x61, 0x6e, + 0x6e, 0x6f, 0x6e, 0x2e, 0x6d, 0x61, 0x69, 0x6c, 0x65, 0x72, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, + 0x2e, 0x53, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x52, 0x06, 0x73, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x12, + 0x18, 0x0a, 0x07, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x07, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x74, 0x65, 0x6d, + 0x70, 0x6c, 0x61, 0x74, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, + 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x49, 0x64, 0x12, 0x46, 0x0a, 0x0e, 0x73, 0x63, + 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x64, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0d, - 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x64, 0x54, 0x69, 0x6d, 0x65, 0x32, 0xbc, 0x01, - 0x0a, 0x06, 0x4d, 0x61, 0x69, 0x6c, 0x65, 0x72, 0x12, 0x54, 0x0a, 0x08, 0x53, 0x65, 0x6e, 0x64, - 0x48, 0x54, 0x4d, 0x4c, 0x12, 0x24, 0x2e, 0x70, 0x6b, 0x67, 0x2e, 0x6b, 0x61, 0x6e, 0x6e, 0x6f, - 0x6e, 0x2e, 0x6d, 0x61, 0x69, 0x6c, 0x65, 0x72, 0x2e, 0x61, 0x70, 0x69, 0x76, 0x31, 0x2e, 0x53, - 0x65, 0x6e, 0x64, 0x48, 0x54, 0x4d, 0x4c, 0x52, 0x65, 0x71, 0x1a, 0x20, 0x2e, 0x70, 0x6b, 0x67, + 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x48, 0x00, + 0x52, 0x0d, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x64, 0x54, 0x69, 0x6d, 0x65, 0x88, + 0x01, 0x01, 0x12, 0x42, 0x0a, 0x0a, 0x72, 0x65, 0x63, 0x69, 0x70, 0x69, 0x65, 0x6e, 0x74, 0x73, + 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x70, 0x6b, 0x67, 0x2e, 0x6b, 0x61, 0x6e, + 0x6e, 0x6f, 0x6e, 0x2e, 0x6d, 0x61, 0x69, 0x6c, 0x65, 0x72, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, + 0x2e, 0x52, 0x65, 0x63, 0x69, 0x70, 0x69, 0x65, 0x6e, 0x74, 0x52, 0x0a, 0x72, 0x65, 0x63, 0x69, + 0x70, 0x69, 0x65, 0x6e, 0x74, 0x73, 0x12, 0x45, 0x0a, 0x0b, 0x61, 0x74, 0x74, 0x61, 0x63, 0x68, + 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x07, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x70, 0x6b, + 0x67, 0x2e, 0x6b, 0x61, 0x6e, 0x6e, 0x6f, 0x6e, 0x2e, 0x6d, 0x61, 0x69, 0x6c, 0x65, 0x72, 0x2e, + 0x61, 0x70, 0x69, 0x76, 0x31, 0x2e, 0x41, 0x74, 0x74, 0x61, 0x63, 0x68, 0x6d, 0x65, 0x6e, 0x74, + 0x52, 0x0b, 0x61, 0x74, 0x74, 0x61, 0x63, 0x68, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x42, 0x11, 0x0a, + 0x0f, 0x5f, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x64, 0x5f, 0x74, 0x69, 0x6d, 0x65, + 0x22, 0x8c, 0x01, 0x0a, 0x07, 0x53, 0x65, 0x6e, 0x64, 0x52, 0x65, 0x73, 0x12, 0x1d, 0x0a, 0x0a, + 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x09, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x49, 0x64, 0x12, 0x1f, 0x0a, 0x0b, 0x74, + 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x0a, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x49, 0x64, 0x12, 0x41, 0x0a, 0x0e, + 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x64, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, + 0x52, 0x0d, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x64, 0x54, 0x69, 0x6d, 0x65, 0x32, + 0xbc, 0x01, 0x0a, 0x06, 0x4d, 0x61, 0x69, 0x6c, 0x65, 0x72, 0x12, 0x54, 0x0a, 0x08, 0x53, 0x65, + 0x6e, 0x64, 0x48, 0x54, 0x4d, 0x4c, 0x12, 0x24, 0x2e, 0x70, 0x6b, 0x67, 0x2e, 0x6b, 0x61, 0x6e, + 0x6e, 0x6f, 0x6e, 0x2e, 0x6d, 0x61, 0x69, 0x6c, 0x65, 0x72, 0x2e, 0x61, 0x70, 0x69, 0x76, 0x31, + 0x2e, 0x53, 0x65, 0x6e, 0x64, 0x48, 0x54, 0x4d, 0x4c, 0x52, 0x65, 0x71, 0x1a, 0x20, 0x2e, 0x70, + 0x6b, 0x67, 0x2e, 0x6b, 0x61, 0x6e, 0x6e, 0x6f, 0x6e, 0x2e, 0x6d, 0x61, 0x69, 0x6c, 0x65, 0x72, + 0x2e, 0x61, 0x70, 0x69, 0x76, 0x31, 0x2e, 0x53, 0x65, 0x6e, 0x64, 0x52, 0x65, 0x73, 0x22, 0x00, + 0x12, 0x5c, 0x0a, 0x0c, 0x53, 0x65, 0x6e, 0x64, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, + 0x12, 0x28, 0x2e, 0x70, 0x6b, 0x67, 0x2e, 0x6b, 0x61, 0x6e, 0x6e, 0x6f, 0x6e, 0x2e, 0x6d, 0x61, + 0x69, 0x6c, 0x65, 0x72, 0x2e, 0x61, 0x70, 0x69, 0x76, 0x31, 0x2e, 0x53, 0x65, 0x6e, 0x64, 0x54, + 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x1a, 0x20, 0x2e, 0x70, 0x6b, 0x67, 0x2e, 0x6b, 0x61, 0x6e, 0x6e, 0x6f, 0x6e, 0x2e, 0x6d, 0x61, 0x69, 0x6c, 0x65, 0x72, 0x2e, 0x61, - 0x70, 0x69, 0x76, 0x31, 0x2e, 0x53, 0x65, 0x6e, 0x64, 0x52, 0x65, 0x73, 0x22, 0x00, 0x12, 0x5c, - 0x0a, 0x0c, 0x53, 0x65, 0x6e, 0x64, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x12, 0x28, - 0x2e, 0x70, 0x6b, 0x67, 0x2e, 0x6b, 0x61, 0x6e, 0x6e, 0x6f, 0x6e, 0x2e, 0x6d, 0x61, 0x69, 0x6c, - 0x65, 0x72, 0x2e, 0x61, 0x70, 0x69, 0x76, 0x31, 0x2e, 0x53, 0x65, 0x6e, 0x64, 0x54, 0x65, 0x6d, - 0x70, 0x6c, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x1a, 0x20, 0x2e, 0x70, 0x6b, 0x67, 0x2e, 0x6b, - 0x61, 0x6e, 0x6e, 0x6f, 0x6e, 0x2e, 0x6d, 0x61, 0x69, 0x6c, 0x65, 0x72, 0x2e, 0x61, 0x70, 0x69, - 0x76, 0x31, 0x2e, 0x53, 0x65, 0x6e, 0x64, 0x52, 0x65, 0x73, 0x22, 0x00, 0x42, 0x38, 0x5a, 0x36, - 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6c, 0x75, 0x64, 0x75, 0x73, - 0x72, 0x75, 0x73, 0x73, 0x6f, 0x2f, 0x6b, 0x61, 0x6e, 0x6e, 0x6f, 0x6e, 0x2f, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x2f, 0x6b, 0x61, 0x6e, 0x6e, 0x6f, 0x6e, 0x2f, 0x6d, 0x61, 0x69, 0x6c, 0x65, 0x72, - 0x2f, 0x61, 0x70, 0x69, 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x70, 0x69, 0x76, 0x31, 0x2e, 0x53, 0x65, 0x6e, 0x64, 0x52, 0x65, 0x73, 0x22, 0x00, 0x42, 0x38, + 0x5a, 0x36, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6c, 0x75, 0x64, + 0x75, 0x73, 0x72, 0x75, 0x73, 0x73, 0x6f, 0x2f, 0x6b, 0x61, 0x6e, 0x6e, 0x6f, 0x6e, 0x2f, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x6b, 0x61, 0x6e, 0x6e, 0x6f, 0x6e, 0x2f, 0x6d, 0x61, 0x69, 0x6c, + 0x65, 0x72, 0x2f, 0x61, 0x70, 0x69, 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -329,32 +413,35 @@ func file_kannon_mailer_apiv1_mailerapiv1_proto_rawDescGZIP() []byte { return file_kannon_mailer_apiv1_mailerapiv1_proto_rawDescData } -var file_kannon_mailer_apiv1_mailerapiv1_proto_msgTypes = make([]protoimpl.MessageInfo, 3) +var file_kannon_mailer_apiv1_mailerapiv1_proto_msgTypes = make([]protoimpl.MessageInfo, 4) var file_kannon_mailer_apiv1_mailerapiv1_proto_goTypes = []interface{}{ - (*SendHTMLReq)(nil), // 0: pkg.kannon.mailer.apiv1.SendHTMLReq - (*SendTemplateReq)(nil), // 1: pkg.kannon.mailer.apiv1.SendTemplateReq - (*SendRes)(nil), // 2: pkg.kannon.mailer.apiv1.SendRes - (*types.Sender)(nil), // 3: pkg.kannon.mailer.types.Sender - (*timestamppb.Timestamp)(nil), // 4: google.protobuf.Timestamp - (*types.Recipient)(nil), // 5: pkg.kannon.mailer.types.Recipient + (*Attachment)(nil), // 0: pkg.kannon.mailer.apiv1.Attachment + (*SendHTMLReq)(nil), // 1: pkg.kannon.mailer.apiv1.SendHTMLReq + (*SendTemplateReq)(nil), // 2: pkg.kannon.mailer.apiv1.SendTemplateReq + (*SendRes)(nil), // 3: pkg.kannon.mailer.apiv1.SendRes + (*types.Sender)(nil), // 4: pkg.kannon.mailer.types.Sender + (*timestamppb.Timestamp)(nil), // 5: google.protobuf.Timestamp + (*types.Recipient)(nil), // 6: pkg.kannon.mailer.types.Recipient } var file_kannon_mailer_apiv1_mailerapiv1_proto_depIdxs = []int32{ - 3, // 0: pkg.kannon.mailer.apiv1.SendHTMLReq.sender:type_name -> pkg.kannon.mailer.types.Sender - 4, // 1: pkg.kannon.mailer.apiv1.SendHTMLReq.scheduled_time:type_name -> google.protobuf.Timestamp - 5, // 2: pkg.kannon.mailer.apiv1.SendHTMLReq.recipients:type_name -> pkg.kannon.mailer.types.Recipient - 3, // 3: pkg.kannon.mailer.apiv1.SendTemplateReq.sender:type_name -> pkg.kannon.mailer.types.Sender - 4, // 4: pkg.kannon.mailer.apiv1.SendTemplateReq.scheduled_time:type_name -> google.protobuf.Timestamp - 5, // 5: pkg.kannon.mailer.apiv1.SendTemplateReq.recipients:type_name -> pkg.kannon.mailer.types.Recipient - 4, // 6: pkg.kannon.mailer.apiv1.SendRes.scheduled_time:type_name -> google.protobuf.Timestamp - 0, // 7: pkg.kannon.mailer.apiv1.Mailer.SendHTML:input_type -> pkg.kannon.mailer.apiv1.SendHTMLReq - 1, // 8: pkg.kannon.mailer.apiv1.Mailer.SendTemplate:input_type -> pkg.kannon.mailer.apiv1.SendTemplateReq - 2, // 9: pkg.kannon.mailer.apiv1.Mailer.SendHTML:output_type -> pkg.kannon.mailer.apiv1.SendRes - 2, // 10: pkg.kannon.mailer.apiv1.Mailer.SendTemplate:output_type -> pkg.kannon.mailer.apiv1.SendRes - 9, // [9:11] is the sub-list for method output_type - 7, // [7:9] is the sub-list for method input_type - 7, // [7:7] is the sub-list for extension type_name - 7, // [7:7] is the sub-list for extension extendee - 0, // [0:7] is the sub-list for field type_name + 4, // 0: pkg.kannon.mailer.apiv1.SendHTMLReq.sender:type_name -> pkg.kannon.mailer.types.Sender + 5, // 1: pkg.kannon.mailer.apiv1.SendHTMLReq.scheduled_time:type_name -> google.protobuf.Timestamp + 6, // 2: pkg.kannon.mailer.apiv1.SendHTMLReq.recipients:type_name -> pkg.kannon.mailer.types.Recipient + 0, // 3: pkg.kannon.mailer.apiv1.SendHTMLReq.attachments:type_name -> pkg.kannon.mailer.apiv1.Attachment + 4, // 4: pkg.kannon.mailer.apiv1.SendTemplateReq.sender:type_name -> pkg.kannon.mailer.types.Sender + 5, // 5: pkg.kannon.mailer.apiv1.SendTemplateReq.scheduled_time:type_name -> google.protobuf.Timestamp + 6, // 6: pkg.kannon.mailer.apiv1.SendTemplateReq.recipients:type_name -> pkg.kannon.mailer.types.Recipient + 0, // 7: pkg.kannon.mailer.apiv1.SendTemplateReq.attachments:type_name -> pkg.kannon.mailer.apiv1.Attachment + 5, // 8: pkg.kannon.mailer.apiv1.SendRes.scheduled_time:type_name -> google.protobuf.Timestamp + 1, // 9: pkg.kannon.mailer.apiv1.Mailer.SendHTML:input_type -> pkg.kannon.mailer.apiv1.SendHTMLReq + 2, // 10: pkg.kannon.mailer.apiv1.Mailer.SendTemplate:input_type -> pkg.kannon.mailer.apiv1.SendTemplateReq + 3, // 11: pkg.kannon.mailer.apiv1.Mailer.SendHTML:output_type -> pkg.kannon.mailer.apiv1.SendRes + 3, // 12: pkg.kannon.mailer.apiv1.Mailer.SendTemplate:output_type -> pkg.kannon.mailer.apiv1.SendRes + 11, // [11:13] is the sub-list for method output_type + 9, // [9:11] is the sub-list for method input_type + 9, // [9:9] is the sub-list for extension type_name + 9, // [9:9] is the sub-list for extension extendee + 0, // [0:9] is the sub-list for field type_name } func init() { file_kannon_mailer_apiv1_mailerapiv1_proto_init() } @@ -364,7 +451,7 @@ func file_kannon_mailer_apiv1_mailerapiv1_proto_init() { } if !protoimpl.UnsafeEnabled { file_kannon_mailer_apiv1_mailerapiv1_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*SendHTMLReq); i { + switch v := v.(*Attachment); i { case 0: return &v.state case 1: @@ -376,7 +463,7 @@ func file_kannon_mailer_apiv1_mailerapiv1_proto_init() { } } file_kannon_mailer_apiv1_mailerapiv1_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*SendTemplateReq); i { + switch v := v.(*SendHTMLReq); i { case 0: return &v.state case 1: @@ -388,6 +475,18 @@ func file_kannon_mailer_apiv1_mailerapiv1_proto_init() { } } file_kannon_mailer_apiv1_mailerapiv1_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*SendTemplateReq); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_kannon_mailer_apiv1_mailerapiv1_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*SendRes); i { case 0: return &v.state @@ -400,15 +499,15 @@ func file_kannon_mailer_apiv1_mailerapiv1_proto_init() { } } } - file_kannon_mailer_apiv1_mailerapiv1_proto_msgTypes[0].OneofWrappers = []interface{}{} file_kannon_mailer_apiv1_mailerapiv1_proto_msgTypes[1].OneofWrappers = []interface{}{} + file_kannon_mailer_apiv1_mailerapiv1_proto_msgTypes[2].OneofWrappers = []interface{}{} type x struct{} out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_kannon_mailer_apiv1_mailerapiv1_proto_rawDesc, NumEnums: 0, - NumMessages: 3, + NumMessages: 4, NumExtensions: 0, NumServices: 1, }, diff --git a/sqlc.yaml b/sqlc.yaml index 0662ea5..8830cc2 100644 --- a/sqlc.yaml +++ b/sqlc.yaml @@ -17,6 +17,9 @@ packages: - column: "sending_pool_emails.status" go_type: type: "SendingPoolStatus" + - column: "messages.attachments" + go_type: + type: "Attachments" - name: "sq" path: "internal/stats_db" queries: "./internal/stats_db/"