Sendgrid will only send utf-8 attachments - php

I've created an employment application that allows applicants to upload their resume in pdf, doc, or docx extensions. I then email their information and resume to Human Resources using Sendgrid.
I've found through testing that when sending the email I receive an error:
Parameter attachment[resume.pdf] is not utf8
How can I fix this issues, should I encode every file that is uploaded to utf-8 before attaching it to the email? Will this create any issues or severally modify an users uploaded resume?
Here is my PHP Curl code I use to send via the SendGrid API:
(Note: I have to use the REST API, SMTP is not configured on the clients web server)
<?php
$mail['from'] = 'humanresources#email.org';
$mail['fromname'] = 'Human Resources';
$mail['to'] = 'person#email.com';
$mail['subject'] = character_limiter('Employment: '. $application['position'], 50);
$mail['html'] = '<p><strong>Name:</strong> '.$application['firstname'].' '.$application['lastname'].'</p>';
$mail['html'] .= '<p><strong>Position:</strong> '.$application['position'].'</p>';
$mail['html'] .= '<p><strong>Date:</strong> '.mdate('%m/%d/%Y %g:%i %A', $application['timestamp_saved']).'</p>';
$mail['html'] .= '<p><strong>Email:</strong> '.$application['email'].'</p>';
$mail['files['.$application['pdf'].']'] = '#saved_applications/'. $application['pdf'];
//Sendgrid Credientals
$mail['api_user'] = 'sendgrid_user';
$mail['api_key'] = 'sendgrid_pass';
print_r($mail);
// Generate curl request
$session = curl_init('https://sendgrid.com/api/mail.send.json');
curl_setopt ($session, CURLOPT_POST, true);
curl_setopt ($session, CURLOPT_POSTFIELDS, $mail);
curl_setopt($session, CURLOPT_HEADER, false);
curl_setopt($session, CURLOPT_RETURNTRANSFER, true);
// obtain response
$response = curl_exec($session);
curl_close($session);
// print everything out
$output = json_decode($response, TRUE);
print_r($output);
?>

The code you have should work (and worked when I tested it).
You may want to use the PHP library, rather than flat cURL. You'll be able to send attachments, from the web Web API by doing the following:
<?php
$sendgrid = new SendGrid('username', 'password');
$mail = new SendGrid\Mail();
$mail->
addTo('humanresources#email.org')->
...
addAttachment('saved_applications/'. $application['pdf']);
$sendgrid->web->send($mail);
?>

Perhaps instead of using sendgrid's web services API to send these messages, simply use phpmailer and send the messages through sendgrid by way of SMTP using their outgoing mail server smtp.sendgrid.net. I'm sure you won't get this error if you send the messages this way. See example at https://github.com/PHPMailer/PHPMailer.

Related

How to implement server to server data with this illustration

I'm setting two virtual hosts on my local pc, the first domain is http://dev.local and the other one handles the api request http://api.server.local/. The idea is simple, but not sure how to implement this kind of setup. So here's the actual process. The dev.local will send some important parameters and values which the API server read it first and validate the data sent from dev.local.
For example I have the API key provided from API server and being stored in the database together with the domain that can only use that API. So the most important thing is that I want to make sure that only dev.local can do the request. Here is some illustration.
[illustration] https://i.imgur.com/OKu34TM.png
I already tried cURL functions but for some reasons, the data can be access by anyone if they have a copy of the api key. So I want to make sure where the request come from or the origin of the request.
This is the script I have for my dev.local in order to get access to my api.server.local
<?php
$__apiServer = 'http://api.server.local';
$__apiVersion = '1.0';
$__apikey = '7c4a8d09ca3762af61e59520943dc26494f8941b'; // API Key
$__apiEmail = 'johnsmith99#gmail.com'; // Registered Email Address
$__apiUser = 'johnsmith'; // Username
$__curlURL = "";
$__curlURL = "{$__curlURL}{$__apiServer}/v{$__apiVersion}";
$__curlURL = "{$__curlURL}/bin.php?user={$__apiUser}";
$__curlURL = "{$__curlURL}&email={$__apiEmail}";
$__curlURL = "{$__curlURL}&key=$__apikey";
$__curlURL = "{$__curlURL}&domain=$_SERVER[SERVER_NAME]";
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $__curlURL);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_TIMEOUT, 30);
if(curl_exec($ch) === FALSE) {
echo "Failed to load resource files from the API Server: $__apiServer";
} else {
$__curlURL = curl_exec($ch);
if($err != 1){
eval(' ?>' . $__curlURL);
}
}
curl_close($ch);
I expect that the value can only be return if the required data are valid. For now the ouput can be read as expected but can be accessible by anyone if they have the copy of api key and other credentials.
I figure it out. I used cURL POST method and it is more secure than using GET. And parse array variables to validate the main parameters.

How integrate free sms api in codeigniter?

