Moments
Mobile
React Native
introduction welcome to the comprehensive guide on integrating the adspostx moments api into your react native application! this guide will provide you with step by step instructions to seamlessly incorporate adspostx offers into your app's user experience before starting before diving into the integration process, there are a few preliminary steps you need to take obtain an api key to access the moments api, you must obtain an api key follow the instructions provided to acquire your unique api key plan your implementation determine where adspostx offers will display within your app decide whether offers will appear as part of a screen or as full screen modal overlays specify whether offers should display once per session or each time a specific section of the app is accessed getting started let's kickstart the integration process by completing the following tasks install dependency packages you'll need to install the necessary dependency packages, axios and react native device info , to make api calls from your app and obtain device related information run the provided command to install these packages dependency packages installation command npm install axios react native device info implement intent filter for android app to ensure offer links open in an external browser on android devices, add the provided intent filter to the androidmanifest xml file of your app \<queries> \<intent> \<action android\ name="android intent action view" /> \<category android\ name="android intent category browsable" /> \<data android\ scheme="https" /> \</intent> \</queries> get your device user agent parameter when calling our api, it's important to include the user agent parameter here's how you can retrieve its value for the device using the react native device info package fetching 'user agent' parameter import deviceinfo from 'react native device info'; export const getuseragent = async () => { return await deviceinfo getuseragent(); }; generating user identifiers when communicating with the api, it's recommended to include an identifier unique to each user in the code example provided, we utilize the device id retrieved from the 'react native device info' package for this purpose to implement this, simply pass an alphanumeric string unique to each user on your system to the adpx fp parameter within the payload of the fetch offers call adspostx uses the adpx fp value to control how often offers are shown to a user and to prevent the same offer from appearing again when a user opts out generating unique user id import deviceinfo from 'react native device info'; export const generateuniqueid = () => { return platform select({ ios deviceinfo getuniqueid(), // idfv for ios android deviceinfo getandroidid(), // androidid for android default 'unknown', }); }; fetch offer data utilize axios to retrieve offers from the moments api structure the api call with relevant parameters such as apikey, query, and payload the function below is a "wrapper" for the moments api for complete information about the moments api, please refer to the moments api documentation call moments api import axios from 'axios'; import {firepixel, getuseragent, openurl} from ' /util'; const \[offers, setoffers] = usestate(null); // function to fetch moment offers from the api const fetchmomentoffers = async (apikey, queryparameters, payload) => { try { let useragent = payload? ua ?? (await getuseragent()); // define headers for the api request const headers = { 'content type' 'application/json', 'accept' 'application/json', // user agent value can be obtained from the // "react native device info" package 'user agent' useragent, }; const allqueryparameters = { api key apikey, (queryparameters || {}), }; // remove undefined values from allparams if (queryparameters) { object keys(allqueryparameters) foreach( key => allqueryparameters\[key] === undefined && delete allqueryparameters\[key], ); } // remove undefined values from payload if (payload) { object keys(payload) foreach( key => payload\[key] === undefined && delete payload\[key], ); } // generate the query string const querystring = object keys(allqueryparameters) map( key => `${encodeuricomponent(key)}=${encodeuricomponent( allqueryparameters\[key], )}`, ) join('&'); // construct the api url const apiurl = `http //api adspostx com/native/v2/offers json${ querystring ? `?${querystring}` '' }`; // make a post request to the api const response = await axios post(apiurl, payload, {headers}); return response; } catch (error) { throw error; } }; const fetchdata = async () => { const queryparameters = {loyaltyboost '0', creative '0'}; const payload = { // 'dev' '1' enables sandbox environment and // returns offers for testing purposes; no activity is recorded // use '1' while testing only and not in production 'dev' '1', // replace the value of 'adpx fp' with your // unique user identifier (customer id, user id, etc) 'adpx fp' (await generateuniqueid()) tostring(), }; try { const result = await fetchmomentoffers( '\<api key>', //replace with your generated api key queryparameters, payload, ); let offerarray = result data? data? offers; setoffers(offerarray); } catch (error) { console log('error in while fetchoffers ', error); setoffers(null); } }; now you can call the fetchdata function anywhere in your app whenever you need to retrieve offer data when dev is set to '1', the sandbox environment is enabled for testing purposes only, with no activity recorded in production in this mode, geo targeting is ignored for publishers, ensuring that all offers are returned in ad responses for comprehensive testing supporting functions in the previous code snippet, several functions are invoked to facilitate various operations here's an overview of each function and its purpose firepixel function this function is utilized to send requests to different urls based on specific conditions when a new offer is displayed on the screen when a negative call to action (cta) like "no thanks" is tapped when the user taps on the close button openurl function this function is invoked when the user interacts positively with the offer image or a call to action (cta) it facilitates opening a link in an external browser for further engagement firepixel function import axios from 'axios'; import {linking} from 'react native'; import deviceinfo from 'react native device info'; export const firepixel = url => { if (url) { console log('\[adspostxapidemo] inside fire pixel'); axios get(url) then(response => { console log('\[adspostxapidemo] fire pixel success ', response data); }) catch(error => { console error('fire pixel error ', error); }); } }; openurl function import axios from 'axios'; import {linking} from 'react native'; import deviceinfo from 'react native device info'; export const openurl = async url => { if (url) { const supported = await linking canopenurl(url); if (supported) { await linking openurl(url); } else { console log(`\[adspostxapidemo] cannot open url ${url}`); } } }; implementing ui and event beacons after obtaining the data in the previous step, it's time to design the user interface (ui) and update it according to the data we'll also want to ensure that different event beacons are fired as the user engages with the ui in this example, we'll showcase a standard modal box that displays a sequence of offers with navigation and a close button while this example features a modal/pop up box, feel free to build any experience you wish the primary purpose of this example is to demonstrate navigation between offers as well as how to fire event beacons as the user moves along the offer sequence ui design we'll split the ui into two main parts part 1 offer container ui (offercontainerview) this section encompasses the navigation buttons, offer display area, and a close button navigation buttons these allow users to move to the previous or next offer close button enables users to close the entire offer container ui input data data required to render the offer ui inside the offer container ui we'll set up a callback function oncloseoffercta we send a request to the url defined in beacons? close is invoked when the user closes an offercontainerview or when the user taps on the negative cta on the last offer presented when invoked by tapping on the close button, shouldfirepixel will be set to true when invoked by tapping on the negative cta on the last offer presented, shouldfirepixel will be set to false const \[offers, setoffers] = usestate(null); const \[isofferclosed, setofferclosed] = usestate(false); {!isofferclosed && offers && offers length > 0 && ( \<offercontainerview offers={offers} oncloseoffercta={(currentindex, shouldfirepixel) => { console log('\[adspostxapidemo] close button tapped'); if (shouldfirepixel) { firepixel(offers\[currentindex]? beacons? close); } setofferclosed(true); }} /> )} once the user closes the offer container ui, the next time you want to show offers, you need to reload them to reload offers, you can reset the offer state and fetch new data here's how you can do it setofferclosed(false); fetchdata(); offercontainerview overview item description currentoffer keeps track of the current offer displayed by the offerview currentofferindex tracks the position of the currently displayed offer in an array of offers openurl function called when the user taps on the offer image or a positive call to action (cta) firepixel function to send requests to various urls under different conditions, including rendering new offers when a new offer is rendered, a request is sent to the pixel url which we can get from pixel when the user taps on the close button, a request is sent to the `close beacon` url which we can get it from beacons? close when the user taps on a negative cta, a request is sent to the beacons? no thanks click url gotonextoffer responsible for handling actions when want to display next offer gotopreviousoffer responsible for handling actions when want to display prev offer oncloseoffercta callback function which will be invoked when user tap on close button and when last offer has been viewed complete source code of offercontainerview\ js import react, {usestate, useeffect} from 'react'; import {view, stylesheet, touchableopacity, text} from 'react native'; import offerview from ' /offerview'; import {firepixel, openurl} from ' /util'; function offercontainerview({offers, oncloseoffercta}) { const \[currentoffer, setcurrentoffer] = usestate(null); const \[currentofferindex, setcurrentofferindex] = usestate(0); useeffect(() => { setcurrentoffer(offers\[currentofferindex]); console log('\[adspostxapidemo] firing pixel now'); firepixel(offers\[currentofferindex]? pixel); }, \[currentofferindex]); const gotonextoffer = shouldclose => { console log('\[adspostxapidemo] go to next offer tapped'); var currentindex = currentofferindex; if (currentindex == offers length 1) { if (!shouldclose) { return; } oncloseoffercta(currentofferindex, shouldclose); return; } currentindex += 1; setcurrentofferindex(currentindex); }; const gotopreviousoffer = () => { var currentindex = currentofferindex; if (currentindex == 0) { return; } console log('\[adspostxapidemo] go to previous offer tapped'); currentindex = 1; setcurrentofferindex(currentindex); }; return ( \<view style={styles container}> \<touchableopacity onpress={() => { oncloseoffercta(currentofferindex, true); }} style={{flexdirection 'row reverse', padding 8}}> \<text>close\</text> \</touchableopacity> {currentoffer && ( \<offerview title={currentoffer title} description={currentoffer description} imageurl={currentoffer image} clickurl={currentoffer click url} imagectaaction={() => { openurl(currentoffer? click url); }} positivecta={currentoffer cta yes} onpositivecta={() => { console log('\[adspostxapidemo] positive cta clicked'); console log('\[adspostxapidemo] opening a link url'); openurl(currentoffer? click url); gotonextoffer(true); }} negativecta={currentoffer cta no} onnegativecta={() => { console log('\[adspostxapidemo] negative cta clicked'); console log( '\[adspostxapidemo] fire no thanks beacon when negative cta tapped ', ); firepixel(currentoffer? beacons? no thanks click); gotonextoffer(true); }} /> )} \<view style={styles bottomtoolbar}> \<touchableopacity onpress={gotopreviousoffer} style={styles navigationbutton}> \<text>{'<'}\</text> \</touchableopacity> \<touchableopacity onpress={() => { gotonextoffer(false); }} style={styles navigationbutton}> \<text>{'>'}\</text> \</touchableopacity> \</view> \</view> ); } const styles = stylesheet create({ container { justifycontent 'flex start', flexdirection 'column', bordercolor 'black', borderradius 8, borderwidth 1, margin 8, }, bottomtoolbar { height 44, width '100%', backgroundcolor 'black', alignitems 'center', justifycontent 'space evenly', flexdirection 'row', }, navigationbutton { backgroundcolor 'grey', padding 8, paddingstart 16, paddingend 16, }, }); export default offercontainerview; part 2 offer ui (offerview) offerview component overview the offerview component is crucial for rendering individual offer units and managing various interactions the primary responsibility of offerview is to render an individual offer unit each offerview has the following parts offer part description title represents the title of the offer title imageurl represents the url of the offer image image description represents the description of the offer description clickurl represents the url to hit when the positive cta is tapped or when the offer image is tapped onimagecta represents a callback function triggered when the offer image is tapped we need to fetch the click url and then open it in an external browser, which is handled by the openurl function positivecta represents the text for the positive call to action (cta) cta yes onpositivecta represents a callback function triggered when the positive cta is tapped in this callback function we open the url stored in click url in an external browser we move the user to the next offer by invoking gotonextoffer negativecta represents the text for the negative cta cta no onnegativecta represents a callback function triggered when the negative cta is tapped in this callback function we send a request using the url stored in beacons? no thanks click we move the user to the next offer by calling gotonextoffer complete source code of offerview\ js offerview\ js source code import react, {useeffect} from 'react'; import {view, stylesheet, text, image, touchableopacity} from 'react native'; function offerview({ title, imageurl, description, clickurl, onimagecta, positivecta, onpositivecta, negativecta, onnegativecta, }) { return ( \<view style={styles container}> {title && \<text style={styles title}>{title}\</text>} {imageurl && ( \<touchableopacity onpress={onimagecta}> \<image source={{uri `${imageurl}`}} resizemode="contain" style={styles image} /> \</touchableopacity> )} {description && \<text style={styles description}>{description}\</text>} \<view style={styles ctacontainer}> {positivecta && ( \<touchableopacity onpress={onpositivecta} style={\[styles cta, {backgroundcolor '#3565a9'}]}> \<text style={styles ctatext}>{positivecta}\</text> \</touchableopacity> )} {negativecta && ( \<touchableopacity onpress={onnegativecta} style={\[styles cta, {backgroundcolor 'grey'}]}> \<text style={styles ctatext}>{negativecta}\</text> \</touchableopacity> )} \</view> \</view> ); } const styles = stylesheet create({ container { backgroundcolor 'transparent', }, title { textalign 'center', color 'white', backgroundcolor '#3565a9', fontsize 20, padding 8, marginbottom 16, }, image { height 150, width '100%', }, description { textalign 'center', padding 8, fontsize 16, marginbottom 16, }, ctacontainer { flexdirection 'column', justifycontent 'space between', alignitems 'center', }, cta { padding 16, marginbottom 16, borderradius 8, }, ctatext { color 'white', }, }); export default offerview; explore the adspostx example on github by visiting the provided link download the example, then run it on your machine to see it in action help 📢 if you're running into any issues while going through the integration process, feel free to contact us at help\@adspostx com