From 5a3be1d759086a2ea753417ca6805e099446d7b2 Mon Sep 17 00:00:00 2001 From: Julien Buret Date: Fri, 31 May 2024 10:35:37 +0200 Subject: [PATCH] resolves #1611 Connector whatsApp Cloud : add image cache --- .../services/WhatsAppCloudApiService.kt | 65 +++++++++++-------- 1 file changed, 39 insertions(+), 26 deletions(-) diff --git a/bot/connector-whatsapp-cloud/src/main/kotlin/services/WhatsAppCloudApiService.kt b/bot/connector-whatsapp-cloud/src/main/kotlin/services/WhatsAppCloudApiService.kt index f22813bcb4..e98314a2d8 100644 --- a/bot/connector-whatsapp-cloud/src/main/kotlin/services/WhatsAppCloudApiService.kt +++ b/bot/connector-whatsapp-cloud/src/main/kotlin/services/WhatsAppCloudApiService.kt @@ -26,13 +26,18 @@ import ai.tock.bot.connector.whatsapp.cloud.model.send.manageTemplate.ResponseCr import ai.tock.bot.connector.whatsapp.cloud.model.send.manageTemplate.WhatsAppCloudTemplate import ai.tock.bot.connector.whatsapp.cloud.model.send.media.FileType import ai.tock.bot.connector.whatsapp.cloud.model.send.media.MediaResponse -import ai.tock.bot.connector.whatsapp.cloud.model.send.message.* +import ai.tock.bot.connector.whatsapp.cloud.model.send.message.WhatsAppCloudSendBotInteractiveMessage +import ai.tock.bot.connector.whatsapp.cloud.model.send.message.WhatsAppCloudSendBotLocationMessage +import ai.tock.bot.connector.whatsapp.cloud.model.send.message.WhatsAppCloudSendBotMessage +import ai.tock.bot.connector.whatsapp.cloud.model.send.message.WhatsAppCloudSendBotTemplateMessage +import ai.tock.bot.connector.whatsapp.cloud.model.send.message.WhatsAppCloudSendBotTextMessage import ai.tock.bot.connector.whatsapp.cloud.model.send.message.content.Component import ai.tock.bot.connector.whatsapp.cloud.model.send.message.content.HeaderParameter import ai.tock.bot.connector.whatsapp.cloud.model.send.message.content.PayloadParameter import ai.tock.bot.connector.whatsapp.cloud.model.send.message.content.WhatsAppCloudBotActionButton import ai.tock.bot.engine.BotRepository import ai.tock.shared.TockProxyAuthenticator +import ai.tock.shared.cache.getOrCache import ai.tock.shared.error import ai.tock.shared.jackson.mapper import mu.KotlinLogging @@ -42,10 +47,12 @@ import okhttp3.OkHttpClient import okhttp3.Request import okhttp3.RequestBody import okhttp3.RequestBody.Companion.toRequestBody +import org.litote.kmongo.toId import retrofit2.Response import java.io.IOException import java.time.Instant -import java.util.* +import java.util.Date +import java.util.UUID class WhatsAppCloudApiService(private val apiClient: WhatsAppCloudApiClient) { @@ -210,32 +217,36 @@ class WhatsAppCloudApiService(private val apiClient: WhatsAppCloudApiClient) { ): MediaResponse { val requestTimerData = BotRepository.requestTimer.start("whatsapp_send_${fileUrl.javaClass.simpleName.lowercase()}") - try { - val file = uploadMedia(client, fileUrl, fileType) - - val body = MultipartBody.Builder().setType(MultipartBody.FORM) - .addFormDataPart("file", "fileimage", file) - .addFormDataPart("messaging_product", "whatsapp") - .build() - val request = Request.Builder() - .url("https://graph.facebook.com/v19.0/$phoneNumberId/media") - .post(body) - .addHeader("Content-Type", "application/json") - .addHeader("Authorization", "Bearer $token") - .build() - client.newCall(request).execute().use { response -> - if (!response.isSuccessful) { - throw ConnectorException("Failed to send message: ${response.code}") + return getOrCache("$phoneNumberId-$fileUrl".toId(), IMAGE_ID_CACHE) { + try { + val file = uploadMedia(client, fileUrl, fileType) + + val body = MultipartBody.Builder().setType(MultipartBody.FORM) + .addFormDataPart("file", "fileimage", file) + .addFormDataPart("messaging_product", "whatsapp") + .build() + val request = Request.Builder() + .url("https://graph.facebook.com/v19.0/$phoneNumberId/media") + .post(body) + .addHeader("Content-Type", "application/json") + .addHeader("Authorization", "Bearer $token") + .build() + client.newCall(request).execute().use { response -> + if (!response.isSuccessful) { + throw ConnectorException("Failed to send message: ${response.code}") + } + mapper.readValue(response.body!!.string(), MediaResponse::class.java).id } - return mapper.readValue(response.body!!.string(), MediaResponse::class.java) + } catch (e: Exception) { + BotRepository.requestTimer.throwable(e, requestTimerData) + throw if (e is ConnectorException) e else ConnectorException("Error sending media: ${e.message}") + } finally { + BotRepository.requestTimer.end(requestTimerData) } - } catch (e: Exception) { - BotRepository.requestTimer.throwable(e, requestTimerData) - throw if (e is ConnectorException) e else ConnectorException("Error sending media: ${e.message}") - } finally { - BotRepository.requestTimer.end(requestTimerData) - } + }?.let { mediaId -> + MediaResponse(mediaId) + } ?: throw ConnectorException("Error sending media") } fun sendBuildTemplate(whatsAppBusinessAccountId: String, token: String, messageTemplate: WhatsAppCloudTemplate) { @@ -334,4 +345,6 @@ class WhatsAppCloudApiService(private val apiClient: WhatsAppCloudApiClient) { //warnRequest(request) { mapper.writeValueAsString(request) } throw ConnectorException(errorMessage) } -} \ No newline at end of file +} + +private const val IMAGE_ID_CACHE = "whatsapp_image_id_cache"