I'm writing an application with codeigniter, which is clearly done but I just want 1 more plugin in it. I would like to catch all the emails from my outlook account to my codeigniter app.
It would be awesome if I could send and receive messages on my codenigter app.
My second question is how can I api my agenda from my codeigniter app to the agenda from outlook?
Email works on some protocols for incoming (IMAP) and outgoing (SMTP) or similar like POP3 etc.
So you must have configured those settings in outlook to read your mails and send mails. Similarly, You can read mails in PHP and Send mails using php.
Sending Emails:
You can use codeigniter core email library which works well for outgoing. sending emails codeigniter
Reading Mails:
This script can read your mail by providing configuration which you provided to outlook.
<?php
class Email_reader {
// imap server connection
public $conn;
// inbox storage and inbox message count
private $inbox;
private $msg_cnt;
// email login credentials
private $server = 'YOUR_MAIL_SERVER';
private $user = 'email#mailprovider.com';
private $pass = 'yourpassword';
private $port = 143; // change according to server settings
// connect to the server and get the inbox emails
function __construct() {
$this->connect();
$this->inbox();
}
// close the server connection
function close() {
$this->inbox = array();
$this->msg_cnt = 0;
imap_close($this->conn);
}
// open the server connection
// the imap_open function parameters will need to be changed for the particular server
// these are laid out to connect to a Dreamhost IMAP server
function connect() {
$this->conn = imap_open('{'.$this->server.'/notls}', $this->user, $this->pass);
}
// move the message to a new folder
function move($msg_index, $folder='INBOX.Processed') {
// move on server
imap_mail_move($this->conn, $msg_index, $folder);
imap_expunge($this->conn);
// re-read the inbox
$this->inbox();
}
// get a specific message (1 = first email, 2 = second email, etc.)
function get($msg_index=NULL) {
if (count($this->inbox) <= 0) {
return array();
}
elseif ( ! is_null($msg_index) && isset($this->inbox[$msg_index]))
{
return $this->inbox[$msg_index];
}
return $this->inbox[0];
}
// read the inbox
function inbox() {
$this->msg_cnt = imap_num_msg($this->conn);
$in = array();
for($i = 1; $i <= $this->msg_cnt; $i++) {
$in[] = array(
'index' => $i,
'header' => imap_headerinfo($this->conn, $i),
'body' => imap_body($this->conn, $i),
'structure' => imap_fetchstructure($this->conn, $i)
);
}
$this->inbox = $in;
}
}
?>
Its a basic script to read mails, you can enhance it according to your requirement.
Related
I am sending emails from my laravel website using SMTP. When i send email to the user then i want to copy that mail to IMAP sent folder too.
Here is my code when i am sending mail to user:
$mail = Mail::to($this->receiver)
->send(new ComplaintMail($this->sender->user_email,$this->subject,$this->complaint,$this->answers,$this->sender));
$path = "{mypath.com:993/imap/ssl}Sent";
$imapStream = imap_open($path,$this->sender->user_email,$this->sender->email_password);
$result = imap_append($imapStream,$path,$mail->getSentMIMEMessage());
imap_close($imapStream);
Also I tried using imap_mail_move() method like so:
$mail = Mail::to($this->receiver)
->send(new ComplaintMail($this->sender->user_email,$this->subject,$this->complaint,$this->answers,$this->sender));
$path = "{mypath.com:993/imap/ssl}Sent";
$imapStream = imap_open($path,$this->sender->user_email,$this->sender->email_password);
imap_mail_move($imapStream,$mail,$path);
imap_close($imapStream);
Both ways it didn't worked out
In ComplaintMail class, build function looks like :
public function build()
{
return $this->from($this->sender)
->subject($this->subject)
->markdown('emails.complaint');
}
When I'm building and testing my website on local server, I would like to emulate successful sending via phpmailer, so I avoid actually sending emails.
I normally use if ($mail->Send()) { the mail was sent, now do this }.
For local testing I think the best would be to skip the whole phpmailer inclusion, instead of adding a lot of if statements etc.
But skipping phpmailer would then cause php to complain about $mail->Send(), $mail->addAddress('emailaddress') etc.
How could I fake the function (or object/class) so that calls to $mail->Send() are always true, and the rest $mail->something() etc. are just ignored/true, so that no email is sent?
Extend the PHPMailer class and override the public function send().
class UnitTestMailer extends PHPMailer {
public function send() {
return $this;
}
}
class User {
public function __construct(PHPMailer $mailer) {
$this->mailer = $mailer;
}
public function sendActiviation() {
return $this->mailer->send();
}
}
// ... somewhere in your test
public function test_if_from_is_properly_set() {
// ...
$user = new User(new UnitTestMailer);
// ...
$mailer = $user->sendActivation();
$this->assertEquals($expectedFrom, $mailer->From);
}
Why emulate?
I use INI files to provide configuration variables for PHPMailer depending on the environment. Live obviously has the server's mail settings. Local uses my Gmail account credentials to send mail.
You can have the best of both worlds :)
Keep a config.ini file for example somewhere in your working directory (I tend to use root but that's preference) and make sure it's in your .gitignore or similar. Your local version would look something like:
[PHPMailer Settings]
EMAIL_HOST = "smtp.gmail.com"
EMAIL_PORT = 587
EMAIL_SMTPSECURE = "tls"
EMAIL_SMTPAUTH = "true"
EMAIL_USERNAME = "my_email#gmail.com"
EMAIL_PASSWORD = "my_password"
then in your PHP:
$ini = parse_ini_file($_SERVER['DOCUMENT_ROOT'] . "/config.ini", true, INI_SCANNER_TYPED);
// use settings from INI file:
$foo = $ini['PHPMailer Settings']['EMAIL_HOST'];
$bar = $ini['PHPMailer Settings']['EMAIL_PORT'];
Security Bonus
Change the syntax of your INI file to look like the below and rename it to config.ini.php:
; <?php
; die();
; /*
[PHPMailer Settings]
EMAIL_HOST = "smtp.gmail.com"
EMAIL_PORT = 587
EMAIL_SMTPSECURE = "tls"
EMAIL_SMTPAUTH = "true"
EMAIL_USERNAME = "my_email#gmail.com"
EMAIL_PASSWORD = "my_password"
; */ ?>
(remember to use the new filename in your PHP code)
PHP can still parse the settings, but if anyone tried to access the INI file it would be parsed as PHP comments and just show ";"
I was following PHPMailer tutorial and some tutorials in Internet but I still can't make execution less than 2 second. On many website it says it shouldn't take more than 0.4s. I tried it from my local machine and from AWS machine. Execution time same.
class BatchMailer {
private static $mail;
private static $initialized = false;
private static function initialize() {
if (self::$initialized)
return;
self::$mail = new PHPMailer;
self::$mail->SMTPDebug = 2;
self::$mail->isSMTP();
self::$mail->Host = 'smtp.gmail.com';
self::$mail->Port = 587;
self::$mail->SMTPSecure = 'tls';
self::$mail->SMTPAuth = true;
self::$mail->Username = '***';
self::$mail->Password = '***';
self::$mail->SMTPKeepAlive = true;
self::$mail->setFrom('***#gmail.com', 'Title');
self::$mail->isHTML(true);
self::$mail->AltBody = 'Please use an HTML-enabled email client to view this message.';
self::$initialized = true;
}
public static function setSubject($subject) {
self::initialize();
self::$mail->Subject = $subject;
}
public static function setBody($body) {
self::initialize();
self::$mail->Body = stripslashes($body);
}
public static function sendTo() {
self::initialize();
self::$mail->clearAddresses();
$recipients = array(
'***#gmail.com' => 'Person One'
);
foreach($recipients as $email => $name) {
self::$mail->AddCC($email, $name);
}
self::$mail->send();
return;
}
static function test() {
self::setSubject('subject');
self::setBody('body');
self::sendTo();
}
}
SMTP is often slow, especially when things like greetdelay/tarpitting are used as anti-spam measures. 2 seconds is not that slow - the SMTP spec allows for timeouts of 10-20 minutes! It's really unsuited to real-time use, i.e. during a web page submission, but that doesn't seem to stop many trying to use it that way. To maximise performance you can install a local mail server to use as a relay, or hand off your message send to a separate process that doesn't mind waiting for a while, for example by submitting using an async ajax request from your page so the user is not blocked from doing other things.
If you're sending larger volumes of email it's important to use a relay and SMTP keepalive while submitting it. I have no trouble sustaining over 200 messages/second with PHPMailer.
Nice class BTW - tidier than most of the things I see on SO! $initialized is not needed - just check whether self::$mail is set instead.
I am developing a online video chat application in which a group of users can see and send message to the model room in which they are present. For this I am using websocket and php.
But when a user sending any mesages it is going to all users instead of the room in which he/she is present. Below is my sample code.
function send_message($msg) {
global $clients;
foreach ($clients as $changed_socket) {
#socket_write($changed_socket, $msg, strlen($msg));
}
return true;
}
Please give your valuable feedback.
From the code provided, it appears that your $clients array holds only the socket handle for that specific connection.
Find the line in your server that has the function socket_accept(). It will probably look like:
$clients[] = socket_accept($socket);
My personal choice for a quick and dirty fix would be to change it as follows:
$handle = socket_accept($socket);
$client = array('handle' => $handle,
'rooms' => array(),
// additional properties...
);
$clients[] = $client;
Then, when you want to send a message to a specific room:
function send_message($message, $handle) {
socket_write($handle, $message, strlen($message);
}
function broadcast($message, $room = null) {
global $clients;
foreach ($clients as $client) {
if (is_null($room) || in_array($room, $client['rooms'])) {
send_message($message, $client['handle']);
}
}
}
broadcast('This message will only go to users in the room "lobby"', 'lobby');
broadcast('This message will go to everybody on the server.');
A better, long term solution is to create a user class and keep a list of instances, but the basics are the same: assign the handle to a property rather than passing the handles around raw.
I'm building a webmail-client-like application, and I'm having issues connecting to POP3 through our beloved corp proxy.
Due to client requirements, I'm obligated to use sockets to talk with their POP3 server (they actively specified this is mandatory and they also explained they have a proxy between the app server and the POP) so besides enabling me to work this is kind of the only option I have.
Does anyone know how to do this?
UPDATED TO ADD:
Here's my socket handler:
<?php
class Socket {
protected $handle = null;
protected static $status = null;
public function __construct($server, $port){
if(!$this->connect($server, $port)){
throw new UnexpectedValueException("Server $server in port $port unreachable.");
}
}
public static function getStatus(){
return self::$status;
}
public function write($string){
fputs($this->handle, $string);
return $this;
}
public function read($lines = 1){
$lines = abs((int)$lines);//people can be morons
for($i = 0; $i < $lines; $i++){
$response []= $this->getLine();
}
if($lines==1){
$response = $response[0];
}
return $response;
}
public function connect($server, $port){
$errNo = 0;
$handle = fsockopen($server, $port);
if(!$handle){
return false;
}
$this->handle = $handle;
return $this;
}
public function disconnect(){
if(gettype($this->handle)=='resource'){
fclose($this->handle);
}
}
public function __destruct(){
$this->disconnect();
}
protected function getLine(){
return fgets($this->handle);
}
}
I'm using it like so:
$plug = new Socket('mx.mailserver.com',110);
$plug->write("USER $username\n")->read();
$could = $plug->write("PASS $password\n")->read();
if(strpos($could,'+OK')!==false){
$mails = $plug->write("STAT\n");
}
And right now our proxy is not letting me out; situation I would like to know how to revert.
First, have you tested with telnet - i.e. if you are on the same server / workstation that the PHP script is running on, and you issue:
telnet mx.mailserver.com 110
Do you get the greeting? (you're also not reading that - so your read from the command where you send the username is going to get that as a response, so your code will work but largely by accident.
If you can't get it to work via telnet then stop and get that working first - no point proceeding otherwise.
You may need to send \r\n at the end of each command.
$plug->write("USER $username\r\n")->read();
So you need to do something like:
$plug = new Socket('mx.mailserver.com',110);
$greeting = $plug->read(); // check this said +OK
$plug->write("USER $username\r\n")->read(); // check this said +OK
$could = $plug->write("PASS $password\r\n")->read();
if(strpos($could,'+OK')!==false) {
$mails = $plug->write("STAT\r\n");
}
I'm not entirely sure about your strpos() line - but I can't test that right now.
As I say, before you do ANYTHING else verify that it all works ok on Telnet.
If it does, then monitor the server logs (if possible) and see whether you're getting in touch with the POP3 server and what it's getting.
Here's an example sequence:
telnet pop.blah.com 110
+OK Welcome to MailEnable POP3 Server
USER matthew
+OK
PASS mypassword
+OK
STAT
+OK 0 0
Hope this helps.
Use this for client
https://github.com/clue/php-socks
Use this for proxy server
https://github.com/clue/psocksd
If your server has more than one public IP and you need these IP act as proxy outgoing, use this for proxy server https://www.inet.no/dante/
Guide to configure proxy to have multi outgoing ip: http://www.inet.no/dante/doc/faq.html#multiple_external_ips
Example config to have multi outgoing ip: http://wiki.jokeru.ro/dante-socks-server
They all work for me