$username = "info#example.com";
$hash = "*******************************************";
$test = "0";
$sender = "php sender";
$numbers = "7575757577";
$message = "verification code";
$message = urlencode($message);
$data = "username=".$username."&hash=".$hash."&message=".$message."&sender=".$sender."&numbers=".$numbers."&test=".$test;
$ch = curl_init('http://api.textlocal.in/send/?');
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$result = curl_exec($ch);
curl_close($ch);
echo"<pre>";
print_r($result);exit;
I am implementing free SMS API with CodeIgniter. Now, problem is that when I click on submit button it throws an error as mention below
{"errors":[{"code":3,"message":"Invalid login details"}],"status":"failure"}
I have no idea why it throwing this error. How can I implement this with CodeIgniter? I have also load curl library in autoload file. Please help me.
Thank You
I found a php class on the textlocal.in api documentation. Download that file and upload it to your site. Here is the download link; click.
Then just use this simple code to send a sms;
require 'textlocal.class.php';
$textlocal=new textlocal('me#textlocal.in','e215398a8820abd2c7a11a6cd5b1009d'); // email and hash
$textlocal->sendSms(['917788990011'],'Your car - KA01 HG 9999 - is due for service on July 24th, please text SERVICE to 92205 92205 for a callback','FORDIN'); // First target phone number, then the message, and then where the sms comes from
(Got the code from here; click)
If you have anymore questions, just ask :)

Send Message to phone using Codeigniter

I have a codeigniter base website and I have tried making forgot password by Phone and Email using Codeigniter framework to change password notification.And email is already working but I don't know how to send message to phone using codeigniter??
And one of my friends told me that use Curl function to send message to phone.But I didn't have any prior idea about CURL function so I searched on google but I couldn't figure out how to do this.
Would you please give me proper suggestion about how to send message to phone using codeigniter.
Any kind of help would be highly appreciated.
Thanks in advance.
Here is a simple code-igniter helper which you need to save as helpers/sendsms_helper.php
function sendsms($number, $message_body, $return = '0') {
$sender = 'SEDEMO'; // Can be customized
$smsGatewayUrl = 'http://springedge.com';
$apikey = '62q3xxxxxxxxxxxxxxxxxxxxxx'; // Need to change
$textmessage = urlencode($textmessage);
$api_element = '/api/web/send/';
$api_params = $api_element.'?apikey='.$apikey.'&sender='.$sender.'&to='.$number.'&message='.$textmessage;
$smsgatewaydata = $smsGatewayUrl.$api_params;
$url = $smsgatewaydata;
$ch = curl_init();
curl_setopt($ch, CURLOPT_POST, false);
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); $output = curl_exec($ch);
curl_close($ch);
if(!$output){ $output = file_get_contents($smsgatewaydata); }
if($return == '1'){ return $output; }else{ echo "Sent"; }
}
How to use:
You can use below function anywhere in project to send sms:
Call sendsms function Ex. sendsms( '919918xxxxxx', 'test message' );
Please make sure to Load sendsms helper as $this->load->helper('sendsms_helper');
There are many companies that provide api for the same. I have used twilio for some time and find it reliable. The code for same can be
<?php
require "Services/Twilio.php";
$AccountSid = ""; //get from twilio
$AuthToken = ""; //get from twilio
$client = new Services_Twilio($AccountSid, $AuthToken);
$sms = $client->account->messages->sendMessage(
$tNumber, // Your twilio number
$number, // Number you want to send to
$message // Message you want to sms
);
Hope this helps. Again there are many other services out there also that you can look into

