Kotlin Module

Kotlin Module

Installation

Add the dependency:

1
2
3
4
5
<dependency>
    <groupId>com.botbye</groupId>
    <artifactId>kotlin-module</artifactId>
    <version>3.0.1</version>
</dependency>
1
implementation("com.botbye:kotlin-module:3.0.1")

Configuration

Phishing lives in its own dedicated BotbyePhishingClient, separate from the evaluate Botbye client. It is identified by a public, browser-safe clientKey, so it needs no server key — construct it standalone and reuse it. On construction it makes a one-off, best-effort server-integration init handshake that reports this server-side integration to BotBye; it is non-blocking and never affects your request path.

BotbyePhishingConfig takes 2 values: endpoint (optional, defaults to https://verify.botbye.com) and clientKey.

Getting clientKey

clientKey is the public, browser-safe identifier of your phishing project. It travels in the asset URL path, so it is safe to expose — no secret token and no Base64 encoding are required.

Find it on the Get Started screen of your phishing project in the BotBye dashboard.

1
2
3
4
5
6
7
8
9
import com.botbye.phishing.BotbyePhishingClient
import com.botbye.phishing.BotbyePhishingConfig

val phishing = BotbyePhishingClient(
    BotbyePhishingConfig(
        endpoint = "https://verify.botbye.com",
        clientKey = "<public-client-key>",
    )
)

Usage

Expose a single endpoint that proxies phishing pixel requests. fetchImage is a suspend function — call it from a coroutine context, or bridge it with runBlocking in a blocking servlet handler (shown below). Framework-specific examples are in the Spring (Kotlin) and Ktor guides.

When you use an SVG image, your application must also expose an endpoint on the client origin that handles requests to /{imageId}.png, where imageId is the value that arrives in the forwarded pixel query as image_id.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
fun doGet(req: HttpServletRequest, resp: HttpServletResponse) = runBlocking {
    val origin = req.getHeader("Origin")
    val query = req.parameterMap.mapValues { (_, v) -> v.first() }

    val response = phishing.fetchImage(origin = origin, query = query)

    if (response.error != null) {
        resp.sendError(502, response.error?.message ?: "upstream error")
        return@runBlocking
    }

    resp.status = response.status
    resp.contentType = response.headers["Content-Type"] ?: "image/png"
    resp.outputStream.write(response.body)
}

Settings

Configuration parameters for phishing integration:

Setting Description Required Default Value
endpoint Host of the phishing API no https://verify.botbye.com
clientKey Public client-key of your phishing project yes -