Mailgun having trouble dealing with attachments PHP - php

I'm currently connecting to Mailgun's webhooks so I can get any emails sent through and pass it somewhere else.
I've managed to deal with the subject, from and body inputs of the API, but I'm currently having trouble grabbing any attachments to an email.
Mailgun says that they send through a multipart file, but I have tried to catch it and write out the info into a file, but it comes back as an empty array...
$file = fopen(__DIR__ . '/files.txt','w') or die("Can't open file.");
ob_start();
var_dump($_FILES);
fwrite($file, ob_get_clean()) or die("Can't save to file.");
fclose($file);
Within the Post information, I get an attachments parameter which has such things like a url, content-type, name etc. I have tried to go the the url of each attachment, but I get a login box asking for a username and password and says "Server says: MG API". I have no idea if I need to pass something here so I can retrieve the attachment as a file to pass it on.
If anyone could help me out here, then I would truly appreciate it.
Thank you.

Great question,
As you said from the inbound webhook coming from mailgun to your server you're being sent a URL from which to fetch the attachment.
In my case it's
https://api.mailgun.net/v2/domains/<<<MYDOMAIN>>>>/messages/WyJjZTL.....SJd/attachments/0
Now if I authenticate to that URL with my username(api) and password, I can fetch the attachement. example:
https://API:PASSWORD#api.mailgun.net/v2/domains/<<<MYDOMAIN>>>>/messages/WyJjZTL.....SJd/attachments/0
The password is simply the API key, that you can find in the control panel on the left. (https://mailgun.com/cp)
hope this works for you as well as its working for me,
best regards

Related

Issue while trying to receive message notifications from Slack

About
I am trying to receive message posted on my server as soon as user post message the message in group or channel or direct in slack.
App Status
Code in the verified file where challenge was posted.
header('Content-type: application/json');
$myfile = fopen("test.txt", "w") or die("Unable to open file!");
$data = json_decode(file_get_contents('php://input'), true);
fwrite($myfile, $data["challenge"]);
fclose($myfile);
$json = '{"challenge":' . $data["challenge"] . '}';
echo json_encode(["challenge" => $json]);
Question
Now that the above url has been verified successfully, I am still not able to receive the posted messages. I was expecting messages posted at same url which was used to verify challenge parameter. Is that correct?
Am I missing anything retrieving the messages posted on my server?
Update - 1
Due to some reasons I am not even able to verify the url anymore. My server is not receiving any data. I am trying to save whatever is being posted my side but it is always blank everytime,
I think your assumptions are correct.
According to slack documentation you should be receiving posts with the given payload in this endpoint:
https://api.slack.com/apis/connections/events-api#the-events-api__receiving-events__events-dispatched-as-json
I'm still unsure how are you validating that this isn't the case though, if you kept the code above you would see no result of the post data sent by slack, also if you don't return a response status 200, slack will stop posting to this endpoint after 1 hour.
https://api.slack.com/apis/connections/events-api#the-events-api__responding-to-events
Can you try adding test.php file something like:
<?php
// get all the POST requests
if ($_SERVER["REQUEST_METHOD"] == "POST") {
file_put_contents('test.json', json_encode($_POST, JSON_PRETTY_PRINT), FILE_APPEND);
// return 200
http_response_code(200);
echo json_encode(["success" => true]);
return;
}
At the very beginning, validate the url again and check if the requests start being saved on test.json.
Alternatively can you check if you web server is routing POST requests to this url?
Try using postman to validate that

Piping email to PHP app

I have a PHP app that I built using the Slim routing framework. The app needs to send dynamic emails from orders so that users can just respond to those emails and the response goes right back into the app (stored in MySQL). I can easily create the dynamic address per order and that goes out just fine. My problem is getting it back.
I setup a subdomain (mailer.example.com) and in cPanel I setup a forwarder to catch all mail to that subdomain and forward it to a specific PHP file. That php file reads stdin and grabs the mime message and currently writes it to a file:
#!/usr/bin/php -q
<?php
// read from stdin
$fd = fopen("php://stdin", "r");
$email = "";
while (!feof($fd))
{
$email .= fread($fd, 1024);
}
fclose($fd);
$filename = "mail_".date("mdYHis").rand(1,99999999);
file_put_contents("mailfiles/".$filename, $email);
header("Location: http://www.example.com/public/mailer/process/".$filename);
As you can see, at the end I would like to forward this to my actual app which has all the database calls and other routines to process the email. But I don't know how to get the request into the app. It seems to ignore the header call above.
Am I doing this all wrong or should I just do all the processing I need in this script? I realize that would maybe be the easiest path forward but I'm also trying to use a mail parse library that fits nicely in my app.
Not sure if that all makes sense. Let me know what other info you need.
I think what you're looking to do isn't to return an HTTP response with a Location header, but rather initiate an HTTP request to your web server.
In that case, you should replace your header() call with:
$ch = curl_init('http://localhost/public/mailer/process/' . $filename);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$result = curl_exec($ch);
Note that your script (the one called to save the mail contents) will wait for your app to finish processing the request. If this is an issue for you, you'll need to use a technique to run PHP processes in the background.
You can read a mailbox with php and parse the emails that way.
// To connect to a POP3 server on port 110 on the local server, use:
$mbox = imap_open ("{localhost:110/pop3}INBOX", "user_id", "password");
I would not, create a custom reply-email/mailbox, per order, instead add the order to the subject as a reference. That way you only need to parse one mailbox.
Find the imap functionality here

php webhook not responding to Stripe test event

I've setup a basic webhook php page as modeled on the stripe documentation and listed below. When I send a test event from the Stripe webhooks dashboard, stripe responds "Test webhook sent successfully" with a blankk reponse. However, the output log file is not written to, no email is sent and there is nothing logged to the http server error log or the php error log. My php version is 5.3.3. What am I doing wrong?
<?php
error_reporting(15);
// Set your secret key: remember to change this to your live secret key in production
// See your keys here: https://dashboard.stripe.com/account/apikeys
require_once('vendor/autoload.php');
\Stripe\Stripe::setApiKey("secret_test_key");
$handle = fopen("webhook.log","a");
// Retrieve the request's body and parse it as JSON
$input = file_get_contents("php://input");
$event_json = json_decode($input);
// Do something with $event_json
if (fwrite($handle, $event_json) === FALSE) {
mail("mike#example.com","Cannot write to webhook.log","");
echo "Cannot write to webhook.log";
exit;
}
mail('mike#example.com','Webhook Event',$event_json);
header(':', true, 200);
//http_response_code(200); // PHP 5.4 or greater
?>
You have a few potential problems. As a quick rule of thumb, the best way to debug this is to start by triggering the event yourself, which you can do simply by loading up your webhook url in a browser yourself. Then you can test it directly and make sure it is doing what you expect it to be doing. There are obviously two possibilities:
Stripe is not triggering your webhook handler for some reason
Your handler is not properly logging itself
The latter first: it could be that Stripe is triggering your handler but it isn't logging that fact successfully. This would mean that both your email logging and file logging are failing. That is actually quite possible. Email logging with the mail function is actually very unreliable, unless you know for a fact that it works. Mail sent with the mail function is dropped silently by most modern email systems (gmail, etc) unless you have your DNS records properly configured, which most people don't. So unless you know for sure that your mail attempt is working properly, it probably isn't. If you also happen to have a permission issue in your attempt to write to a log file (which is not uncommon for a newly setup server), your logs could simply be failing. The easiest way to check that is to load up the webhook URL in a browser yourself. That way you know it is being triggered, and can know for sure if the issue is improper logging or Stripe not calling your webhook.
If you determine for sure that stripe isn't calling your webhook, the most likely culprit would be an invalid HTTPS certificate. Is your webhook connected via HTTPS (it should be)? If so, is it a valid certificate? You can tell your browser to ignore an invalid certificate when you browse your own site, but stripe will simply refuse to send the request if it encounters an invalid certificate.
If none of the above fixes it then it will be time for more digging, but I would start with those: they are probably the most likely problems.
The solution is that $event_json is an object and the fwrite failed because it expects a string not an object. By converting to an array and then serializing I was able to both write to the log and send the email.
$event_json = (array)json_decode($input);
$event = serialize($event_json);

Dealing with Mandrill Webhook data

I am trying to handle Mandrill's webhook data when I get a bounce I want Mandrill to tell my app which email it was and save various data in a MySql Database.
I am working with PHP here, according to Mandrill they send a URL I give them a $_POST request with JSON data.
Normally I would json_decode() this request, but when I do so, it appears to be blank. To me the JSON looks malformed, but perhaps I need to do something else with it first?
This is what I receive in my script:
[mandrill_events] =>
[{\"event\":\"hard_bounce\",\"msg\":{\"ts\":1365109999,\"subject\":\"This an example webhook message\",\"email\":\"example.webhook#mandrillapp.com\",\"sender\":\"example.sender#mandrillapp.com\",\"tags\":[\"webhook-example\"],\"state\":\"bounced\",\"metadata\":{\"user_id\":111},\"_id\":\"exampleaaaaaaaaaaaaaaaaaaaaaaaaa\",\"_version\":\"exampleaaaaaaaaaaaaaaa\",\"bounce_description\":\"bad_mailbox\",\"bgtools_code\":10,\"diag\":\"smtp;550 5.1.1 The email account that you tried to reach does not exist. Please try double-checking the recipient\'s email address for typos or unnecessary spaces.\"},\"_id\":\"exampleaaaaaaaaaaaaaaaaaaaaaaaaa\",\"ts\":1390483382},{\"event\":\"soft_bounce\",\"msg\":{\"ts\":1365109999,\"subject\":\"This an example webhook message\",\"email\":\"example.webhook#mandrillapp.com\",\"sender\":\"example.sender#mandrillapp.com\",\"tags\":[\"webhook-example\"],\"state\":\"soft-bounced\",\"metadata\":{\"user_id\":111},\"_id\":\"exampleaaaaaaaaaaaaaaaaaaaaaaaaa1\",\"_version\":\"exampleaaaaaaaaaaaaaaa\",\"bounce_description\":\"mailbox_full\",\"bgtools_code\":22,\"diag\":\"smtp;552 5.2.2 Over Quota\"},\"_id\":\"exampleaaaaaaaaaaaaaaaaaaaaaaaaa1\",\"ts\":1390483382}]
You have the magic_quotes option set in your server.
You can disable it, or simply remove the trailing slashes from the response and then do the json_decode:
$response = json_decode(stripslashes($_RESPONSE['mandrill_events']), true);
More information about stripslashes: http://php.net/manual/en/function.stripslashes.php

Processing POST data from a third party

I have been struggling with the following problem for few days. I am expected to receive POST data from a third party company for certain real time events. I have been in contact with them as to why my script isn't seeing anything. Unfortunately, they are less then helpful and just tell me "it works for everybody else".
I setup a simple PHP script after doing some research on the web but it always shows no post data. This isn't my area of expertise so I may be missing something obvious.
Here is the only documentation they give:
This API will send a real-time http request upon every successful event with all of the conversion data. The data is sent via an http POST method, and the data is JSON formatted.
This is my script which for now is trying to just log it to a file. The file is created and I see the IP address of the request but the output is empty in terms of post data.
ob_start();
echo "Request from :" . $_SERVER[REMOTE_ADDR];
echo "print_r:".print_r($_POST,true);
if(array_key_exists('app_id', $_POST))// me attempting to access a specific key they claim is in the post data
{
echo "app id = " . $_POST['app_id'];
}
//I also tried both of these and neither output anything
//foreach ($_POST as $key => $value) //idea 1
foreach($_POST as $item) //idea 2
{
//echo "key=".$key." value=".$value; //idea 1 log
echo "next=";//idea 2 log
echo $item;
}
$contents = ob_get_flush();
file_put_contents("log.txt",$contents,FILE_APPEND);
There's not a lot to go on here -- who knows what the client is actually sending -- but here's a thought:
POST is just an HTTP command. It's traditional for the body of a POST to be a series of key-value pairs from a form, but it is not actually necessary. It's possible that the remote client is issuing a POST request to your server and then just delivering a JSON blob in the request body, which would not be successfully parsed into the $_POST array.
I recommend exploring the answer at How to get body of a POST in php? to see if that helps shed light on this problem.

Categories