Emailing entire userbase in one PHP script? [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 8 years ago.
Improve this question
I'm wondering how do people handle emailing their userbase. I'm using PHP and SendGrid is handling the emails. The use case is a newsletter.
When I send myself 50 emails in testing the script already takes quite a long time and I worry that the application will time out if go for more emails at a time.
I don't really want to send myself 100, then 1,000, then 10,000 emails to see what the upper limit is testing this out.
I'm running this on a medium EC2 Linux if that is helpful.
There are several ways to accomplish this with SendGrid.
Send Emails in Parallel
It's likely that you're currently sending your emails in a series (i.e. send one email, wait for it to send, then send the next). This means if it takes you 1 second to send an email, it will take you 100 seconds to send one hundred.
Luckily, PHP's cURL Library allows you to send many POST requests in parallel, rather than in a series.
// An array of the emails you want to send to:
$emails = array("joe#example.org", "sue#example.com");
$credentials = array("api_user" => YOUR_SENDGRID_USERNAME, "api_key" => YOUR_SENDGRID_PASSWORD);
$multi_handle = curl_multi_init();
$handles = array();
// Loop through each email and create a cURL Handle for the email
// The cURL handle will POST an email to SendGrid with the proper info
foreach ($emails as $key => $email) {
// Create an email data object with your credentials in it,
// we'll POST this to SendGrid
$email_data = $credentials;
// Fill out all the information you want for the email
$email_data = array(
"to" => $email,
"from" => "you#example.net",
"subject" => generate_subject(),
"html" => generate_html(),
"text" => generate_text()
);
$handles[$key] = curl_init();
curl_setopt($handles[$key], CURLOPT_URL, "https://api.sendgrid.com/api/mail.send.json");
curl_setopt($handles[$key], CURLOPT_POST, 1);
curl_setopt($handles[$key], CURLOPT_POSTFIELDS, $email_data);
curl_setopt($handles[$key], CURLOPT_RETURNTRANSFER, true);
curl_multi_add_handle($multi_handle, $handles[$key]);
}
$running = null;
// Run through each cURL handle and execute it.
do {
curl_multi_exec($multi_handle, $running);
} while ($running);
curl_multi_close($multi_handle);
This method works well if you have lots of hyper-unique emails that you want to send, however it still results in a bunch of POST requests from your server, which are slow and resource consuming. There's often a better way.
Send Emails Using the SMTPAPI
SendGrid has an SMTPAPI which allows you to send up to 10,000 emails with one POST request using the to parameter. You can make these emails semi-unique by using substitution tags.
For this you'd do something like the following:
// An array of the emails you want to send to:
$emails = array("joe#example.org", "sue#example.com");
// Encode it into the SendGrid SMTPAPI Format
$smtpapi = array( "to" => $emails );
$params = array(
"api_user" => YOUR_SENDGRID_USERNAME,
"api_key" => YOUR_SENDGRID_PASSWORD,
"to" => "you#example.com",
"subject" => "testing from curl",
"html" => "testing body",
"text" => "testing body",
"from" => "you#example.com",
"x-smtpapi" => json_encode($smtpapi);
);
$request = "https://api.sendgrid.com/api/mail.send.json";
// Generate curl request
$session = curl_init($request);
// Tell curl to use HTTP POST
curl_setopt ($session, CURLOPT_POST, true);
// Tell curl that this is the body of the POST
curl_setopt ($session, CURLOPT_POSTFIELDS, $params);
// Tell curl not to return headers, but do return the response
curl_setopt($session, CURLOPT_HEADER, false);
curl_setopt($session, CURLOPT_RETURNTRANSFER, true);
// obtain response
$response = curl_exec($session);
curl_close($session);
However, it's probably better to do this with SendGrid's PHP Library
$emails = array("joe#example.org", "sue#example.com");
$sendgrid = new SendGrid(YOUR_SENDGRID_USERNAME, YOUR_SENDGRID_PASSWORD);
$email = new SendGrid\Email();
$email->setTos($emails)->
setFrom('me#bar.com')->
setSubject('Subject goes here')->
setText('Hello World!')->
setHtml('<strong>Hello World!</strong>');
$sendgrid->send($email);
Queueing
Finally, you could utilize a queue and send all the emails from a different process to speed up your execution time, information on how to do that is in this StackOverflow response.

SendGrid - Curl php external file attachment broken

I'm using SendGrid for a customer project with curl method.
All works fine but the(ir) file(s) attached on my email sending with SendGrid are broken.
Here is my code :
$documentList = array(
"DOC1.php" => "http://www.customerdomain.com/my/path/where/my/attachment/file/is/myfile.pdf"
);
$params = array(
'api_user' => $user;
'api_key' => $pass,
'x-smtpapi' => json_encode($json_string),
'from' => $from,
'to' => $to,
'subject' => $subject,
'html' => $mailHtml,
'text' => $mailText
);
if(count($documentList)>0){
foreach($documentList as $fileName=>$documentPath){
$params['files['.$fileName.']'] = $documentPath;
}
}
$request = $url.'api/mail.send.json';
// Generate curl request
$session = curl_init($request);
// Tell curl to use HTTP POST
curl_setopt ($session, CURLOPT_POST, true);
// Tell curl that this is the body of the POST
curl_setopt ($session, CURLOPT_POSTFIELDS, $params);
// Tell curl not to return headers, but do return the response
curl_setopt($session, CURLOPT_HEADER, false);
curl_setopt($session, CURLOPT_RETURNTRANSFER, true);
// obtain response
$response = curl_exec($session);
curl_close($session);
When I don't have extension file on my key of array, I've a text file containing the related value.
I think I'm not alone to have this problem, well, if you've any idea to solve this problem, thanks for your help !
The issue you're experiencing is because you are giving SendGrid a URL for file, rather than the file itself, and SendGrid's API needs the file.
To get your code to work, simply change the $documentList variable to:
$documentList = array(
"DOC1.pdf" => "#" . realpath("/path/where/my/attachment/file/is/myfile.pdf")
);
Instructions on this kind of file upload can be found in this StackOverflow Question, but you might otherwise want to use curl_file_create, to do this.
However, perhaps the best/easiest way to do this is to use SendGrid's PHP Library which makes sending attachments, trivially simple.:
require("path/to/sendgrid-php/sendgrid-php.php");
$sendgrid = new SendGrid('username', 'password');
$email = new SendGrid\Email();
$email->addTo('foo#bar.com')->
setFrom('me#bar.com')->
setSubject('Subject goes here')->
setText('Hello World!')->
setHtml('<strong>Hello World!</strong>')
addAttachment("../path/to/file.txt");
$sendgrid->send($email);
My initial issue was because the path is an autogenerated link and that's why I didn't use an url than realpath.
Anyway, I changed my code and I use now the realpath with mimetype mentioned after the file realpath (and # before).
It seems work fine now.
I'll like to thank you for your help.
Regards

Categories