From 14dc33368faa7097fcb889e25b7d1e9a766a8b54 Mon Sep 17 00:00:00 2001 From: Pavel Date: Sun, 2 Jun 2024 17:49:20 +0300 Subject: [PATCH 01/12] fix badge some deleted if expired --- app/app.go | 20 ++++++-------------- privilegewc/check.go | 31 +++++++++++++------------------ 2 files changed, 19 insertions(+), 32 deletions(-) diff --git a/app/app.go b/app/app.go index 6517e59..7d744fe 100644 --- a/app/app.go +++ b/app/app.go @@ -11,7 +11,6 @@ import ( "go.uber.org/zap" "google.golang.org/grpc" "penahub.gitlab.yandexcloud.net/backend/quiz/common.git/dal" - "penahub.gitlab.yandexcloud.net/backend/quiz/common.git/model" "penahub.gitlab.yandexcloud.net/backend/quiz/worker.git/answerwc" "penahub.gitlab.yandexcloud.net/backend/quiz/worker.git/clients/customer" "penahub.gitlab.yandexcloud.net/backend/quiz/worker.git/clients/mailclient" @@ -50,19 +49,16 @@ var _ appInit.CommonApp = (*App)(nil) type Options struct { ServiceName string `env:"SERVICE_NAME" default:"squiz"` - KafkaBroker string `env:"KAFKA_BROKER"` - KafkaTopic string `env:"KAFKA_TOPIC"` - PrivilegeID string `env:"QUIZ_ID"` - Amount uint64 `env:"AMOUNT"` - UnlimID string `env:"UNLIM_ID"` + KafkaBroker string `env:"KAFKA_BROKER" default:"localhost:6379"` + KafkaTopic string `env:"KAFKA_TOPIC" default:"test-topic"` LoggerProdMode bool `env:"IS_PROD_LOG" default:"false"` IsProd bool `env:"IS_PROD" default:"false"` MinioEP string `env:"MINIO_EP" default:"localhost:3002"` MinioAK string `env:"MINIO_AK" default:"minio"` MinioSK string `env:"MINIO_SK" default:"miniostorage"` - PostgresCredentials string `env:"PG_CRED" default:"host=localhost port=5432 user=squiz password=Redalert2 dbname=squiz sslmode=disable"` + PostgresCredentials string `env:"PG_CRED" default:"host=localhost port=35432 user=squiz password=Redalert2 dbname=squiz sslmode=disable"` RedisHost string `env:"REDIS_HOST" default:"localhost:6379"` - RedisPassword string `env:"REDIS_PASSWORD"` + RedisPassword string `env:"REDIS_PASSWORD" default:"test"` RedisDB uint64 `env:"REDIS_DB" default:"2"` SmtpHost string `env:"SMTP_HOST" default:"connect.mailclient.bz"` SmtpPort string `env:"SMTP_PORT" default:"587"` @@ -71,7 +67,7 @@ type Options struct { SmtpPassword string `env:"SMTP_PASSWORD" default:"vWwbCSg4bf0p"` SmtpApiKey string `env:"SMTP_API_KEY" default:"P0YsjUB137upXrr1NiJefHmXVKW1hmBWlpev"` SmtpApiUrl string `env:"SMTP_API_URL" default:"https://api.smtp.bz/v1/smtp/send"` - CustomerServiceAddress string `env:"CUSTOMER_SERVICE_ADDRESS"` + CustomerServiceAddress string `env:"CUSTOMER_SERVICE_ADDRESS" default:"http://localhost:8081"` } func New(ctx context.Context, opts interface{}, ver appInit.Version) (appInit.CommonApp, error) { @@ -171,11 +167,7 @@ func New(ctx context.Context, opts interface{}, ver appInit.Version) (appInit.Co } checkWorker := privilegewc.NewCheckWorker(privilegewc.CheckWorkerConfig{ - DefaultData: model.DefaultData{ - PrivilegeID: options.PrivilegeID, - Amount: options.Amount, - UnlimID: options.UnlimID, - }, + PrivilegeIDs: []string{"quizUnlimTime", "squizHideBadge"}, TickerInterval: time.Minute, Logger: logger, ErrChan: errChan, diff --git a/privilegewc/check.go b/privilegewc/check.go index c2fd482..835f51c 100644 --- a/privilegewc/check.go +++ b/privilegewc/check.go @@ -5,15 +5,14 @@ import ( "fmt" "github.com/themakers/hlog" "penahub.gitlab.yandexcloud.net/backend/quiz/common.git/dal" - "penahub.gitlab.yandexcloud.net/backend/quiz/common.git/model" "time" ) type CheckWorkerConfig struct { TickerInterval time.Duration - DefaultData model.DefaultData Logger hlog.Logger ErrChan chan<- error + PrivilegeIDs []string } type CheckWorker struct { @@ -36,7 +35,7 @@ func (w *CheckWorker) Start(ctx context.Context) { select { case <-ticker.C: fmt.Println("CHECK") - w.performScheduledTasks(ctx) + w.deleteExpired(ctx) case <-ctx.Done(): fmt.Println("Check worker terminated") return @@ -44,24 +43,20 @@ func (w *CheckWorker) Start(ctx context.Context) { } } -// TODO: Maybe one query? -func (w *CheckWorker) performScheduledTasks(ctx context.Context) { - fmt.Println("CHEC0") - w.deleteExpired(ctx) -} - func (w *CheckWorker) deleteExpired(ctx context.Context) { - expiredData, err := w.privilegeDAL.AccountRepo.GetExpired(ctx, w.config.DefaultData.UnlimID) - if err != nil { - w.config.Logger.Module("Error getting expired quizUnlimTime records") - w.config.ErrChan <- err - } - - for _, data := range expiredData { - err := w.privilegeDAL.AccountRepo.DeletePrivilegeByID(ctx, data.ID) + for _, id := range w.config.PrivilegeIDs { + expiredData, err := w.privilegeDAL.AccountRepo.GetExpired(ctx, id) if err != nil { - w.config.Logger.Module("Error deleting expired quizUnlimTime record") + w.config.Logger.Module("Error getting expired quizUnlimTime records") w.config.ErrChan <- err } + + for _, data := range expiredData { + err := w.privilegeDAL.AccountRepo.DeletePrivilegeByID(ctx, data.ID) + if err != nil { + w.config.Logger.Module("Error deleting expired quizUnlimTime record") + w.config.ErrChan <- err + } + } } } From a939ae5194be0e8d7292702aacbcabdf5d04c74c Mon Sep 17 00:00:00 2001 From: Pavel Date: Mon, 3 Jun 2024 14:23:28 +0300 Subject: [PATCH 02/12] delete rpc customer client, import from pj customer pkg, and rework check worker, now check days and count privilege and write to history with customer rpc client --- answerwc/respondent.go | 6 +- answerwc/to_client.go | 87 +++++++------ app/app.go | 36 +++--- clients/customer/service.pb.go | 182 ---------------------------- clients/customer/service_grpc.pb.go | 108 ----------------- go.mod | 19 ++- go.sum | 89 +------------- privilegewc/check.go | 78 ++++++++---- privilegewc/consumer.go | 2 - 9 files changed, 126 insertions(+), 481 deletions(-) delete mode 100644 clients/customer/service.pb.go delete mode 100644 clients/customer/service_grpc.pb.go diff --git a/answerwc/respondent.go b/answerwc/respondent.go index 06790f3..31a0b0e 100644 --- a/answerwc/respondent.go +++ b/answerwc/respondent.go @@ -5,7 +5,6 @@ import ( "encoding/json" "fmt" "github.com/go-redis/redis/v8" - "github.com/themakers/hlog" "penahub.gitlab.yandexcloud.net/backend/quiz/common.git/dal" "penahub.gitlab.yandexcloud.net/backend/quiz/common.git/model" "penahub.gitlab.yandexcloud.net/backend/quiz/worker.git/clients/mailclient" @@ -21,14 +20,12 @@ type DepsRespWorker struct { type RespWorker struct { deps DepsRespWorker - logger hlog.Logger errChan chan<- error } -func NewRespWorker(deps DepsRespWorker, logger hlog.Logger, errChan chan<- error) *RespWorker { +func NewRespWorker(deps DepsRespWorker, errChan chan<- error) *RespWorker { return &RespWorker{ deps: deps, - logger: logger, errChan: errChan, } } @@ -43,7 +40,6 @@ func (w *RespWorker) Start(ctx context.Context) { w.processPendingAnswer(ctx) case <-ctx.Done(): - w.logger.Module("To respondent worker terminated") return } diff --git a/answerwc/to_client.go b/answerwc/to_client.go index d8a7bd2..47c6897 100644 --- a/answerwc/to_client.go +++ b/answerwc/to_client.go @@ -5,12 +5,11 @@ import ( _ "embed" "encoding/json" "fmt" - "github.com/themakers/hlog" "penahub.gitlab.yandexcloud.net/backend/quiz/common.git/dal" "penahub.gitlab.yandexcloud.net/backend/quiz/common.git/model" - "penahub.gitlab.yandexcloud.net/backend/quiz/worker.git/clients/customer" "penahub.gitlab.yandexcloud.net/backend/quiz/worker.git/clients/mailclient" "penahub.gitlab.yandexcloud.net/backend/quiz/worker.git/wctools" + "penahub.gitlab.yandexcloud.net/pena-services/customer/pkg/customer_clients" "time" @@ -21,13 +20,15 @@ type DepsSendToClient struct { Redis *redis.Client Dal *dal.DAL MailClient *mailclient.Client - CustomerService customer.CustomerServiceClient + CustomerService *customer_clients.CustomersClient } type SendToClient struct { - deps DepsSendToClient - logger hlog.Logger - errChan chan<- error + redis *redis.Client + dal *dal.DAL + mailClient *mailclient.Client + customerService *customer_clients.CustomersClient + errChan chan<- error } type PendingTasks struct { @@ -41,11 +42,13 @@ var toClientTemplate string //go:embed mail/reminder.tmpl var reminderTemplate string -func NewSendToClient(deps DepsSendToClient, logger hlog.Logger, errChan chan<- error) *SendToClient { +func NewSendToClient(deps DepsSendToClient, errChan chan<- error) *SendToClient { return &SendToClient{ - deps: deps, - logger: logger, - errChan: errChan, + redis: deps.Redis, + dal: deps.Dal, + mailClient: deps.MailClient, + customerService: deps.CustomerService, + errChan: errChan, } } @@ -59,7 +62,6 @@ func (w *SendToClient) Start(ctx context.Context) { w.processPendingAnswer(ctx) case <-ctx.Done(): - w.logger.Module("To client worker terminated") return } @@ -67,7 +69,7 @@ func (w *SendToClient) Start(ctx context.Context) { } func (w *SendToClient) processPendingAnswer(ctx context.Context) { - pendingAnswers, err := w.deps.Redis.Keys(ctx, "answer:*").Result() + pendingAnswers, err := w.redis.Keys(ctx, "answer:*").Result() if err != nil { fmt.Println("Error getting keys from redis") w.errChan <- err @@ -79,7 +81,7 @@ func (w *SendToClient) processPendingAnswer(ctx context.Context) { for _, key := range pendingAnswers { func() { fmt.Println("ANS1", key) - answerJSON, err := w.deps.Redis.GetDel(ctx, key).Result() + answerJSON, err := w.redis.GetDel(ctx, key).Result() if err == redis.Nil { return } else if err != nil { @@ -91,7 +93,7 @@ func (w *SendToClient) processPendingAnswer(ctx context.Context) { if r := recover(); r != nil { w.reportError(nil, fmt.Sprintf("recovering from panic or error setting redis value %v", r)) fmt.Println("ANS1ERRR", r) - _ = w.deps.Redis.Set(ctx, key, answerJSON, 0).Err() + _ = w.redis.Set(ctx, key, answerJSON, 0).Err() } }() @@ -110,14 +112,14 @@ func (w *SendToClient) processPendingAnswer(ctx context.Context) { return } - allAnswers, err := w.deps.Dal.AnswerRepo.GetAllAnswersByQuizID(ctx, answer.Session) + allAnswers, err := w.dal.AnswerRepo.GetAllAnswersByQuizID(ctx, answer.Session) fmt.Println("ANS4", err) if err != nil { w.reportError(err, "Error getting all answers by quizID") return } - questionsMap, sortedallAnswers, err := w.deps.Dal.QuestionRepo.GetMapQuestions(ctx, allAnswers) + questionsMap, sortedallAnswers, err := w.dal.QuestionRepo.GetMapQuestions(ctx, allAnswers) fmt.Println("ANS5", err) if err != nil { w.reportError(err, "Error getting questionsMap") @@ -128,14 +130,14 @@ func (w *SendToClient) processPendingAnswer(ctx context.Context) { return } - quizConfig, accountId, err := w.deps.Dal.QuizRepo.GetQuizConfig(ctx, answer.QuizId) + quizConfig, accountId, err := w.dal.QuizRepo.GetQuizConfig(ctx, answer.QuizId) fmt.Println("ANS6", err) if err != nil { w.reportError(err, "Error getting quiz config") return } - quiz, err := w.deps.Dal.QuizRepo.GetQuizById(ctx, accountId, answer.QuizId) + quiz, err := w.dal.QuizRepo.GetQuizById(ctx, accountId, answer.QuizId) fmt.Println("ANS60", err, accountId, answer.QuizId) if err != nil { w.reportError(err, "Error getting quiz") @@ -148,7 +150,7 @@ func (w *SendToClient) processPendingAnswer(ctx context.Context) { quizConfig.Mailing.Theme = quiz.Name } - account, privileges, err := w.deps.Dal.AccountRepo.GetAccAndPrivilegeByEmail(ctx, accountId) + account, privileges, err := w.dal.AccountRepo.GetAccAndPrivilegeByEmail(ctx, accountId) fmt.Println("ANS7", err) if err != nil { w.reportError(err, "Error getting account and privileges by email") @@ -162,7 +164,7 @@ func (w *SendToClient) processPendingAnswer(ctx context.Context) { return } if !result { - err = w.deps.Redis.Set(ctx, fmt.Sprintf("%s:%s", account.ID, key), answerJSON, 0).Err() + err = w.redis.Set(ctx, fmt.Sprintf("%s:%s", account.ID, key), answerJSON, 0).Err() if err != nil { w.reportError(err, "Error setting redis value") return @@ -176,7 +178,7 @@ func (w *SendToClient) processAnswerWithPrivileges(ctx context.Context, quizName questionsMap map[uint64]string, privileges []model.ShortPrivilege, account model.Account, allAnswers []model.ResultAnswer, answerContent model.ResultContent, answerTime time.Time) (bool, error) { - err := w.notificationCustomer(account, privileges) + err := w.notificationCustomer(ctx, account, privileges) fmt.Println("ANS81", err) if err != nil { return false, err @@ -198,13 +200,13 @@ func (w *SendToClient) processAnswerWithPrivileges(ctx context.Context, quizName } privilege.Amount-- - err = w.deps.Dal.AccountRepo.UpdatePrivilegeAmount(ctx, privilege.ID, privilege.Amount) + err = w.dal.AccountRepo.UpdatePrivilegeAmount(ctx, privilege.ID, privilege.Amount) if err != nil { return false, err } return true, nil } else { - w.checkAndSendTaskReminders(ctx, sendTaskRemindersDeps{ + w.checkAndSendTaskReminders(sendTaskRemindersDeps{ email: account.Email, theme: quizName, config: model.QuizConfig{ @@ -224,7 +226,7 @@ func (w *SendToClient) recordPendingTasks(ctx context.Context, Email string, qui key := fmt.Sprintf("pending_tasks:%s", Email) var pendingTasks PendingTasks - val, err := w.deps.Redis.HGet(ctx, key, "data").Result() + val, err := w.redis.HGet(ctx, key, "data").Result() if err == nil { err := json.Unmarshal([]byte(val), &pendingTasks) if err != nil { @@ -243,7 +245,7 @@ func (w *SendToClient) recordPendingTasks(ctx context.Context, Email string, qui return err } - err = w.deps.Redis.HSet(ctx, key, "data", string(pendingTasksJSON)).Err() + err = w.redis.HSet(ctx, key, "data", string(pendingTasksJSON)).Err() if err != nil { return err } @@ -256,7 +258,7 @@ type sendTaskRemindersDeps struct { config model.QuizConfig } -func (w *SendToClient) checkAndSendTaskReminders(ctx context.Context, deps sendTaskRemindersDeps) { +func (w *SendToClient) checkAndSendTaskReminders(deps sendTaskRemindersDeps) { err := w.processReminderToClient(deps.email, deps.config) fmt.Println("PMC1", err) if err != nil { @@ -264,19 +266,17 @@ func (w *SendToClient) checkAndSendTaskReminders(ctx context.Context, deps sendT } } -func (w *SendToClient) notificationCustomer(account model.Account, privileges []model.ShortPrivilege) error { +func (w *SendToClient) notificationCustomer(ctx context.Context, account model.Account, privileges []model.ShortPrivilege) error { for _, privilege := range privileges { fmt.Println("NOTIFIC", privilege.PrivilegeID, privilege.Amount, !wctools.IsPrivilegeExpired(privilege)) if privilege.PrivilegeID == "quizUnlimTime" && !wctools.IsPrivilegeExpired(privilege) { - rawDetail, err := wctools.ToJSON(privilege) - historyData := &customer.History{ - UserID: account.UserID, - Comment: fmt.Sprintf("Привилегия %s просрочена", privilege.PrivilegeID), - Key: "privilege_expired", - RawDetails: rawDetail, + historyData := customer_clients.InsertHistoryDeps{ + UserID: account.UserID, + Comment: fmt.Sprintf("%s privilege has expired, it was created at %d", privilege.PrivilegeID, privilege.CreatedAt.Unix()), + Key: "end", } - _, err = w.deps.CustomerService.InsertHistory(context.Background(), historyData) + err := w.customerService.InsertHistory(ctx, historyData) if err != nil { return err } @@ -284,18 +284,13 @@ func (w *SendToClient) notificationCustomer(account model.Account, privileges [] } if privilege.PrivilegeID == "quizCnt" && privilege.Amount == 0 { - rawDetail, err := wctools.ToJSON(privilege) - if err != nil { - return err - } - historyData := &customer.History{ - UserID: account.UserID, - Comment: fmt.Sprintf("У привилегии %s истек amount", privilege.PrivilegeID), - Key: "privilege_expired", - RawDetails: rawDetail, + historyData := customer_clients.InsertHistoryDeps{ + UserID: account.UserID, + Comment: fmt.Sprintf("%s privilege has expired, it was created at %d", privilege.PrivilegeID, privilege.CreatedAt.Unix()), + Key: "end", } - _, err = w.deps.CustomerService.InsertHistory(context.Background(), historyData) + err := w.customerService.InsertHistory(ctx, historyData) if err != nil { return err } @@ -334,7 +329,7 @@ func (w *SendToClient) ProcessMessageToClient(quizConfig model.QuizConfig, quest fmt.Println("SUBJECT", theme, account.Email) - err := w.deps.MailClient.SendMailWithAttachment(account.Email, theme, toClientTemplate, data, nil) + err := w.mailClient.SendMailWithAttachment(account.Email, theme, toClientTemplate, data, nil) if err != nil { return err } @@ -358,7 +353,7 @@ func (w *SendToClient) processReminderToClient(email string, quizConfig model.Qu fmt.Println("PRTC", data, email, quizConfig) - err := w.deps.MailClient.SendMailWithAttachment(email, quizConfig.Mailing.Theme, reminderTemplate, data, nil) + err := w.mailClient.SendMailWithAttachment(email, quizConfig.Mailing.Theme, reminderTemplate, data, nil) if err != nil { return err } diff --git a/app/app.go b/app/app.go index 7d744fe..6883863 100644 --- a/app/app.go +++ b/app/app.go @@ -9,14 +9,13 @@ import ( "github.com/skeris/appInit" "github.com/themakers/hlog" "go.uber.org/zap" - "google.golang.org/grpc" "penahub.gitlab.yandexcloud.net/backend/quiz/common.git/dal" "penahub.gitlab.yandexcloud.net/backend/quiz/worker.git/answerwc" - "penahub.gitlab.yandexcloud.net/backend/quiz/worker.git/clients/customer" "penahub.gitlab.yandexcloud.net/backend/quiz/worker.git/clients/mailclient" "penahub.gitlab.yandexcloud.net/backend/quiz/worker.git/privilegewc" "penahub.gitlab.yandexcloud.net/backend/quiz/worker.git/workers/shortstat" "penahub.gitlab.yandexcloud.net/backend/quiz/worker.git/workers/timeout" + "penahub.gitlab.yandexcloud.net/pena-services/customer/pkg/customer_clients" "fmt" "time" @@ -58,7 +57,7 @@ type Options struct { MinioSK string `env:"MINIO_SK" default:"miniostorage"` PostgresCredentials string `env:"PG_CRED" default:"host=localhost port=35432 user=squiz password=Redalert2 dbname=squiz sslmode=disable"` RedisHost string `env:"REDIS_HOST" default:"localhost:6379"` - RedisPassword string `env:"REDIS_PASSWORD" default:"test"` + RedisPassword string `env:"REDIS_PASSWORD" default:"admin"` RedisDB uint64 `env:"REDIS_DB" default:"2"` SmtpHost string `env:"SMTP_HOST" default:"connect.mailclient.bz"` SmtpPort string `env:"SMTP_PORT" default:"587"` @@ -67,7 +66,7 @@ type Options struct { SmtpPassword string `env:"SMTP_PASSWORD" default:"vWwbCSg4bf0p"` SmtpApiKey string `env:"SMTP_API_KEY" default:"P0YsjUB137upXrr1NiJefHmXVKW1hmBWlpev"` SmtpApiUrl string `env:"SMTP_API_URL" default:"https://api.smtp.bz/v1/smtp/send"` - CustomerServiceAddress string `env:"CUSTOMER_SERVICE_ADDRESS" default:"http://localhost:8081"` + CustomerServiceAddress string `env:"CUSTOMER_SERVICE_ADDRESS" default:"localhost:9001"` } func New(ctx context.Context, opts interface{}, ver appInit.Version) (appInit.CommonApp, error) { @@ -133,11 +132,10 @@ func New(ctx context.Context, opts interface{}, ver appInit.Version) (appInit.Co mailClient := mailclient.NewClient(smtpData) - customerServiceConn, err := grpc.Dial(options.CustomerServiceAddress, grpc.WithInsecure()) - if err != nil { - return nil, err - } - customerServiceClient := customer.NewCustomerServiceClient(customerServiceConn) + customerClient := customer_clients.NewCustomersClient(customer_clients.CustomersClientDeps{ + Logger: zapLogger, + CustomerServiceHost: options.CustomerServiceAddress, + }) minioClient, err := minio.New(options.MinioEP, &minio.Options{ Creds: credentials.NewStaticV4(options.MinioAK, options.MinioSK, ""), @@ -158,7 +156,6 @@ func New(ctx context.Context, opts interface{}, ver appInit.Version) (appInit.Co KafkaTopic: options.KafkaTopic, ServiceKey: options.ServiceName, TickerInterval: time.Second * 10, - Logger: logger, ErrChan: errChan, }, redisClient, pgdal) if err != nil { @@ -166,12 +163,13 @@ func New(ctx context.Context, opts interface{}, ver appInit.Version) (appInit.Co return nil, err } - checkWorker := privilegewc.NewCheckWorker(privilegewc.CheckWorkerConfig{ - PrivilegeIDs: []string{"quizUnlimTime", "squizHideBadge"}, - TickerInterval: time.Minute, - Logger: logger, - ErrChan: errChan, - }, pgdal) + checkWorker := privilegewc.NewCheckWorker(privilegewc.Deps{ + PrivilegeIDsDays: []string{"quizUnlimTime", "squizHideBadge"}, + PrivilegeIDsCount: []string{"quizCnt"}, + TickerInterval: time.Minute, + PrivilegeDAL: pgdal, + CustomerClient: customerClient, + }, errChan) go kafkaWorker.Start(ctx) go checkWorker.Start(ctx) @@ -179,14 +177,14 @@ func New(ctx context.Context, opts interface{}, ver appInit.Version) (appInit.Co Redis: redisClient, Dal: pgdal, MailClient: mailClient, - CustomerService: customerServiceClient, - }, logger, errChan) + CustomerService: customerClient, + }, errChan) toRespWorker := answerwc.NewRespWorker(answerwc.DepsRespWorker{ Redis: redisClient, Dal: pgdal, MailClient: mailClient, - }, logger, errChan) + }, errChan) go toClientWorker.Start(ctx) go toRespWorker.Start(ctx) diff --git a/clients/customer/service.pb.go b/clients/customer/service.pb.go deleted file mode 100644 index 510635d..0000000 --- a/clients/customer/service.pb.go +++ /dev/null @@ -1,182 +0,0 @@ -// Code generated by protoc-gen-go. DO NOT EDIT. -// versions: -// protoc-gen-go v1.31.0 -// protoc (unknown) -// source: customer/service.proto - -package customer - -import ( - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" - emptypb "google.golang.org/protobuf/types/known/emptypb" - reflect "reflect" - sync "sync" -) - -const ( - // Verify that this generated code is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) - // Verify that runtime/protoimpl is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) -) - -type History struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - UserID string `protobuf:"bytes,1,opt,name=UserID,proto3" json:"UserID,omitempty"` - Comment string `protobuf:"bytes,2,opt,name=Comment,proto3" json:"Comment,omitempty"` - Key string `protobuf:"bytes,3,opt,name=Key,proto3" json:"Key,omitempty"` - RawDetails string `protobuf:"bytes,4,opt,name=RawDetails,proto3" json:"RawDetails,omitempty"` -} - -func (x *History) Reset() { - *x = History{} - if protoimpl.UnsafeEnabled { - mi := &file_customer_service_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *History) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*History) ProtoMessage() {} - -func (x *History) ProtoReflect() protoreflect.Message { - mi := &file_customer_service_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 History.ProtoReflect.Descriptor instead. -func (*History) Descriptor() ([]byte, []int) { - return file_customer_service_proto_rawDescGZIP(), []int{0} -} - -func (x *History) GetUserID() string { - if x != nil { - return x.UserID - } - return "" -} - -func (x *History) GetComment() string { - if x != nil { - return x.Comment - } - return "" -} - -func (x *History) GetKey() string { - if x != nil { - return x.Key - } - return "" -} - -func (x *History) GetRawDetails() string { - if x != nil { - return x.RawDetails - } - return "" -} - -var File_customer_service_proto protoreflect.FileDescriptor - -var file_customer_service_proto_rawDesc = []byte{ - 0x0a, 0x16, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x65, 0x72, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x69, - 0x63, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x08, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, - 0x65, 0x72, 0x1a, 0x1b, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x62, 0x75, 0x66, 0x2f, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, - 0x6d, 0x0a, 0x07, 0x48, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x16, 0x0a, 0x06, 0x55, 0x73, - 0x65, 0x72, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x55, 0x73, 0x65, 0x72, - 0x49, 0x44, 0x12, 0x18, 0x0a, 0x07, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x07, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x10, 0x0a, 0x03, - 0x4b, 0x65, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x4b, 0x65, 0x79, 0x12, 0x1e, - 0x0a, 0x0a, 0x52, 0x61, 0x77, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x18, 0x04, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x0a, 0x52, 0x61, 0x77, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x32, 0x4f, - 0x0a, 0x0f, 0x43, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x65, 0x72, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, - 0x65, 0x12, 0x3c, 0x0a, 0x0d, 0x49, 0x6e, 0x73, 0x65, 0x72, 0x74, 0x48, 0x69, 0x73, 0x74, 0x6f, - 0x72, 0x79, 0x12, 0x11, 0x2e, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x65, 0x72, 0x2e, 0x48, 0x69, - 0x73, 0x74, 0x6f, 0x72, 0x79, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x42, - 0x0c, 0x5a, 0x0a, 0x2e, 0x2f, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x65, 0x72, 0x62, 0x06, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x33, -} - -var ( - file_customer_service_proto_rawDescOnce sync.Once - file_customer_service_proto_rawDescData = file_customer_service_proto_rawDesc -) - -func file_customer_service_proto_rawDescGZIP() []byte { - file_customer_service_proto_rawDescOnce.Do(func() { - file_customer_service_proto_rawDescData = protoimpl.X.CompressGZIP(file_customer_service_proto_rawDescData) - }) - return file_customer_service_proto_rawDescData -} - -var file_customer_service_proto_msgTypes = make([]protoimpl.MessageInfo, 1) -var file_customer_service_proto_goTypes = []interface{}{ - (*History)(nil), // 0: customer.History - (*emptypb.Empty)(nil), // 1: google.protobuf.Empty -} -var file_customer_service_proto_depIdxs = []int32{ - 0, // 0: customer.CustomerService.InsertHistory:input_type -> customer.History - 1, // 1: customer.CustomerService.InsertHistory:output_type -> google.protobuf.Empty - 1, // [1:2] is the sub-list for method output_type - 0, // [0:1] is the sub-list for method input_type - 0, // [0:0] is the sub-list for extension type_name - 0, // [0:0] is the sub-list for extension extendee - 0, // [0:0] is the sub-list for field type_name -} - -func init() { file_customer_service_proto_init() } -func file_customer_service_proto_init() { - if File_customer_service_proto != nil { - return - } - if !protoimpl.UnsafeEnabled { - file_customer_service_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*History); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - } - type x struct{} - out := protoimpl.TypeBuilder{ - File: protoimpl.DescBuilder{ - GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_customer_service_proto_rawDesc, - NumEnums: 0, - NumMessages: 1, - NumExtensions: 0, - NumServices: 1, - }, - GoTypes: file_customer_service_proto_goTypes, - DependencyIndexes: file_customer_service_proto_depIdxs, - MessageInfos: file_customer_service_proto_msgTypes, - }.Build() - File_customer_service_proto = out.File - file_customer_service_proto_rawDesc = nil - file_customer_service_proto_goTypes = nil - file_customer_service_proto_depIdxs = nil -} diff --git a/clients/customer/service_grpc.pb.go b/clients/customer/service_grpc.pb.go deleted file mode 100644 index 74454d3..0000000 --- a/clients/customer/service_grpc.pb.go +++ /dev/null @@ -1,108 +0,0 @@ -// Code generated by protoc-gen-go-grpc. DO NOT EDIT. -// versions: -// - protoc-gen-go-grpc v1.3.0 -// - protoc (unknown) -// source: customer/service.proto - -package customer - -import ( - context "context" - grpc "google.golang.org/grpc" - codes "google.golang.org/grpc/codes" - status "google.golang.org/grpc/status" - emptypb "google.golang.org/protobuf/types/known/emptypb" -) - -// This is a compile-time assertion to ensure that this generated file -// is compatible with the grpc package it is being compiled against. -// Requires gRPC-Go v1.32.0 or later. -const _ = grpc.SupportPackageIsVersion7 - -const ( - CustomerService_InsertHistory_FullMethodName = "/customer.CustomerService/InsertHistory" -) - -// CustomerServiceClient is the client API for CustomerService service. -// -// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. -type CustomerServiceClient interface { - InsertHistory(ctx context.Context, in *History, opts ...grpc.CallOption) (*emptypb.Empty, error) -} - -type customerServiceClient struct { - cc grpc.ClientConnInterface -} - -func NewCustomerServiceClient(cc grpc.ClientConnInterface) CustomerServiceClient { - return &customerServiceClient{cc} -} - -func (c *customerServiceClient) InsertHistory(ctx context.Context, in *History, opts ...grpc.CallOption) (*emptypb.Empty, error) { - out := new(emptypb.Empty) - err := c.cc.Invoke(ctx, CustomerService_InsertHistory_FullMethodName, in, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -// CustomerServiceServer is the server API for CustomerService service. -// All implementations should embed UnimplementedCustomerServiceServer -// for forward compatibility -type CustomerServiceServer interface { - InsertHistory(context.Context, *History) (*emptypb.Empty, error) -} - -// UnimplementedCustomerServiceServer should be embedded to have forward compatible implementations. -type UnimplementedCustomerServiceServer struct { -} - -func (UnimplementedCustomerServiceServer) InsertHistory(context.Context, *History) (*emptypb.Empty, error) { - return nil, status.Errorf(codes.Unimplemented, "method InsertHistory not implemented") -} - -// UnsafeCustomerServiceServer may be embedded to opt out of forward compatibility for this service. -// Use of this interface is not recommended, as added methods to CustomerServiceServer will -// result in compilation errors. -type UnsafeCustomerServiceServer interface { - mustEmbedUnimplementedCustomerServiceServer() -} - -func RegisterCustomerServiceServer(s grpc.ServiceRegistrar, srv CustomerServiceServer) { - s.RegisterService(&CustomerService_ServiceDesc, srv) -} - -func _CustomerService_InsertHistory_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(History) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(CustomerServiceServer).InsertHistory(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: CustomerService_InsertHistory_FullMethodName, - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(CustomerServiceServer).InsertHistory(ctx, req.(*History)) - } - return interceptor(ctx, in, info, handler) -} - -// CustomerService_ServiceDesc is the grpc.ServiceDesc for CustomerService service. -// It's only intended for direct use with grpc.RegisterService, -// and not to be introspected or modified (even as a copy) -var CustomerService_ServiceDesc = grpc.ServiceDesc{ - ServiceName: "customer.CustomerService", - HandlerType: (*CustomerServiceServer)(nil), - Methods: []grpc.MethodDesc{ - { - MethodName: "InsertHistory", - Handler: _CustomerService_InsertHistory_Handler, - }, - }, - Streams: []grpc.StreamDesc{}, - Metadata: "customer/service.proto", -} diff --git a/go.mod b/go.mod index ee372d0..8dd1768 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,8 @@ module penahub.gitlab.yandexcloud.net/backend/quiz/worker.git -go 1.21.4 +go 1.22.0 + +toolchain go1.22.2 require ( github.com/go-redis/redis/v8 v8.11.5 @@ -11,9 +13,8 @@ require ( github.com/themakers/hlog v0.0.0-20191205140925-235e0e4baddf github.com/twmb/franz-go v1.17.0 go.uber.org/zap v1.27.0 - google.golang.org/grpc v1.64.0 - google.golang.org/protobuf v1.34.1 - penahub.gitlab.yandexcloud.net/backend/quiz/common.git v0.0.0-20240530133953-8649c342543a + penahub.gitlab.yandexcloud.net/backend/quiz/common.git v0.0.0-20240603085333-e860e550daba + penahub.gitlab.yandexcloud.net/pena-services/customer v1.0.1-0.20240603075153-27f3ccdc57f4 ) require ( @@ -22,11 +23,7 @@ require ( github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect github.com/dustin/go-humanize v1.0.1 // indirect github.com/goccy/go-json v0.10.3 // indirect - github.com/golang-migrate/migrate/v4 v4.17.1 // indirect github.com/google/uuid v1.6.0 // indirect - github.com/hashicorp/errwrap v1.1.0 // indirect - github.com/hashicorp/go-multierror v1.1.1 // indirect - github.com/json-iterator/go v1.1.12 // indirect github.com/klauspost/compress v1.17.8 // indirect github.com/klauspost/cpuid/v2 v2.2.7 // indirect github.com/lib/pq v1.10.9 // indirect @@ -34,9 +31,6 @@ require ( github.com/mattn/go-isatty v0.0.20 // indirect github.com/mattn/go-runewidth v0.0.15 // indirect github.com/minio/md5-simd v1.1.2 // indirect - github.com/minio/sha256-simd v1.0.1 // indirect - github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect - github.com/modern-go/reflect2 v1.0.2 // indirect github.com/pierrec/lz4/v4 v4.1.21 // indirect github.com/rivo/uniseg v0.4.7 // indirect github.com/rs/xid v1.5.0 // indirect @@ -44,13 +38,14 @@ require ( github.com/valyala/bytebufferpool v1.0.0 // indirect github.com/valyala/fasthttp v1.54.0 // indirect github.com/valyala/tcplisten v1.0.0 // indirect - go.uber.org/atomic v1.11.0 // indirect go.uber.org/multierr v1.11.0 // indirect golang.org/x/crypto v0.23.0 // indirect golang.org/x/net v0.25.0 // indirect golang.org/x/sys v0.20.0 // indirect golang.org/x/text v0.15.0 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20240528184218-531527333157 // indirect + google.golang.org/grpc v1.64.0 // indirect + google.golang.org/protobuf v1.34.1 // indirect gopkg.in/ini.v1 v1.67.0 // indirect penahub.gitlab.yandexcloud.net/backend/penahub_common v0.0.0-20240527160654-bd1c2126bc6c // indirect ) diff --git a/go.sum b/go.sum index a72c538..1b92441 100644 --- a/go.sum +++ b/go.sum @@ -1,8 +1,4 @@ -github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 h1:L/gRVlceqvL25UVaW/CKtUDjefjrs0SPonmDGUVOYP0= -github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= -github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow= -github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM= github.com/andybalholm/brotli v1.1.0 h1:eLKJA0d02Lf0mVpIDgYnqXcUn0GqVmEFny3VuID1U3M= github.com/andybalholm/brotli v1.1.0/go.mod h1:sms7XGricyQI9K10gOSf56VKKWS4oLer58Q+mhRPtnY= github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= @@ -12,16 +8,6 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78= github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc= -github.com/dhui/dktest v0.4.0 h1:z05UmuXZHO/bgj/ds2bGMBu8FI4WA+Ag/m3ghL+om7M= -github.com/dhui/dktest v0.4.0/go.mod h1:v/Dbz1LgCBOi2Uki2nUqLBGa83hWBGFMu5MrgMDCc78= -github.com/docker/distribution v2.8.2+incompatible h1:T3de5rq0dB1j30rp0sA2rER+m322EBzniBPB6ZIzuh8= -github.com/docker/distribution v2.8.2+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= -github.com/docker/docker v24.0.7+incompatible h1:Wo6l37AuwP3JaMnZa226lzVXGA3F9Ig1seQen0cKYlM= -github.com/docker/docker v24.0.7+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= -github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ= -github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec= -github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4= -github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY= github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4= @@ -32,27 +18,13 @@ github.com/goccy/go-json v0.10.3 h1:KZ5WoDbxAIgm2HNbYckL0se1fHD6rz5j4ywS6ebzDqA= github.com/goccy/go-json v0.10.3/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M= github.com/gofiber/fiber/v2 v2.52.4 h1:P+T+4iK7VaqUsq2PALYEfBBo6bJZ4q3FP8cZ84EggTM= github.com/gofiber/fiber/v2 v2.52.4/go.mod h1:KEOE+cXMhXG0zHc9d8+E38hoX+ZN7bhOtgeF2oT6jrQ= -github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= -github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= -github.com/golang-migrate/migrate/v4 v4.17.0 h1:rd40H3QXU0AA4IoLllFcEAEo9dYKRHYND2gB4p7xcaU= -github.com/golang-migrate/migrate/v4 v4.17.0/go.mod h1:+Cp2mtLP4/aXDTKb9wmXYitdrNx2HGs45rbWAo6OsKM= -github.com/golang-migrate/migrate/v4 v4.17.1 h1:4zQ6iqL6t6AiItphxJctQb3cFqWiSpMnX7wLTPnnYO4= -github.com/golang-migrate/migrate/v4 v4.17.1/go.mod h1:m8hinFyWBn0SA4QKHuKh175Pm9wjmxj3S2Mia7dbXzM= github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= -github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I= -github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= -github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= -github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= -github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= -github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/klauspost/compress v1.17.8 h1:YcnTYrq7MikUT7k0Yb5eceMmALQPYBW/Xltxn0NAMnU= github.com/klauspost/compress v1.17.8/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= @@ -73,36 +45,17 @@ github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZ github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= github.com/minio/md5-simd v1.1.2 h1:Gdi1DZK69+ZVMoNHRXJyNcxrMA4dSxoYHZSQbirFg34= github.com/minio/md5-simd v1.1.2/go.mod h1:MzdKDxYpY2BT9XQFocsiZf/NKVtR7nkE4RoEpN+20RM= -github.com/minio/minio-go/v7 v7.0.69 h1:l8AnsQFyY1xiwa/DaQskY4NXSLA2yrGsW5iD9nRPVS0= -github.com/minio/minio-go/v7 v7.0.69/go.mod h1:XAvOPJQ5Xlzk5o3o/ArO2NMbhSGkimC+bpW/ngRKDmQ= github.com/minio/minio-go/v7 v7.0.70 h1:1u9NtMgfK1U42kUxcsl5v0yj6TEOPR497OAQxpJnn2g= github.com/minio/minio-go/v7 v7.0.70/go.mod h1:4yBA8v80xGA30cfM3fz0DKYMXunWl/AV/6tWEs9ryzo= -github.com/minio/sha256-simd v1.0.1 h1:6kaan5IFmwTNynnKKpDHe6FWHohJOHhCPchzK49dzMM= -github.com/minio/sha256-simd v1.0.1/go.mod h1:Pz6AKMiUdngCLpeTL/RJY1M9rUuPMYujV5xJjtbRSN8= -github.com/moby/term v0.5.0 h1:xt8Q1nalod/v7BqbG21f8mQPqH+xAaC9C3N3wfWbVP0= -github.com/moby/term v0.5.0/go.mod h1:8FzsFHVUBGZdbDsJw/ot+X+d5HLUbvklYLJ9uGfcI3Y= -github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= -github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= -github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= -github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= -github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= -github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A= -github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc= github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= github.com/onsi/gomega v1.18.1 h1:M1GfJqGRrBrrGGsbxzV5dqM2U2ApXefZCQpkukxYRLE= github.com/onsi/gomega v1.18.1/go.mod h1:0q+aL8jAiMXy9hbwj2mr5GziHiwhAIQpFmmtT5hitRs= -github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= -github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= -github.com/opencontainers/image-spec v1.0.2 h1:9yCKha/T5XdGtO0q9Q9a6T5NUCsTn/DrBg0D7ufOcFM= -github.com/opencontainers/image-spec v1.0.2/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0= github.com/pierrec/lz4/v4 v4.1.21 h1:yOVMLb6qSIDP67pl/5F7RepeKYu/VmTyEXvuMI5d9mQ= github.com/pierrec/lz4/v4 v4.1.21/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= -github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= @@ -120,25 +73,17 @@ github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcU github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/themakers/hlog v0.0.0-20191205140925-235e0e4baddf h1:TJJm6KcBssmbWzplF5lzixXl1RBAi/ViPs1GaSOkhwo= github.com/themakers/hlog v0.0.0-20191205140925-235e0e4baddf/go.mod h1:1FsorU3vnXO9xS9SrhUp8fRb/6H/Zfll0rPt1i4GWaA= -github.com/twmb/franz-go v1.16.1 h1:rpWc7fB9jd7TgmCyfxzenBI+QbgS8ZfJOUQE+tzPtbE= -github.com/twmb/franz-go v1.16.1/go.mod h1:/pER254UPPGp/4WfGqRi+SIRGE50RSQzVubQp6+N4FA= github.com/twmb/franz-go v1.17.0 h1:hawgCx5ejDHkLe6IwAtFWwxi3OU4OztSTl7ZV5rwkYk= github.com/twmb/franz-go v1.17.0/go.mod h1:NreRdJ2F7dziDY/m6VyspWd6sNxHKXdMZI42UfQ3GXM= -github.com/twmb/franz-go/pkg/kmsg v1.7.0 h1:a457IbvezYfA5UkiBvyV3zj0Is3y1i8EJgqjJYoij2E= -github.com/twmb/franz-go/pkg/kmsg v1.7.0/go.mod h1:se9Mjdt0Nwzc9lnjJ0HyDtLyBnaBDAd7pCje47OhSyw= github.com/twmb/franz-go/pkg/kmsg v1.8.0 h1:lAQB9Z3aMrIP9qF9288XcFf/ccaSxEitNA1CDTEIeTA= github.com/twmb/franz-go/pkg/kmsg v1.8.0/go.mod h1:HzYEb8G3uu5XevZbtU0dVbkphaKTHk0X68N5ka4q6mU= github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= -github.com/valyala/fasthttp v1.52.0 h1:wqBQpxH71XW0e2g+Og4dzQM8pk34aFYlA1Ga8db7gU0= -github.com/valyala/fasthttp v1.52.0/go.mod h1:hf5C4QnVMkNXMspnsUlfM3WitlgYflyhHYoKol/szxQ= github.com/valyala/fasthttp v1.54.0 h1:cCL+ZZR3z3HPLMVfEYVUMtJqVaui0+gu7Lx63unHwS0= github.com/valyala/fasthttp v1.54.0/go.mod h1:6dt4/8olwq9QARP/TDuPmWyWcl4byhpvTJ4AAtcz+QM= github.com/valyala/tcplisten v1.0.0 h1:rBHj/Xf+E1tRGZyWIWwJDiRY0zc1Js+CV5DqwacVSA8= github.com/valyala/tcplisten v1.0.0/go.mod h1:T0xQ8SeCZGxckz9qRXTfG43PvQ/mcWh7FwZEA7Ioqkc= go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= -go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE= -go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU= @@ -150,19 +95,13 @@ go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8= go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.22.0 h1:g1v0xeRhjcugydODzvb3mEM9SQ0HGp9s/nh3COQ/C30= -golang.org/x/crypto v0.22.0/go.mod h1:vr6Su+7cTlO45qkww3VDJlzDn0ctJvRgYbC2NvXHt+M= golang.org/x/crypto v0.23.0 h1:dIJU/v2J8Mdglj/8rJ6UUOM3Zc9zLZxVZwwxMooUSAI= golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8= golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= -golang.org/x/mod v0.11.0 h1:bUO06HqtnRcc/7l71XBe4WcqTZ+3AH1J59zWDDwLKgU= -golang.org/x/mod v0.11.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.24.0 h1:1PcaxkF854Fu3+lvBIx5SYn9wRlBzzcnHZSiaFFAb0w= -golang.org/x/net v0.24.0/go.mod h1:2Q7sJY5mzlzWjKtYUEXSlBWCdyaioyXzRB2RtU8KVE8= golang.org/x/net v0.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac= golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -171,34 +110,20 @@ golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o= -golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y= golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= -golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/text v0.15.0 h1:h1V/4gjBv8v9cjcR6+AR5+/cIYK5N/WAgiv4xlsEtAk= golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.10.0 h1:tvDr/iQoUqNdohiYm0LmmKcBk+q86lb9EprIUFhHHGg= -golang.org/x/tools v0.10.0/go.mod h1:UJwyiVBsOA2uwvK/e5OY3GTpDUJriEd+/YlqAwLPmyM= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240412170617-26222e5d3d56 h1:zviK8GX4VlMstrK3JkexM5UHjH1VOkRebH9y3jhSBGk= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240412170617-26222e5d3d56/go.mod h1:WtryC6hu0hhx87FDGxWCDptyssuo68sk10vYjF+T9fY= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240415180920-8c6c420018be h1:LG9vZxsWGOmUKieR8wPAUR3u3MpnYFQZROPIMaXh7/A= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240415180920-8c6c420018be/go.mod h1:WtryC6hu0hhx87FDGxWCDptyssuo68sk10vYjF+T9fY= google.golang.org/genproto/googleapis/rpc v0.0.0-20240528184218-531527333157 h1:Zy9XzmMEflZ/MAaA7vNcoebnRAld7FsPW1EeBB7V0m8= google.golang.org/genproto/googleapis/rpc v0.0.0-20240528184218-531527333157/go.mod h1:EfXuqaE1J41VCDicxHzUDm+8rk+7ZdXzHV0IhO/I6s0= -google.golang.org/grpc v1.63.2 h1:MUeiw1B2maTVZthpU5xvASfTh3LDbxHd6IJ6QQVU+xM= -google.golang.org/grpc v1.63.2/go.mod h1:WAX/8DgncnokcFUldAxq7GeB5DXHDbMF+lLvDomNkRA= google.golang.org/grpc v1.64.0 h1:KH3VH9y/MgNQg1dE7b3XfVK0GsPSIzJwdF617gUSbvY= google.golang.org/grpc v1.64.0/go.mod h1:oxjF8E3FBnjp+/gVFYdWacaLDx9na1aqy9oovLpxQYg= -google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI= -google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= google.golang.org/protobuf v1.34.1 h1:9ddQBjfCyZPOHPUiPxpYESBLc+T8P3E+Vo4IbKZgFWg= google.golang.org/protobuf v1.34.1/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -214,15 +139,9 @@ gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= -penahub.gitlab.yandexcloud.net/backend/penahub_common v0.0.0-20240223054633-6cb3d5ce45b6 h1:oV+/HNX+JPoQ3/GUx08hio7d45WpY0AMGrFs7j70QlA= -penahub.gitlab.yandexcloud.net/backend/penahub_common v0.0.0-20240223054633-6cb3d5ce45b6/go.mod h1:lTmpjry+8evVkXWbEC+WMOELcFkRD1lFMc7J09mOndM= penahub.gitlab.yandexcloud.net/backend/penahub_common v0.0.0-20240527160654-bd1c2126bc6c h1:jxnyIeC2CNDNmfdFx2qnLS4Qd0v5ocYrY9X+OL9qsvc= penahub.gitlab.yandexcloud.net/backend/penahub_common v0.0.0-20240527160654-bd1c2126bc6c/go.mod h1:lTmpjry+8evVkXWbEC+WMOELcFkRD1lFMc7J09mOndM= -penahub.gitlab.yandexcloud.net/backend/quiz/common.git v0.0.0-20240416113525-c29d16cc12c1 h1:gGvPQDfeHhY1NF1CDc6VkbAHg10JTluud1Oab+GYBbg= -penahub.gitlab.yandexcloud.net/backend/quiz/common.git v0.0.0-20240416113525-c29d16cc12c1/go.mod h1:/DcyAjBh41IbomuDu5QzhL9flZW6lWO3ZAEbUXKobk0= -penahub.gitlab.yandexcloud.net/backend/quiz/common.git v0.0.0-20240416115631-f1ce4de66ba5 h1:TJEQtWmyURH/ame0X/rzlPcpc348IPj1LezjvO/qnxg= -penahub.gitlab.yandexcloud.net/backend/quiz/common.git v0.0.0-20240416115631-f1ce4de66ba5/go.mod h1:/DcyAjBh41IbomuDu5QzhL9flZW6lWO3ZAEbUXKobk0= -penahub.gitlab.yandexcloud.net/backend/quiz/common.git v0.0.0-20240416124050-a3c9b5c94966 h1:Ienp0nvaEowGBxKQQidMQnU2I9Z7ry+/KOJ2ppO8hp8= -penahub.gitlab.yandexcloud.net/backend/quiz/common.git v0.0.0-20240416124050-a3c9b5c94966/go.mod h1:/DcyAjBh41IbomuDu5QzhL9flZW6lWO3ZAEbUXKobk0= -penahub.gitlab.yandexcloud.net/backend/quiz/common.git v0.0.0-20240530133953-8649c342543a h1:zzcZseH9k6BSDI6wy8+OixQK6YciowKdeMeDlshYlFM= -penahub.gitlab.yandexcloud.net/backend/quiz/common.git v0.0.0-20240530133953-8649c342543a/go.mod h1:oRyhT55ctjqp/7ZxIzkR7OsQ7T/NLibsfrbb7Ytns64= +penahub.gitlab.yandexcloud.net/backend/quiz/common.git v0.0.0-20240603085333-e860e550daba h1:v6Gc0P8dMWRGZsz0Ed5TUq0+niN7ErtoLLUvkTMA/No= +penahub.gitlab.yandexcloud.net/backend/quiz/common.git v0.0.0-20240603085333-e860e550daba/go.mod h1:G1ZAWaQq6WW1wG9Shy57K4ZIezuhaBckQgsqQ+lhe94= +penahub.gitlab.yandexcloud.net/pena-services/customer v1.0.1-0.20240603075153-27f3ccdc57f4 h1:70kin8a95vs+bq7Iba1CpO0akYtZg22hzW0SDF1cwxg= +penahub.gitlab.yandexcloud.net/pena-services/customer v1.0.1-0.20240603075153-27f3ccdc57f4/go.mod h1:fKiHnVzo7ScG4LNQABOxe7EdAfyu6RpkpAIXBx2I19k= diff --git a/privilegewc/check.go b/privilegewc/check.go index 835f51c..622e672 100644 --- a/privilegewc/check.go +++ b/privilegewc/check.go @@ -3,32 +3,42 @@ package privilegewc import ( "context" "fmt" - "github.com/themakers/hlog" "penahub.gitlab.yandexcloud.net/backend/quiz/common.git/dal" + "penahub.gitlab.yandexcloud.net/backend/quiz/common.git/model" + "penahub.gitlab.yandexcloud.net/pena-services/customer/pkg/customer_clients" "time" ) -type CheckWorkerConfig struct { - TickerInterval time.Duration - Logger hlog.Logger - ErrChan chan<- error - PrivilegeIDs []string +type Deps struct { + PrivilegeDAL *dal.DAL + TickerInterval time.Duration + PrivilegeIDsDays []string + PrivilegeIDsCount []string + CustomerClient *customer_clients.CustomersClient } type CheckWorker struct { - config CheckWorkerConfig - privilegeDAL *dal.DAL + privilegeDAL *dal.DAL + tickerInterval time.Duration + errChan chan<- error + privilegeIDsDays []string + privilegeIDsCount []string + customerClient *customer_clients.CustomersClient } -func NewCheckWorker(config CheckWorkerConfig, privilegeDAL *dal.DAL) *CheckWorker { +func NewCheckWorker(deps Deps, errChan chan<- error) *CheckWorker { return &CheckWorker{ - config: config, - privilegeDAL: privilegeDAL, + privilegeDAL: deps.PrivilegeDAL, + tickerInterval: deps.TickerInterval, + errChan: errChan, + privilegeIDsCount: deps.PrivilegeIDsCount, + privilegeIDsDays: deps.PrivilegeIDsDays, + customerClient: deps.CustomerClient, } } func (w *CheckWorker) Start(ctx context.Context) { - ticker := time.NewTicker(w.config.TickerInterval) + ticker := time.NewTicker(w.tickerInterval) defer ticker.Stop() for { @@ -44,19 +54,43 @@ func (w *CheckWorker) Start(ctx context.Context) { } func (w *CheckWorker) deleteExpired(ctx context.Context) { - for _, id := range w.config.PrivilegeIDs { - expiredData, err := w.privilegeDAL.AccountRepo.GetExpired(ctx, id) + var toHistory []customer_clients.InsertHistoryDeps + var expiredData []model.ExpiredPrivileges + + for _, id := range w.privilegeIDsDays { + expired, err := w.privilegeDAL.AccountRepo.GetExpired(ctx, id) if err != nil { - w.config.Logger.Module("Error getting expired quizUnlimTime records") - w.config.ErrChan <- err + w.errChan <- err + } + expiredData = append(expiredData, expired...) + } + + for _, id := range w.privilegeIDsCount { + expired, err := w.privilegeDAL.AccountRepo.GetExpiredCount(ctx, id) + if err != nil { + w.errChan <- err + } + expiredData = append(expiredData, expired...) + } + + for _, data := range expiredData { + err := w.privilegeDAL.AccountRepo.DeletePrivilegeByID(ctx, data.Privilege.ID) + if err != nil { + w.errChan <- err + continue } - for _, data := range expiredData { - err := w.privilegeDAL.AccountRepo.DeletePrivilegeByID(ctx, data.ID) - if err != nil { - w.config.Logger.Module("Error deleting expired quizUnlimTime record") - w.config.ErrChan <- err - } + toHistory = append(toHistory, customer_clients.InsertHistoryDeps{ + UserID: data.UserID, + Comment: fmt.Sprintf("%s privilege has expired, it was created at %d", data.Privilege.PrivilegeID, data.Privilege.CreatedAt.Unix()), + Key: "end", + }) + } + + for _, to := range toHistory { + err := w.customerClient.InsertHistory(ctx, to) + if err != nil { + w.errChan <- err } } } diff --git a/privilegewc/consumer.go b/privilegewc/consumer.go index 4ab26fe..334cc89 100644 --- a/privilegewc/consumer.go +++ b/privilegewc/consumer.go @@ -4,7 +4,6 @@ import ( "context" "fmt" "github.com/go-redis/redis/v8" - "github.com/themakers/hlog" "github.com/twmb/franz-go/pkg/kgo" "penahub.gitlab.yandexcloud.net/backend/quiz/common.git/dal" "penahub.gitlab.yandexcloud.net/backend/quiz/common.git/model" @@ -19,7 +18,6 @@ type Config struct { KafkaTopic string ServiceKey string TickerInterval time.Duration - Logger hlog.Logger ErrChan chan<- error } From a15998dbaa1d4232ca65b1edb81575dfcb767c2c Mon Sep 17 00:00:00 2001 From: Pavel Date: Mon, 3 Jun 2024 15:37:29 +0300 Subject: [PATCH 03/12] change key --- answerwc/to_client.go | 4 ++-- privilegewc/check.go | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/answerwc/to_client.go b/answerwc/to_client.go index 47c6897..5e3a4c1 100644 --- a/answerwc/to_client.go +++ b/answerwc/to_client.go @@ -273,7 +273,7 @@ func (w *SendToClient) notificationCustomer(ctx context.Context, account model.A historyData := customer_clients.InsertHistoryDeps{ UserID: account.UserID, Comment: fmt.Sprintf("%s privilege has expired, it was created at %d", privilege.PrivilegeID, privilege.CreatedAt.Unix()), - Key: "end", + Key: "privilege_expired", } err := w.customerService.InsertHistory(ctx, historyData) @@ -287,7 +287,7 @@ func (w *SendToClient) notificationCustomer(ctx context.Context, account model.A historyData := customer_clients.InsertHistoryDeps{ UserID: account.UserID, Comment: fmt.Sprintf("%s privilege has expired, it was created at %d", privilege.PrivilegeID, privilege.CreatedAt.Unix()), - Key: "end", + Key: "privilege_expired", } err := w.customerService.InsertHistory(ctx, historyData) diff --git a/privilegewc/check.go b/privilegewc/check.go index 622e672..4440f59 100644 --- a/privilegewc/check.go +++ b/privilegewc/check.go @@ -83,7 +83,7 @@ func (w *CheckWorker) deleteExpired(ctx context.Context) { toHistory = append(toHistory, customer_clients.InsertHistoryDeps{ UserID: data.UserID, Comment: fmt.Sprintf("%s privilege has expired, it was created at %d", data.Privilege.PrivilegeID, data.Privilege.CreatedAt.Unix()), - Key: "end", + Key: "privilege_expired", }) } From 199742010cbb540e5ea66bc899409a4ff5ad56df Mon Sep 17 00:00:00 2001 From: Pavel Date: Mon, 3 Jun 2024 16:23:27 +0300 Subject: [PATCH 04/12] add quizManual to check worker --- app/app.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/app.go b/app/app.go index 6883863..9c4cc1d 100644 --- a/app/app.go +++ b/app/app.go @@ -165,7 +165,7 @@ func New(ctx context.Context, opts interface{}, ver appInit.Version) (appInit.Co checkWorker := privilegewc.NewCheckWorker(privilegewc.Deps{ PrivilegeIDsDays: []string{"quizUnlimTime", "squizHideBadge"}, - PrivilegeIDsCount: []string{"quizCnt"}, + PrivilegeIDsCount: []string{"quizCnt", "quizManual"}, TickerInterval: time.Minute, PrivilegeDAL: pgdal, CustomerClient: customerClient, From d09b7b0823478a2341dccaca5fa406879f95d4d4 Mon Sep 17 00:00:00 2001 From: Pavel Date: Mon, 10 Jun 2024 17:01:40 +0300 Subject: [PATCH 05/12] add LeadSender interface --- answerwc/to_client.go | 33 ++++++++++++++++++++++++++------- app/app.go | 7 ++++++- initialize/senders.go | 39 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 71 insertions(+), 8 deletions(-) create mode 100644 initialize/senders.go diff --git a/answerwc/to_client.go b/answerwc/to_client.go index d8a7bd2..9994ab4 100644 --- a/answerwc/to_client.go +++ b/answerwc/to_client.go @@ -10,6 +10,7 @@ import ( "penahub.gitlab.yandexcloud.net/backend/quiz/common.git/model" "penahub.gitlab.yandexcloud.net/backend/quiz/worker.git/clients/customer" "penahub.gitlab.yandexcloud.net/backend/quiz/worker.git/clients/mailclient" + "penahub.gitlab.yandexcloud.net/backend/quiz/worker.git/initialize" "penahub.gitlab.yandexcloud.net/backend/quiz/worker.git/wctools" "time" @@ -20,7 +21,7 @@ import ( type DepsSendToClient struct { Redis *redis.Client Dal *dal.DAL - MailClient *mailclient.Client + LeadsSenders []initialize.LeadSender CustomerService customer.CustomerServiceClient } @@ -334,9 +335,18 @@ func (w *SendToClient) ProcessMessageToClient(quizConfig model.QuizConfig, quest fmt.Println("SUBJECT", theme, account.Email) - err := w.deps.MailClient.SendMailWithAttachment(account.Email, theme, toClientTemplate, data, nil) - if err != nil { - return err + leadData := initialize.LeadData{ + To: account.Email, + Subject: theme, + Template: toClientTemplate, + TemplateData: data, + } + + for _, sender := range w.deps.LeadsSenders { + err := sender.SendLead(leadData) + if err != nil { + w.reportError(err, fmt.Sprintf("Error sending lead through %s", sender.Name())) + } } return nil @@ -358,9 +368,18 @@ func (w *SendToClient) processReminderToClient(email string, quizConfig model.Qu fmt.Println("PRTC", data, email, quizConfig) - err := w.deps.MailClient.SendMailWithAttachment(email, quizConfig.Mailing.Theme, reminderTemplate, data, nil) - if err != nil { - return err + leadData := initialize.LeadData{ + To: email, + Subject: quizConfig.Mailing.Theme, + Template: reminderTemplate, + TemplateData: data, + } + + for _, sender := range w.deps.LeadsSenders { + err := sender.SendLead(leadData) + if err != nil { + w.reportError(err, fmt.Sprintf("Error sending lead through %s", sender.Name())) + } } return nil diff --git a/app/app.go b/app/app.go index 6517e59..a92ca79 100644 --- a/app/app.go +++ b/app/app.go @@ -15,6 +15,7 @@ import ( "penahub.gitlab.yandexcloud.net/backend/quiz/worker.git/answerwc" "penahub.gitlab.yandexcloud.net/backend/quiz/worker.git/clients/customer" "penahub.gitlab.yandexcloud.net/backend/quiz/worker.git/clients/mailclient" + "penahub.gitlab.yandexcloud.net/backend/quiz/worker.git/initialize" "penahub.gitlab.yandexcloud.net/backend/quiz/worker.git/privilegewc" "penahub.gitlab.yandexcloud.net/backend/quiz/worker.git/workers/shortstat" "penahub.gitlab.yandexcloud.net/backend/quiz/worker.git/workers/timeout" @@ -137,6 +138,10 @@ func New(ctx context.Context, opts interface{}, ver appInit.Version) (appInit.Co mailClient := mailclient.NewClient(smtpData) + mailSender := initialize.NewMailLeadSender(mailClient) + + leadsSenders := []initialize.LeadSender{mailSender} + customerServiceConn, err := grpc.Dial(options.CustomerServiceAddress, grpc.WithInsecure()) if err != nil { return nil, err @@ -186,7 +191,7 @@ func New(ctx context.Context, opts interface{}, ver appInit.Version) (appInit.Co toClientWorker := answerwc.NewSendToClient(answerwc.DepsSendToClient{ Redis: redisClient, Dal: pgdal, - MailClient: mailClient, + LeadsSenders: leadsSenders, CustomerService: customerServiceClient, }, logger, errChan) diff --git a/initialize/senders.go b/initialize/senders.go new file mode 100644 index 0000000..46fb196 --- /dev/null +++ b/initialize/senders.go @@ -0,0 +1,39 @@ +package initialize + +import ( + _ "embed" + "penahub.gitlab.yandexcloud.net/backend/quiz/worker.git/clients/mailclient" +) + +type LeadSender interface { + SendLead(leadData LeadData) error + Name() string +} + +type LeadData struct { + To interface{} + Subject string + Template string + TemplateData mailclient.EmailTemplateData +} + +type MailLeadSender struct { + client *mailclient.Client +} + +func NewMailLeadSender(client *mailclient.Client) *MailLeadSender { + return &MailLeadSender{client: client} +} + +func (m *MailLeadSender) SendLead(data LeadData) error { + err := m.client.SendMailWithAttachment(data.To.(string), data.Subject, data.Template, data.TemplateData, nil) + if err != nil { + return err + } + + return nil +} + +func (m *MailLeadSender) Name() string { + return "MailLeadSender" +} From 2572747d95d98ddd5dca084d18106d89bcdf6edd Mon Sep 17 00:00:00 2001 From: Pavel Date: Mon, 10 Jun 2024 17:05:45 +0300 Subject: [PATCH 06/12] add LeadSender interface --- answerwc/to_client.go | 6 +++--- app/app.go | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/answerwc/to_client.go b/answerwc/to_client.go index 9994ab4..56137b9 100644 --- a/answerwc/to_client.go +++ b/answerwc/to_client.go @@ -21,7 +21,7 @@ import ( type DepsSendToClient struct { Redis *redis.Client Dal *dal.DAL - LeadsSenders []initialize.LeadSender + LeadSenders []initialize.LeadSender CustomerService customer.CustomerServiceClient } @@ -342,7 +342,7 @@ func (w *SendToClient) ProcessMessageToClient(quizConfig model.QuizConfig, quest TemplateData: data, } - for _, sender := range w.deps.LeadsSenders { + for _, sender := range w.deps.LeadSenders { err := sender.SendLead(leadData) if err != nil { w.reportError(err, fmt.Sprintf("Error sending lead through %s", sender.Name())) @@ -375,7 +375,7 @@ func (w *SendToClient) processReminderToClient(email string, quizConfig model.Qu TemplateData: data, } - for _, sender := range w.deps.LeadsSenders { + for _, sender := range w.deps.LeadSenders { err := sender.SendLead(leadData) if err != nil { w.reportError(err, fmt.Sprintf("Error sending lead through %s", sender.Name())) diff --git a/app/app.go b/app/app.go index a92ca79..e186b72 100644 --- a/app/app.go +++ b/app/app.go @@ -140,7 +140,7 @@ func New(ctx context.Context, opts interface{}, ver appInit.Version) (appInit.Co mailSender := initialize.NewMailLeadSender(mailClient) - leadsSenders := []initialize.LeadSender{mailSender} + leadSenders := []initialize.LeadSender{mailSender} customerServiceConn, err := grpc.Dial(options.CustomerServiceAddress, grpc.WithInsecure()) if err != nil { @@ -191,7 +191,7 @@ func New(ctx context.Context, opts interface{}, ver appInit.Version) (appInit.Co toClientWorker := answerwc.NewSendToClient(answerwc.DepsSendToClient{ Redis: redisClient, Dal: pgdal, - LeadsSenders: leadsSenders, + LeadSenders: leadSenders, CustomerService: customerServiceClient, }, logger, errChan) From 8958504671445de994a6e2404f7aae258602adcf Mon Sep 17 00:00:00 2001 From: Pavel Date: Mon, 10 Jun 2024 17:11:24 +0300 Subject: [PATCH 07/12] add LeadSender interface --- app/app.go | 2 -- 1 file changed, 2 deletions(-) diff --git a/app/app.go b/app/app.go index e186b72..9095544 100644 --- a/app/app.go +++ b/app/app.go @@ -137,9 +137,7 @@ func New(ctx context.Context, opts interface{}, ver appInit.Version) (appInit.Co } mailClient := mailclient.NewClient(smtpData) - mailSender := initialize.NewMailLeadSender(mailClient) - leadSenders := []initialize.LeadSender{mailSender} customerServiceConn, err := grpc.Dial(options.CustomerServiceAddress, grpc.WithInsecure()) From 9afab5d7a6668b7463c90e705e182719ab01eee5 Mon Sep 17 00:00:00 2001 From: Pavel Date: Tue, 11 Jun 2024 19:56:32 +0300 Subject: [PATCH 08/12] prepare for merge --- answerwc/respondent.go | 6 +- answerwc/to_client.go | 13 ++-- app/app.go | 21 +++--- clients/mailclient/client.go | 129 ---------------------------------- clients/mailclient/message.go | 104 --------------------------- clients/mailclient/utils.go | 63 ----------------- go.mod | 2 +- go.sum | 2 + initialize/senders.go | 39 ---------- senders/senders.go | 87 +++++++++++++++++++++++ 10 files changed, 109 insertions(+), 357 deletions(-) delete mode 100644 clients/mailclient/client.go delete mode 100644 clients/mailclient/message.go delete mode 100644 clients/mailclient/utils.go delete mode 100644 initialize/senders.go create mode 100644 senders/senders.go diff --git a/answerwc/respondent.go b/answerwc/respondent.go index 06790f3..4e70f18 100644 --- a/answerwc/respondent.go +++ b/answerwc/respondent.go @@ -8,7 +8,7 @@ import ( "github.com/themakers/hlog" "penahub.gitlab.yandexcloud.net/backend/quiz/common.git/dal" "penahub.gitlab.yandexcloud.net/backend/quiz/common.git/model" - "penahub.gitlab.yandexcloud.net/backend/quiz/worker.git/clients/mailclient" + "penahub.gitlab.yandexcloud.net/backend/quiz/worker.git/senders" "penahub.gitlab.yandexcloud.net/backend/quiz/worker.git/wctools" "time" ) @@ -16,7 +16,7 @@ import ( type DepsRespWorker struct { Redis *redis.Client Dal *dal.DAL - MailClient *mailclient.Client + MailClient *senders.MailLeadSender } type RespWorker struct { @@ -132,7 +132,7 @@ func (w *RespWorker) processMessageToSMTP(quizConfig model.QuizConfig, questions theme := quizConfig.Mailing.Theme quizConfig.Mailing.Theme = quizConfig.Mailing.Reply - data := mailclient.EmailTemplateData{ + data := senders.TemplateData{ QuizConfig: quizConfig.Mailing, AnswerContent: answerContent, AllAnswers: allAnswers, diff --git a/answerwc/to_client.go b/answerwc/to_client.go index 56137b9..4258bc9 100644 --- a/answerwc/to_client.go +++ b/answerwc/to_client.go @@ -9,8 +9,7 @@ import ( "penahub.gitlab.yandexcloud.net/backend/quiz/common.git/dal" "penahub.gitlab.yandexcloud.net/backend/quiz/common.git/model" "penahub.gitlab.yandexcloud.net/backend/quiz/worker.git/clients/customer" - "penahub.gitlab.yandexcloud.net/backend/quiz/worker.git/clients/mailclient" - "penahub.gitlab.yandexcloud.net/backend/quiz/worker.git/initialize" + "penahub.gitlab.yandexcloud.net/backend/quiz/worker.git/senders" "penahub.gitlab.yandexcloud.net/backend/quiz/worker.git/wctools" "time" @@ -21,7 +20,7 @@ import ( type DepsSendToClient struct { Redis *redis.Client Dal *dal.DAL - LeadSenders []initialize.LeadSender + LeadSenders []senders.LeadSender CustomerService customer.CustomerServiceClient } @@ -311,7 +310,7 @@ func (w *SendToClient) ProcessMessageToClient(quizConfig model.QuizConfig, quest theme := quizConfig.Mailing.Theme quizConfig.Mailing.Theme = quizConfig.Mailing.Reply - data := mailclient.EmailTemplateData{ + data := senders.TemplateData{ QuizConfig: quizConfig.Mailing, AnswerContent: answerContent, AllAnswers: allAnswers, @@ -335,7 +334,7 @@ func (w *SendToClient) ProcessMessageToClient(quizConfig model.QuizConfig, quest fmt.Println("SUBJECT", theme, account.Email) - leadData := initialize.LeadData{ + leadData := senders.LeadData{ To: account.Email, Subject: theme, Template: toClientTemplate, @@ -354,7 +353,7 @@ func (w *SendToClient) ProcessMessageToClient(quizConfig model.QuizConfig, quest func (w *SendToClient) processReminderToClient(email string, quizConfig model.QuizConfig) error { - data := mailclient.EmailTemplateData{ + data := senders.TemplateData{ QuizConfig: model.ResultInfo{ When: quizConfig.Mailing.When, Theme: quizConfig.Mailing.Theme, @@ -368,7 +367,7 @@ func (w *SendToClient) processReminderToClient(email string, quizConfig model.Qu fmt.Println("PRTC", data, email, quizConfig) - leadData := initialize.LeadData{ + leadData := senders.LeadData{ To: email, Subject: quizConfig.Mailing.Theme, Template: reminderTemplate, diff --git a/app/app.go b/app/app.go index 9095544..4a4074a 100644 --- a/app/app.go +++ b/app/app.go @@ -10,13 +10,13 @@ import ( "github.com/themakers/hlog" "go.uber.org/zap" "google.golang.org/grpc" + "penahub.gitlab.yandexcloud.net/backend/quiz/common.git/clients" "penahub.gitlab.yandexcloud.net/backend/quiz/common.git/dal" "penahub.gitlab.yandexcloud.net/backend/quiz/common.git/model" "penahub.gitlab.yandexcloud.net/backend/quiz/worker.git/answerwc" "penahub.gitlab.yandexcloud.net/backend/quiz/worker.git/clients/customer" - "penahub.gitlab.yandexcloud.net/backend/quiz/worker.git/clients/mailclient" - "penahub.gitlab.yandexcloud.net/backend/quiz/worker.git/initialize" "penahub.gitlab.yandexcloud.net/backend/quiz/worker.git/privilegewc" + "penahub.gitlab.yandexcloud.net/backend/quiz/worker.git/senders" "penahub.gitlab.yandexcloud.net/backend/quiz/worker.git/workers/shortstat" "penahub.gitlab.yandexcloud.net/backend/quiz/worker.git/workers/timeout" @@ -128,17 +128,16 @@ func New(ctx context.Context, opts interface{}, ver appInit.Version) (appInit.Co DB: int(options.RedisDB), }) - smtpData := mailclient.ClientDeps{ - Host: options.SmtpHost, - Port: options.SmtpPort, - Sender: options.SmtpSender, + mailClent := clients.NewSmtpClient(clients.Deps{ + SmtpHost: options.SmtpHost, + SmtpPort: options.SmtpPort, + SmtpSender: options.SmtpSender, ApiKey: options.SmtpApiKey, SmtpApiUrl: options.SmtpApiUrl, - } + }) - mailClient := mailclient.NewClient(smtpData) - mailSender := initialize.NewMailLeadSender(mailClient) - leadSenders := []initialize.LeadSender{mailSender} + mailSender := senders.NewMailLeadSender(mailClent) + leadSenders := []senders.LeadSender{mailSender} customerServiceConn, err := grpc.Dial(options.CustomerServiceAddress, grpc.WithInsecure()) if err != nil { @@ -196,7 +195,7 @@ func New(ctx context.Context, opts interface{}, ver appInit.Version) (appInit.Co toRespWorker := answerwc.NewRespWorker(answerwc.DepsRespWorker{ Redis: redisClient, Dal: pgdal, - MailClient: mailClient, + MailClient: mailSender, }, logger, errChan) go toClientWorker.Start(ctx) diff --git a/clients/mailclient/client.go b/clients/mailclient/client.go deleted file mode 100644 index 73bf38a..0000000 --- a/clients/mailclient/client.go +++ /dev/null @@ -1,129 +0,0 @@ -package mailclient - -import ( - "bytes" - _ "embed" - "fmt" - "github.com/gofiber/fiber/v2" - "mime/multipart" - "penahub.gitlab.yandexcloud.net/backend/quiz/common.git/model" - "strings" - "text/template" -) - -type ClientDeps struct { - Host string - Port string - Sender string - ApiKey string - SmtpApiUrl string - FiberClient *fiber.Client -} - -type Client struct { - deps ClientDeps -} - -type EmailTemplateData struct { - QuizConfig model.ResultInfo - AnswerContent model.ResultContent - AllAnswers []model.ResultAnswer - QuestionsMap map[uint64]string - AnswerTime string -} - -func NewClient(deps ClientDeps) *Client { - if deps.FiberClient == nil { - deps.FiberClient = fiber.AcquireClient() - } - return &Client{ - deps: deps, - } -} - -func (c *Client) SendMailWithAttachment(recipient, subject string, emailTemplate string, data EmailTemplateData, attachments []Attachment) error { - text, err := generateTextFromTemplate(data, emailTemplate) - if err != nil { - return err - } - - msg := &Message{ - From: c.deps.Sender, - To: []string{recipient}, - Subject: subject, - Body: text, - Attachments: attachments, - } - - return c.Send(msg) -} - -func (c *Client) Send(msg *Message) error { - form := new(bytes.Buffer) - writer := multipart.NewWriter(form) - defer writer.Close() - - fields := map[string]string{ - "from": msg.From, - "to": strings.Join(msg.To, ","), - "subject": msg.Subject, - "html": msg.Body, - } - for key, value := range fields { - if err := writer.WriteField(key, value); err != nil { - return err - } - } - - // пока не используется так как Attachments из воркеров = nil, нужен ли будет потом - for _, attachment := range msg.Attachments { - part, err := writer.CreateFormFile("attachments", attachment.Name) - if err != nil { - return err - } - _, err = part.Write(attachment.Data) - if err != nil { - return err - } - } - - if err := writer.Close(); err != nil { - return err - } - - agent := c.deps.FiberClient.Post(c.deps.SmtpApiUrl).Body(form.Bytes()).ContentType(writer.FormDataContentType()) - if c.deps.ApiKey != "" { - agent.Set("Authorization", c.deps.ApiKey) - } - - statusCode, body, errs := agent.Bytes() - if errs != nil { - return errs[0] - } - - if statusCode != fiber.StatusOK { - return fmt.Errorf("SMTP service returned error: %d, Response body: %s", statusCode, body) - } - - return nil -} - -func generateTextFromTemplate(data EmailTemplateData, tpl string) (string, error) { - t, err := template.New("email").Parse(tpl) - if err != nil { - return "", fmt.Errorf("error parsing template: %w", err) - } - - var text bytes.Buffer - if err := t.Execute(&text, EmailTemplateData{ - QuizConfig: data.QuizConfig, - AnswerContent: data.AnswerContent, - AllAnswers: data.AllAnswers, - QuestionsMap: data.QuestionsMap, - AnswerTime: data.AnswerTime, - }); err != nil { - return "", fmt.Errorf("error executing template: %w", err) - } - - return text.String(), nil -} diff --git a/clients/mailclient/message.go b/clients/mailclient/message.go deleted file mode 100644 index 06261ca..0000000 --- a/clients/mailclient/message.go +++ /dev/null @@ -1,104 +0,0 @@ -package mailclient - -import ( - "bytes" - "encoding/base64" - "fmt" - "net/http" - "os" - "path/filepath" - "strings" -) - -type Message struct { - To []string - From string - Subject string - Body string - Attachments []Attachment -} - -type Attachment struct { - Name string - Data []byte -} - -func NewMessage(subject, body string) *Message { - if subject == "" { - subject = "Вам пришла заявка с PenaQuiz" - } - return &Message{Subject: subject, Body: body, Attachments: []Attachment{}} -} - -func (m *Message) AttachFile(src string) error { - data, err := os.ReadFile(src) - if err != nil { - return err - } - - _, filename := filepath.Split(src) - m.Attachments = append(m.Attachments, Attachment{Name: filename, Data: data}) - - return nil -} - -func (m *Message) AttachBytesFile(filename string, data []byte) { - m.Attachments = append(m.Attachments, Attachment{Name: filename, Data: data}) -} - -func (m *Message) ToBytes() []byte { - buf := bytes.NewBuffer(nil) - - buf.WriteString("MIME-Version: 1.0\r\n") - fmt.Fprintf(buf, "From: %s\r\n", m.From) - fmt.Fprintf(buf, "Subject: %s\r\n", m.Subject) - fmt.Fprintf(buf, "To: %s\r\n", strings.Join(m.To, ",")) - - boundary := randomBoundary() - - if len(m.Attachments) > 0 { - buf.WriteString("Content-Type: multipart/mixed;\r\n") - - fmt.Fprintf(buf, " boundary=\"%s\"\r\n", boundary) - - fmt.Fprintf(buf, "\r\n--%s", boundary) - for _, attachment := range m.Attachments { - buf.WriteString("\r\n") - switch strings.Split(attachment.Name, ".")[1] { - case "htmlmsg": - - buf.WriteString("Content-Type: text/html; charset=\"utf-8\"\r\n") - buf.WriteString("Content-Transfer-Encoding: base64\r\n") - case "docx": - - buf.WriteString("Content-Type: application/vnd.openxmlformats-officedocument.wordprocessingml.document\r\n") - buf.WriteString("Content-Transfer-Encoding: base64\r\n") - fmt.Fprintf(buf, "Content-Disposition: attachment; filename=\"%s\"\r\n", attachment.Name) - default: - fmt.Fprintf(buf, "Content-Type: %s\r\n", http.DetectContentType(attachment.Data)) - buf.WriteString("Content-Transfer-Encoding: base64\r\n") - fmt.Fprintf(buf, "Content-Disposition: attachment; filename=\"%s\"\r\n", attachment.Name) - } - - buf.WriteString("\r\n") - - b := make([]byte, base64.StdEncoding.EncodedLen(len(attachment.Data))) - base64.StdEncoding.Encode(b, attachment.Data) - - writer := NewLineWriter(buf, 76) - _, err := writer.Write(b) - if err != nil { - fmt.Println("mailclient-client err:", err) - } - - fmt.Fprintf(buf, "\r\n\r\n--%s", boundary) - } - - buf.WriteString("--") - } else { - buf.WriteString("Content-Type: text/plain; charset=utf-8\r\n") - buf.WriteString(m.Body) - } - - return buf.Bytes() -} diff --git a/clients/mailclient/utils.go b/clients/mailclient/utils.go deleted file mode 100644 index 1f01408..0000000 --- a/clients/mailclient/utils.go +++ /dev/null @@ -1,63 +0,0 @@ -package mailclient - -import ( - "crypto/rand" - "fmt" - "io" -) - -type LineWriter struct { - w io.Writer - length int -} - -func NewLineWriter(w io.Writer, length int) *LineWriter { - return &LineWriter{ - w: w, - length: length, - } -} - -func (r *LineWriter) Write(p []byte) (n int, err error) { - for i := 0; i < len(p); i += r.length { - end := i + r.length - - if end > len(p) { - end = len(p) - 1 - } - - var chunk []byte - chunk = append(chunk, p[i:end]...) - - if len(p) >= end+r.length { - chunk = append(chunk, []byte("\r\n")...) - } - - addN, err := r.w.Write(chunk) - if err != nil { - return n, err - } - n += addN - } - - return n, nil -} - -func (r *LineWriter) WriteString(s string) (n int, err error) { - p := []byte(s) - return r.Write(p) -} - -func (r *LineWriter) WriteFormatString(format string, a ...any) (n int, err error) { - p := []byte(fmt.Sprintf(format, a...)) - return r.Write(p) -} - -func randomBoundary() string { - var buf [30]byte - _, err := io.ReadFull(rand.Reader, buf[:]) - if err != nil { - panic(err) - } - return fmt.Sprintf("%x", buf[:]) -} diff --git a/go.mod b/go.mod index ee372d0..400cea4 100644 --- a/go.mod +++ b/go.mod @@ -13,7 +13,7 @@ require ( go.uber.org/zap v1.27.0 google.golang.org/grpc v1.64.0 google.golang.org/protobuf v1.34.1 - penahub.gitlab.yandexcloud.net/backend/quiz/common.git v0.0.0-20240530133953-8649c342543a + penahub.gitlab.yandexcloud.net/backend/quiz/common.git v0.0.0-20240611163623-9a8f348b2cc4 ) require ( diff --git a/go.sum b/go.sum index a72c538..428b4bf 100644 --- a/go.sum +++ b/go.sum @@ -226,3 +226,5 @@ penahub.gitlab.yandexcloud.net/backend/quiz/common.git v0.0.0-20240416124050-a3c penahub.gitlab.yandexcloud.net/backend/quiz/common.git v0.0.0-20240416124050-a3c9b5c94966/go.mod h1:/DcyAjBh41IbomuDu5QzhL9flZW6lWO3ZAEbUXKobk0= penahub.gitlab.yandexcloud.net/backend/quiz/common.git v0.0.0-20240530133953-8649c342543a h1:zzcZseH9k6BSDI6wy8+OixQK6YciowKdeMeDlshYlFM= penahub.gitlab.yandexcloud.net/backend/quiz/common.git v0.0.0-20240530133953-8649c342543a/go.mod h1:oRyhT55ctjqp/7ZxIzkR7OsQ7T/NLibsfrbb7Ytns64= +penahub.gitlab.yandexcloud.net/backend/quiz/common.git v0.0.0-20240611163623-9a8f348b2cc4 h1:cac/1YTF+7xZCINwrsvqPn0VAOja0X30xDK39NXjuXY= +penahub.gitlab.yandexcloud.net/backend/quiz/common.git v0.0.0-20240611163623-9a8f348b2cc4/go.mod h1:n66zm88Dh12+idyfqh0vU5nd9BZYxM6Pv0XYnmy0398= diff --git a/initialize/senders.go b/initialize/senders.go deleted file mode 100644 index 46fb196..0000000 --- a/initialize/senders.go +++ /dev/null @@ -1,39 +0,0 @@ -package initialize - -import ( - _ "embed" - "penahub.gitlab.yandexcloud.net/backend/quiz/worker.git/clients/mailclient" -) - -type LeadSender interface { - SendLead(leadData LeadData) error - Name() string -} - -type LeadData struct { - To interface{} - Subject string - Template string - TemplateData mailclient.EmailTemplateData -} - -type MailLeadSender struct { - client *mailclient.Client -} - -func NewMailLeadSender(client *mailclient.Client) *MailLeadSender { - return &MailLeadSender{client: client} -} - -func (m *MailLeadSender) SendLead(data LeadData) error { - err := m.client.SendMailWithAttachment(data.To.(string), data.Subject, data.Template, data.TemplateData, nil) - if err != nil { - return err - } - - return nil -} - -func (m *MailLeadSender) Name() string { - return "MailLeadSender" -} diff --git a/senders/senders.go b/senders/senders.go new file mode 100644 index 0000000..5df1527 --- /dev/null +++ b/senders/senders.go @@ -0,0 +1,87 @@ +package senders + +import ( + "bytes" + _ "embed" + "fmt" + "html/template" + "penahub.gitlab.yandexcloud.net/backend/quiz/common.git/clients" + "penahub.gitlab.yandexcloud.net/backend/quiz/common.git/model" +) + +type LeadSender interface { + SendLead(leadData LeadData) error + Name() string +} + +type LeadData struct { + To interface{} + Subject string + Template string + TemplateData TemplateData +} + +type TemplateData struct { + QuizConfig model.ResultInfo + AnswerContent model.ResultContent + AllAnswers []model.ResultAnswer + QuestionsMap map[uint64]string + AnswerTime string +} + +type MailLeadSender struct { + client *clients.SmtpClient +} + +func NewMailLeadSender(client *clients.SmtpClient) *MailLeadSender { + return &MailLeadSender{client: client} +} + +func (m *MailLeadSender) SendLead(data LeadData) error { + err := m.SendMailWithAttachment(data.To.(string), data.Subject, data.Template, data.TemplateData, nil) + if err != nil { + return err + } + + return nil +} + +func (m *MailLeadSender) Name() string { + return "mail" +} + +func (m *MailLeadSender) SendMailWithAttachment(recipient, subject string, emailTemplate string, data TemplateData, attachments []clients.Attachment) error { + text, err := m.generateTextFromTemplate(data, emailTemplate) + if err != nil { + return err + } + + msg := clients.Message{ + To: recipient, + Subject: subject, + HtmlBody: text, + Attachments: attachments, + } + + return m.client.MailSender(msg) +} + +func (m *MailLeadSender) generateTextFromTemplate(data TemplateData, tpl string) (string, error) { + t, err := template.New("email").Parse(tpl) + if err != nil { + return "", fmt.Errorf("error parsing template: %w", err) + } + + var text bytes.Buffer + if err := t.Execute(&text, TemplateData{ + QuizConfig: data.QuizConfig, + AnswerContent: data.AnswerContent, + AllAnswers: data.AllAnswers, + QuestionsMap: data.QuestionsMap, + AnswerTime: data.AnswerTime, + }); err != nil { + return "", fmt.Errorf("error executing template: %w", err) + } + + return text.String(), nil +} From b9e15fba4ee41ea4002f41d8bf15ef60cf6f2d94 Mon Sep 17 00:00:00 2001 From: Pavel Date: Tue, 11 Jun 2024 20:17:22 +0300 Subject: [PATCH 09/12] add todo for another senders --- senders/senders.go | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/senders/senders.go b/senders/senders.go index 5df1527..028e7df 100644 --- a/senders/senders.go +++ b/senders/senders.go @@ -85,3 +85,28 @@ func (m *MailLeadSender) generateTextFromTemplate(data TemplateData, tpl string) return text.String(), nil } + +type TgSender struct { +} + +func (tg *TgSender) SendLead(data LeadData) error { + fmt.Println("TODO") + + return nil +} + +func (tg *TgSender) Name() string { + return "telegram" +} + +type WhatsAppSender struct { +} + +func (wa *WhatsAppSender) SendLead(data LeadData) error { + fmt.Println("TODO") + return nil +} + +func (wa *WhatsAppSender) Name() string { + return "whatsapp" +} From 95b54eda56e16054c82044a61a5c5291b99db0de Mon Sep 17 00:00:00 2001 From: Pavel Date: Tue, 11 Jun 2024 21:50:35 +0300 Subject: [PATCH 10/12] added tg sender, tg tmpl and separate file senders to 4 files for simply code style --- answerwc/to_client.go | 1 - app/app.go | 8 +- deployments/test/docker-compose.yaml | 42 +- go.mod | 6 + go.sum | 13 + senders/common.go | 58 +++ senders/mail_sender.go | 40 ++ senders/senders.go | 112 ------ senders/template/client_mail.tmpl | 537 ++++++++++++++++++++++++++ senders/template/client_tg.tmpl | 26 ++ senders/template/client_whatsapp.tmpl | 0 senders/tg_sender.go | 45 +++ senders/whatsapp_sender.go | 19 + tests/tg_sender_test.go | 47 +++ 14 files changed, 819 insertions(+), 135 deletions(-) create mode 100644 senders/common.go create mode 100644 senders/mail_sender.go delete mode 100644 senders/senders.go create mode 100644 senders/template/client_mail.tmpl create mode 100644 senders/template/client_tg.tmpl create mode 100644 senders/template/client_whatsapp.tmpl create mode 100644 senders/tg_sender.go create mode 100644 senders/whatsapp_sender.go create mode 100644 tests/tg_sender_test.go diff --git a/answerwc/to_client.go b/answerwc/to_client.go index 01a8c3e..5f0ed5f 100644 --- a/answerwc/to_client.go +++ b/answerwc/to_client.go @@ -332,7 +332,6 @@ func (w *SendToClient) ProcessMessageToClient(quizConfig model.QuizConfig, quest //todo //To: account.Email, Subject: theme, - Template: toClientTemplate, TemplateData: data, } diff --git a/app/app.go b/app/app.go index 4c61fcc..8335935 100644 --- a/app/app.go +++ b/app/app.go @@ -68,6 +68,7 @@ type Options struct { SmtpApiKey string `env:"SMTP_API_KEY" default:"P0YsjUB137upXrr1NiJefHmXVKW1hmBWlpev"` SmtpApiUrl string `env:"SMTP_API_URL" default:"https://api.smtp.bz/v1/smtp/send"` CustomerServiceAddress string `env:"CUSTOMER_SERVICE_ADDRESS" default:"localhost:9001"` + TgToken string `env:"TG_TOKEN"` } func New(ctx context.Context, opts interface{}, ver appInit.Version) (appInit.CommonApp, error) { @@ -131,8 +132,13 @@ func New(ctx context.Context, opts interface{}, ver appInit.Version) (appInit.Co SmtpApiUrl: options.SmtpApiUrl, }) + tgSender, err := senders.NewTgSender(options.TgToken) + if err != nil { + fmt.Println(err) + return nil, err + } mailSender := senders.NewMailLeadSender(mailClent) - leadSenders := []senders.LeadSender{mailSender} + leadSenders := []senders.LeadSender{mailSender, tgSender} customerClient := customer_clients.NewCustomersClient(customer_clients.CustomersClientDeps{ Logger: zapLogger, diff --git a/deployments/test/docker-compose.yaml b/deployments/test/docker-compose.yaml index b66713c..2761eac 100644 --- a/deployments/test/docker-compose.yaml +++ b/deployments/test/docker-compose.yaml @@ -7,7 +7,7 @@ services: POSTGRES_USER: squiz POSTGRES_DB: squiz volumes: - - test-postgres:/var/lib/postgresql/data + - tests-postgres:/var/lib/postgresql/data ports: - 35432:5432 networks: @@ -19,62 +19,62 @@ services: retries: 10 # need update! -# test-pena-auth-service: +# tests-pena-auth-service: # image: penahub.gitlab.yandexcloud.net:5050/pena-services/pena-auth-service:staging.872 -# container_name: test-pena-auth-service +# container_name: tests-pena-auth-service # init: true -# env_file: auth.env.test +# env_file: auth.env.tests # healthcheck: -# test: wget -T1 --spider http://localhost:8000/user +# tests: wget -T1 --spider http://localhost:8000/user # interval: 2s # timeout: 2s # retries: 5 # environment: -# - DB_HOST=test-pena-auth-db +# - DB_HOST=tests-pena-auth-db # - DB_PORT=27017 # - ENVIRONMENT=staging # - HTTP_HOST=0.0.0.0 # - HTTP_PORT=8000 -# - DB_USERNAME=test -# - DB_PASSWORD=test +# - DB_USERNAME=tests +# - DB_PASSWORD=tests # - DB_NAME=admin # - DB_AUTH=admin # # ports: # # - 8000:8000 # depends_on: -# - test-pena-auth-db +# - tests-pena-auth-db # # - pena-auth-migration # networks: # - penatest # -# test-pena-auth-db: -# container_name: test-pena-auth-db +# tests-pena-auth-db: +# container_name: tests-pena-auth-db # init: true # image: "mongo:6.0.3" # command: mongod --quiet --logpath /dev/null # volumes: -# - test-mongodb:/data/db -# - test-mongoconfdb:/data/configdb +# - tests-mongodb:/data/db +# - tests-mongoconfdb:/data/configdb # environment: -# MONGO_INITDB_ROOT_USERNAME: test -# MONGO_INITDB_ROOT_PASSWORD: test +# MONGO_INITDB_ROOT_USERNAME: tests +# MONGO_INITDB_ROOT_PASSWORD: tests # # ports: # # - 27017:27017 # networks: # - penatest test-minio: - container_name: test-minio + container_name: tests-minio init: true image: quay.io/minio/minio volumes: - - test-minio:/data + - tests-minio:/data command: [ "minio", "--quiet", "server", "/data" ] networks: - penatest test-squiz: - container_name: test-squiz + container_name: tests-squiz init: true build: context: ../.. @@ -82,12 +82,12 @@ services: depends_on: test-postgres: condition: service_healthy -# test-pena-auth-service: +# tests-pena-auth-service: # condition: service_healthy # volumes: # - ./../..:/app:ro - # command: [ "go", "test", "./tests", "-run", "TestFoo" ] - command: [ "go", "test", "-parallel", "1", "./tests" ] + # command: [ "go", "tests", "./tests", "-run", "TestFoo" ] + command: [ "go", "tests", "-parallel", "1", "./tests" ] networks: - penatest diff --git a/go.mod b/go.mod index 41749ac..1cb6d0b 100644 --- a/go.mod +++ b/go.mod @@ -9,9 +9,11 @@ require ( github.com/golang/protobuf v1.5.4 github.com/minio/minio-go/v7 v7.0.70 github.com/skeris/appInit v1.0.2 + github.com/stretchr/testify v1.8.4 github.com/themakers/hlog v0.0.0-20191205140925-235e0e4baddf github.com/twmb/franz-go v1.17.0 go.uber.org/zap v1.27.0 + gopkg.in/tucnak/telebot.v2 v2.5.0 penahub.gitlab.yandexcloud.net/backend/quiz/common.git v0.0.0-20240611163623-9a8f348b2cc4 penahub.gitlab.yandexcloud.net/pena-services/customer v1.0.1-0.20240608222239-5c78187bf014 ) @@ -19,6 +21,7 @@ require ( require ( github.com/andybalholm/brotli v1.1.0 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect + github.com/davecgh/go-spew v1.1.1 // indirect github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect github.com/dustin/go-humanize v1.0.1 // indirect github.com/goccy/go-json v0.10.3 // indirect @@ -32,6 +35,8 @@ require ( github.com/mattn/go-runewidth v0.0.15 // indirect github.com/minio/md5-simd v1.1.2 // indirect github.com/pierrec/lz4/v4 v4.1.21 // indirect + github.com/pkg/errors v0.9.1 // indirect + github.com/pmezard/go-difflib v1.0.0 // indirect github.com/rivo/uniseg v0.4.7 // indirect github.com/rs/xid v1.5.0 // indirect github.com/twmb/franz-go/pkg/kmsg v1.8.0 // indirect @@ -47,5 +52,6 @@ require ( google.golang.org/grpc v1.64.0 // indirect google.golang.org/protobuf v1.34.1 // indirect gopkg.in/ini.v1 v1.67.0 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect penahub.gitlab.yandexcloud.net/backend/penahub_common v0.0.0-20240607202348-efe5f2bf3e8c // indirect ) diff --git a/go.sum b/go.sum index 6b534fe..71846a6 100644 --- a/go.sum +++ b/go.sum @@ -32,8 +32,12 @@ github.com/klauspost/cpuid/v2 v2.0.1/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa02 github.com/klauspost/cpuid/v2 v2.2.7 h1:ZWSB3igEs+d0qvnxR/ZBzXVmxkgt8DdzP6m9pfuVLDM= github.com/klauspost/cpuid/v2 v2.2.7/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw= github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= @@ -56,12 +60,16 @@ github.com/onsi/gomega v1.18.1/go.mod h1:0q+aL8jAiMXy9hbwj2mr5GziHiwhAIQpFmmtT5h github.com/pierrec/lz4/v4 v4.1.21 h1:yOVMLb6qSIDP67pl/5F7RepeKYu/VmTyEXvuMI5d9mQ= github.com/pierrec/lz4/v4 v4.1.21/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ= github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= +github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= github.com/rs/xid v1.5.0 h1:mKX4bl4iPYJtEIxp6CYiUuLQ/8DYMoz0PUdtGgMFRVc= github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= github.com/skeris/appInit v1.0.2 h1:Hr4KbXYd6kolTVq4cXGqDpgnpmaauiOiKizA1+Ep4KQ= @@ -69,6 +77,7 @@ github.com/skeris/appInit v1.0.2/go.mod h1:4ElEeXWVGzU3dlYq/eMWJ/U5hd+LKisc1z3+y github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/themakers/hlog v0.0.0-20191205140925-235e0e4baddf h1:TJJm6KcBssmbWzplF5lzixXl1RBAi/ViPs1GaSOkhwo= @@ -128,11 +137,15 @@ google.golang.org/protobuf v1.34.1 h1:9ddQBjfCyZPOHPUiPxpYESBLc+T8P3E+Vo4IbKZgFW google.golang.org/protobuf v1.34.1/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/tucnak/telebot.v2 v2.5.0 h1:i+NynLo443Vp+Zn3Gv9JBjh3Z/PaiKAQwcnhNI7y6Po= +gopkg.in/tucnak/telebot.v2 v2.5.0/go.mod h1:BgaIIx50PSRS9pG59JH+geT82cfvoJU/IaI5TJdN3v8= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= diff --git a/senders/common.go b/senders/common.go new file mode 100644 index 0000000..aba80b8 --- /dev/null +++ b/senders/common.go @@ -0,0 +1,58 @@ +package senders + +import ( + "bytes" + _ "embed" + "fmt" + "html/template" + "penahub.gitlab.yandexcloud.net/backend/quiz/common.git/model" +) + +//go:embed template/client_mail.tmpl +var toClientMailTemplate string + +//go:embed template/client_tg.tmpl +var toClientTgTemplate string + +//go:embed template/client_whatsapp.tmpl +var toClientWhatsAppTemplate string + +type LeadSender interface { + SendLead(leadData LeadData) error + Name() string +} + +type LeadData struct { + To interface{} + Subject string + Template string + TemplateData TemplateData +} + +type TemplateData struct { + QuizConfig model.ResultInfo + AnswerContent model.ResultContent + AllAnswers []model.ResultAnswer + QuestionsMap map[uint64]string + AnswerTime string +} + +func generateTextFromTemplate(data TemplateData, tpl string) (string, error) { + t, err := template.New("email").Parse(tpl) + if err != nil { + return "", fmt.Errorf("error parsing template: %w", err) + } + + var text bytes.Buffer + if err := t.Execute(&text, TemplateData{ + QuizConfig: data.QuizConfig, + AnswerContent: data.AnswerContent, + AllAnswers: data.AllAnswers, + QuestionsMap: data.QuestionsMap, + AnswerTime: data.AnswerTime, + }); err != nil { + return "", fmt.Errorf("error executing template: %w", err) + } + + return text.String(), nil +} diff --git a/senders/mail_sender.go b/senders/mail_sender.go new file mode 100644 index 0000000..65d8961 --- /dev/null +++ b/senders/mail_sender.go @@ -0,0 +1,40 @@ +package senders + +import "penahub.gitlab.yandexcloud.net/backend/quiz/common.git/clients" + +type MailLeadSender struct { + client *clients.SmtpClient +} + +func NewMailLeadSender(client *clients.SmtpClient) *MailLeadSender { + return &MailLeadSender{client: client} +} + +func (m *MailLeadSender) SendLead(data LeadData) error { + err := m.SendMailWithAttachment(data.To.(string), data.Subject, toClientMailTemplate, data.TemplateData, nil) + if err != nil { + return err + } + + return nil +} + +func (m *MailLeadSender) SendMailWithAttachment(recipient, subject string, emailTemplate string, data TemplateData, attachments []clients.Attachment) error { + text, err := generateTextFromTemplate(data, emailTemplate) + if err != nil { + return err + } + + msg := clients.Message{ + To: recipient, + Subject: subject, + HtmlBody: text, + Attachments: attachments, + } + + return m.client.MailSender(msg) +} + +func (m *MailLeadSender) Name() string { + return "mail" +} diff --git a/senders/senders.go b/senders/senders.go deleted file mode 100644 index 028e7df..0000000 --- a/senders/senders.go +++ /dev/null @@ -1,112 +0,0 @@ -package senders - -import ( - "bytes" - _ "embed" - "fmt" - "html/template" - "penahub.gitlab.yandexcloud.net/backend/quiz/common.git/clients" - "penahub.gitlab.yandexcloud.net/backend/quiz/common.git/model" -) - -type LeadSender interface { - SendLead(leadData LeadData) error - Name() string -} - -type LeadData struct { - To interface{} - Subject string - Template string - TemplateData TemplateData -} - -type TemplateData struct { - QuizConfig model.ResultInfo - AnswerContent model.ResultContent - AllAnswers []model.ResultAnswer - QuestionsMap map[uint64]string - AnswerTime string -} - -type MailLeadSender struct { - client *clients.SmtpClient -} - -func NewMailLeadSender(client *clients.SmtpClient) *MailLeadSender { - return &MailLeadSender{client: client} -} - -func (m *MailLeadSender) SendLead(data LeadData) error { - err := m.SendMailWithAttachment(data.To.(string), data.Subject, data.Template, data.TemplateData, nil) - if err != nil { - return err - } - - return nil -} - -func (m *MailLeadSender) Name() string { - return "mail" -} - -func (m *MailLeadSender) SendMailWithAttachment(recipient, subject string, emailTemplate string, data TemplateData, attachments []clients.Attachment) error { - text, err := m.generateTextFromTemplate(data, emailTemplate) - if err != nil { - return err - } - - msg := clients.Message{ - To: recipient, - Subject: subject, - HtmlBody: text, - Attachments: attachments, - } - - return m.client.MailSender(msg) -} - -func (m *MailLeadSender) generateTextFromTemplate(data TemplateData, tpl string) (string, error) { - t, err := template.New("email").Parse(tpl) - if err != nil { - return "", fmt.Errorf("error parsing template: %w", err) - } - - var text bytes.Buffer - if err := t.Execute(&text, TemplateData{ - QuizConfig: data.QuizConfig, - AnswerContent: data.AnswerContent, - AllAnswers: data.AllAnswers, - QuestionsMap: data.QuestionsMap, - AnswerTime: data.AnswerTime, - }); err != nil { - return "", fmt.Errorf("error executing template: %w", err) - } - - return text.String(), nil -} - -type TgSender struct { -} - -func (tg *TgSender) SendLead(data LeadData) error { - fmt.Println("TODO") - - return nil -} - -func (tg *TgSender) Name() string { - return "telegram" -} - -type WhatsAppSender struct { -} - -func (wa *WhatsAppSender) SendLead(data LeadData) error { - fmt.Println("TODO") - return nil -} - -func (wa *WhatsAppSender) Name() string { - return "whatsapp" -} diff --git a/senders/template/client_mail.tmpl b/senders/template/client_mail.tmpl new file mode 100644 index 0000000..071e014 --- /dev/null +++ b/senders/template/client_mail.tmpl @@ -0,0 +1,537 @@ + + + + + + Document + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {{ range .AllAnswers }} + {{ if index $.QuestionsMap .AnswerID }} + + + + {{ end }} + {{end}} + + + + +
+ + +

Квиз для вашего бизнеса

+
+

+ Поступила новая заявка с квиза “{{.QuizConfig.Theme}}”! +

+
+

+ Время заявки: {{ .AnswerTime }} +

+
+ + Посмотреть в личном кабинете + +
+

+ Контакты +

+
+ + + + + + {{ if .AnswerContent.Email }} + + + + + {{ end }} + {{ if .AnswerContent.Phone }} + + + + + {{ end }} + + {{ if .AnswerContent.Telegram }} + + + + + {{ end }} + {{ if .AnswerContent.Wechat }} + + + + + {{ end }} + {{ if .AnswerContent.Viber }} + + + + + {{ end }} + {{ if .AnswerContent.Vk }} + + + + + {{ end }} + {{ if .AnswerContent.Skype }} + + + + + {{ end }} + {{ if .AnswerContent.Whatsup }} + + + + + {{ end }} + {{ if .AnswerContent.Messenger }} + + + + + {{ end }} + {{ if .AnswerContent.Address }} + + + + + {{ end }} + {{ range $key, $value := .AnswerContent.Custom }} + + + + + + {{ end }} +
+ Имя + +

+ {{ .AnswerContent.Name}} +

+
+ Email + +

+ {{ .AnswerContent.Email }} +

+
+ Телефон + + {{ .AnswerContent.Phone }} +
+ Telegram + + {{ .AnswerContent.Telegram }} +
+ Wechat + + {{ .AnswerContent.Wechat }} +
+ Viber + + {{ .AnswerContent.Viber }} +
+ Vk + + {{ .AnswerContent.Vk }} +
+ Skype + + {{ .AnswerContent.Skype }} +
+ Whatsup + + {{ .AnswerContent.Whatsup }} +
+ Messenger + + {{ .AnswerContent.Messenger }} +
+ Адрес + + {{ .AnswerContent.Address }} +
+ {{ $key }} + + {{ $value }} +
+
+

+ Ответы +

+
+ + + + + + + + +
+

+ {{ index $.QuestionsMap .AnswerID }} +

+
+ {{ .Content }} +
+
+ + quiz.pena.digital + +
+ + diff --git a/senders/template/client_tg.tmpl b/senders/template/client_tg.tmpl new file mode 100644 index 0000000..5c9a4fa --- /dev/null +++ b/senders/template/client_tg.tmpl @@ -0,0 +1,26 @@ +*Квиз для вашего бизнеса* + +*Поступила новая заявка с квиза "{{.QuizConfig.Theme}}"!* +Время заявки: {{ .AnswerTime }} + +Имя: {{ .AnswerContent.Name }} +{{ if .AnswerContent.Email }}Email: {{ .AnswerContent.Email }}{{ end }} +{{ if .AnswerContent.Phone }}Телефон: {{ .AnswerContent.Phone }}{{ end }} +{{ if .AnswerContent.Telegram }}Telegram: {{ .AnswerContent.Telegram }}{{ end }} +{{ if .AnswerContent.Wechat }}Wechat: {{ .AnswerContent.Wechat }}{{ end }} +{{ if .AnswerContent.Viber }}Viber: {{ .AnswerContent.Viber }}{{ end }} +{{ if .AnswerContent.Vk }}Vk: {{ .AnswerContent.Vk }}{{ end }} +{{ if .AnswerContent.Skype }}Skype: {{ .AnswerContent.Skype }}{{ end }} +{{ if .AnswerContent.Whatsup }}Whatsup: {{ .AnswerContent.Whatsup }}{{ end }} +{{ if .AnswerContent.Messenger }}Messenger: {{ .AnswerContent.Messenger }}{{ end }} +{{ if .AnswerContent.Address }}Адрес: {{ .AnswerContent.Address }}{{ end }} +{{ range $key, $value := .AnswerContent.Custom }}{{ $key }}: {{ $value }}{{ end }} + +*Ответы:* +{{ range .AllAnswers }} + {{ if index $.QuestionsMap .AnswerID }} + *{{ index $.QuestionsMap .AnswerID }}* + {{ .Content }} + {{ end }} +{{ end }} + diff --git a/senders/template/client_whatsapp.tmpl b/senders/template/client_whatsapp.tmpl new file mode 100644 index 0000000..e69de29 diff --git a/senders/tg_sender.go b/senders/tg_sender.go new file mode 100644 index 0000000..e7855e7 --- /dev/null +++ b/senders/tg_sender.go @@ -0,0 +1,45 @@ +package senders + +import ( + "fmt" + "gopkg.in/tucnak/telebot.v2" + "time" +) + +type TgSender struct { + bot *telebot.Bot +} + +func NewTgSender(tgToken string) (*TgSender, error) { + bot, err := telebot.NewBot(telebot.Settings{ + Token: tgToken, + Poller: &telebot.LongPoller{Timeout: 10 * time.Second}, + }) + + if err != nil { + return nil, fmt.Errorf("error creating Telegram bot: %w", err) + } + + return &TgSender{bot: bot}, nil +} + +func (tg *TgSender) SendLead(data LeadData) error { + text, err := generateTextFromTemplate(data.TemplateData, toClientTgTemplate) + if err != nil { + return err + } + + chat := data.To.(int64) + _, err = tg.bot.Send(telebot.ChatID(chat), text, &telebot.SendOptions{ + ParseMode: telebot.ModeHTML, + }) + if err != nil { + return fmt.Errorf("error sending Telegram message: %w", err) + } + + return nil +} + +func (tg *TgSender) Name() string { + return "telegram" +} diff --git a/senders/whatsapp_sender.go b/senders/whatsapp_sender.go new file mode 100644 index 0000000..6ae9eaf --- /dev/null +++ b/senders/whatsapp_sender.go @@ -0,0 +1,19 @@ +package senders + +import "fmt" + +type WhatsAppSender struct { +} + +func NewWhatsAppSender() *WhatsAppSender { + return &WhatsAppSender{} +} + +func (wa *WhatsAppSender) SendLead(data LeadData) error { + fmt.Println("TODO") + return nil +} + +func (wa *WhatsAppSender) Name() string { + return "whatsapp" +} diff --git a/tests/tg_sender_test.go b/tests/tg_sender_test.go new file mode 100644 index 0000000..5471e24 --- /dev/null +++ b/tests/tg_sender_test.go @@ -0,0 +1,47 @@ +package tests + +import ( + "github.com/stretchr/testify/assert" + "penahub.gitlab.yandexcloud.net/backend/quiz/common.git/model" + "penahub.gitlab.yandexcloud.net/backend/quiz/worker.git/senders" + "testing" + "time" +) + +func Test_Tg_Sender(t *testing.T) { + tg_Sender, err := senders.NewTgSender("6712573453:AAFbioUuXf0Te73MUCqa0_h09qEQ1iQREas") + assert.NoError(t, err) + err = tg_Sender.SendLead(senders.LeadData{ + To: int64(542073142), + Subject: "test_TG_Sender", + TemplateData: senders.TemplateData{ + QuizConfig: model.ResultInfo{ + Theme: "Taemplste Quiz", + }, + AnswerContent: model.ResultContent{ + Name: "Pasha", + Phone: "+723456789", + Email: "test@example.com", + //Adress: "chtoto tam", + Telegram: "@test", + Wechat: "test_wechat", + Viber: "+723456789", + Vk: "test_vk", + Skype: "test_skype", + Whatsup: "test_whatsup", + Messenger: "test_messenger", + }, + AllAnswers: []model.ResultAnswer{ + {AnswerID: 1, QuestionID: 1, Content: "Pasha", CreatedAt: time.Now()}, + {AnswerID: 2, QuestionID: 2, Content: "From a friend", CreatedAt: time.Now()}, + }, + QuestionsMap: map[uint64]string{ + 1: "How did you hear about us?", + 2: "How did you hear about us?", + }, + AnswerTime: time.Now().Format("Monday, 2 January 2006 г., 15:04 UTC-07:00"), + }, + }) + + assert.NoError(t, err) +} From 47c43abd7d8a4b2803d6eae007c7b9f6a9888a0b Mon Sep 17 00:00:00 2001 From: Pavel Date: Tue, 11 Jun 2024 21:53:12 +0300 Subject: [PATCH 11/12] returned after goland linter --- deployments/test/docker-compose.yaml | 44 ++++++++++++++-------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/deployments/test/docker-compose.yaml b/deployments/test/docker-compose.yaml index 2761eac..0f498a0 100644 --- a/deployments/test/docker-compose.yaml +++ b/deployments/test/docker-compose.yaml @@ -7,7 +7,7 @@ services: POSTGRES_USER: squiz POSTGRES_DB: squiz volumes: - - tests-postgres:/var/lib/postgresql/data + - test-postgres:/var/lib/postgresql/data ports: - 35432:5432 networks: @@ -19,75 +19,75 @@ services: retries: 10 # need update! -# tests-pena-auth-service: +# test-pena-auth-service: # image: penahub.gitlab.yandexcloud.net:5050/pena-services/pena-auth-service:staging.872 -# container_name: tests-pena-auth-service +# container_name: test-pena-auth-service # init: true -# env_file: auth.env.tests +# env_file: auth.env.test # healthcheck: -# tests: wget -T1 --spider http://localhost:8000/user +# test: wget -T1 --spider http://localhost:8000/user # interval: 2s # timeout: 2s # retries: 5 # environment: -# - DB_HOST=tests-pena-auth-db +# - DB_HOST=test-pena-auth-db # - DB_PORT=27017 # - ENVIRONMENT=staging # - HTTP_HOST=0.0.0.0 # - HTTP_PORT=8000 -# - DB_USERNAME=tests -# - DB_PASSWORD=tests +# - DB_USERNAME=test +# - DB_PASSWORD=test # - DB_NAME=admin # - DB_AUTH=admin # # ports: # # - 8000:8000 # depends_on: -# - tests-pena-auth-db +# - test-pena-auth-db # # - pena-auth-migration # networks: # - penatest # -# tests-pena-auth-db: -# container_name: tests-pena-auth-db +# test-pena-auth-db: +# container_name: test-pena-auth-db # init: true # image: "mongo:6.0.3" # command: mongod --quiet --logpath /dev/null # volumes: -# - tests-mongodb:/data/db -# - tests-mongoconfdb:/data/configdb +# - test-mongodb:/data/db +# - test-mongoconfdb:/data/configdb # environment: -# MONGO_INITDB_ROOT_USERNAME: tests -# MONGO_INITDB_ROOT_PASSWORD: tests +# MONGO_INITDB_ROOT_USERNAME: test +# MONGO_INITDB_ROOT_PASSWORD: test # # ports: # # - 27017:27017 # networks: # - penatest test-minio: - container_name: tests-minio + container_name: test-minio init: true image: quay.io/minio/minio volumes: - - tests-minio:/data + - test-minio:/data command: [ "minio", "--quiet", "server", "/data" ] networks: - penatest test-squiz: - container_name: tests-squiz + container_name: test-squiz init: true build: context: ../.. - dockerfile: TestsDockerfile + dockerfile: testDockerfile depends_on: test-postgres: condition: service_healthy -# tests-pena-auth-service: +# test-pena-auth-service: # condition: service_healthy # volumes: # - ./../..:/app:ro - # command: [ "go", "tests", "./tests", "-run", "TestFoo" ] - command: [ "go", "tests", "-parallel", "1", "./tests" ] + # command: [ "go", "test", "./test", "-run", "TestFoo" ] + command: [ "go", "test", "-parallel", "1", "./test" ] networks: - penatest From 4d2abfd8f5b0c56fcdaef8c4e6f73e711ce34681 Mon Sep 17 00:00:00 2001 From: Pavel Date: Wed, 12 Jun 2024 21:04:16 +0300 Subject: [PATCH 12/12] add base logic with leadTarget --- answerwc/to_client.go | 155 +++++++++++++++++++++++++++++------------- go.mod | 2 +- go.sum | 4 +- 3 files changed, 110 insertions(+), 51 deletions(-) diff --git a/answerwc/to_client.go b/answerwc/to_client.go index 5f0ed5f..20d29cd 100644 --- a/answerwc/to_client.go +++ b/answerwc/to_client.go @@ -2,6 +2,7 @@ package answerwc import ( "context" + "database/sql" _ "embed" "encoding/json" "fmt" @@ -155,7 +156,16 @@ func (w *SendToClient) processPendingAnswer(ctx context.Context) { return } - result, err := w.processAnswerWithPrivileges(ctx, quiz.Name, quizConfig, questionsMap, privileges, account, sortedallAnswers, answerContent, answer.CreatedAt) + result, err := w.processAnswerWithPrivileges(ctx, ProcessAnsWithPriv{ + quiz: quiz, + quizConfig: quizConfig, + questionsMap: questionsMap, + privileges: privileges, + account: account, + allAnswers: sortedallAnswers, + answerContent: answerContent, + answerTime: answer.CreatedAt, + }) fmt.Println("ANS8", err, result, privileges) if err != nil { w.reportError(err, "Error process answer with privileges") @@ -172,26 +182,51 @@ func (w *SendToClient) processPendingAnswer(ctx context.Context) { } } -func (w *SendToClient) processAnswerWithPrivileges(ctx context.Context, quizName string, quizConfig model.QuizConfig, - questionsMap map[uint64]string, privileges []model.ShortPrivilege, account model.Account, allAnswers []model.ResultAnswer, - answerContent model.ResultContent, answerTime time.Time) (bool, error) { +type ProcessAnsWithPriv struct { + quiz *model.Quiz + quizConfig model.QuizConfig + questionsMap map[uint64]string + privileges []model.ShortPrivilege + account model.Account + allAnswers []model.ResultAnswer + answerContent model.ResultContent + answerTime time.Time +} - err := w.notificationCustomer(ctx, account, privileges) +func (w *SendToClient) processAnswerWithPrivileges(ctx context.Context, data ProcessAnsWithPriv) (bool, error) { + + err := w.notificationCustomer(ctx, data.account, data.privileges) fmt.Println("ANS81", err) if err != nil { return false, err } - if wctools.HasUnlimitedPrivilege(privileges) { - err := w.ProcessMessageToClient(quizConfig, questionsMap, account, allAnswers, answerContent, answerTime) + if wctools.HasUnlimitedPrivilege(data.privileges) { + err := w.ProcessMessageToClient(ctx, DepsProcessMsgToClient{ + quizConfig: data.quizConfig, + questionsMap: data.questionsMap, + account: data.account, + allAnswers: data.allAnswers, + answerContent: data.answerContent, + answerTime: data.answerTime, + quiz: data.quiz, + }) if err != nil { return false, err } return true, nil } - privilege := wctools.HasQuizCntPrivilege(privileges) + privilege := wctools.HasQuizCntPrivilege(data.privileges) if privilege != nil { - err := w.ProcessMessageToClient(quizConfig, questionsMap, account, allAnswers, answerContent, answerTime) + err := w.ProcessMessageToClient(ctx, DepsProcessMsgToClient{ + quizConfig: data.quizConfig, + questionsMap: data.questionsMap, + account: data.account, + allAnswers: data.allAnswers, + answerContent: data.answerContent, + answerTime: data.answerTime, + quiz: data.quiz, + }) fmt.Println("PMC", err) if err != nil { return true, err @@ -205,13 +240,12 @@ func (w *SendToClient) processAnswerWithPrivileges(ctx context.Context, quizName return true, nil } else { w.checkAndSendTaskReminders(sendTaskRemindersDeps{ - // todo - //email: account.Email, - theme: quizName, + account: data.account, + theme: data.quiz.Name, config: model.QuizConfig{ Mailing: model.ResultInfo{ When: "email", - Theme: fmt.Sprintf("не удалось отправить заявку по опросу\"%s\"", quizName), + Theme: fmt.Sprintf("не удалось отправить заявку по опросу\"%s\"", data.quiz.Name), Reply: "noreply@pena.digital", ReplName: "Reminder", }, @@ -253,12 +287,13 @@ func (w *SendToClient) recordPendingTasks(ctx context.Context, Email string, qui } type sendTaskRemindersDeps struct { - email, theme string - config model.QuizConfig + account model.Account + theme string + config model.QuizConfig } -func (w *SendToClient) checkAndSendTaskReminders(deps sendTaskRemindersDeps) { - err := w.processReminderToClient(deps.email, deps.config) +func (w *SendToClient) checkAndSendTaskReminders(data sendTaskRemindersDeps) { + err := w.processReminderToClient(data.account, data.config) fmt.Println("PMC1", err) if err != nil { w.reportError(err, "Error sending tasks reminder email") @@ -299,59 +334,83 @@ func (w *SendToClient) notificationCustomer(ctx context.Context, account model.A return nil } -// сделал экспортируемым для теста -func (w *SendToClient) ProcessMessageToClient(quizConfig model.QuizConfig, questionsMap map[uint64]string, account model.Account, allAnswers []model.ResultAnswer, answerContent model.ResultContent, answerTime time.Time) error { - theme := quizConfig.Mailing.Theme - quizConfig.Mailing.Theme = quizConfig.Mailing.Reply +type DepsProcessMsgToClient struct { + quizConfig model.QuizConfig + questionsMap map[uint64]string + account model.Account + allAnswers []model.ResultAnswer + answerContent model.ResultContent + answerTime time.Time + quiz *model.Quiz +} - data := senders.TemplateData{ - QuizConfig: quizConfig.Mailing, - AnswerContent: answerContent, - AllAnswers: allAnswers, - QuestionsMap: questionsMap, +// сделал экспортируемым для теста +func (w *SendToClient) ProcessMessageToClient(ctx context.Context, constructData DepsProcessMsgToClient) error { + leadTargetForAll, err := w.dal.AccountRepo.GetLeadTarget(ctx, constructData.quiz.AccountId, 0) + if err != nil { + return err + } + leadTargetForQuiz, err := w.dal.AccountRepo.GetLeadTarget(ctx, constructData.quiz.AccountId, int32(constructData.quiz.Id)) + if err != nil && err != sql.ErrNoRows { + return err + } + if len(leadTargetForQuiz) > 0 { + leadTargetForAll = append(leadTargetForAll, leadTargetForQuiz...) } - dayOfWeek := wctools.DaysOfWeek[answerTime.Format("Monday")] - monthOfYear := wctools.MonthsOfYear[answerTime.Format("January")] + theme := constructData.quizConfig.Mailing.Theme + constructData.quizConfig.Mailing.Theme = constructData.quizConfig.Mailing.Reply + + data := senders.TemplateData{ + QuizConfig: constructData.quizConfig.Mailing, + AnswerContent: constructData.answerContent, + AllAnswers: constructData.allAnswers, + QuestionsMap: constructData.questionsMap, + } + + dayOfWeek := wctools.DaysOfWeek[constructData.answerTime.Format("Monday")] + monthOfYear := wctools.MonthsOfYear[constructData.answerTime.Format("January")] formattedTime := fmt.Sprintf("%s, %d %s %d г., %02d:%02d (UTC%s)", dayOfWeek, - answerTime.Day(), + constructData.answerTime.Day(), monthOfYear, - answerTime.Year(), - answerTime.Hour(), - answerTime.Minute(), - answerTime.Format("-07:00"), + constructData.answerTime.Year(), + constructData.answerTime.Hour(), + constructData.answerTime.Minute(), + constructData.answerTime.Format("-07:00"), ) data.AnswerTime = formattedTime - //fmt.Println("SUBJECT", theme, account.Email) - - leadData := senders.LeadData{ - //todo - //To: account.Email, - Subject: theme, - TemplateData: data, + mapLeadTarget := make(map[string][]senders.LeadData) // ключ имя сендера, модель отправки + for _, leadTarget := range leadTargetForAll { + mapLeadTarget[string(leadTarget.Type)] = append(mapLeadTarget[string(leadTarget.Type)], senders.LeadData{ + To: leadTarget.Target, + Subject: theme, + TemplateData: data, + }) } for _, sender := range w.leadSenders { - err := sender.SendLead(leadData) - if err != nil { - w.reportError(err, fmt.Sprintf("Error sending lead through %s", sender.Name())) + for _, sendData := range mapLeadTarget[sender.Name()] { + err := sender.SendLead(sendData) + if err != nil { + w.reportError(err, fmt.Sprintf("Error sending lead through %s", sender.Name())) + } } } return nil } -func (w *SendToClient) processReminderToClient(email string, quizConfig model.QuizConfig) error { - +// todo email +func (w *SendToClient) processReminderToClient(account model.Account, quizConfig model.QuizConfig) error { data := senders.TemplateData{ QuizConfig: model.ResultInfo{ When: quizConfig.Mailing.When, Theme: quizConfig.Mailing.Theme, - Reply: email, + Reply: "email", ReplName: quizConfig.Mailing.ReplName, }, AnswerContent: model.ResultContent{}, @@ -359,10 +418,10 @@ func (w *SendToClient) processReminderToClient(email string, quizConfig model.Qu QuestionsMap: nil, } - fmt.Println("PRTC", data, email, quizConfig) + //fmt.Println("PRTC", data, email, quizConfig) leadData := senders.LeadData{ - To: email, + To: "email", Subject: quizConfig.Mailing.Theme, Template: reminderTemplate, TemplateData: data, diff --git a/go.mod b/go.mod index 1cb6d0b..ef4a177 100644 --- a/go.mod +++ b/go.mod @@ -14,7 +14,7 @@ require ( github.com/twmb/franz-go v1.17.0 go.uber.org/zap v1.27.0 gopkg.in/tucnak/telebot.v2 v2.5.0 - penahub.gitlab.yandexcloud.net/backend/quiz/common.git v0.0.0-20240611163623-9a8f348b2cc4 + penahub.gitlab.yandexcloud.net/backend/quiz/common.git v0.0.0-20240612083524-11882ffe22cf penahub.gitlab.yandexcloud.net/pena-services/customer v1.0.1-0.20240608222239-5c78187bf014 ) diff --git a/go.sum b/go.sum index 71846a6..d0addeb 100644 --- a/go.sum +++ b/go.sum @@ -154,7 +154,7 @@ gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= penahub.gitlab.yandexcloud.net/backend/penahub_common v0.0.0-20240607202348-efe5f2bf3e8c h1:CWb4UcuNXhd1KTNOmy2U0TJO4+Qxgxrj5cwkyFqbgrk= penahub.gitlab.yandexcloud.net/backend/penahub_common v0.0.0-20240607202348-efe5f2bf3e8c/go.mod h1:+bPxq2wfW5S1gd+83vZYmHm33AE7nEBfznWS8AM1TKE= -penahub.gitlab.yandexcloud.net/backend/quiz/common.git v0.0.0-20240611163623-9a8f348b2cc4 h1:cac/1YTF+7xZCINwrsvqPn0VAOja0X30xDK39NXjuXY= -penahub.gitlab.yandexcloud.net/backend/quiz/common.git v0.0.0-20240611163623-9a8f348b2cc4/go.mod h1:n66zm88Dh12+idyfqh0vU5nd9BZYxM6Pv0XYnmy0398= +penahub.gitlab.yandexcloud.net/backend/quiz/common.git v0.0.0-20240612083524-11882ffe22cf h1:cTmv0YZE1B+ofsWfHYEiNxzToWKMy12rVW3cPOrtp30= +penahub.gitlab.yandexcloud.net/backend/quiz/common.git v0.0.0-20240612083524-11882ffe22cf/go.mod h1:n66zm88Dh12+idyfqh0vU5nd9BZYxM6Pv0XYnmy0398= penahub.gitlab.yandexcloud.net/pena-services/customer v1.0.1-0.20240608222239-5c78187bf014 h1:ziG55nv824SGFZ02AfagKQC5D4ODirGXnpVPQTL6YFA= penahub.gitlab.yandexcloud.net/pena-services/customer v1.0.1-0.20240608222239-5c78187bf014/go.mod h1:hIMkN5Xe01vAVaX22QWsGD87Oi93IfX1hJGqxy0oJbE=