水曜日, 7月 16, 2025
水曜日, 7月 16, 2025
- Advertisment -
ホームニューステックニュースFirebase Dynamic Links Short Links API -> AppsFlyer OneLink API 移行

Firebase Dynamic Links Short Links API -> AppsFlyer OneLink API 移行


みてねでは以下の要件を満たすために Short Links API を利用していました

  • Deep Link
    • URL タップでアプリの指定した画面に飛ばす
  • Deferred Deep Link
    • アプリ未インストール時は App Store / Google Play Store に遷移してユーザーがインストールしたあとの初回アプリ起動時に指定したDeep Link の画面に飛ばす
  • URL をできるだけ短く
    • 文字数制限がある SMS 内のリンクとして利用しているため
  • 動的な URL を生成する

大体同じことができる印象ですが強いて言えばリンクの有効期限が異なっています

項目 Firebase DynamicLinks Short Links API AppsFlyer OneLinks API
仕様 https://firebase.google.com/docs/reference/dynamic-links/link-shortener?hl=ja https://dev.appsflyer.com/hc/reference/create-onelink-attribution-link
APIエンドポイント https://firebasedynamiclinks.googleapis.com/v1/shortLinks https://api.appsflyer.com/v1/shortlink/#{onelink-id}
(onelink-idはAppsFlyerの管理画面で作成したテンプレートのID)
認証方法 URLパラメーターで key=YOUR_API_KEY を指定 HTTPヘッダー authentication: #{dev_key} を指定
ベースURL #{your_subdomain}.page.link #{your_subdomain}.onelink.me
リンク有効期限 明示的な期限指定不可。1年以上有効だったという話もあり半永久的に有効かも デフォルトおよび最大は31日。時/分/日で指定可能
SDK統合 Firebase SDK 必須 AppsFlyer SDK 必須
  • AppsFlyer の管理画面で OneLink テンプレートを作成
  • OneLink テンプレート作成後に表示されるテンプレートIDをこれ以降の server 側の実装で利用します

server(ruby)

https://dev.appsflyer.com/hc/reference/create-onelink-attribution-link

require 'uri'
require 'net/http'

template_id = 'AppsFlyerの管理画面で作成したテンプレートのID'
url = URI("https://onelink.appsflyer.com/shortlink/v1/#{template_id}")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Post.new(url)
request['accept'] = 'application/json'
request['content-type'] = 'application/json'
request['authorization'] = 'AppsFlyer OneLink API Token を指定'
request.body = {
  data: {
    deep_link_value: 'https://feedme.ca/deeplink', 
    deep_link_sub1: 10, 
    
    
    
    pid: 'my_media_source_SMS' 
    af_android_url: 'https://feedme.ca/buybananas', 
    af_ios_url: 'https://feedme.ca/buybananas', 
    is_retargeting: true,
    af_adset: 'my_adset',
    af_channel: 'my_channel',
    af_dp: 'afbasicapp://mainactivity',
    c: 'my_campaign',
  }
}.to_json

response = http.request(request)


puts response.read_body

iOS



class AppDelegate: UIResponder, UIApplicationDelegate,
    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? = nil) -> Bool {
        AppsFlyerLib.shared().deepLinkDelegate = self
    }
}

extension AppDelegate: DeepLinkDelegate {
    func didResolveDeepLink(_ result: DeepLinkResult) {
        switch result.status {
        case .notFound:
            print("Deep link not found")
        case .found:
            guard let deepLinkStr = result.deepLink?.toString() else { return }
            print("DeepLink data is: \(deepLinkStr)")
            if( result.deepLink?.isDeferred == true) {
                print("This is a deferred deep link")
            } else {
                print("This is a direct deep link")
            }

            
        case .failure:
            print("Error \(result.error?.localizedDescription ?? "")")
        }
    }
}

Android

  • AndroidManifest.xml に OneLink のドメイン(xxx.onelink.me)の intent-filter を追加
        activity
            android:name=".SampleActivity"
            android:theme="@style/xxxx" />
            
            
            intent-filter android:autoVerify="true">
                action android:name="android.intent.action.VIEW" />

                category android:name="android.intent.category.DEFAULT" />
                category android:name="android.intent.category.BROWSABLE" />

                data
                    android:host="${one_link_domain}" 
                    android:scheme="https" />
            intent-filter>
  • Unified Deep Linking タップした時の処理を実装


class AppsflyerBasicApp : Application {

    override fun onCreate() {
        val conversionListener = object : AppsFlyerConversionListener {
            override fun onConversionDataSuccess(data: MutableMapString, Any>?) {}
            override fun onConversionDataFail(error: String?) {}
            override fun onAppOpenAttribution(data: MutableMapString, String>?) {}
            override fun onAttributionFailure(error: String?) {}
        }
        AppsFlyerLib.getInstance().init(AF_DEV_KEY, conversionListener, this).apply {
            subscribeForDeepLink {
                val deepLinkValue = it.deepLink.deepLinkValue ?: return@subscribeForDeepLink

                if (it.deepLink.isDeferred()) {
                    Log.d(LOG_TAG, "This is a deferred deep link")
                } else {
                    Log.d(LOG_TAG, "This is a direct deep link")
                }

                
            }
            start(this@AppsflyerBasicApp)
        }
    }
}
  • iOS / Android アプリをテストするにはテストデバイスとしてAppsFlyerの管理画面に登録する必要があります
  • みてねでは、Firebase DynamicLinks で実現していた機能(Deep Link、Deferred Deep Link、短縮URLの生成など)を AppsFlyer OneLink API で代替できました

  • 移行にあたっては、AppsFlyer管理画面でのテンプレート作成と、OneLink生成のAPI実装(サーバー)、アプリ側の Unified Deep Linking 対応(iOS/Android) が必要でした。

  • もし Firebase DynamicLinks の廃止で困っている方がいたら参考にしてもらえると嬉しいです。



Source link

Views: 0

RELATED ARTICLES

返事を書く

あなたのコメントを入力してください。
ここにあなたの名前を入力してください

- Advertisment -