package handlers import ( "encoding/json" "net/http" "otaupdate/services" "strings" "github.com/fiskerinc/cloud-services/pkg/grpc/sms" "github.com/pkg/errors" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" "google.golang.org/protobuf/encoding/protojson" "github.com/fiskerinc/cloud-services/pkg/loggerdataresp" ) // HandleSMSSend godoc // @Summary Send SMS // @Description Send SMS using SMS service // @Accept json // @Produce json // @Param Authorization header string false "Bearer " // @Param Api-Key header string false "" // @Param config body sms.SendSMSRequest true "SMS data" // @Success 200 {object} sms.SMSDetailsResponse // @Failure 400 {object} common.JSONError "Bad request" // @Failure 401 {object} common.JSONError "Unauthorized" // @Failure 408 {object} common.JSONError "Request timeout" // @Failure 503 {object} common.JSONError "Service unavailable" // @Router /sms [post] func HandleSMSSend(w http.ResponseWriter, r *http.Request) { var smsReq sms.SendSMSRequest if err := json.NewDecoder(r.Body).Decode(&smsReq); err != nil { loggerdataresp.BadDataErrorResp(w, err, http.StatusBadRequest) return } res, err := services.GetSMSClient().HandleSMSSend(r.Context(), &smsReq) if err != nil { s, ok := status.FromError(err) if !ok { loggerdataresp.BadDataErrorResp(w, err, http.StatusInternalServerError) return } errMsg, httpCode := grpcErrToHttpErr(s) loggerdataresp.BadDataErrorResp(w, errors.New(errMsg), httpCode) return } w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusOK) tow, err := protojson.Marshal(res) if loggerdataresp.BadDataErrorResp(w, err, http.StatusBadRequest) { return } w.Write(tow) return } func grpcErrToHttpErr(s *status.Status) (string, int) { switch s.Code() { case codes.Canceled: return s.Message(), 499 case codes.Unknown: return s.Message(), http.StatusInternalServerError case codes.InvalidArgument: return s.Message(), http.StatusBadRequest case codes.DeadlineExceeded: return s.Message(), http.StatusRequestTimeout case codes.NotFound: return s.Message(), http.StatusNotFound case codes.AlreadyExists: return s.Message(), http.StatusConflict case codes.PermissionDenied: return s.Message(), http.StatusForbidden case codes.ResourceExhausted: return s.Message(), http.StatusTooManyRequests case codes.FailedPrecondition: return s.Message(), http.StatusPreconditionFailed case codes.Aborted: return s.Message(), http.StatusConflict case codes.OutOfRange: return s.Message(), http.StatusBadRequest case codes.Unimplemented: return s.Message(), http.StatusNotImplemented case codes.Unavailable: return s.Message(), http.StatusServiceUnavailable case codes.DataLoss: return s.Message(), http.StatusInternalServerError case codes.Unauthenticated: return s.Message(), http.StatusUnauthorized case codes.Internal: if strings.Contains(s.Message(), "bad message status") { return s.Message(), http.StatusExpectationFailed } return s.Message(), http.StatusInternalServerError default: return s.Message(), http.StatusInternalServerError } }