Discord oAuth2 API ratelimit triggered without any (known) cause - php

First question! Woho!
I'm currently coding a Dashboard for a Discord bot in PHP.
Recently, when trying to select a server, it would only display 3 malfunctioning items. So I checked the complete array using print_r() and it turned out it rate-limited me.
Now, I got no idea why that happened, as I'm the only person on the server. So what am I doing wrong? Here is the code for listing the selection page:
$all = DiscordAPI("/users/#me/guilds");
foreach ($all as $guild) {
echo "<a href='/?server=" . $guild['id'] . "'><p>";
if ($guild['icon']) {
if (substr($guild['icon'], 0, 2) == "a_") {
echo "<img class='server-icon' src='https://cdn.discordapp.com/icons/" . $guild['id'] . "/" . $guild['icon'] . ".gif?size=64'>";
} else {
echo "<img class='server-icon' src='https://cdn.discordapp.com/icons/" . $guild['id'] . "/" . $guild['icon'] . ".webp?size=64'>";
}
} else {
$words = explode(" ", $guild['name']);
$acronym = "";
foreach ($words as $w) {
$acronym .= $w[0];
}
echo "<img class='server-icon' src='https://cdn.statically.io/avatar/s=64/" . $acronym . "'>";
}
echo $guild['name'];
echo "</p></a>";
}
And here is the code for the DiscordAPI() function:
function DiscordAPI($endpoint)
{
if (!$_SESSION['token']) {
die("No token provided");
}
$ch = curl_init("https://discord.com/api" . $endpoint);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
"Authorization: Bearer " . $_SESSION['token']
));
$data = curl_exec($ch);
curl_close($ch);
return json_decode($data, true);
}
There are 2 API calls before this code to verify that there is a valid token.
Quick sidenote: I got Autism, so I might understand stuff a bit differently. Don't be scared to ask if I worded something hard to understand. Thank you for trying to understand me.

Related

Plain text (HTML) in wordpress admin

I am developing my custom theme and I noticed that some of the links result in showing me plain text HTML instead of normal webpage. I tracked down the issue and found out that this happens when I include one custom php file inside my functions.php. I found that code on one of the tutorial on how to create social share buttons. If I comment include out everything works like a charm. I tried to investigate the file but I couldn't find anything wrong with it, could you please have a look what might be wrong?
<?php
function get_likes($url) {
$json_string = file_get_contents('https://api.facebook.com/method/links.getStats?urls=' . $url . '&format=json');
$json = json_decode($json_string, true);
if(isset($json[0]['total_count'])){
return intval( $json[0]['total_count'] );
} else { return 0;}
}
function get_tweets($url) {
$json_string = file_get_contents('http://urls.api.twitter.com/1/urls/count.json?url=' . $url);
$json = json_decode($json_string, true);
if(isset($json['count'])){
return intval( $json['count'] );
} else {return 0;}
}
function get_plusones($url) {
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, "https://clients6.google.com/rpc");
curl_setopt($curl, CURLOPT_POST, 1);
curl_setopt($curl, CURLOPT_POSTFIELDS, '[{"method":"pos.plusones.get","id":"p","params":{"nolog":true,"id":"' . $url . '","source":"widget","userId":"#viewer","groupId":"#self"},"jsonrpc":"2.0","key":"p","apiVersion":"v1"}]');
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_HTTPHEADER, array('Content-type: application/json'));
$curl_results = curl_exec ($curl);
curl_close ($curl);
$json = json_decode($curl_results, true);
if(isset($json[0]['result']['metadata']['globalCounts']['count'])){
return intval( $json[0]['result']['metadata']['globalCounts']['count'] );
} else {return 0;}
}
function get_stumble($url) {
$json_string = file_get_contents('http://www.stumbleupon.com/services/1.01/badge.getinfo?url='.$url);
$json = json_decode($json_string, true);
if (isset($json['result']['views'])) {
return intval($json['result']['views']);
} else {return 0;}
}
if(isset($_GET["thisurl"])){
$thisUrl=$_GET["thisurl"];
$firstpart = substr("$thisUrl", 0, 22);
// Change http://medialoot.com to your own domain!
if ($firstpart == 'http://mdbootstrap.com') {
$data = "{";
$data .= '"facebook": '. json_encode(get_likes($thisUrl)) . ", ";
$data .= '"twitter": ' . json_encode(get_tweets($thisUrl)) . ", ";
$data .= '"gplus": ' . json_encode(get_plusones($thisUrl)) . ", ";
$data .= '"stumble": ' . json_encode(get_stumble($thisUrl)) . "}";
} else {
//throw error
$data = 'ERROR - you are trying to use this script for something outside of the allowed domain';
}
} else {
$data = '';
}
header('Content-Type: application/json');
echo $data;
?>
You are echoing the contents of $data – I guess thats also what you are seeing if I understood that correctly.
If the code is included in your functions.php like this, it probably gets executed as soon as the functions.php file is loaded, which might be too late or too early.
To be able to control when the code executes, you should have a look into WordPress Hooks and hook your code into this mechanism.
If you can tell me more about what exactly you are trying to do, I might be able to give a more detailed answer.
Just as a sidenote: Take care not to cross over into Plugin territory with your theme. As soon as you are trying to do anything more than modifying the look of something, it doesn't belong into functions.php anymore but a separate plugin.

