Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -94,3 +94,6 @@ logs
npm-debug.log*
yarn-debug.log*
yarn-error.log*

# Test files
test-image.jpg
4 changes: 4 additions & 0 deletions src/main/kotlin/com/cloudcontactai/sdk/mms/MMSModels.kt
Original file line number Diff line number Diff line change
Expand Up @@ -41,3 +41,7 @@ data class SignedUploadUrlResponse(
val signedS3Url: String,
val fileKey: String? = null
)

data class StoredUrlResponse(
val storedUrl: String
)
41 changes: 39 additions & 2 deletions src/main/kotlin/com/cloudcontactai/sdk/mms/MMSService.kt
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import okhttp3.OkHttpClient
import okhttp3.Request
import okhttp3.RequestBody.Companion.toRequestBody
import java.io.File
import java.io.FileInputStream
import java.security.MessageDigest

class MMSService(private val config: CCAIConfig, private val apiClient: ApiClient) {
private val httpClient = OkHttpClient()
Expand Down Expand Up @@ -113,22 +115,57 @@ class MMSService(private val config: CCAIConfig, private val apiClient: ApiClien
imageFile: File,
senderPhone: String? = null
): MMSResponse {
val md5Image = md5(imageFile)
val extension = imageFile.extension.lowercase()
val fileName = "${md5Image}.${extension}"
val fileKey = "${config.clientId}/campaign/${fileName}"

//Check if the same image has already been uploaded
val storedUrlResponse = checkFileUploaded(fileKey)
if(storedUrlResponse.storedUrl.isNotEmpty()){
return send(accounts, message, title, fileKey, senderPhone)
}

val contentType = when (extension) {
"jpg", "jpeg" -> "image/jpeg"
"png" -> "image/png"
"gif" -> "image/gif"
else -> "image/jpeg"
}
val fileName = "${System.currentTimeMillis()}_${imageFile.name}"
val uploadRequest = SignedUploadUrlRequest(
fileName = fileName,
fileType = contentType,
publicFile = true
)
val fileKey = "${config.clientId}/campaign/${fileName}"
val uploadResponse = getSignedUploadUrl(uploadRequest)
uploadImageToSignedUrl(uploadResponse.signedS3Url, imageFile, contentType)
return send(accounts, message, title, fileKey, senderPhone)
}

private fun md5(file: File): String {
val digest = MessageDigest.getInstance("MD5")
FileInputStream(file).use { fis ->
val buffer = ByteArray(8192)
var bytesRead: Int

while (fis.read(buffer).also { bytesRead = it } != -1) {
digest.update(buffer, 0, bytesRead)
}
}

return digest.digest().joinToString("") { "%02x".format(it) }
}

fun checkFileUploaded(fileKey: String):StoredUrlResponse{
return try {
apiClient.request(
method = "GET",
endpoint = "/clients/${config.clientId}/storedUrl?fileKey=${fileKey}",
responseClass = StoredUrlResponse::class.java
)
} catch (e: Exception) {
e.printStackTrace()
StoredUrlResponse("")
}
}
}
18 changes: 18 additions & 0 deletions src/test/kotlin/com/cloudcontactai/sdk/mms/MMSServiceTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -134,4 +134,22 @@ class MMSServiceTest {
assertEquals("mms-single-123", response.campaignId)
assertTrue(response.success == true)
}

@Test
fun `should check if file is uploaded and return stored URL`() {
val responseJson = """
{
"storedUrl": "https://s3.amazonaws.com/bucket/test-client/campaign/image.jpg"
}
""".trimIndent()

mockServer.enqueue(MockResponse()
.setResponseCode(200)
.setBody(responseJson)
.addHeader("Content-Type", "application/json"))

val response = client.mms.checkFileUploaded("test-client/campaign/image.jpg")

assertEquals("https://s3.amazonaws.com/bucket/test-client/campaign/image.jpg", response.storedUrl)
}
}