셀러 구독 기능

    셀러 구독 기능


    Article Summary

    셀러 구독기능 사용을 위해서는 Shoplive 담당자와 협의가 필요합니다.



    셀러 구독 기능

    셀러의 아이콘을 클릭하거나, 구독 버튼을 클릭하였을때 발생하는 콜백을 이용해 구독상태를 변경하거나 셀러의 페이지로 이동 시킬 수 있습니다.

    • ON_RECEIVED_SELLER_CONFIG 콜백을 통해 방송에 등록된 셀러의 정보를 수신받습니다. 

    • ON_CLICK_VIEW_SELLER_STORE 콜백을 통해 셀러이미지의 클릭 이벤트를 수신하여 셀러의 페이지로 랜딩시킬 수 있습니다.

    • ON_CLICK_SELLER_SUBSCRIPTION 콜백을 통해 셀러 구독 버튼의 클릭이벤트를 수신할 수 있습니다

    • SET_SELLER_SAVED_STATE Command를 통해 UI의 구독상태를 표시를 변경합니다.


    방송 실행시 등록되어 있는 셀러의 정보를 수신하는 messageCallback : 

    ON_RECEIVED_SELLER_CONFIG

    방송에 진입시 셀러의 정보를 수신합니다.

    • 수신한 셀러/사용자 정보를 통해 해당 사용자의 구독상태를 내부 시스템에서 체크하고 구독상태 변경 명령을 플레이어에 보내 상태를 동기화 합니다


    주요 Payload

    Payload

    Type

    description

    seller

    Seller

    방송의 셀러 정보

    campaignKey

    string

    방송의 campaignKey


    플레이어에 구독상태를 표시하는 명령어 : 

    SET_SELLER_SAVED_STATE

    플레이어에 sendMessage() 의 SEND_COMMAND_MESSAGE action을 통해 구독상태를 표시 명령인 SET_SELLER_SAVED_STATE 를 전송합니다. 

    Boolean 형태의 payload를 통해 구독상태를 정의합니다.

    사용방법

    const player = cloud.shoplive.getPlayer();
    const action = 'SEND_COMMAND_MESSAGE'
    const payload = { command: "SET_SELLER_SAVED_STATE", payload: { status } }
    player.sendMessage(action,payload);

    사용예제

    Web

    var messageCallback = {
      // seller정보 응답 이벤트
            ON_RECEIVED_SELLER_CONFIG: (payload) => {
              // 고객사의 기존 구독 상태값을 가져와 플레이어의 UI 상태 sync 처리
              fetchGetSavedSeller.then(({ status }) => {
                  const player = cloud.shoplive.getPlayer();
                  player.sendMessage("SEND_COMMAND_MESSAGE", { command: "SET_SELLER_SAVED_STATE", payload: { saved:status } })
              });
            },
    }
    cloud.shoplive.init({ accessKey: "ACCESS_KEY", messageCallback: messageCallback });

    Android

    fun onReceivedCommand(context: Context, command: String, data: JSONObject) {
        when (command) {
            "ON_RECEIVED_SELLER_CONFIG" -> {
                val sellerSavedData = JSONObject()
                sellerSavedData.put("saved", true)
                ShopLive.sendCommandMessage(
                    "SET_SELLER_SAVED_STATE",
                    sellerSavedData.toString()
                )
            }
        }
    }

    iOS

    func handleReceivedCommand(_ command: String, data: [String : Any]?) {
            switch command {
            case "ON_RECEIVED_SELLER_CONFIG":
                var sellerSavedData : [String : Any] = ["saved" : true]
                ShopLive.sendCommandMessage(command: "SET_SELLER_SAVED_STATE", payload: sellerSavedData)
            default:
                break
            }
        }

    플레이어에 토스트 메시지 띄우는  명령어 : 

    SHOW_LAYER_TOAST

    • Web: sendMessage의 showToast명령어를 통해 토스트 메시지를 표시합니다.

    • App: sendCommandMessage() 를 통해 토스트 표시 명령인 SHOW_LAYER_TOAST 를 전송하여 토스트 메시지를 표시합니다.

     

    사용예제

    Web

    const player = cloud.shoplive.getPlayer();
    const toastData = {
                        message: "구독 상태를 업데이트 했습니다.",
                        position: "CENTER",
                        duration: 3000,
                    };
    player.sendMessage("showToast", toastData);

    Android

    
    val jsonObject = JSONObject()
    jsonObject.put("message", "구독 상태를 업데이트 했습니다.")
    jsonObject.put("duration", 3000)
    jsonObject.put("position", "CENTER")
    ShopLive.sendCommandMessage("SHOW_LAYER_TOAST", jsonObject.toString())
    

    iOS

    var payload : [String : Any] = [:]
    payload["message"] = "구독 상태를 업데이트 했습니다."
    payload["duration"] = 3000
    payload["position"] = "center"
    ShopLive.sendCommandMessage(command: "SHOW_LAYER_TOAST", payload: payload)

    셀러 프로파일 클릭시의 동작을 정의하는 messageCallback : 

    ON_CLICK_VIEW_SELLER_STORE

    셀러 프로파일 이미지를 클릭시 셀러 스토어로의 랜딩 등의 동작을 정의하기 위한 콜백 입니다.


    주요 Payload

    Payload

    Type

    description

    seller

    Seller

    방송의 셀러 정보

    campaignKey

    string

    방송의 campaignKey

    사용예제

    Web

    var messageCallback = {
     ON_CLICK_VIEW_SELLER_STORE: (payload) => {
                    console.log('ON_CLICK_VIEW_SELLER_STORE', payload)
                    location.href=payload.seller.storeUrl
                },
    }
    cloud.shoplive.init({ accessKey: "ACCESS_KEY", messageCallback: messageCallback });

    Android

    fun onReceivedCommand(context: Context, command: String, data: JSONObject) {
        when (command) {
            "ON_CLICK_VIEW_SELLER_STORE" -> {
                val sellerStoreData =
                    Gson().fromJson(data.toString(), SellerStoreData::class.java)
                CustomerWebViewActivity.startActivity(
                    this@MainActivity,
                    sellerStoreData.seller?.storeUrl ?: return
                )
            }
        }
    }
    
    private data class SellerStoreData(
        val campaignKey: String?,
        val campaignStatus: String?,
        val campaignTitle: String?,
        val seller: Seller?
    )
    
    private data class Seller(
        val description: String?,
        val name: String?,
        val profileUrl: String?,
        val schemes: String?,
        val sellerId: Int,
        val sellerIdentifier: String,
        val storeUrl: String?
    )

    iOS

    func handleReceivedCommand(_ command: String, data: [String : Any]?) {
        switch command {
        case "ON_CLICK_VIEW_SELLER_STORE":
            var sellerStoreData = SellerStoreData(dict: payload)
            if let urlString = sellerStoreData.seller?.storeUrl, let url = URL(string: urlString)  {
                UIApplication.shared.canOpenURL(url)
            }
        default:
            break
        }
    }
    
    class SellerStoreData {
        var campaignKey : String?
        var campaignStatus : String?
        var campaignTitle : String?
        var seller : SellerData?
        
        init(campaignKey: String? = nil, campaignStatus: String? = nil, campaignTitle: String? = nil, seller: SellerData? = nil) {
            self.campaignKey = campaignKey
            self.campaignStatus = campaignStatus
            self.campaignTitle = campaignTitle
            self.seller = seller
        }
        
        init(dict : [String : Any]) {
            self.campaignKey = dict["campaignKey"] as? String
            self.campaignStatus = dict["campaignStatus"] as? String
            self.campaignTitle = dict["campaignTitle"] as? String
            self.seller = .init(dict: dict["seller"] as? [String : Any] ?? [:])
        }
    }
    
    class SellerData {
        var descriptions : String?
        var name : String?
        var profileUrl : String?
        var scheme : String?
        var sellerId : Int?
        var sellerIdentifier : String?
        var storeUrl : String
        
        init(descriptions: String? = nil, name: String? = nil, profileUrl: String? = nil, scheme: String? = nil, sellerId: Int? = nil, sellerIdentifier: String? = nil, storeUrl: String) {
            self.descriptions = descriptions
            self.name = name
            self.profileUrl = profileUrl
            self.scheme = scheme
            self.sellerId = sellerId
            self.sellerIdentifier = sellerIdentifier
            self.storeUrl = storeUrl
        }
        
        
        init(dict : [String : Any]) {
            self.descriptions = dict["descriptions"] as? String
            self.name = dict["name"] as? String
            self.profileUrl = dict["profileUrl"] as? String
            self.scheme = dict["scheme"] as? String
            self.sellerId = dict["sellerId"] as? Int
            self.sellerIdentifier = dict["sellerIdentifier"] as? String
            self.storeUrl = dict["storeUrl"] as? String ?? ""
        }
    }

    셀러 구독버튼을 클릭했을때의 동작을 정의하는 messageCallback : 

    ON_CLICK_SELLER_SUBSCRIPTION

    셀러의 구독버튼이 클릭 되었을때 발생하는 messageCallback입니다. 

    고객사의 기능으로 구독 처리를 하고 결과값을 리턴하여 UI의 구독상태를 변경시키는 형태로 활용합니다.

    주요 Payload

    Payload

    Type

    description

    seller

    Seller

    셀러 정보

    campaignKey

    string

    방송의 campaignKey

    isLogin

    bollean

    유저의 로긴 상태


    사용예제

    Web

    
    
    var messageCallback = {
        ON_CLICK_SELLER_SUBSCRIPTION: (payload) => {
                const player = cloud.shoplive.getPlayer();
    
    // 고객사의 서버에 저장후 플레이어의 UI 상태 업데이트
                fetchPostSavedSeller.then(({ saved }) => {
                    player.sendMessage("SEND_COMMAND_MESSAGE", { command: "SET_SELLER_SAVED_STATE", payload: { saved } })
              });
    
    // 예시. 플레이어 표시할 토스트 데이터
               const toastData = {
                        message: "구독 상태를 업데이트 했습니다.",
                        position: "CENTER",
                        duration: 3000,
                    };
               player.sendMessage("showToast", toastData);
    
                },
    }
    cloud.shoplive.init({ accessKey: "ACCESS_KEY", messageCallback: messageCallback });


    Android

    fun onReceivedCommand(context: Context, command: String, data: JSONObject) {
        when (command) {
            "ON_CLICK_SELLER_SUBSCRIPTION" -> {
                val sellerSubscriptionData =
                    Gson().fromJson(data.toString(), SellerSubscriptionData::class.java)
                // 고객사의 서버에 저장후 플레이어의 UI 상태 업데이트
                SomthingCustomerJob(sellerSubscriptionData) {
                    val sellerSavedData = JSONObject()
                    sellerSavedData.put("saved", !sellerSubscriptionData.saved)
                    ShopLive.sendCommandMessage(
                        "SET_SELLER_SAVED_STATE",
                        sellerSavedData.toString()
                    )
                }
            }
        }
    }
    
    private data class SellerSubscriptionData(
        val campaignKey: String?,
        val campaignStatus: String?,
        val campaignTitle: String?,
        val isLogin: Boolean,
        val saved: Boolean,
        val seller: Seller?
    )
    
    private data class Seller(
        val description: String?,
        val name: String?,
        val profileUrl: String?,
        val schemes: String?,
        val sellerId: Int,
        val sellerIdentifier: String,
        val storeUrl: String?
    )

    iOS

    func handleReceivedCommand(_ command: String, data: [String : Any]?) {
        switch command {
        case "ON_RECEIVED_SELLER_CONFIG","ON_CLICK_VIEW_SELLER_STORE","ON_CLICK_SELLER_SUBSCRIPTION":
            var sellerSubsciptionData = SellerSubscriptionData(dict: payload)
            var sellerSavedData : [String : Any] = ["saved" : !(sellerSubsciptionData.saved ?? true)]
            ShopLive.sendCommandMessage(command: "SET_SELLER_SAVED_STATE", payload: sellerSavedData)
        default:
            break
        }
    }
    class SellerSubscriptionData {
        var campaignKey : String?
        var campaignStatus : String?
        var campaignTitle : String?
        var isLogin : Bool?
        var saved : Bool?
        var seller : SellerData?
        
        init(campaignKey: String? = nil, campaignStatus: String? = nil, campaignTitle: String? = nil, isLogin: Bool? = nil, saved: Bool? = nil, seller: SellerData? = nil) {
            self.campaignKey = campaignKey
            self.campaignStatus = campaignStatus
            self.campaignTitle = campaignTitle
            self.isLogin = isLogin
            self.saved = saved
            self.seller = seller
        }
        
        
        init(dict  : [String : Any] ) {
            self.campaignKey = dict["campaignKey"] as? String
            self.campaignStatus = dict["campaignStatus"] as? String
            self.campaignTitle = dict["campaignTitle"] as? String
            self.isLogin = dict["isLogin"] as? Bool
            self.saved = dict["saved"] as? Bool
            self.seller = SellerData(dict: dict["seller"] as? [String : Any] ?? [:])
            
        }
        
    }
    
    class SellerData {
        var descriptions : String?
        var name : String?
        var profileUrl : String?
        var scheme : String?
        var sellerId : Int?
        var sellerIdentifier : String?
        var storeUrl : String
        
        init(descriptions: String? = nil, name: String? = nil, profileUrl: String? = nil, scheme: String? = nil, sellerId: Int? = nil, sellerIdentifier: String? = nil, storeUrl: String) {
            self.descriptions = descriptions
            self.name = name
            self.profileUrl = profileUrl
            self.scheme = scheme
            self.sellerId = sellerId
            self.sellerIdentifier = sellerIdentifier
            self.storeUrl = storeUrl
        }
        
        
        init(dict : [String : Any]) {
            self.descriptions = dict["descriptions"] as? String
            self.name = dict["name"] as? String
            self.profileUrl = dict["profileUrl"] as? String
            self.scheme = dict["scheme"] as? String
            self.sellerId = dict["sellerId"] as? Int
            self.sellerIdentifier = dict["sellerIdentifier"] as? String
            self.storeUrl = dict["storeUrl"] as? String ?? ""
        }
    }

    연관기능