502 Bad Gateway - Sendgrid PHP Mail Issue - php

I am getting 502 Bad Gateway error when I try to send email using Sendgrid's PHP library. I have attached the error log below,
502 Array (
[0] => HTTP/1.1 502 Bad Gateway
[1] => Server: nginx
[2] => Date: Thu, 27 Dec 2018 19:30:14 GMT
[3] => Content-Type: text/html
[4] => Content-Length: 166
[5] => Connection: keep-alive
[6] => Access-Control-Allow-Origin: https://sendgrid.api-docs.io
[7] => Access-Control-Allow-Methods: POST
[8] => Access-Control-Allow-Headers: Authorization, Content-Type, On-behalf-of, x-sg-elas-acl
[9] => Access-Control-Max-Age: 600
[10] => X-No-CORS-Reason:
https://sendgrid.com/docs/Classroom/Basics/API/cors.html
[11] =>
[12] => )
I don't know where I am wrong and I followed as per the documentation in SendGrid's website (Github as well). I have attached the code below what I used.
I have already tried possible troubleshooting found in other questions and issues in the GitHub repository of sendgrid-php.
<?php
require("sendgrid/sendgrid-php.php");
$email = new \SendGrid\Mail\Mail();
$email->setFrom("noreply#mydomain.com", "Leads");
$email->setSubject($_POST['school'] . " - Appointment");
$tos = [
"support#mydomain.com" => "Support",
$_POST['email'] => $_POST['name']
];
$email->addTos($tos);
$email->addContent("text/html", "<p><strong>Name:</strong> {$_POST['name']}</p>");
$email->addContent("text/html", "<p><strong>Email:</strong> {$_POST['email']}</p>");
$email->addContent("text/html", "<p><strong>Mobile:</strong> {$_POST['mobile']}</p>");
$email->addContent("text/html", "<p><strong>School:</strong> {$_POST['school']}</p>");
$email->addContent("text/html", "<p><strong>Count:</strong> {$_POST['count']}</p>");
$email->addContent("text/html", "<p><strong>Gender:</strong> {$_POST['gender']}</p>");
$sendgrid = new \SendGrid('xxxxxxxxxxxxxxAPIKEYxxxxxxxxxxxxxxxx');
try {
$response = $sendgrid->send($email);
print $response->statusCode() . "\n";
print_r($response->headers());
print $response->body() . "\n";
} catch (Exception $e) {
echo 'Caught exception: '. $e->getMessage() ."\n";
}
?>
The email should be sent when the code is executed.

There is some weird issue with SendGrid. Sometimes, the API gets soft deleted automatically in the backend. To make the code work, I had to create a new API key and retry. And the solution worked.
Note - Some issues in GitHub instructed to initialize a constructor with a from address, but that was not the actual issue.
The workaround is to create a new API key in the dashboard till
SendGrid investigates why the API is soft deleted so that the API call
returns an error.

Related

Vimeo: how to use php official client to add a domain whitelist for a video?

I am using official Vimeo PHP client.
I can upload a video, and set privacy.embed to whitelist.
Then doc tells me:
To add a domain to the whitelist, send a PUT request to /videos/{video_id}/privacy/domains/{domain}.
I tried
$privacy_uri = $uri . "/privacy/domains/testdomain.tld";
$domain_add_response = $client->request($privacy_uri);
where
- $uri is the /vimeo/<video_id>
- $client is born from new Vimeo(CLIENT_ID, CLIENT_SECRET, VIMEO_TOKEN);
Problem
Printing the $domain_add_response I get a 405 error, probably because of Allow (see the following response dump)
Array
(
[body] =>
[status] => 405
[headers] => Array
(
[Server] => nginx
[Content-Type] => application/json
[Allow] => PUT,DELETE,OPTIONS
[X-Vimeo-DC] => ge
[Accept-Ranges] => bytes
[Via] => 1.1 varnish
[Content-Length] => 0
[Date] => Mon, 15 Apr 2019 08:30:47 GMT
[Connection] => keep-alive
[X-Served-By] => cache-bwi5125-BWI, cache-mxp19820-MXP
[X-Cache] => MISS, MISS
[X-Cache-Hits] => 0, 0
[X-Timer] => S1555317047.232635,VS0,VE148
[Vary] => Accept-Encoding
)
)
I imagine I must set the PUT method in my request, but ... how ?
Solution found looking at api source code: https://github.com/vimeo/vimeo.php/blob/master/src/Vimeo/Vimeo.php#L88
where the signature of request is
public function request($url, $params = array(), $method = 'GET', $json_body = true, array $headers = array()): array
I understand that I can fix the problem, simply passing an empty $params array and specifing PUT as request $method
I changed this line
$domain_add_response = $client->request($privacy_uri);
Into this form
$domain_add_response = $client->request($privacy_uri, [], 'PUT');
And it works as expected