How get geolocation info outside of pc "LocalHost"?

I want obtain some geolocation informations using a external service (website service), but this works fine only in my pc (localhost using WampServer http client); already when my php file is transfered for a remote host (pc), it fails for get these information. Already tried several services of hosts, but still without success.
PS: My reference of website was http://ip-api.com/.
Here is my code:
$ip = $_REQUEST['REMOTE_ADDR'];
$query = #unserialize(file_get_contents('http://ip-api.com/php/'.$ip));
if($query && $query['status'] == 'success') {
$regiao = $query['regionName'];
$cidade = $query['city'];
$isp = $query['isp'];
$sigla_regiao = $query['region'];
}
else {
echo '';
}
So, someone have some ideia why this api don't works in a remote host?
Thanks in advance.
According to the error you posted, the file_get_contents function is not able to create a connection to the remote host. It may be that the access to remote resources is disabled for certain functions.
You can try to access the remote URL with cURL:
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, "http://ip-api.com/php" . $ipAddr);
curl_setopt ($curl, CURLOPT_RETURNTRANSFER, 1);
$content = curl_exec ($curl);
curl_close ($curl);
if (curl_errno($curl))
throw new \Exception(sprintf("Connection error %s: %s", curl_errno($curl), curl_error($curl)));
print_r(unserialize($content));
If you're interested in another provider, you can use the services of https://geoip-db.com
A working JSON example:
<?php
$json = file_get_contents('https://geoip-db.com/json');
$data = json_decode($json);
print $data->country_code . '<br>';
print $data->country_name . '<br>';
print $data->state . '<br>';
print $data->city . '<br>';
print $data->postal . '<br>';
print $data->latitude . '<br>';
print $data->longitude . '<br>';
print $data->IPv4 . '<br>';
?>
Or a JSONP callback with php:
<?php
$jsonp = file_get_contents('https://geoip-db.com/jsonp');
$data = jsonp_decode($jsonp);
print $data->country_code . '<br>';
print $data->country_name . '<br>';
print $data->state . '<br>';
print $data->city . '<br>';
print $data->postal . '<br>';
print $data->latitude . '<br>';
print $data->longitude . '<br>';
print $data->IPv4 . '<br>';
// Strip callback function name and parenthesis
function jsonp_decode($jsonp) {
if($jsonp[0] !== '[' && $jsonp[0] !== '{') {
$jsonp = substr($jsonp, strpos($jsonp, '('));
}
return json_decode(trim($jsonp,'();'));
}
?>

Etsy API Pagination with PHP

