Roku-এর জন্য প্রোগ্রাম্যাটিক অ্যাক্সেস লাইব্রেরি (PAL) SDK DVC-ভিত্তিক Roku অ্যাপ্লিকেশনগুলিকে নগদীকরণ করতে সরাসরি VAST কল (DVC) অনুমোদন সহ প্রকাশকদের সক্ষম করে৷ PAL SDK আপনাকে Google থেকে ননসেস, যা এনক্রিপ্ট করা স্ট্রিং, অনুরোধ করার অনুমতি দেয়, যাতে আপনি DVC অনুরোধে স্বাক্ষর করতে পারেন। প্রতিটি নতুন স্ট্রিম অনুরোধের সাথে অবশ্যই একটি নতুন জেনারেট হওয়া নন্স থাকতে হবে। যাইহোক, আপনি একই স্ট্রীমের মধ্যে একাধিক বিজ্ঞাপন অনুরোধের জন্য একই ননস পুনরায় ব্যবহার করতে পারেন।
এই নির্দেশিকাটি একটি উদাহরণ ব্যাখ্যা করে যে কীভাবে PAL SDK-কে একটি Roku অ্যাপ্লিকেশনে অন্তর্ভুক্ত করতে হয়, একটি ননস অনুরোধ করতে হয় এবং বিজ্ঞাপন ইম্প্রেশন নিবন্ধন করতে হয়।
পূর্বশর্ত
এই নির্দেশিকাটি শুরু করার আগে, আপনাকে নিম্নলিখিতগুলি করতে হবে:
- একটি Roku ডেভেলপমেন্ট এনভায়রনমেন্ট — আরও তথ্যের জন্য Roku ডেভেলপার এনভায়রনমেন্ট সেটআপ গাইড দেখুন।
নিম্নলিখিত কাঠামো সহ একটি প্রকল্প ফোল্ডার:
./ components/ MainScene.xml PALInterface.xml SampleVideoPlayer.xml images/ icon_focus_hd.png icon_focus_sd.png icon_side_hd.png icon_side_sd.png splash_fhd.png splash_hd.png splash_sd.png source/ main.brs manifest
আপনার প্রকল্প সেট আপ করুন
আপনি PAL SDK সংহত করার আগে, আপনাকে আপনার প্রকল্প ফাইলগুলি কনফিগার করতে হবে৷
প্রকাশ
title=PAL for Roku Sample
subtitle=As seen in the PAL for Roku Get Started Guide
major_version=1
minor_version=0
build_version=00001
mm_icon_focus_hd=pkg:/images/icon_focus_hd.png
mm_icon_side_hd=pkg:/images/icon_side_hd.png
mm_icon_focus_sd=pkg:/images/icon_focus_sd.png
mm_icon_side_sd=pkg:/images/icon_side_sd.png
splash_screen_sd=pkg:/images/splash_sd.jpg
splash_screen_hd=pkg:/images/splash_hd.jpg
splash_screen_fhd=pkg:/images/splash_fhd.jpg
splash_color=#000000
splash_min_time=1000
ui_resolutions=hd
source/main.brs
sub Main()
showChannelSGScreen()
end sub
sub showChannelSGScreen()
screen = CreateObject("roSGScreen")
m.port = CreateObject("roMessagePort")
screen.setMessagePort(m.port)
m.scene = screen.CreateScene("MainScene")
screen.show()
while(true)
msg = wait(0, m.port)
msgType = type(msg)
if msgType = "roSGScreenEvent"
if msg.isScreenClosed() then return
end if
end while
end sub
একটি নমুনা ভিডিও প্লেয়ার তৈরি করুন
SampleVideoPlayer
উপাদানটি রিমোট কন্ট্রোল প্রেসগুলি ক্যাপচার করতে একটি ভিডিও কম্পোনেন্টকে সহজভাবে মোড়ানো হয়। onKeyEvent
ওভাররাইড করুন যাতে একবার রিমোটের ফোকাস ভিডিও/বিজ্ঞাপন প্লেয়ারে স্থানান্তরিত হলে আর কোন কী প্রেস (উপর, নিচে, বাম, ডান, ক্লিক, ইত্যাদি), ক্যাপচার করা হয় এবং PAL পর্যন্ত বুদবুদ করা হয়।
components/SampleVideoPlayer.xml
<?xml version="1.0" encoding="utf-8" ?>
<component name="SampleVideoPlayer" extends="Video">
<interface>
<field id="pressedKey" type="String" />
</interface>
<script type="text/brightscript">
<![CDATA[
Function onKeyEvent(key as String, press as Boolean) as Boolean
If press
m.top.pressedKey = key
End If
return True
End Function
]]>
</script>
<children>
<Label text="VIDEO" color="0xFFFFFFFF" font="font:MediumBoldSystemFont" horizAlign="center" vertAlign="center" width="720" height="480" />
</children>
</component>
একটি পরীক্ষা ইন্টারফেস তৈরি করুন
নিম্নলিখিত কাজ করতে বোতাম সহ একটি দৃশ্য প্রয়োগ করে:
- একটি nonce অনুরোধ.
- একটি বিজ্ঞাপন ক্লিক পাঠান.
- একটি প্লেব্যাক-শুরু ইভেন্ট পাঠান.
- একটি প্লেব্যাক-সমাপ্ত ইভেন্ট পাঠান।
- ভিডিও বোতামে ফোকাস স্থানান্তর করুন।
components/MainScene.xml
<?xml version="1.0" encoding="utf-8" ?>
<component name="MainScene" extends="Scene" initialFocus="requestNonceButton">
<children>
<ButtonGroup>
<button text="Request Nonce" id="requestNonceButton" />
<button text="Send Ad Click" id="sendAdClickButton" />
<button text="Send Playback Start" id="sendPlaybackStartButton" />
<button text="Send Playback End" id="sendPlaybackEndButton" />
<button text="Transfer Focus to Video" id="transferFocusToVideoButton" />
</ButtonGroup>
<SampleVideoPlayer id="YourVideoPlayer" width="720" height="480" focusable="true" />
</children>
</component>
একটি SDK ইন্টারফেস উপাদান তৈরি করুন
প্রধান দৃশ্য এবং PAL SDK-এর মধ্যে যোগাযোগ করতে, আপনার একটি উপাদান প্রয়োজন যাতে অ্যাসিঙ্ক্রোনাস কোড থাকে। এটি প্রয়োজনীয় কারণ PAL SDK বাহ্যিক নেটওয়ার্ক অনুরোধ করে, যা একটি Roku অ্যাপ্লিকেশনের মূল থ্রেডে ঘটতে পারে না। এই উপাদানটিতে ডেটা পাঠাতে, আপনার একটি ইন্টারফেস প্রয়োজন যা সংজ্ঞায়িত করে যে উপাদানটি কী ডেটা পাঠায় এবং গ্রহণ করে।
components/PALInterface.xml
<?xml version="1.0" encoding="utf-8" ?>
<component name="PALInterface" extends="Task">
<interface>
<!--Commands-->
<field id="requestNonce" type="Boolean" />
<field id="sendAdClick" type="Boolean" />
<field id="sendAdTouchKey" type="String" />
<field id="sendPlaybackStart" type="Boolean" />
<field id="sendPlaybackEnd" type="Boolean" />
<field id="endThread" type="Boolean" />
<!--Responses-->
<field id="errors" type="stringarray" />
<field id="nonce" type="String" />
</interface>
</component>
IMA SDK আমদানি করুন৷
PAL লাইব্রেরি ব্যবহার করার জন্য, আপনার অ্যাপ ম্যানিফেস্টে Roku-এর জন্য IMA SDK প্রয়োজন এবং এটি PALInterface
উপাদানে আমদানি করতে হবে।
প্রকাশ
... splash_color=#000000 splash_min_time=1000 ui_resolutions=hd bs_libs_required=googleima3
components/PALInterface.xml
<?xml version = "1.0" encoding = "utf-8" ?> <component name="PALInterface" extends="Task"> <interface> <!-- commands --> <field id="requestNonce" type="Boolean" /> <field id="sendAdClick" type="Boolean" /> <field id="sendAdTouchKey" type="String" /> <field id="sendPlaybackStart" type="Boolean" /> <field id="sendPlaybackEnd" type="Boolean" /> <field id="endThread" type="Boolean" /> <!-- responses --> <field id="errors" type="stringarray" /> <field id="nonce" type="String" /> </interface> <script type = "text/brightscript"> <![CDATA[ Library "IMA3.brs" ]]> </script> </component>
দৃশ্য থেকে ট্রিগার ইন্টারফেস উপাদান
এরপরে, ব্রাইটস্ক্রিপ্ট কোড যোগ করুন যা ব্যবহারকারীর ইন্টারঅ্যাকশনের জন্য শোনে এবং ইন্টারফেস উপাদানে পরিবর্তনগুলি ট্রিগার করে:
ইন্টারফেস উপাদান থেকে আউটপুট গ্রহণ করতে, সেই আউটপুটগুলির সাথে যুক্ত ইন্টারফেস ক্ষেত্রগুলিতে ফিল্ড পর্যবেক্ষকদের প্রয়োগ করুন এবং তাদের মূল উপাদানের কলব্যাক ফাংশনের সাথে সংযুক্ত করুন। উপাদানটি প্রথম নিবন্ধিত হলে এটি করুন।
ইন্টারফেস উপাদানে ব্যবহারকারীর মিথস্ক্রিয়া পাঠাতে, সেই কমান্ডগুলির সাথে যুক্ত ইন্টারফেস ক্ষেত্রের পরিবর্তনগুলি ট্রিগার করার জন্য আপনি আগে তৈরি করা বোতামগুলিতে ক্ষেত্র পর্যবেক্ষকগুলি প্রয়োগ করুন।
components/MainScene.xml
<?xml version="1.0" encoding="utf-8" ?> <component name="MainScene" extends="Scene" initialFocus="requestNonceButton"> <children> <ButtonGroup> <button text="Request Nonce" id="requestNonceButton" /> <button text="Send Ad Click" id="sendAdClickButton" /> <button text="Send Ad Touch" id="sendAdTouchButton" /> <button text="Send Playback Start" id="sendPlaybackStartButton" /> <button text="Send Playback End" id="sendPlaybackEndButton" /> </ButtonGroup> <Video id="YourVideoPlayer" width="720" height="480" focusable="true" /> </children> <script type="text/brightscript"> <![CDATA[ Function init() requestNonceButton = m.top.findNode("requestNonceButton") requestNonceButton.observeField("buttonSelected", "requestNonce") sendAdClickButton = m.top.findNode("sendAdClickButton") sendAdClickButton.observeField("buttonSelected", "sendAdClick") sendPlaybackStart = m.top.findNode("sendPlaybackStartButton") sendPlaybackStart.observeField("buttonSelected", "sendPlaybackStart") sendPlaybackEnd = m.top.findNode("sendPlaybackEndButton") sendPlaybackEnd.observeField("buttonSelected", "sendPlaybackEnd") loadImaSdk() End Function ' Initialize SDK Interface component and attach callbacks to field observers. Function loadImaSdk() as Void m.sdkTask = createObject("roSGNode", "PALInterface") m.sdkTask.observeField("errors", "onSdkLoadedError") m.sdkTask.observeField("nonce", "onNonceLoaded") print "Running load IMA task." m.sdkTask.control = "RUN" End Function Sub onSdkLoadedError(message as Object) print "----- errors in the sdk loading process --- ";message.getData() End Sub ' Callback triggered when Nonce is loaded. Sub onNonceLoaded(message as Object) nonce = m.sdkTask.nonce print "onNonceLoaded ";nonce End Sub Function requestNonceButtonPressed() As Void print "Request Nonce" ' Inform the SDK interface component to request a nonce. m.sdkTask.requestNonce = True End Function ' Action triggered on player start, either from user action or autoplay. Function sendPlaybackStart() As Void m.sdkTask.sendPlaybackStart = True End Function ' Action triggered on player end, either when content ends or the user exits ' playback of this content. Function sendPlaybackEnd() As Void m.sdkTask.sendPlaybackEnd = True End Function ]]> </script> </component>
ফোকাস স্থানান্তর করার পদ্ধতি যোগ করুন
এরপরে, আপনার ভিডিও উপাদানে এবং থেকে ফোকাস স্থানান্তর করতে ব্যবহারকারীর কী টিপে ক্যাপচার করুন।
components/MainScene.xml
... <script type="text/brightscript"> <![CDATA[ Function init() ... m.sendPlaybackStart = m.top.findNode("sendPlaybackStartButton") m.sendPlaybackStart.observeField("buttonSelected", "sendPlaybackStart") m.sendPlaybackEnd = m.top.findNode("sendPlaybackEndButton") m.sendPlaybackEnd.observeField("buttonSelected", "sendPlaybackEnd") m.transferFocusToVideoButton = m.top.findNode("transferFocusToVideoButton") m.transferFocusToVideoButton.observeField("buttonSelected", "transferFocusToVideo") ' Your video player set up to handle key press events. m.video = m.top.findNode("YourVideoPlayer") m.video.observeField("pressedKey", "onVideoKeyPress") loadImaSdk() End Function ... ' Action triggered on player end, either when content ends or the user exits ' playback of this content. Function sendPlaybackEnd() As Void m.sdkTask.sendPlaybackEnd = True End Function Function transferFocusToVideo() As Void m.video.setFocus(true) End Function Function onVideoKeyPress() As Void key = m.video.pressedKey If key = "" Return End If m.sdkTask.sendAdTouchKey = key ' If back or up is pressed, transfer focus back up to the buttons. If key = "back" or key = "up" m.transferFocusToVideoButton.setFocus(true) End If ' Reset so that we get the next key press, even if it's a repeat of the last ' key. m.video.pressedKey = "" End Function ]]> </script> </component>
PAL SDK শুরু করুন এবং একটি ননলোডার তৈরি করুন
এখন আপনি PAL SDK বাস্তবায়নের মূল যুক্তি তৈরি করা শুরু করতে পারেন। প্রথমে, একটি পৃথক থ্রেড থেকে SDK শুরু করুন।
components/PALInterface.xml
... <script type = "text/brightscript"> <![CDATA[ Library "IMA3.brs" Sub init() ' It is not possible to access roUrlTransfer on the main thread. Setting ' functionName to a function and then setting control to "RUN" causes that 'function to run on a separate thread. m.top.functionName = "runPalThread" ' Loads the SDK on the current thread if it is not yet loaded. ' This blocks execution of other functions on this thread until the SDK is loaded. If m.sdk = Invalid m.sdk = new_imaSdk() End If m.nonceLoader = m.sdk.CreateNonceLoader() End Sub ' Starts the player event loop. This loop only terminates when "endThread" is sent. Function runPalThread() as Void ' Used for the player life cycle loop. m.top.endThread = False port = CreateObject("roMessagePort") End Function ]]> </script> </component>
প্রক্রিয়া ছাড়া অনুরোধ
একবার nonceLoader
তৈরি হয়ে গেলে, আপনাকে requestNonce
ক্ষেত্রে একজন পর্যবেক্ষক সংযুক্ত করে ননস অনুরোধগুলি পরিচালনা করতে হবে। nonceLoader
আরম্ভ হওয়ার পরেই এই পর্যবেক্ষকটিকে সংযুক্ত করে, আপনি নিশ্চিত করতে পারেন যে nonce অনুরোধগুলি SDK থ্রেডে পরিচালনা করা হয়েছে এবং একটি বৈধ nonceLoader
থাকলেই কেবলমাত্র একটি ননস অনুরোধ করা যেতে পারে।
components/PALInterface.xml
... ' Starts the player event loop. This loop only terminates when "endThread" is sent. Function runPalThread() as Void ' Used for the player life cycle loop. m.top.endThread = False port = CreateObject("roMessagePort") ' Now that the nonceLoader exists, begin listening for nonce requests. m.top.observeField("requestNonce", m.port) End Function ' Requests a nonce from the PAL SDK. Function requestNonce() as Void nonceRequest = m.sdk.CreateNonceRequest() m.nonceManager = m.nonceLoader.loadNonceManager(nonceRequest) m.top.nonce = nonceManager.getNonce() End Function ]]> </script> </component>
স্টোরেজ সম্মতি তথ্য সংগ্রহ করুন
NonceRequest.storageAllowed
এর ডিফল্ট মান true
, কিন্তু আপনি উপযুক্ত সম্মতি সংগ্রহ করার পরে এই মানটি পরিবর্তন করা যেতে পারে। getConsentToStorage()
পদ্ধতি হল একটি CMP-এর সাথে একীভূত করে, অথবা স্টোরেজ সম্মতি পরিচালনা করার জন্য অন্যান্য পদ্ধতির উপর ভিত্তি করে ব্যবহারকারীর সম্মতি পাওয়ার আপনার নিজস্ব পদ্ধতির জন্য একটি স্থানধারক।
components/PALInterface.xml
... <script type = "text/brightscript"> <![CDATA[ Library "IMA3.brs" Sub init() ' It is not possible to access roUrlTransfer on the main thread. Setting ' functionName to a function and then setting control to "RUN" causes that 'function to run on a separate thread. m.top.functionName = "runPalThread" ' Loads the SDK on the current thread if it is not yet loaded. ' This blocks execution of other functions on this thread until the SDK is loaded. If m.sdk = Invalid m.sdk = new_imaSdk() End If m.isConsentToStorage = getConsentToStorage() m.nonceLoader = m.sdk.CreateNonceLoader() End Sub ... ' Requests a nonce from the PAL SDK. Function requestNonce() as Void nonceRequest = m.sdk.CreateNonceRequest() ' Include changes to storage consent here. nonceRequest.storageAllowed = m.isConsentToStorage m.nonceManager = m.nonceLoader.loadNonceManager(nonceRequest) m.top.nonce = nonceManager.getNonce() End Function
খেলোয়াড় জীবন চক্র সংকেত জন্য শুনুন
আপনার PAL ইন্টিগ্রেশনকে সঠিকভাবে সিগন্যাল পাঠানোর অনুমতি দিতে, আপনাকে আপনার প্লেয়ারের জীবন চক্রের সংকেত শোনার জন্য একটি লুপ সেট আপ করতে হবে।
components/PALInterface.xml
... ' Now that the nonceLoader exists, begin listening for nonce requests. m.top.observeField("requestNonce", m.port) m.top.observeField("sendAdClick", m.port) m.top.observeField("sendAdTouchKey", m.port) m.top.observeField("sendPlaybackStart", m.port) m.top.observeField("sendPlaybackEnd", m.port) ' Setting endThread to true causes the while loop to exit. m.top.observeField("endThread", m.port) While Not m.top.endThread message = m.port.waitMessage(1000) If message = Invalid pollManager() Else If message.getField() = "requestNonce" And m.top.requestNonce = True requestNonce() m.top.requestNonce = False Else If message.getField() = "sendAdClick" And m.top.sendAdClick = True sendAdClick() m.top.sendAdClick = False Else If message.getField() = "sendAdTouchKey" And m.top.sendAdTouchKey <> "" sendAdTouch(m.top.sendAdTouchKey) m.top.sendAdTouchKey = "" Else If message.getField() = "sendPlaybackStart" And m.top.sendPlaybackStart = True sendPlaybackStart() m.top.sendPlaybackStart = False Else If message.getField() = "sendPlaybackEnd" And m.top.sendPlaybackEnd = True sendPlaybackEnd() m.top.sendPlaybackEnd = False End If End While End Function Function pollManager() as Void If m.nonceManager <> Invalid m.nonceManager.poll() End If End Function ' Requests a nonce from the PAL SDK. Function requestNonce() as Void nonceRequest = m.sdk.CreateNonceRequest() m.nonceManager = m.nonceLoader.loadNonceManager(nonceRequest) m.top.nonce = nonceManager.getNonce() End Function ]]> </script> </component>
sendPlaybackStart
, sendPlaybackEnd
, sendAdClick
, এবং sendAdTouch
এর জন্য শ্রোতাদের নিবন্ধন করুন
এরপর, "ভিডিও প্লেয়ার স্টার্ট"-এ sendPlaybackStart
কল করুন। এই পদ্ধতিটি IVT পর্যবেক্ষণ এবং সনাক্তকরণের জন্য প্রয়োজনীয় সংকেত সংগ্রহ করতে Google সার্ভারে অ্যাসিঙ্ক্রোনাস কল শুরু করে। প্লেব্যাক শেষ হলে sendPlaybackEnd
কল করুন। বিজ্ঞাপন ক্লিকথ্রু উত্তরে sendAdClick
কল করুন. তারপর, অ-ক্লিকথ্রু ব্যবহারকারী স্পর্শ বা ক্লিক ইভেন্টের জন্য sendAdTouch
কল করুন।
components/PALInterface.xml
... ' Requests a nonce from the IMA SDK. Function requestNonce() as Void nonceRequest = m.sdk.CreateNonceRequest() m.nonceManager = m.nonceLoader.loadNonceManager(nonceRequest) m.top.nonce = nonceManager.getNonce() End Function ' Registers an ad click using the IMA SDK. Function sendAdClick() as Void If m.nonceManager <> Invalid m.nonceManager.sendAdClick() End If End Function ' Registers an ad touch event using the IMA SDK. Function sendAdTouch(touch as String) as Void If m.nonceManager <> Invalid m.nonceManager.sendAdTouch(touch) End If End Function ' Registers the start of playback using the IMA SDK. Function sendPlaybackStart() as Void If m.nonceManager <> Invalid m.nonceManager.sendPlaybackStart() End If End Function ' Registers the end of playback using the IMA SDK. Function sendPlaybackEnd() as Void If m.nonceManager <> Invalid m.nonceManager.sendPlaybackEnd() End If End Function ]]> </script> </component>
বিজ্ঞাপনের অনুরোধে নন্স সংযুক্ত করুন
একটি প্রোডাকশন অ্যাপ্লিকেশনে আপনি PAL লাইব্রেরি থেকে প্রাপ্ত ননস ব্যবহার করতে, ননস তৈরি হওয়ার পরেই আপনার বিজ্ঞাপনের অনুরোধগুলি শুরু করুন। তারপরে, u_paln
প্যারামিটার ব্যবহার করে বিজ্ঞাপন ট্যাগে nonce যোগ করুন।
components/MainScene.xml
... ' Callback triggered when Nonce is loaded. Sub onNonceLoaded(message as Object) nonce = m.sdkTask.nonce print "onNonceLoaded ";nonce makeAdRequest(nonce) End Sub Sub makeAdRequest(nonce) ' Sample ad tag URL used in this sample. Your apps method of getting this ' URL will likely be different. adTag = "https://pubads.g.doubleclick.net/gampad/ads?iu=/124319096/external/single_ad_samples" preparedTag = adTag + "&u_paln=" + nonce ' Implement custom ad request logic here. Print "ad tag with nonce ";preparedTag End Sub ...
তাই তো! আপনার কাছে এখন একটি Roku অ্যাপ রয়েছে যা PAL ননসের অনুরোধ করতে পারে এবং PAL SDK-এর সাথে প্লেব্যাক সেশন ইভেন্টগুলি নিবন্ধন করতে পারে৷
(ঐচ্ছিক) তৃতীয় পক্ষের বিজ্ঞাপন সার্ভারের মাধ্যমে Google Ad Manager সংকেত পাঠান
অ্যাড ম্যানেজারের জন্য তৃতীয় পক্ষের বিজ্ঞাপন সার্ভারের অনুরোধ কনফিগার করুন।
অ্যাড ম্যানেজারের কাছে সার্ভারের অনুরোধে ননস অন্তর্ভুক্ত করতে আপনার তৃতীয় পক্ষের বিজ্ঞাপন সার্ভার কনফিগার করুন। তৃতীয় পক্ষের বিজ্ঞাপন সার্ভারের ভিতরে কনফিগার করা একটি বিজ্ঞাপন ট্যাগের উদাহরণ এখানে দেওয়া হল:
'https://pubads.serverside.net/gampad/ads?givn=%%custom_key_for_google_nonce%%&...'
আরও বিশদ বিবরণের জন্য, Google অ্যাড ম্যানেজার সার্ভার-সাইড বাস্তবায়ন নির্দেশিকা দেখুন।
বিজ্ঞাপন ম্যানেজার নন্স ভ্যালু সনাক্ত করতে givn=
খোঁজে। তৃতীয় পক্ষের বিজ্ঞাপন সার্ভারের নিজস্ব কিছু ম্যাক্রো সমর্থন করতে হবে, যেমন %%custom_key_for_google_nonce%%
, এবং এটিকে আপনার পূর্ববর্তী ধাপে দেওয়া ননস কোয়েরি প্যারামিটার দিয়ে প্রতিস্থাপন করতে হবে। এটি কীভাবে সম্পন্ন করা যায় সে সম্পর্কে আরও তথ্য তৃতীয় পক্ষের বিজ্ঞাপন সার্ভারের ডকুমেন্টেশনে পাওয়া উচিত।
তাই তো! আপনার এখন PAL SDK থেকে আপনার মধ্যস্থতাকারী সার্ভারের মাধ্যমে এবং তারপর Google Ad Manager-এর মাধ্যমে ননস প্যারামিটার প্রচার করা উচিত। এটি Google Ad Manager-এর মাধ্যমে আরও ভাল নগদীকরণ সক্ষম করে৷