Trying to send data from Google App Script to a php site which sends an email from my database. For most of the date it is no problem I send it via the url(example.com/example.php?id=test&id2=test2&id3=test3).
For most of the data it is no problem except for the third parameter, the given value is way longer than the other two and may contain newlines as well. My idea was to send the third(or all values) as JSON object.
My Google AppScript code so far:
function sendData(){
var options = {'text' : 'A longer example text'} ;
try {
var url = "https://example.com/example.php?id1=test1&id2=test2&id3="+options;
var httpRequest = UrlFetchApp.fetch(url, options).getContentText();
}
catch(e){
Logger.log(e);
}
return;
}
My PHP code:
<?php
require 'includes/functions.php';
include_once 'config.php';
include 'ChromePhp.php';
$email = $_GET["id1"];
$name = $_GET["id2"];
$text = $_GET["id3"];
$json = json_decode($text, true);
ChromePhp::log($json->text);
if(strpos($text, "\n") !== FALSE) {
$text = str_replace("\n", "<br>", $text);
}
$replace_to_standard=[$name, $text];
$replace_standard =['nametochange', 'textochange'];
$delivery_added = str_replace($replace_standard, $replace_to_standard, file_get_contents('standardMail.html'));
echo "" . $delivery_added . "";
$m = new MailSender;
$m-> sendMail($email, $email, $delivery_added, "Mail All");
The chrome logger will log "null"
Any ideas?
Using an AJAX post as an example, you can use the POST capability of Google apps script to send a post request to your PHP file and process it using the $_POST function of PHP.
Try in you GAS:
var payload = {
'text' : 'A longer example text',
'email' : 'test#email.com'
};
var options = {
'method' : 'post',
'payload' : payload
};
//var text = String(jsonData.comment);
try {
var url = "https://etadres.nl/login/mailAll.php";
var httpRequest = UrlFetchApp.fetch(url, options).getContentText();
}
catch(e){
Logger.log(e);
}
Catch your POST request in PHP and edit it as follows:
<?php
require 'includes/functions.php';
include_once 'config.php';
include 'ChromePhp.php';
//Receive the RAW post data via the php://input IO stream.
$content = file_get_contents("php://input");
$email = $_POST["email"];
$text= $_POST["text"];
if(strpos($text, "\n") !== FALSE) {
$text = str_replace("\n", "<br>", $text);
}
$replace_to_standard=[$name, $text];
$replace_standard =['nametochange', 'textochange'];
$delivery_added = str_replace($replace_standard, $replace_to_standard, file_get_contents('standardMail.html'));
echo "" . $delivery_added . "";
$m = new MailSender;
$m-> sendMail($email, $email, $delivery_added, "Mail All");
Related
I am able to consume the php endpoint from postman. I try to do the same from angular post, I get this error - Http failure during parsing for. Even though everything looks perfect to me, the problem is surprising. Here is my snippet
php file
<?php
header('Access-Control-Allow-Origin: *');
// check for post
if ($_SERVER['REQUEST_METHOD']=='POST') {
$name = $_POST['name'];
$email = $_POST['email'];
$subject = $_POST['subject'];
$message = $_POST['message'];
// include db connect class
require_once __DIR__ . '/db_connect.php';
// connecting to db
$conn = new db_CONNECT();
$cone=$conn->con;
//escpae the strings to be inserted to DB
$escapedname = mysqli_real_escape_string($cone, $name);
$escapedemail = mysqli_real_escape_string($cone, $email);
$escapedsubject= mysqli_real_escape_string($cone, $subject);
$escapedmessage = mysqli_real_escape_string($cone, $message);
// mysql inserting a new row
$sql = "INSERT INTO contacts(name, email, subject, message) VALUES ('$escapedname', '$escapedemail', '$escapedsubject', '$escapedmessage')";
// $result= $cone -> query($sql);
// $affected = $cone -> affected_rows;
if (mysqli_query($cone,$sql)) {
echo "Information saved successfully.";
} else {
echo "Not successful";
}
} else {
echo "Some field missing.";
}
?>
here is the angular snippet
saveContactDetails = function () {
this.proceed = true;
this.success = false;
const myheader = new HttpHeaders().set('Content-Type', 'application/x-www-form-urlencoded');
data.append('name', this.contactDeJson.name);
data.append('email', this.contactDeJson.email);
data.append('subject', this.contactDeJson.subject);
data.append('message', this.contactDeJson.message);
this.http
.post('http://localhost:80/'+'api/create_contact.php', data.toString(), {headers: myheader})
Please why am I getting this error
{"headers":{"normalizedNames":{},"lazyUpdate":null},"status":200,"statusText":"OK","url":"http://localhost/api/create_contact.php","ok":false,"name":"HttpErrorResponse","message":"Http failure during parsing for http://localhost/api/create_contact.php",
I believe the issue is that your angular script is expecting a json response (the default responseType), but not receiving the correct headers or data. In stead of just echoing out your result in php, I would make a function that can handle sending the response. Something like this:
function sendJsonResponse(data, status = 200) {
header('Content-Type: application/json', true, status);
echo json_encode($data);
exit();
}
In stead of of doing this:
echo "Not successful";
You can now do this:
sendJsonResponse("Not successful", 500);
This should give you more valuable information in the frontend. And the response should now be formatted correctly, and no longer produce the parse error in angular that you are getting now.
I believe you are trying to send some query parameters using data variable. You could actually send a JS object as the parameters. Try the following
private saveContactDetails() {
this.proceed = true;
this.success = false;
const myheader = new HttpHeaders().set('Content-Type', 'application/x-www-form-urlencoded');
const data = {
'name': this.contactDeJson.name,
'email': this.contactDeJson.email,
'subject': this.contactDeJson.subject,
'message': this.contactDeJson.message
}
this.http.post('http://localhost:80/'+'api/create_contact.php', { params: data }, { headers: myheader })
}
If I call the script on browser it does send email to my domain email. Anyway I'm trying to send some contact email from angular 7 apps. I did use HttpClient post and try to send the data as JSON. (Apache server PHP -v 5.6)
I have tried to send the data with URL like mail.php?param1="info#test.test"¶m2="Test email". I did not have any luck. I tried file_get_contents("php://input"); no luck either.
<?php
echo("called");
$postdata = file_get_contents("php://input");
$request = json_decode($postdata);
header('Content-type: application/json');
header("Access-Control-Allow-Origin: *");
header('Access-Control-Allow-Headers: X-Requested-With, content-type, access-control-allow-origin, access-control-allow-methods, access-control-allow-headers');
// Sanitize.
// $title = $_GET['title'];;
// $message = $_GET['message'];;
// $name = $_GET['name'];;
// $from = $_GET['from'];;
$title = $request->title;
$message = $request->message;
$name = $request->name;
$from = $request->from;
$to = "info#test.com";
// Sending email
if(mail($to, $title, $message, $name)){
echo 'Your mail has been sent successfully.';
} else{
echo 'Unable to send email. Please try again.';
}
?>
Here is my Angular Service
export class PollServiceService {
PHP_API_SERVER: string = "/api";
constructor(private http: HttpClient) {
}
public SendEmail(e: any): Observable<any>{
var tmp1 = "/?title=" + e.title + "&message=" +e.message + "&name=" +e.name + "&from=" + e.from ;
return this.http.post<any>(`${this.PHP_API_SERVER}/mail.php`, e);
}
}
I do call the SendEmail(e: any) method on the form. Anyway it does not seem to do to anything. I'm suspect that the php file does not get called at all from the script. Thanks in advance guys.
Your SendEmail function returns an Observable.
You have to subsribe to this Observable in order to make the call happen.
So you should do something like that in a function in your component:
this.pollServiceService.SendEmail(e).subscribe(res => {
// here you can do whatever you want with the result of the call
});
this function should then be called from your form.
I'm using Zapier to collect leads from facebook,and than send them to my CRM.
I Have a script connected to my CRM,that is supposed to handle the leads.
for every new lead the script will trigger,
the script collects the data passed from Zapier and converts it to an XML and sends it my client.
Everything works except for one thing.
The PHPMailer seems to cause trouble with zapier,because whenever the email() function is enabled Zapier will give me an Error.
FYI - this works when I go to the script url and set the GET parameters by hand .
the xml is being sent. But when triggering the script from zapier the problem occurs.
Zapier Error:
"We had trouble sending your test through.
The app returned "Internal Server Error" with no further details. It looks like the server for your connected app is down or currently experiencing problems. Please check the app's status page or contact support if there are no reported issues."
<?php
$firstName = isset($_GET['firstName']) ? $_GET['firstName'] : '';
$lastName = isset($_GET['lastName']) ? $_GET['lastName'] : '';
$fullName = isset($_GET['fullName']) ? $_GET['fullName'] : '';
$phone = isset($_GET['phone']) ? $_GET['phone'] : '';
$experience = isset($_GET['experience']) ? $_GET['experience'] : '';
$city = isset($_GET['city']) ? $_GET['city'] : '';
$email = isset($_GET['email']) ? $_GET['email'] : '';
$utm_source = isset($_GET['utm_source']) ? $_GET['utm_source'] : '';
$campaignId = isset($_GET['campaignId']) ? $_GET['campaignId'] : '';
$utm_medium = isset($_GET['utm_medium']) ? $_GET['utm_medium'] : '';
require 'vendor/autoload.php';
header('Content-Type: text/plain');
function createXML($data,$dataSource){
$dom = new DOMDocument('1.0', 'utf-8');
$cv = $dom->createElement("cv");
$candidate = $dom->createElement('candidate');
$source_type = $dom->createElement('source_type');
function recursive($dom, $parent, $key, $value) {
if(is_array($value)) {
$new_parent = $dom->createElement($key);
foreach($value as $k => $v){
recursive($dom, $new_parent, $k, $v);
}
$parent->appendChild($new_parent);
} else {
$field = $dom->createElement($key, htmlspecialchars($value));
$parent->appendChild($field);
}
}
foreach($dataSource as $key => $value){
// api need COLUMN without end of _<number>
if(preg_match('/COLUMN_([0-9]+)/', $key)) $key = 'COLUMN';
recursive($dom, $source_type, $key, $value);
}
foreach($data as $key => $value){
// api need COLUMN without end of _<number>
if(preg_match('/COLUMN_([0-9]+)/', $key)) $key = 'COLUMN';
recursive($dom, $candidate, $key, $value);
}
// $cv->appendChild($candidate)
$cv->appendChild($candidate);
$cv->appendChild($source_type);
$dom->appendChild($cv);
$node = $cv->appendChild($source_type);
$node->setAttribute('type','other');
$dom->formatOutput = true;
return $dom;
}
$data = array(
"first_name" => filter_var($firstName, FILTER_SANITIZE_STRING),
"last_name" => filter_var($lastName, FILTER_SANITIZE_STRING),
"mobile" => filter_var($phone, FILTER_SANITIZE_STRING),
'email' => '',
'id' => '',
);
$dataSource = array(
"source_title" => filter_var($utm_source, FILTER_SANITIZE_STRING),
"first_name" => '',
"last_name" => '',
"mobile" => '',
"email" => '',
"employee_number" => '',
"department" => '',
"email" => '',
);
//problematic function
function email(){
global $xmlData;
$mail = new PHPMailer(true);
$mail->isHTML(false);
$mail->isSMTP();
$mail->setFrom('XML#gmail.com', 'Yashir CV Lead');
$mail->addAddress("BinaryRx#gmail.com");
$mail->Subject = "Yashir CV Lead";
$mail->Body = $xmlData;
$today = date('d-m-Y H:i:s');
$mail->send();
echo "Report Sent - " . $today;
}
///////// IF I uncomment bellow,Zapier will give me the following error:
//We had trouble sending your test through.
//The app returned "Internal Server Error" with no further details.
//It looks like the server for your connected app is down or currently experiencing problems.
//Please check the app's status page or contact support if there are no reported issues.
//Uncomment bellow.
// email();
?>
I Expect for every Lead to send an email containing a XML.
Two key problems. Firstly, you're using SMTP, but you have not set Host to your mail server - so it won't work unless it's localhost - is that the case?
You're asking PHPMailer to throw exceptions (by passing true to the constructor), but you don't have a try/catch block wrapped around the calls to PHPMailer, so any errors will result in uncaught exceptions - which will give you exactly the symptom you're seeing. Try this:
function email()
{
global $xmlData;
$mail = new PHPMailer(true);
try {
$mail->isHTML(false);
$mail->isSMTP();
$mail->setFrom('XML#gmail.com', 'Yashir CV Lead');
$mail->addAddress("BinaryRx#gmail.com");
$mail->Subject = "Yashir CV Lead";
$mail->Body = $xmlData;
$today = date('d-m-Y H:i:s');
$mail->send();
echo "Report Sent - ".$today;
} catch (Exception $e) {
echo 'Sending failed'.$e->getMessage();
}
}
Overall, the main thing is to debug one thing at a time - check that the email() function actually works independently before you start trying to do things that depend on it working, because otherwise you won't know which bit of the code is failing.
If you're using PHP 7.0 or later, you can simplify those initial checks for params by using the null coalesce operator. You can replace this:
$firstName = isset($_GET['firstName']) ? $_GET['firstName'] : '';
with:
$firstName = $_GET['firstName'] ?? '';
I've got a problem with the file transfer plugin that i can't seem to figure out. My code works when i'm using http, but when I try to upload over https it seems that it doesn't send the parameters to my api but it does reach my api. only the the file is missing, the x-session-token header is present and valid. This is the code i use for uploading the file:
$scope.options = {};
$scope.options.fileKey = "file";
$scope.options.fileName = $scope.img.substr($scope.img.lastIndexOf('/') + 1);
$scope.options.mimeType = "image/jpeg";
$scope.options.headers = {
'x-session-token' : window.localStorage.auth
};
// parameters: source, filePath, options
$cordovaFile.uploadFile("https:/****/api.php/profielpic/", $scope.img, $scope.options, true).then(function(result) {
console.log(result);
$cordovaToast.showShortTop('Uploaden gelukt!').then(function(success) {
$ionicLoading.hide();
$state.go('tab.profiel');
}, function (error) {
$ionicLoading.hide();
$state.go('tab.profiel');
});
}, function(err) {
console.log(err);
$ionicLoading.hide();
});
This is the code i use Server side to see if there's anything:
$app->post('/profielpic/', function () use ($app) {
$auth = new api\src\Auth;
$users = new api\src\Users;
$authdata = json_decode($app->request->headers->get('x-session-token'));
$data = json_decode($app->request->getBody());
$userid = $authdata->userID ;
$session_token = $authdata->session_token;
$userdata = $data->userdata;
$alertsarray = array();
$message = null;
$isValid = true;
$authresult = $auth->authenticate($userid, $session_token);
$imgname = time();
print_r(json_encode($authdata));
print_r(json_encode($_FILES));
print_r(json_encode($_POST));
print_r(json_encode($data));
print_r(json_encode(file_get_contents("php://input")));
/*
if($authresult === true) {
$res = $users->updateUserPicture($userid, $_FILES['file']);
if($res === false) {
$isValid = false;
$message = "Er ging iets mis.";
}else{
$message = $res;
}
}else {
$isValid = true;
$message = $authresult;
}*/
$dataArray = array(
'isValid' => $isValid,
'message' => $message
);
echo ")]}',\n".json_encode($dataArray);
});
but everything is empty with https:// if i upload to http:// it works
Does anyone know why http works but https isn't working? the only case where https isn't working is with file uploads. the rest of my api routes work with https.
It happens on iOS devices and Android devices so the problem is more likely to be with the slim api i'd guess
Api response:
{
"bytesSent": 32889,
"responseCode": 200,
"response": "{\"userID\":\"2\",\"session_token\":\"****"
} {\
"file\":{\"name\":\"modified.jpg?1427448587960\",\"type\":\"image\\/jpeg\",\"tmp_name\":\"\\/tmp\\/phpABKyF2\",\"error\":0,\"size\":37491}}[]null\"\")]}',\n{\"isValid\":true,\"message\":null}",
"objectId": ""
}
Make sure you are using a valid SSL certificate. If your app is reaching the API but not sending the data, its likely that your app has realised the connection is unsafe. It will only send data once it establishes a secure connection to a server it can trust.
A self signed certificate will not be trusted.
I am trying to retrieve data from AngularJS file to PHP file, but I get the error that it's empty.
I can't find any good examples that are dealing with posting data from angularJS to php file and so I need help.
Angularjs file:
angular.module('myApp', ['ajoslin.promise-tracker'])
.controller('help', function ($scope, $http, $log, promiseTracker, $timeout) {
$scope.ph_numbr =/[0-9]+/;
// Form submit handler.
$scope.submit = function(form) {
// Trigger validation flag.
$scope.submitted = true;
// If form is invalid, return and let AngularJS show validation errors.
if (!$scope.toggle || $scope.toggle.length <= 0 || form.$invalid) {
return;
}
// Default values for the request.
$scope.progress = promiseTracker('progress');
var config = {
params : {
//'callback' : 'JSON_CALLBACK',
'name' : $scope.name,
'email' : $scope.email,
'toggle' : $scope.toggle,
'phone' : $scope.phone,
'comments' : $scope.comments
},
tracker : 'progress'
};
$http({
method : 'POST',
url : 'js/contact.php',
data: config,
headers : {'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'}
})
.success(function(data, status, headers, config) {
if (data.success) {
$scope.name = null;
$scope.email = null;
$scope.toggle = null;
$scope.phone = null;
$scope.comments = null;
$scope.messages = 'Your form has been sent!';
$scope.submitted = false;
} else {
$scope.messages = 'Oops, we received your request, but there was an error processing it.';
$log.error(data);
}
})
.error(function(data, status, headers, config) {
$scope.progress = data;
$scope.messages = 'There was a network error. Try again later.';
$log.error(data);
});
// Hide the status message which was set above after 3 seconds.
var promise = $timeout(function() {
$scope.messages = null;
}, 3000);
$scope.progress.addPromise(promise);
};
});
php file:
<?php
/*error_reporting(E_ALL);
ini_set('display_errors', '1');
require_once 'js/PHPMailerAutoload.php';*/
ini_set('display_errors', 'On');
error_reporting(E_ALL | E_STRICT);
$data = file_get_contents("php://input");
$postData = json_decode($data);
if (isset($_POST['name']) && isset($_POST['email']) && isset($_POST['toggle']) && isset($_POST['comments'])) {
//check if any of the inputs are empty
if (empty($_POST['name']) || empty($_POST['email']) || empty($_POST['toggle']) || empty($_POST['comments'])) {
$data = array('success' => false, 'message' => 'Please fill out the form completely.');
echo json_encode($data);
exit;
}
$email = trim($_POST['email']);
$subject = trim($_POST['toggle']);
//email address settings
$my_address = "*#yahoo.com";
$headers = "From: ".$email;
$message = "Name: " . $_POST['name'] . "\r\n\r\nMessage: " . $_POST["phone"] . "\r\n\r\nMessage: " . stripslashes($_POST['comments']);
$to = $my_address;
if (isset($_POST['ref'])) {
$mail->Body .= "\r\n\r\nRef: " . $_POST['ref'];
}
if(!$mail->send()) {
$data = array('success' => false, 'message' => 'Message could not be sent. Mailer Error: ' . $mail->ErrorInfo);
echo json_encode($data);
exit;
}
mail($to, $subject, $message, $headers);
$data = array('success' => true, 'message' => 'Thanks! We have received your message.');
echo json_encode($data);
} else {
$data = array('success' => false, 'message' => 'Please fill out the form completely.');
echo json_encode($data);
}
?>
The error message that I get is: "Please fill out the form completely" - which means it doesn't get the values.
My other question is how in the AngularJS do I retrieve the data.success value from the php file?
You seem to be getting the data here:
$data = file_get_contents("php://input");
$postData = json_decode($data);
but then you're using $_POST instead. Perhaps this would work:
if (empty($postData['name']) //etc
It looks like you're accessing data.success appropriately and the value should be set to false as your code currently is.
Additional code review:
If there are errors on the server, it's best to return a status code that indicates that. As is, the server is returning 200 (default), which means everything is OK, even though the request is actually failing. That would eliminate the need for data.success. If the server sends status 200, your .success function will fire. If it returns an error status, like 404, then your .error function would fire instead.
I have doubts about your need of the Content-Type header. You might want to reconsider if that's necessary.
On your Angular form, you ought to nest those $scope properties in an object:
$scope.formData = {
name: '',
email: '',
//etc
}
Then, you can simply pass that directly to your $http call and to reset the values you can simply do $scope.formData = {}.