So, I'm fairly new to working with APIs, and am just trying to play around with using the Etsy API to display a certain set of listings.
By default, the API returns a set of 25 results, and can do a max of 100 at a time. I'd like to show more than that, so I'm trying to add pagination to my call. Here's what I've got so far:
<?php
//setting API key
define("API_KEY", XXX);
//setting request url
$url = "https://openapi.etsy.com/v2/listings/active?keywords=unicorn,unicorns&includes=Images:1:0&api_key=" . API_KEY;
while (isset($url) && $url != '') {
$curl = curl_init($url);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
$response_body=curl_exec($curl);
curl_close($curl);
$response = json_decode($response_body);
foreach ($response->results as $listing) {
echo "<li>" . $listing->title . " ~*~ " . $listing->price . " " . $listing->currency_code . " ~*~ " . 'View on Etsy!' . "</li>" . "<br>";
}
$url = $response->pagination->next_page;
}
?>
I thought this would loop through and return the next set of 25 results, but it didn't. Anyone have experience working with this? Is there somewhere I'm getting tripped up?
Thanks!
In your while block, you are assigning the value of the next_page property to $url.
But the actual value is an int, 2, not an url.
Instead append the next_page to the initial url, as a query string variable.
$url .= "&page=" . $response->pagination->next_page;
See below an example on how you can isolate each process to a function.
We move the curl operation into its own function where it returns an object from json_decode.
We move the whole processing of the listings into a separate function, where for now, it just prints out the listings.
This second function is recursive, meaning, that if the next page exists it will call the first function, get the response, then process it.
<?php
//setting API key
define("API_KEY", 'br4j52uzdtlcpp6qxb6we3ge');
function get_listings($page=1){
$url = "https://openapi.etsy.com/v2/listings/active?keywords=unicorn,unicorns&includes=Images:1:0&api_key=" . API_KEY;
$url .= "&page=$page";
$curl = curl_init($url);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
$response_body=curl_exec($curl);
curl_close($curl);
$responseObject = json_decode($response_body);
return $responseObject;
}
function process_listings($responseObject){
foreach ($responseObject->results as $listing) {
echo "Title: " . $listing->title . PHP_EOL .
"Price " . $listing->price . PHP_EOL .
"Currency code " . $listing->currency_code . PHP_EOL .
'URL ' . $listing->url . PHP_EOL;
}
print PHP_EOL . "Pagination " . $responseObject->pagination->next_page . PHP_EOL;
$next_page = $responseObject->pagination->next_page;
if ($next_page) {
$nextPageResponse = get_listings($next_page);
process_listings($nextPageResponse);
}
}
$firstPage = get_listings(); // page 1 is default
process_listings($firstPage);

youtube v3 api, check if Video existing

I've tried to check if a youtube video is online, not private, not deleted etc. I need it for a Video-Blog.
All of the code I've found and tried hadn't worked. I hope you can help me.
I've registered for the new API v3.
My code is as follows, but I always get "Bad Request 400"
$theURL = "https://www.googleapis.com/youtube/v3/videos?part=status&id=". get_post_meta($post->ID,"wpzoom_post_embed_code", true) ."&key=my_api_key";
// echo $theURL;
//$theURL = "http://www.youtube.com/oembed?url=http://www.youtube.com/watch?v=". get_post_meta($post->ID,"wpzoom_post_embed_code", true) ."&format=json";
$headers = get_headers($theURL);
print_r ($headers);
if (substr($headers[0], 9, 3) !== "404") {
echo "online";
} else {
echo "offline";
}
Found a solution. But I didn't figured it out, how can I display locked Videos as offline. I search in my curl data string for "totalResults": 0," cause I fetch at once one ID for video.
Here is my code. - Maybe someone has a better idea to fix this little problem.
$theURL = "https://www.googleapis.com/youtube/v3/videos?part=status&id=" . get_post_meta($post->ID, "wpzoom_post_embed_code", true) . "&key=my_api_key";
$ch = curl_init();
curl_setopt($ch,CURLOPT_URL,$theURL);
curl_setopt($ch,CURLOPT_HEADER,1);
curl_setopt($ch,CURLOPT_RETURNTRANSFER,1);
curl_setopt($ch, CURLOPT_VERBOSE, 0);
$data = curl_exec($ch);
//var_dump($data);
if (strpos($data,'totalResults": 0,') !== false) {
echo '<span> <img src="link_for_button" alt="online"/> Offline</span><br />'; //echo "<span style='color:red;'>Video Offline</span>";
} else echo '<span><img src="link_for_button" alt="online"/> Online</span><br />'; //echo "<span style='color:green;'>Video Online</span>";

Barclaycard ePDQ MPI using PHP & CURL just doesn't want to work, no repsonse, not sure CURL is working?