Getting error "invalid_client" from Vimeo API on user authentication

I'm attempting to authenticate a user through Vimeo in order to view a list of their videos on the website.
I'm using the Vimeo php library https://github.com/vimeo/vimeo.php with no errors when including it in my code.
I get the authentication URL and am able to navigate to the Allow APP Access page on Vimeo and when I click "Allow" I'm getting the "invalid_client" error on my redirect page, even though they send back a code in the $_GET.
I'm thoroughly confused at this point since I've got the official API library and the APP is set up correctly as far as I can tell. I'm hoping someone might be able to point me in the right direction as to why I'm getting this error and how to fix it!
My Code:
//init Vimeo
require_once("modules/classes/Vimeo/autoload.php");
$lib = new \Vimeo\Vimeo($vimeo_id, $vimeo_secret, $vimeo_access);
if(!isset($_SESSION['vstate'])){
$_SESSION['vstate'] = base64_encode(openssl_random_pseudo_bytes(30));
}
$vimeo_authurl = $lib->buildAuthorizationEndpoint($redirecturi,'public private',$_SESSION['vstate']);
if(isset($_GET['code'])){
echo "Code returned: ".$_GET['code'];
if ($_SESSION['vstate'] != $_GET['state']) {
echo 'Something is wrong. Vimeo sent back a different state than this script was expecting. Please let an administrator know that this has happened.';
}
$tokens = $lib->accessToken($_GET['code'], $redirecturi);
if ($tokens['status'] == 200) {
echo 'Vimeo account successfully connected!';
$_SESSION['access_token'] = $tokens['body']['access_token'];
$lib->setToken($token['body']['access_token']);
} else {
echo 'Sorry, we were unable to connect to your Vimeo account due to the following error:<br/>{'.$tokens['body']['error']."} ".$tokens['body']['error_description'];
}
echo "<br/><br/><pre>";
print_r($tokens);
echo "</pre>";
exit();
}
The print_r($tokens) gives this:
Array
(
[body] => Array
(
[error] => invalid_client
[error_description] => A valid client ID must be provided along with any request made to Vimeo's API
)
[status] => 400
[headers] => Array
(
[Server] => nginx
[Content-Type] => application/json
[Expires] => Fri, 10 Mar 2017 03:11:17 GMT
[Cache-Control] => no-store
[Strict-Transport-Security] => max-age=15552000; includeSubDomains; preload
[Pragma] => no-cache
[X-UA-Compatible] => IE=edge
[X-XSS-Protection] => 1; mode=block
[X-Content-Type-Options] => nosniff
[X-Frame-Options] => sameorigin
[Content-Security-Policy-Report-Only] => default-src https: data: blob: 'unsafe-inline' 'unsafe-eval'; report-uri /_csp
[Accept-Ranges] => bytes
[Via] => 1.1 varnish
[Fastly-Debug-Digest] => 5da2a3ac863afd5f2ad0963779e0dbc4c54c7d97d19f87fd227c5eb8c92bd621
[Content-Length] => 126
[Date] => Fri, 10 Mar 2017 15:11:17 GMT
[Connection] => keep-alive
[X-Served-By] => cache-iad2146-IAD, cache-ord1731-ORD
[X-Cache] => MISS, MISS
[X-Cache-Hits] => 0, 0
[X-Timer] => S1489158677.346607,VS0,VE55
[Vary] => Accept,Vimeo-Client-Id,Accept-Encoding,User-Agent
)
)
So I'm not exactly sure why, but I created a new APP with the same details and this new APP seemed to authenticate fine.
The first APP I was having troubles with I had originally sent a request for Upload Access, but was denied (due to local testing links), so perhaps that was the underlying issue with the "invalid_client" error.

