I have never played with fetching and moving emails before using IMAP and PHP, so im struggeling with moving emails that are sent to the trash back to the inbox.
Ok, so i'm fetching my emails from Gmail correctly, and i am able to delete them, or move them to trash rather.
When i try to move them back to Inbox i get the following error:
Notice: Unknown: [TRYCREATE] No folder [Gmail]/Inbox (Failure) (errflg=2) in Unknown on line 0
So obviously there is something i dont quite get, and i have been searching the web and stackoverflow for the answer the last couple of hours with no luck. Does anyone know why this particular action does not succeed?
Any help is as usual much appreciated, i would love to get the hang of this and make myself a little email app.
Below is the class i have made, see the method undo(), thats where this particular warning pops up.
class Gmail {
public $emailsexists = false;
public $emailarray = '';
private $username;
private $password;
private $inbox;
public function __construct($username,$password) {
/* connect to gmail using imap */
$hostname = '{imap.gmail.com:993/imap/ssl}INBOX';
$this->username = $username;
$this->password = $password;
/* try to connect using username and password set in core/init.php (gmail_credentials) */
$this->inbox = imap_open($hostname,$this->username,$this->password) or die('Cannot connect to Gmail: ' . imap_last_error());
}
public function delete($email) {
if ($email !== '' && is_numeric($email)) {
if (imap_mail_move($this->inbox, $email, '[Gmail]/Trash')) {
return true;
} else {
return false;
}
} else {
return false;
}
imap_close($this->inbox);
}
public function undo($email) {
if ($email !== '' && is_numeric($email)) {
if (imap_mail_move($this->inbox, $email, '[Gmail]/Inbox')) { // FIX Throws back a warning
return true;
} else {
return false;
}
} else {
return false;
}
imap_close($this->inbox);
}
public function unseen($number = false) {
/* grab emails */
$emails = imap_search($this->inbox,'UNSEEN');
/* if emails are returned, cycle through each... */
if($emails) {
/* statement that tells that emails exist */
$this->emailsexists = true;
/* put the newest emails on top */
rsort($emails);
/* Start the counter */
$x = 0;
/* Open up the accordion */
$this->emailarray.= '<div id="accordion">';
/* for every email... */
foreach($emails as $email) {
/* get information specific to this email */
$overview = imap_fetch_overview($this->inbox,$email,0);
$structure = imap_fetchstructure($this->inbox, $email);
$message = imap_fetchbody($this->inbox,$email,1,FT_PEEK);
if(isset($structure->parts) && is_array($structure->parts) && isset($structure->parts[1])) {
$part = $structure->parts[1];
$message = imap_fetchbody($this->inbox,$email,2,FT_PEEK);
}
/* escape and decode the mimeheaders */
$subject = escape(str_replace("_"," ", mb_decode_mimeheader($overview[0]->subject)));
/* decode and put the subject into the accordion header */
$this->emailarray.= '<h3>'.html_entity_decode(escape($subject)).'</h3>';
$this->emailarray.= '<div>';
$this->emailarray.= '<div class="btn-group pull-right">';
$this->emailarray.= '<span class="glyphicon glyphicon-share-alt text-success"></span>';
$this->emailarray.= '<span class="glyphicon glyphicon-send text-success"></span>';
$this->emailarray.= '<span class="glyphicon glyphicon-fire text-danger"></span>';
$this->emailarray.= '</div>';
$this->emailarray.= '<p>';
/* decode the email body using the built in quoted_printable_decode function */
$this->emailarray.= quoted_printable_decode($message);
$this->emailarray.= '</p>';
$this->emailarray.= '</div>';
/* if the counter reaches a certain number, break out and continue the script */
$x++;
if ($number) {
if ($x >= $number) {
break;
}
}
}
/* close off the accordion */
$this->emailarray.= '</div>';
/* If no emails are found return a message */
} else {
echo "No emails";
}
/* close the imap connection */
imap_close($this->inbox);
}
}
I found that if i connect to the Trash and then use an asterix to get the last message it works as intended.
public function undo($email) {
// check if message id exists and is numeric
if ($email !== '' && is_numeric($email)) {
// set hostname to trash
$hostname = '{imap.gmail.com:993/imap/ssl}[Gmail]/Trash';
$this->inbox = imap_open($hostname,$this->username,$this->password) or die('Cannot connect to Gmail: ' . imap_last_error());
// return true if the message was moved
if (imap_mail_move($this->inbox, '*', 'Inbox')) {
return true;
} else {
return false;
}
} else {
return false;
}
imap_close($this->inbox,CL_EXPUNGE);
}
Move mail INBOX To TRASH THROUGH IMAP using node-imap.
const Imap = require("imap");
const mailBox = new Imap({
host: "imap.gmail.com",
password: "password",
port: 993,
user: "email",
tls: true,
connTimeout: 30000,
authTimeout: 30000,
keepalive: false,
tlsOptions: {
rejectUnauthorized: false,
},
});
mailBox.once("error", console.error);
mailBox.once("ready", () => {
mailBox.openBox("INBOX", false, (error, box) => {
if (error) throw error;
mailBox.search(
[
// "UNSEEN",
["SUBJECT", "When to say 'sorry' at work"],
["FROM", "taco#trello.com"]
],
(error, results) => {
if (error) throw error;
console.log("results",results);
for (const uid of results) {
const mails = mailBox.fetch(uid, {
bodies: ""
// markSeen: true
});
mails.once("end", () => mailBox.end());
mails.on("message", (message, seq) => {
console.log('message',message);
message.on("body", stream => {
console.log("results123456--------",uid);
let buffer = "";
stream.on("data", chunk => (buffer += chunk.toString("utf8")));
stream.once("end", () => mailBox.move(uid, "[Gmail]/Trash"));
});
});
}
}
);
});
});
mailBox.connect();
Related
so i have a login form where in iwant to show a error message if the account is not exsisting or the inputed account is incorrect. but the error message using snackbar is not showing.
here is my code for vue js.
const Login = Vue.component('login-view', {
data () {
return {
validate: {
login: false,
forgot: false
},
loading: {
login: false
},
form: {
email: null,
password: null
},
showPassword: false
}
},
computed: {
passField () {
var type = null
if (this.showPassword) {
type = 'text'
} else {
type = 'password'
}
return type
}
},
methods: {
signIn () {
if (this.$refs.login.validate()) {
this.loading.login = true
axios.post('./sql/login.php', this.form)
.then((res) => {
const data = res.data
console.log(data)
if(data) {
sessionStorage.setItem('uid', data.uid)
sessionStorage.setItem('displayName', data.displayName)
sessionStorage.setItem('email', data.email)
sessionStorage.setItem('type', data.type)
if (data.type === 'customer') { router.push('/'); location.reload() }
else if (data.type === 'seller') { router.push('/seller') }
}
this.loading.login = false
})/* Catching the error and displaying it in the console. */
.catch((error) => { console.log(error); this.$emit('snackbar', "incorrect"); this.loading.login = false })
}
}
},
here is my code for php
<?php
require_once("connection.php");
// Used to recognize JSON data posted by Axios.js
$data = json_decode(file_get_contents("php://input"), true);
//Check if the account exists
$sql = $handler->prepare("SELECT * FROM accounts WHERE email = ?");
$sql->execute(array($data['email']));
$count = $sql->rowCount();
// If account exists, its data will be fetched.
if($count === 1) {
$info = $sql->fetch(PDO::FETCH_OBJ);
$verified = password_verify($data['password'], $info->password);
// Checks if password entered matches the hashed password in account's data.
if ($verified) {
// Encodes initial account information as a JSON and sends it back.
$accountData = new \stdClass();
$accountData->uid = $info->uid;
$accountData->displayName = $info->fname . ' ' . $info->lname;
$accountData->email = $info->email;
$accountData->type = $info->type;
header("HTTP/1.1 200 OK");
/* Encoding the account data as a JSON and sending it back to the client. */
die(json_encode($accountData));
} else {
console_log(json_encode(array('message' => 'ERROR', 'code' => 2000)));
$error = 'Wrong email or password. Please try again.';
header('HTTP/1.1 500 Internal Server');
header('Content-Type: application/json; charset=UTF-8');
/* Sending a JSON object back to the client. */
die(json_encode(array('message' => 'ERROR', 'code' => 2000)));
}
die();
}
else {
$error = 'Account does not exists under this email. Please try again.';
}
die();
function console_log($output, $with_script_tags = true) {
$js_code = 'console.log(' . json_encode($output, JSON_HEX_TAG) .
');';
if ($with_script_tags) {
$js_code = '<script>' . $js_code . '</script>';
}
echo $js_code;
}
?>
here is the link to the website that i built. https://www.tailorshopthesis.online/tailorshop%20twofish/shop/#/sign-in
i hope some of you guys will help me. thanks
I'm retrieving Gmail e-mails through IMAP. I'm setting the FT_PEEK option wherever I can, and finally, I've even opened the mailbox as read-only (OP_READONLY). Yet, my code is marking the messages as read.
Here is the code:
class imap{
CONST HOSTNAME='{imap.gmail.com:993/imap/ssl}INBOX';
CONST USERNAME = '[Address hidden]';
CONST PASSWORD = '[Password hidden]'; //App password from Google
function getMessagesSince($date){
//This will return a collection of email objects.
$messages=array();
if(!$imap=imap_open($this::HOSTNAME, $this::USERNAME, $this::PASSWORD, OP_READONLY)) throw new exception("Unable to connect to IMAP mailbox. ".imap_last_error());
$since=date_format($date, 'j F Y');
$emails=imap_search($imap, 'SINCE "'.$since.'"', SE_UID|FT_PEEK);
foreach($emails as $email){
$messages[]=$this->getMessage($email, $imap);
}
imap_close($imap);
return $messages;
}
private function getMessage($uid, $imap){
//First get the headers
$headers=$this->getHeaders($uid, $imap);
$datereceived=date('Y-m-d H:i:s', strtotime($headers->date));
$sender=$headers->from[0]->mailbox."#".$headers->from[0]->host;
$cc=$headers->cc;
$subject=$headers->subject;
//Now get the message body
$message=$this->getBody($uid, $imap);
$email=new email();
$email->uid=$uid;
$email->datereceived=$datereceived;
$email->sender=$sender;
$email->cc=$cc;
$email->subject=$subject;
$email->message=$message;
return $email;
}
private function getHeaders($uid, $imap){
//Return an array of headers for the referenced message
//$overview = imap_fetch_overview($imap, $uid, FT_UID); //As we used the SE_UID flag when searching, we have to use it when fetching.
//We use this, rather than fetch_overview, because the overview doesn't have the cc information.
$hText = imap_fetchbody($imap, $uid, '0', FT_UID|FT_PEEK);
$headers = imap_rfc822_parse_headers($hText);
return $headers;
}
private function getBody($uid, $imap){
$body = $this->get_part($imap, $uid, "TEXT/HTML");
// if HTML body is empty, try getting text body
if ($body == "") {
$body = $this->get_part($imap, $uid, "TEXT/PLAIN");
}
return $body;
}
private function get_part($imap, $uid, $mimetype, $structure = false, $partNumber = false){
if (!$structure) {
$structure = imap_fetchstructure($imap, $uid, FT_UID);
}
if ($structure) {
if ($mimetype == $this->get_mime_type($structure)) {
if (!$partNumber) {
$partNumber = 1;
}
$text = imap_fetchbody($imap, $uid, $partNumber, FT_UID|FT_PEEK);
switch ($structure->encoding) {
case 3:
return imap_base64($text);
case 4:
return imap_qprint($text);
default:
return $text;
}
}
// multipart
if ($structure->type == 1) {
foreach ($structure->parts as $index => $subStruct) {
$prefix = "";
if ($partNumber) {
$prefix = $partNumber . ".";
}
$data = $this->get_part($imap, $uid, $mimetype, $subStruct, $prefix . ($index + 1));
if ($data) {
return $data;
}
}
}
}
return false;
}
private function get_mime_type($structure){
$primaryMimetype = ["TEXT", "MULTIPART", "MESSAGE", "APPLICATION", "AUDIO", "IMAGE", "VIDEO", "OTHER"];
if ($structure->subtype) {
return $primaryMimetype[(int)$structure->type] . "/" . $structure->subtype;
}
return "TEXT/PLAIN";
}
}
Can anyone spot something I'm missing?
(This is just some extra text, because it's saying that the post is mostly code. I'm just typing here until it lets me post.)
You should delete OP_READONLY flag from imap_open() .
Trying to sent packages from my webhost to a game server, using this code. However it always results in Unable to open socket: Connection timed out (110) ad I can't figure out why it times out. When I try this on my localhost, it works perfectly but when on webhost, it just times out. I've tried to set the timeout to something else but it didn't help.
define("SERVERDATA_EXECCOMMAND",2);
define("SERVERDATA_AUTH",3);
class RCon {
var $Password;
var $Host;
var $Port = 27015;
var $_Sock = null;
var $_Id = 0;
function RCon ($Host,$Port,$Password) {
$this->Password = $Password;
$this->Host = $Host;
$this->Port = $Port;
$this->_Sock = #fsockopen($this->Host,$this->Port, $errno, $errstr, 30) or
die("Unable to open socket: $errstr ($errno)\n");
$this->_Set_Timeout($this->_Sock,2,500);
}
function Auth () {
$PackID = $this->_Write(SERVERDATA_AUTH,$this->Password);
// Real response (id: -1 = failure)
$ret = $this->_PacketRead();
if ($ret[1]['id'] == -1) {
die("Authentication Failure\n");
}
}
function _Set_Timeout(&$res,$s,$m=0) {
if (version_compare(phpversion(),'4.3.0','<')) {
return socket_set_timeout($res,$s,$m);
}
return stream_set_timeout($res,$s,$m);
}
function _Write($cmd, $s1='', $s2='') {
// Get and increment the packet id
$id = ++$this->_Id;
// Put our packet together
$data = pack("VV",$id,$cmd).$s1.chr(0).$s2.chr(0);
// Prefix the packet size
$data = pack("V",strlen($data)).$data;
// Send packet
fwrite($this->_Sock,$data,strlen($data));
// In case we want it later we'll return the packet id
return $id;
}
function _PacketRead() {
//Declare the return array
$retarray = array();
//Fetch the packet size
while ($size = #fread($this->_Sock,4)) {
$size = unpack('V1Size',$size);
//Work around valve breaking the protocol
if ($size["Size"] > 4096) {
//pad with 8 nulls
$packet = "\x00\x00\x00\x00\x00\x00\x00\x00".fread($this->_Sock,4096);
} else {
//Read the packet back
$packet = fread($this->_Sock,$size["Size"]);
}
array_push($retarray,unpack("V1ID/V1Response/a*S1/a*S2",$packet));
}
return $retarray;
}
function Read() {
$Packets = $this->_PacketRead();
foreach($Packets as $pack) {
if (isset($ret[$pack['ID']])) {
$ret[$pack['ID']]['S1'] .= $pack['S1'];
$ret[$pack['ID']]['S2'] .= $pack['S1'];
} else {
$ret[$pack['ID']] = array(
'Response' => $pack['Response'],
'S1' => $pack['S1'],
'S2' => $pack['S2'],
);
}
}
return $ret;
}
function sendCommand($Command) {
$Command = '"'.trim(str_replace(' ','" "', $Command)).'"';
$this->_Write(SERVERDATA_EXECCOMMAND,$Command,'');
}
function rconCommand($Command) {
$this->sendcommand($Command);
$ret = $this->Read();
//ATM: Source servers don't return the request id, but if they fix this the code below should read as
// return $ret[$this->_Id]['S1'];
return $ret[0]['S1'];
}
}
If I specify udp connection in fsockopen it does not timeout, however if I try tcp, it times out. Most likely caused by the host, but I have no idea where to go from this.
https://developer.valvesoftware.com/wiki/Source_RCON_Protocol
https://developer.valvesoftware.com/wiki/Server_queries
Using the following class:
class Email_reader {
// imap server connection
public $conn;
// inbox storage and inbox message count
private $inbox;
private $msg_cnt;
// email login credentials
private $server = 'xxxxxxxxxxxx.com';
private $user = 'admin#xxxxxxxxx.com';
private $pass = 'xxxxxxxxx';
private $port = 143; // adjust 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;
}
}
And the following usage code:
$email = new Email_reader();
$msg = $email->get(1);
echo "message body is [".$msg['body']."]<br />"; //prints body //good
echo "message index is [".$msg['index']."]<br />"; //prints "2" //good
echo "message subject is [".$msg['header']->Subject."]<br />"; //prints strangness
echo "message toaddress is [".$msg['header']->toaddress."]<br />"; //prints strangeness
the attempt to print subject line prints "=?utf-8?B?TWljcm9zb2Z0IE9mZmljZSBPdXRsb29rIFRlc3QgTWVzc2FnZQ==?="
and the toaddress also something similar.
I looked at some other examples online but i dont see anything different that they do than what im doing.
You have to decode the RFC 2047 encoding of the Unicode data. Check the imap_utf8 function.
I've a Php SMS API which send SMS to my client. All is OK right now but it's send 2 sms once i submit the form. I can't understand why it's send 2 SMS. Can you guys tell me why its send 2 sms ?
Api Code:
<?php
class Sender{
var $host;
var $port;
/*
* Username that is to be used for submission
*/
var $strUserName;
/*
* password that is to be used along with username
*/
var $strPassword;
/*
* Sender Id to be used for submitting the message
*/
var $strSender;
/*
* Message content that is to be transmitted
*/
var $strMessage;
/*
* Mobile No is to be transmitted.
*/
var $strMobile;
/*
* What type of the message that is to be sent
* <ul>
* <li>0:means plain text</li>
* <li>1:means flash</li>
* <li>2:means Unicode (Message content should be inHex)</li>
* <li>6:means Unicode Flash (Message content shouldbe in Hex)</li>
* </ul>
*/
var $strMessageType;
/*
* Require DLR or not
* <ul>
* <li>0:means DLR is not Required</li>
* <li>1:means DLR is Required</li>
* </ul>
*/
var $strDlr;
private function sms__unicode($message){
$hex1='';
if (function_exists('iconv')) {
$latin = #iconv('UTF-8', 'ISO-8859-1', $message);
if (strcmp($latin, $message)) {
$arr = unpack('H*hex', #iconv('UTF-8', 'UCS-2BE', $message));
$hex1 = strtoupper($arr['hex']);
}
if($hex1 ==''){
$hex2='';
$hex='';
for ($i=0; $i < strlen($message); $i++){
$hex = dechex(ord($message[$i]));
$len =strlen($hex);
$add = 4 - $len;
if($len < 4){
for($j=0;$j<$add;$j++){
$hex="0".$hex;
}
}
$hex2.=$hex;
}
return $hex2;
}
else{
return $hex1;
}
}
else{
print 'iconv Function Not Exists !';
}
}
//Constructor..
public function Sender ($host,$port,$username,$password, $sender, $message,
$mobile,$msgtype,$dlr){
$this->host=$host;
$this->port=$port;
$this->strUserName = $username;
$this->strPassword = $password;
$this->strSender= $sender;
$this->strMessage=$message; //URL Encode The Message..
$this->strMobile=$mobile;
$this->strMessageType=$msgtype;
$this->strDlr=$dlr;
}
public function Submit(){
if($this->strMessageType=="2" ||
$this->strMessageType=="6") {
//Call The Function Of String To HEX.
$this->strMessage = $this->sms__unicode(
$this->strMessage);
try{
//Smpp http Url to send sms.
$live_url="http://".$this->host.":".$this->port."/bulksms
/bulksms?username=".$this->strUserName."&password=".$this->strPassword."&
type=".$this->strMessageType."&dlr=".$this->strDlr."&destination=".$this->strMobile."&
source=".$this->strSender."&message=".$this->strMessage."";
$parse_url=file($live_url);
//echo $parse_url[0];
}catch(Exception $e){
//echo 'Message:' .$e->getMessage();
}
}
else
$this->strMessage=urlencode($this->strMessage);
try{
//Smpp http Url to send sms.
$live_url="http://".$this->host.":".
$this->port."/bulksms/bulksms?username=".$this->strUserName."&password=".$this->strPassword."&
type=".$this->strMessageType."&dlr=".$this->strDlr."&destination=".$this->strMobile."&
source=".$this->strSender."&message=".$this->strMessage."";
$parse_url=file($live_url);
//echo $parse_url[0];
}
catch(Exception $e){
//echo 'Message:' .$e->getMessage();
}
}
}
//Call The Constructor.
$obj = new Sender("mywebserver","myport","username","password","sender name", "my message",
"mobile number","2","1");
$obj->Submit();
?>
Thanks.
You forgot to put the routine in case of "else" in braces. it should be like:
else {
$this->strMessage=urlencode( $this->strMessage );
try {
//Smpp http Url to send sms.
$live_url = "http://".$this->host . ":" .
$this->port."/bulksms/bulksms?username = ".$this->strUserName."&password=".$this->strPassword."&
type = ".$this->strMessageType."&dlr=".$this->strDlr."&destination=".$this->strMobile."&
source = ".$this->strSender."&message=".$this->strMessage."";
$parse_url = file( $live_url );
//echo $parse_url[0];
} catch( Exception $e ) {
//echo 'Message:' .$e->getMessage();
}
}
Note the braces for "else".