I've been putting this off for a while as I just don't seem to have a clue with what I'm doing. I'm trying to use PHP and Curl to talk to the Barclaycard ePDQ MPI. I've done this before using the HSBC XML API but the Barclaycard ePDQ MPI seems to be giving me a few headaches. I have a form which posts card details/address details and the to a page that contains the following functions Please note that I have SSL set up on the domain, CURL is installed on the server, I had the HSBC XML API working just fine on the same box/URL.
<?php
function process_card($users_ip, $Temp_Order_ID, $User_NameX, $First_Name, $Surname, $Address_Line1, $Address_Line2, $Town, $Country, $Postcode, $CardNumber, $CardExpiryDate, $issue_node, $CardCVV, $totalCost ) {
if ($CardCVV == "")
$cvvindicator = 0;
else
$cvvindicator=1;
global $status;
//$amount = $amount * 100;
$xml = '
<?XML version="1.0" encoding="UTF-8"?>
<EngineDocList>
<DocVersion>1.0</DocVersion>
<EngineDoc>
<IPAddress>' . $users_ip . '</IPAddress>
<ContentType>OrderFormDoc</ContentType>
<User>
<Name>XXXXX</Name>
<Password>XXXXXXX</Password>
<ClientId DataType="S32">12345</ClientId>
</User>
<Instructions>
<Pipeline>Payment</Pipeline>
</Instructions>
<OrderFormDoc>
<Mode>T</Mode>
<Id>' . $Temp_Order_ID. '</Id>
<Consumer>
<Email>' . $User_NameX . '</Email>
<BillTo>
<Location>
<Address>
<FirstName>' . $First_Name . '</FirstName>
<LastName>' . $Surname .'</LastName>
<Street1>' . $Address_Line1 . '</Street1>
<Street2>' . $Address_Line2 . '</Street2>
<Street3></Street3>
<City>' . $Town . '</City>
<StateProv>' . $Country . '</StateProv>
<PostalCode>' . $Postcode . '</PostalCode>
<Country>' . getCuntCode($Country) . '</Country>
</Address>
</Location>
</BillTo>
<ShipTo>
<Location>
<Address>
<FirstName>' . $First_Name . '</FirstName>
<LastName>' . $Surname .'</LastName>
<Street1>' . $Address_Line1 . '</Street1>
<Street2>' . $Address_Line2 . '</Street2>
<Street3></Street3>
<City>' . $Town . '</City>
<StateProv>' . $Country . '</StateProv>
<PostalCode>' . $Postcode . '</PostalCode>
<Country>' . getCuntCode($Country) . '</Country>
</Address>
</Location>
</ShipTo>
<PaymentMech>
<CreditCard>
<Type DataType="S32">1</Type>
<Number>' . $CardNumber . '</Number>
<Expires DataType="ExpirationDate" Locale="826">' . $CardExpiryDate . '</Expires>
' . $issue_node . '
<Cvv2Indicator>' . $cvvindicator . '</Cvv2Indicator>
<Cvv2Val>' . $CardCVV . '</Cvv2Val>
</CreditCard>
</PaymentMech>
</Consumer>
<Transaction>
<Type>Auth</Type>
<CurrentTotals>
<Totals>
<Total DataType="Money" Currency="826">' . $totalCost . '</Total>
</Totals>
</CurrentTotals>
<CardholderPresentCode DataType="S32"></CardholderPresentCode>
<PayerSecurityLevel DataType="S32"></PayerSecurityLevel>
<PayerAuthenticationCode></PayerAuthenticationCode>
<PayerTxnId></PayerTxnId>
</Transaction>
</OrderFormDoc>
</EngineDoc>
</EngineDocList>';
$url = "https://secure2.epdq.co.uk:11500";
$params = array("CLRCMRC_XML" => $xml);
$params = formatData($params);
$response = post_to_epdq($url, $xml);
$auth_code = strstr($response, "<AuthCode>");
echo "auth_code=" . $auth_code;
if ($auth_code <> "") {
$splt = split("</AuthCode>", $auth_code);
$status = strip_tags($splt[0]);
return $xml . "<hr/>" . $response . "Good";
} else {
$error = strstr($response, "<Text>");
$splt = split("</Text>", $error);
$status = strip_tags($splt[0]);
return $xml . "<hr/>" . $response . "Bad";
}
}
function post_to_epdq($url, $data) {
set_time_limit(120);
$output = array();
$curlSession = curl_init();
curl_setopt($curlSession, CURLOPT_URL, $url);
curl_setopt($curlSession, CURLOPT_PORT, 443);
curl_setopt($curlSession, CURLOPT_HEADER, 0);
curl_setopt($curlSession, CURLOPT_POST, 1);
curl_setopt($curlSession, CURLOPT_POSTFIELDS, $data);
curl_setopt($curlSession, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($curlSession, CURLOPT_TIMEOUT, 60);
#$response = split(chr(10),curl_exec ($curlSession));
$response = curl_exec($curlSession);
if (curl_error($curlSession)) {
$this->error = curl_error($curlSession);
return "ERROR";
}
curl_close($curlSession);
return $response;
}
function formatData($data) {
$output = "";
foreach ($data as $key => $value)
$output .= "&" . $key . "=" . urlencode($value);
$output = substr($output, 1);
return $output;
}
Needless to say I validate the user input, generate their IP and determine a country code, I then call the above function:
process_card($users_ip,$Temp_Order_ID,$User_NameX,$First_Name,$Surname,$Address_Line1,$Address_Line2,$Town,$Country,$Postcode,$CardNumber, $CardExpiryDate, $issue_node, $CardCVV, $totalCost );
I don't get a response? I'm unsure if the port and url items are incorrect or if the whole CURL request is wrong. Nothing is returned from the request.
Sorry about this being a long post but this is really doing my head in!
Has anyone done this before?
I've managed to fix my problem now. It turned out that the CURL connection to the Barclays website was blocked by a firewall on the server which was why I was getting no error message back.
I modified the CURL code a bit to check for errors:
$data = curl_exec($ch);
if(curl_errno($ch)) {
print curl_error($ch);
}
curl_close ($ch);
This then says: couldn't connect to host at which point I tried it on another server and it got past this error.
The error I am getting now is: "Insufficient permissions to perform requested operation." I have tried all the accounts I have been given but if I log into the EPDQ control panel I seem to only be able to assign up to EPDQ Level 4 and CPI access with no mention of MPI and even though it says technical support is available from 8AM until 12PM, it is not. It is really just office hours for anything but the most basic queries.
Is there any advantage to using this over SagePay? SagePay allows you to send through the individual transaction details as well where Barclays only lets you send the total amount payable and they really do offer support out of office hours.
The only reason I am changing the site to MPI is the fact that with CPI the customer can close the browser before returning to the website so the order details and invoice are not sent so there is no way of knowing what has been purchased.
Thanks
Robin
Howdy, after some playing around here's the correct CURL set up you have to do...
I realise that the variables could be better and I should make this as an object but I just want to get a quick answer up there. The script also needs to sift through the different accept and error messages but this is what I've got so far...
$ch = curl_init();
$url = "https://secure2.epdq.co.uk:11500"; // Don't need to add curl_setopt($curlSession, CURLOPT_PORT, 443); as port is included
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $vars); // $vars is your XML
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_TIMEOUT, 120);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
$data = curl_exec($ch);
curl_close ($ch);
$xml = new domDocument;
$xml->loadXML($data);
if (!$xml) {
echo 'Error while parsing the document - Please Contact to determine if payment has gone though';
exit;
}
$x = $xml->getElementsByTagName( "CcErrCode" );
$approved = $x->item(0)->nodeValue;
$xx = $xml->getElementsByTagName( "CcReturnMsg" );
$CcReturnMsg = $xx->item(0)->nodeValue;
if($approved) {
// the card is valid.
$y = $xml->getElementsByTagName( "Id" );
$BCardId = $y->item(1)->nodeValue;
$z = $xml->getElementsByTagName( "MessageList" );
$MessageList = $z->item(0)->nodeValue;
$zz = $xml->getElementsByTagName( "AvsRespCode" );
$AvsRespCode = $zz->item(0)->nodeValue;
$zzz = $xml->getElementsByTagName( "AvsDisplay" );
$AvsDisplay = $zzz->item(0)->nodeValue;
$zzzz = $xml->getElementsByTagName( "ProcReturnMsg" );
$ProcReturnMsg = $zzzz->item(0)->nodeValue;
if($approved == "1"){
echo "approved!<br />";
echo "BCardId: " . $BCardId . ", MessageList=" . $MessageList . ", " . $AvsRespCode . ", " . $AvsDisplay . ", " . $ProcReturnMsg;
die();
}else{
// raise that it's been partially accepted,
echo "partially approved";
echo "BCardId: " . $BCardId . ", MessageList=" . $MessageList . ", " . $AvsRespCode . ", " . $AvsDisplay . ", " . $ProcReturnMsg;
die();
}
}else{
echo "you have been completely knocked back";
$zzzzz = $xml->getElementsByTagName( "Text" );
$BCard_Text = $zzzzz->item(0)->nodeValue;
echo "The reason:" . $BCard_Text;
die();
}
hope this helps other people who have to set this up!

Categories