Reading time: 5 minutes

Cloudflare skriptas (Amazon affiliate API)






Ką gi, pažadus reikia tęsėti. artefaktas.eu tinklaraštyje minėjau, jog aprašysiu būdą pasidaryti affiliate API panaudojant React, Cloudflare skriptą ir Google Sheets. Prieš pažvelgiant į programinį kodą pateiktą žemiau, patariu apsilankyti viename senesnių artefaktas.eu tinklaraščio įrašų. Jį galite rasti paspaudę mygtuką “Skaityti” pridėtoje Embed kortelėje.

Cloudflare skriptas sukurti automatizuotai užduočiai

Skriptas ganėtinai paprastas ir nesudėtingas. Jo veikimui būtini keletas svarbių aspektų:

  • Viešai prieinamas Google Sheet dokumentas
  • Google Sheets viešai prieinamo dokumento id (identifikacinis unikalus numeris)
  • Google Sheets API raktas
  • Google Sheets rėžis, kurį norima paimti iš dokumento talpinamo Google Drive

Kas čia atliekama?

/update

  1. Reguliariu laiko intervalu vykdoma funkcija siunčianti užklausas į /update nuorodą
  2. Sukonstruojama nauja nuoroda pagal iš anksto pateiktus kintamuosius (Referrer užklausos antraštę galima naudoti priklausomai nuo API rakto apribojimų)
  3. Sukonstruotosios nuorodos adresu pateikiama užklausa
  4. Gaunamas atsakas, kuris atgal pateikia duomenų masyvą
  5. Duomenų masyvas sulyginamas su KV vardų porų bazėje esančiu duomenų masyvu
  6. Jei masyvų tekstinės reikšmės nesutampa, tai naujausiai gautų duomenų masyvas patalpinamas į KV vardų porų bazę pažymint jį vardo raktu “data”. Taip duomenys atnaujinami arba patalpinami pirmąjį kartą.

/api

Šiuo adresu besibaigianti nuoroda grąžina masyvą suformuotą iš dviejų atsitiktinai parinktų elementų esančių KV bazėje.

addEventListener("fetch", (event) => {
  event.respondWith(
    handleRequest(event.request).catch(
      (err) => new Response(err.stack, { status: 500 })
    )
  );
});

/**
 * Many more examples available at:
 *   https://developers.cloudflare.com/workers/examples
 * @param {Request} request
 * @returns {Promise<Response>}
 */

async function returnArray(){
  const RANGE = `A1:D170`;
    let fetchUrl = `https://sheets.googleapis.com/v4/spreadsheets/${SHEET_ID}/values/Sheet1!${RANGE}?key=${API_KEY}`;
     let headers = {
      "Referer":"",
    }
    let res = await fetch(fetchUrl,{
      headers:headers
    });
    let jsonData = await res.json();
   
    let names = jsonData.values[0];
    let data = jsonData.values.splice(1);
    let newData = [];
    data.forEach((element, index) => {
      let obj = {};
      names.forEach((el, sh) => {
          obj[el] = element[sh];
      });
      newData.push(obj);
    });
    newData = JSON.stringify(newData);
    return newData;
}

async function returnRandom(){
  let d = await AF_BASE.get("data");
  let parsedJson = JSON.parse(d);
  let randomEel = parsedJson[Math.floor(Math.random() * parsedJson.length)];
  return randomEel;
}

async function returnCurrentdata(){
  let firstEl = await returnRandom();
  let secondEl = await returnRandom();
  let newArr = [];
  newArr.push(firstEl);
  newArr.push(secondEl);
  newArr = JSON.stringify(newArr);
  return newArr;
}


async function handleRequest(request) {
  const { pathname } = new URL(request.url);

  if (pathname.startsWith("/api")) {
    let arr;
    let currentData = await returnCurrentdata();
    if(currentData == ""){
    arr = await returnArray();
    await AF_BASE.put("data",arr);
    }
    else{
    arr = await returnCurrentdata();
    }
    return new Response(arr, {
      headers: { 
        "Access-Control-Allow-Origin":"*",
        "Content-Type": "application/json", 
        'Cache-Control': 'no-store', 
        "Access-Control-Allow-Headers": "GET",
       },
    });
  }
  else if (pathname.startsWith("/update")) {
  let requestData = await returnArray();
  let baseData = await returnCurrentdata();
  if(String(requestData) !== String(baseData)){
      await AF_BASE.put("data",requestData);
  }
  return new Response(JSON.stringify("Updated"), {
      headers: { 
        "Access-Control-Allow-Origin":"*",
        "Content-Type": "application/json", 
        'Cache-Control': 'no-store', 
        "Access-Control-Allow-Headers": "GET",
       },
    }); 
  }
 else{
    return new Response(JSON.stringify("Error"), {
      headers: { 
        "Access-Control-Allow-Origin":"*",
        "Content-Type": "application/json", 
        'Cache-Control': 'no-store', 
        "Access-Control-Allow-Headers": "GET",
       },
    }); 
 }
}

Affiliate Widget kodas

Reikalingas elementas

<div id="affiliateLine"></div>

Algoritmas parenka affiliateLine ir užpildo jį informacija gauta iš užklausos išsiųstos į /api nuorodą, parinkdamas vieną iš dviejų galimų panaudojimo variantų atsitiktiniu būdu.

class AffilliateWidget extends React.Component {
	constructor() {
		super();
		this.fetchLink = `https://somethingsomething.workers.dev/api`;
		this.state = {
			data: null,
		};
		this.cardStyle = {
			maxWidth: 400 + `px`,
			padding: 1 + `rem`,
			boxShadow: `0 4px 8px 0 rgba(0,0,0,0.2)`,
			textAlign: `center`,
			alignItems: `center`,
			borderRadius: 8 + `px`,
			display: `block`,
			marginLeft: `auto`,
			marginRight: `auto`,
		};
		this.returnData = this.returnData.bind(this);
	}

	returnData(arr) {
		let item = arr[Math.floor(Math.random() * arr.length)];
		return (
			<div>
				<h3>Affiliate links</h3>
				<br />
				<h4>{item.Title}</h4>
				<br />
				<h4>{item.Text}</h4>
				<br />
				<p dangerouslySetInnerHTML={{ __html: item.Code }}></p>
			</div>
		);
	}

	componentDidMount() {
		let fetchUrl = this.fetchLink;
		async function fetchData() {
			let res = await fetch(fetchUrl);
			let jsonData = await res.json();
			return jsonData;
		}

		fetchData().then((d) => {
			this.setState({ data: d });
		});
	}

	render() {
		return (
			<div style={this.cardStyle}>
				{this.state.data !== null
					? this.returnData(this.state.data)
					: ""}
			</div>
		);
	}
}

ReactDOM.render(<AffilliateWidget />, document.getElementById("affiliateLine"));

Kaip turėtų atrodyti Google sheets dokumentas?

Dokumentą pagal čia esantį pavyzdį turėtų sudaryti keturi stulpeliai pradedant A ir baigiant D raide. Pavyzdinį paveikslėlį prisegu apačioje.

sheets

Visa pateikiama informacija - asmeninė autoriaus nuomonė. Kilus naiškumams rekomenduojama susisiekti elektroniniu paštu: admin@artefaktas.eu

Comments

comments powered by Disqus