Check if Dropbox App Folder Exists

I am trying to check when users log into my dashboard if they have a connected Dropbox account. I can do this fine, but, I also want to check if the App folder exists in the Dropbox, otherwise users can start uploading files and fail because the path doesn't exist because there is no root. I'd rather catch this at the start then during the upload process.
I was trying to use findErrorNonRoot but the obviously doesn't accept the root.
$pathError = dbx\Path::findErrorNonRoot($dropboxPath);
I also tried isValid
$pathError = dbx\Path::isValid("/");
In case if the user has removed their "App" folder, Dropbox API throws Dropbox\Exception_InvalidAccessToken exception. So you should only handle this exception properly. For example:
use \Dropbox as dbx;
define ('API_CONF_FILE', '/path/to/api-conf.json');
define ('CLIENT_ID', 'Your Upload App/1.0');
$accessToken = obtain_the_access_token();
$appInfo = dbx\AppInfo::loadFromJsonFile(API_CONF_FILE);
for (;;) {
echo "Connecting to Dropbox...\n";
$dbxClient = new dbx\Client($accessToken, CLIENT_ID);
try {
// This call will also throw `Dropbox\Exception_InvalidAccessToken`
//$folderMetadata = $dbxClient->getMetadataWithChildren("/");
$f = fopen("/path/to/test.txt", "r");
$result = $dbxClient->uploadFile("/test.txt", dbx\WriteMode::add(), $f);
fclose($f);
print_r($result);
break;
} catch (Dropbox\Exception_InvalidAccessToken $e) {
$message = $e->getMessage();
if ($brace_pos = strpos($message, '{')) {
$error_title = substr($message, 0, $brace_pos);
if ($json_error = json_decode(substr($message, $brace_pos), true)) {
$error_description = $json_error['error'] ?? 'N/A';
}
fprintf(STDERR, "Error: %s\nDescription: %s\n",
$error_title, $error_description ?? 'N/A');
$webAuth = new dbx\WebAuthNoRedirect($appInfo, CLIENT_ID);
$authorizeUrl = $webAuth->start();
echo "1. Go to: $authorizeUrl\n";
echo "2. Click \"Allow\" (you might have to log in first).\n";
echo "3. Copy the authorization code.\n";
$authCode = \trim(\readline("Enter the authorization code here: "));
list($accessToken, $dropboxUserId) = $webAuth->finish($authCode);
echo "Access Token: $accessToken\n";
}
} catch (Exception $e) {
fprintf(STDERR, "Unknown exception: %s\n", $e->getMessage());
exit(1);
}
}
Note, I've used PHP7 Null coalescing operator.
Sample output (when the folder is initially removed)
Connecting to Dropbox...
Error: HTTP status 401
Description: User has removed their App folder.
1. Go to: https://www.dropbox.com/1/oauth2/authorize?locale=&client_id=2deadbeef2ofaft&response_type=code
2. Click "Allow" (you might have to log in first).
3. Copy the authorization code.
Enter the authorization code here: IugIByIMdKkAAAAAAAAAhVTH02dF7LW70_fFEHHohXo
Access Token: IugIByIMdKkAAAAAAAAAhtPGKSoVOBs557XXrq-zX57L4QRAmqiUTagktS7YDmg1
Connecting to Dropbox...
Array
(
[revision] => 1
[bytes] => 10
[thumb_exists] =>
[rev] => 14ef8952b
[modified] => Tue, 04 Oct 2016 09:02:31 +0000
[mime_type] => text/plain
[path] => /working-draft.txt
[is_dir] =>
[size] => 10 bytes
[root] => app_folder
[id] => id:rmvcpq3LHlAAAAAAAAAAAw
[client_mtime] => Tue, 04 Oct 2016 09:02:31 +0000
[icon] => page_white_text
)
Sample output (when the folder initially exists)
Connecting to Dropbox...
Array
(
[revision] => 2
[bytes] => 10
[thumb_exists] =>
[rev] => 24ef8b68e
[modified] => Tue, 04 Oct 2016 09:18:20 +0000
[mime_type] => text/plain
[path] => /test.txt
[is_dir] =>
[size] => 10 bytes
[root] => app_folder
[id] => id:VMaySA3Ug5AAAAAAAAAABA
[client_mtime] => Tue, 04 Oct 2016 09:18:20 +0000
[icon] => page_white_text
)
The root App folder is created when the user follows the link and clicks on "Allow" button.

