diff --git a/s3/s3.go b/s3/s3.go
index 2c5eab9fb3d1589be018717d8d695cc4c81c6e36..ba607b1954159fb147b59abaf46d5e178b303135 100644
--- a/s3/s3.go
+++ b/s3/s3.go
@@ -28,11 +28,14 @@ type S3UploadResponse struct {
 }
 
 type S3UploadSettings struct {
-	MimeType              MIMEType
-	RetrieveSignedUrl     bool
-	ExpiryDuration        *time.Duration
-	AddContentDisposition bool
-	FileName              string
+	MimeType                  MIMEType
+	RetrieveSignedUrl         bool
+	ExpiryDuration            *time.Duration // Used to set expiry datetime of download links. NB: does not affect deletion of object from S3 bucket.
+	AddContentDisposition     bool
+	FileName                  string
+	GenerateFileNameFromParts bool   // Whether the file extension needs to be specified. If true, supply FilePrefix and FileExt.
+	FilePrefix                string // Required when GenerateFileNameFromParts is true
+	FileExt                   string // Required when GenerateFileNameFromParts is true
 }
 
 type MIMEType string
@@ -142,6 +145,71 @@ func (s SessionWithHelpers) UploadWithSettings(data []byte, bucket, fileName str
 	return "", nil
 }
 
+// UploadWithSettingsRevised can be renamed to UploadWithSettings once original function has been deprecated.
+func (s SessionWithHelpers) UploadWithSettingsRevised(data []byte, bucket string, settings S3UploadSettings) (S3UploadResponse, error) {
+	var fileName, uploadUrl string
+
+	if settings.FileName != "" {
+		fileName = settings.FileName
+	}
+	if settings.GenerateFileNameFromParts {
+		fileName = fmt.Sprintf("%s_%s.%s", settings.FilePrefix, uuid.New().String(), settings.FileExt)
+	}
+
+	if settings.MimeType == "" {
+		settings.MimeType = getTypeForFilename(fileName)
+	}
+
+	putInput := &s3.PutObjectInput{
+		Bucket:      aws.String(bucket),
+		Key:         aws.String(fileName),
+		ContentType: aws.String(string(settings.MimeType)),
+		Body:        bytes.NewReader(data),
+	}
+
+	if settings.ExpiryDuration != nil {
+		expiry := time.Now().Add(*settings.ExpiryDuration)
+		putInput.Expires = &expiry
+	}
+
+	_, err := s.S3Session.PutObject(putInput)
+	if err != nil {
+		return S3UploadResponse{}, err
+	}
+
+	if settings.RetrieveSignedUrl {
+		var headers map[string]string
+
+		fileNameHeader := fileName
+		if settings.FileName != "" {
+			fileNameHeader = settings.FileName
+		}
+
+		if settings.AddContentDisposition {
+			headers = map[string]string{
+				"content-disposition": "attachment; filename=\"" + fileNameHeader + "\"",
+			}
+		}
+
+		uploadUrl, err = s.GetSignedDownloadURL(bucket, fileName, 24*time.Hour, headers)
+		if err != nil {
+			return S3UploadResponse{}, err
+		}
+
+	}
+
+	fileSizeInBytes := binary.Size(data)
+
+	response := S3UploadResponse{
+		URL:      uploadUrl,
+		Filename: fileName,
+		Bucket:   bucket,
+		FileSize: fileSizeInBytes,
+	}
+
+	return response, nil
+}
+
 func (s SessionWithHelpers) UploadWith1DayExpiry(data []byte, bucket, fileName string, mimeType MIMEType, shouldDownloadInsteadOfOpen bool) (string, error) {
 	if mimeType == "" {
 		mimeType = getTypeForFilename(fileName)