suspend fun provideUnfurlContent()

in kotlin/slack-link-previews/src/main/kotlin/com/linkpreviews/unfurls.kt [15:78]


suspend fun provideUnfurlContent(item: ApplicationUnfurlQueueItem, spaceUserId: String) {
    val url = Url(item.target)
    val parts = url.encodedPath.split('/').dropWhile { it != "archives" }.drop(1)
    val channelId = parts.firstOrNull()
    val messageId = parts.drop(1).firstOrNull()
    if (channelId == null || messageId == null)
        return

    var tokens = slackUserTokens[spaceUserId] ?: run {
        requestAuthentication(item, spaceUserId)
        return
    }

    val threadTs = url.parameters["thread_ts"]

    val message = try {
        fetchMessage(channelId, messageId, threadTs, tokens.accessToken)
    } catch (ex: SlackApiException) {
        if (ex.error.error == "token_expired") {
            val response = slackApiClient.methods().oauthV2Access {
                it
                    .clientId(SlackWorkspace.clientId)
                    .clientSecret(SlackWorkspace.clientSecret)
                    .grantType("refresh_token")
                    .refreshToken(tokens.refreshToken)
            }
            val accessToken = response.accessToken ?: response.authedUser?.accessToken
            val newRefreshToken = response.refreshToken ?: tokens.refreshToken
            if (accessToken != null) {
                tokens = SlackUserTokens(accessToken, newRefreshToken)
                slackUserTokens[spaceUserId] = SlackUserTokens(accessToken, newRefreshToken)
                fetchMessage(channelId, messageId, threadTs, tokens.accessToken)
            } else null
        } else null
    }

    if (message == null)
        return

    val channelLink = if (threadTs != null) {
        // converting message timestamp value to id for the message link (an operation opposite to `messageIdToTs`)
        val parentMessageId = "p" + threadTs.filterNot { it == '.' }
        "https://${SlackWorkspace.domain}/archives/$channelId/$parentMessageId"
    } else {
        fetchChannelName(tokens.accessToken, channelId)
    }
    val authorName = fetchAuthorName(tokens.accessToken, message.user)
    // Build link preview with message constructor DSL
    val content: ApplicationUnfurlContent.Message = unfurl {
        outline(
            MessageOutline(
                ApiIcon("slack"),
                "*$authorName* in $channelLink"
            )
        )
        section {
            text(message.text)
            text("[View message](${item.target})")
        }
    }
    spaceClient.applications.unfurls.queue.postUnfurlsContent(
        listOf(ApplicationUnfurl(item.id, content))
    )
}