Facebook Ads API/SDK - The global ID [xxxx] is not allowed. Please use the application specific ID instead

I am trying to get the name associated with an Ad Account. Using the API calling /me gets my user info no problem. Calling /me/adaccounts gets me an object with a data node that is an array of account id objects which has an id node. I use this ID to try and get the Ad Account and I get the following error:
The global ID [xxxx] is not allowed. Please use the application specific ID instead.
The code is included below, can someone tell me what I am doing wrong?
FacebookSession::setDefaultApplication($config['id'], $config['secret']);
$session = new FacebookSession($accessToken);
$api = new Api($session);
echo '<pre>';
$adAccountsResponse = $api->call('/me/adaccounts','GET');
$adAccounts = $adAccountsResponse->getResponse();
foreach($adAccounts->data as $adAccount)
{
$adAccountId = $adAccount->account_id;
$adAccount = new AdAccount($adAccountId, null, $api);
$adAccount->read(array(AdAccountFields::NAME));
print_r($adAccount);
}
I did a print_r($api) and it says I am using version 2 of the API.
[responseHeaders:protected] => Array
(
[http_code] => HTTP/1.1 200 OK
[Last-Modified] => 2014-07-20T14:37:10+0000
[Facebook-API-Version] => v2.0
[ETag] => "XXXXXXXXXXXXXX"
[Content-Type] => application/json; charset=UTF-8
[Pragma] => no-cache
[Access-Control-Allow-Origin] => *
[X-FB-Rev] => 1454522
[Cache-Control] => private, no-cache, no-store, must-revalidate
[Expires] => Sat, 01 Jan 2000 00:00:00 GMT
[X-FB-Debug] => "XXXXXXXXXXXXXX"
[Date] => Wed, 15 Oct 2014 15:10:36 GMT
[Connection] => keep-alive
[Content-Length] => 234
)
Interesting enough when I use the Graph API Explorer switching between API version numbers using the token that I have I get the same user ID no matter what the version of the API. So something is messed up.
That is an extremely odd error to receive as it doesn't actually relate to adaccounts.
There is however an easier way to retrieve the list of attributes you want in a single call using connections of the object AdUser:
use FacebookAds\Object\AdUser;
use FacebookAds\Object\Fields\AdAccountFields;
$user = new AdUser('me');
$accounts = $user->getAdAccounts(array(AdAccountFields::NAME)));
foreach($accounts as $account) {
echo $account->name."\n";
}
You could try to add the Graph API version prefix to your call:
$adAccountsResponse = $api->call('/v2.1/me/adaccounts','GET');

Wordpress Instagram Plugin

I'm working with a wordpress plugin called Instagrabber: pluggin page. The plugin had been working perfectly for several months up until about a week ago when it started failing authentication while updating the image stream. At first, I thought the token expired, but after creating a few new testing accounts, the problem persisted.
I've isolated the problem to a couple lines of code in the main instagrabber-api.class.php file, pertaining to authenticating and retrieving the content:
$response = wp_remote_post( $request_uri, array(
'timeout'=> 10,
'method' => 'POST',
'body' => $data
)
);
$decoded_response = json_decode($response['body']);
This throws an 500 internal server error, and authentication fails. I've successfully authenticated using instagram's localhost setting, and connected with their API console, but when I make the request from our host, it fails.
This may not cover everything, so I'm happy to provide additional information, if needed.
** Edited **
Here are the values for $data and $response:
$data = Array (
'client_id' => $InstagramClientID,
'client_secret' => InstagramClientSecret,
'grant_type' => 'authorization_code',
'redirect_uri' => $InstagramRedirectURI,
'code' => $auth_code
)
If I print $data, everything appears fine, with all values pulling correctly.
$response is an array using wp_remote_post default return values, which can be found here for reference. The following is what we get returned:
Array (
[headers] =>
Array (
[cache-control] => no-cache
[content-type] => text/html
[date] => Mon, 07 Apr 2014 13:15:33 GMT
[server] => nginx
[content-length] => 87
[connection] => Close )
[body] =>
This seems to be where the 500 server error stems from. My thought is because of the Connection = Close, and empty body content.

Categories