Skip to content

Instantly share code, notes, and snippets.

@filipebrandao
Last active January 26, 2023 11:50
Show Gist options
  • Save filipebrandao/037603973b7239ab63102e8ec23b47bf to your computer and use it in GitHub Desktop.
Save filipebrandao/037603973b7239ab63102e8ec23b47bf to your computer and use it in GitHub Desktop.
/**
Example usage:
BranchLinkShortener() {
url = deeplinkWithoutUtmParameters
utmSource = "mobile-share"
}.shorten(context) { shortenedUrl ->
shortenedUrl?.let {
logger.i(TAG, "Got my Branch link to share: %s", shortenedUrl)
} ?: logger.e(
TAG,
"Could not shorten link with Branch"
) // TODO: fallback to passthrough?
}
*/
private const val PARAM_UTM_SOURCE = "utm_source"
private const val PARAM_UTM_MEDIUM = "utm_medium"
private const val PARAM_UTM_CAMPAIGN = "utm_campaign"
class BranchLinkShortener() {
constructor(init: BranchLinkShortener.() -> Unit) : this() {
this.init()
}
var url: String? = null
var customTitle: String? = null
var customDescription: String? = null
var customThumbnailUrl: String? = null
var utmSource: String? = null
var utmCampaign: String? = null
var utmMedium: String? = null
fun shorten(context: Context, listener: ((String?) -> Unit)) {
requireNotNull(url)
val urlWithUtmParameters = with(Uri.parse(url).buildUpon()) {
utmSource?.let {
appendQueryParameter(PARAM_UTM_SOURCE, utmSource)
}
utmMedium?.let {
appendQueryParameter(PARAM_UTM_MEDIUM, utmMedium)
}
utmCampaign?.let {
appendQueryParameter(PARAM_UTM_CAMPAIGN, utmCampaign)
}
toString()
}
val branchUniversalObject = with(BranchUniversalObject()) {
// The identifier is what Branch will use to de-dupe the content across many different Universal Objects
canonicalIdentifier = urlWithUtmParameters
// The canonical URL
canonicalUrl = urlWithUtmParameters
// You use this to specify whether this content can be discovered publicly - default is public
setContentIndexingMode(BranchUniversalObject.CONTENT_INDEX_MODE.PRIVATE)
// This is where you define the open graph structure and how the object will appear on external apps or in a deepview
if (customTitle?.isNotBlank() == true) {
title = customTitle
}
if (customDescription?.isNotBlank() == true) {
setContentDescription(customDescription!!)
}
if (customThumbnailUrl?.isNotBlank() == true) {
setContentImageUrl(customThumbnailUrl!!)
}
// TODO: remove if not needed
// Here is how you can add custom keys/values to the deep link data
// setContentMetadata(
// ContentMetadata()
// .addCustomMetadata("property1", "blue")
// .addCustomMetadata("property2", "red")
// )
return@with this
}
// TODO: make this "trip/" configurable through a new builder parameter
val alias = "trip/${UUID.randomUUID()}" // 128 char limit in the alias
// the same alias must have the same properties for all arguments
val linkProperties = with(LinkProperties()) {
setAlias(alias)
addControlParameter("\$desktop_url", urlWithUtmParameters)
// url to redirect an Android user to if they don't have the android app installed (instead of the Play Store)
addControlParameter(
"\$android_url",
urlWithUtmParameters
)
// url to redirect an iOS user to if they don't have the android app installed (instead of the App Store)
addControlParameter(
"\$ios_url",
urlWithUtmParameters
)
utmSource?.let {
setChannel(it) // Branch equivalent of utm_source
}
utmMedium?.let {
setFeature(it) // Branch equivalent of utm_medium
}
utmCampaign?.let {
setCampaign(it) // Branch equivalent of utm_campaign
}
// TODO: remove if not needed
// Set custom control parameters
// addControlParameter("custom", "data")
// addControlParameter("custom_random", "" + System.currentTimeMillis())
return@with this
}
branchUniversalObject.generateShortUrl(context, linkProperties) { url, error ->
listener.invoke(if (error == null) url else null)
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment