sending email to all newsletter members with codeigniter - codeigniter

I want to send an email using codeigniter library to my newsletter members and I want to mention each members' Email address in email's content. For doing that, I used foreach loop to send the email one by one. The problem is that the code sends email to just one member ( the first member ) of my newsletter. I've checked my code which gets members from the database and it printed out all the members.
This is my model:
function send_news()
{
$subscribers = $this->get_subscriber_data();
foreach($subscribers as $subscriber)
{
$this->load->helper('typography');
//Format email content using an HTML file
$data['news_Title'] = $this->input->post('news_Title');
$HTML_Message = $this->load->view('admin/includes/newsletter_html_format', $data, true);
$config['mailtype'] = 'html';
$this->email->initialize($config);
$this->email->from('newsletter#site.com', 'newsletter of site.com');
$this->email->to($subscriber->subscriber_Email);
$this->email->subject('newsletter of site.com');
$this->email->message($HTML_Message);
return $this->email->send();
}
}
and this is how I'm getting subscribers list:
function get_subscriber_data($options = array())
{
$query = $this->db->get('mg_newsletter');
if(isset($options['subscriber_Id']))
return $query->row(0);
return $query->result();
}
when I try to echo $subscriber->subscriber_Email it prints all the emails in the database one after another. but it does not send email to all of them. What am I doing wrong?!

use
$this->email->clear()
As codeignitor says:
Initializes all the email variables to an empty state. This function is intended for use if you run the email sending function in a loop, permitting the data to be reset between cycles.
foreach ($list as $name => $address)
{
$this->email->clear();
$this->email->to($address);
$this->email->from('your#example.com');
$this->email->subject('Here is your info '.$name);
$this->email->message('Hi '.$name.' Here is the info you requested.');
$this->email->send();
}
If you set the parameter to TRUE any attachments will be cleared as well. Then let us know

You are "return" -ing inside your loop, which exits the function.
Just send

You can keep the loading helper file and email configuration outside the loop and then remove the return from for loop, it will send to all subscribers one by one and then after loop finishes you can do the return statement.

Related

Calling at the users at once and disconnect other calls if any one of the user receives the call

I want to have the round robin call functionality using twilio.
Let's say. I have 100 users and their phone numbers.
I want to call of them at the same time.
Then whoever the first person receives the call I will connect that call to my sales department and immediately cut or disconnect a the other calls.
I known through twiML I could dial to my sales team and I also know I could check the in-progess event to check to see call is connected.
However I am stuck at calling all my users at the same time and disconnecting after the first user is connected to the call which is my first step.
i am making more updates as my scenario has been changed a little.
in this case i am first calling the user who has filled out my lead form. once the lead user receives the call then i am going to call 10 agents from my sales team but i want to track which agent has received the lead call and want to save the agent information into my database and cut the other calls.
in my countroller
<?php
namespace App\Http\Controllers;
use App\Listing;
use App\User;
use Illuminate\Http\Request;
use Twilio\Rest\Client;
use Twilio\TwiML\VoiceResponse;
use Twilio\Twiml;
class TwilioController extends Controller
{
public function leadCall(Request $request)
{
// Lead user
$lead = Lead::where('id', $request->lead_id)->first();
$country_code = "+1";
$visitor_phone = $country_code . $lead->details_phone;
$url = "https://www.samplewebsite.com/outbound?multi_call=true";
// Twilio Credentials
$AccountSid = 'xyz';
$AuthToken = 'xyz';
$twilio_number = "123";
$client = new Client($AccountSid, $AuthToken);
// Calling the lead visitor first
try {
$call = $client->account->calls->create($visitor_phone, $twilio_number,
array(
"url" => $url
)
);
} catch (Exception $e) {
echo "Error: " . $e->getMessage();
}
}
if($request->multi_call)
{
// Fetch 10 agents
$users = User::all()->take(10);
// Calling Twilio
$twiml = new VoiceResponse();
$twiml->say('Please hold, we are connecting your call to one of our agent.', array('voice' => 'alice'));
$dial = $twiml->dial();
foreach ($users as $user) {
if($user->phone && $user->live_call)
{
$dial->number($user->phone,
['statusCallbackEvent' => 'answered',
'statusCallback' => 'https://www.samplewebsite.com/outbound?agent_call=true',
'statusCallbackMethod' => 'GET']);
}
}
$response = response()->make($twiml, 200);
$response->header('Content-Type', 'text/xml');
return $response;
}
if($request->agent_call)
{
return "Call was made to: " . $request->to;
}
}
this is what i have done so far
and in routes file
Route::post('lead-call', 'TwilioController#leadCall')->name('leadCall');
Route::get('outbound', 'TwilioController#outboundMultiCall');
And TwiML resonse
<Response>
<Say voice="alice">Please hold, we are connecting your call to one of our agent.</Say>
<Dial>
<Number statusCallbackEvent="answered" statusCallback="https://www.samplewebsite.com/outbound?agent_call=true" statusCallbackMethod="GET">xxx-xxx-xxxx</Number>
<Number statusCallbackEvent="answered" statusCallback="https://www.samplewebsite.com/outbound?agent_call=true" statusCallbackMethod="GET">xxx-xxx-xxxx</Number>
<Number statusCallbackEvent="answered" statusCallback="https://www.samplewebsite.com/outbound?agent_call=true" statusCallbackMethod="GET">xxx-xxx-xxxx</Number>
</Dial>
</Response>
i am having two problems. when i add the get parameter like multi_call=true in my webhook then i get application error. so i can't make 10 dials to my agents.
plus i want to keep track of which user has attend the call first so i could maintain into my database and increase their rating.
Thank you
Twilio developer evangelist here.
First, I just need to warn you that by default Twilio accounts have a limit of creating 1 call per second, so with any code, you calls will still be placed sequentially.
If you can make one call then you can make more than one call at a time. You need to loop through the numbers you want to place calls to and make an API request for each call you want to create.
The next part is to cancel the other calls once one call connects. When you create the call, you will receive a response from the API with the call SID. Once your first call connects, you will receive a webhook to your application. The parameters will include the call SID. So, to cancel the other calls you need to take the list of call SIDs that you have created remove the one that connected and then make API calls to update the the other calls to the "completed" status, which will hang up the call.
Edit:
I see that you're connecting your outbound call first, then using TwiML to multi-dial. That should work, there's just a couple of things you've done wrong.
First, you are using multiple <Dial>s instead of multiple <Number>s within a <Dial> to make the multi calls. Try the following:
public function outboundMultiCall(Request $request)
{
if($request->multi_call)
{
// Fetch 10 agents
$users = User::all()->take(10);
// Calling Twilio
$twiml = new VoiceResponse();
$twiml->say('Please hold, we are connecting your call to one of our agent.', array('voice' => 'alice'));
$dial = $twiml->dial();
foreach ($users as $user) {
$dial->number($user->phone);
}
$response = response()->make($twiml, 200);
$response->header('Content-Type', 'text/xml');
return $response;
}
return 'Some other action based on GET URL paramter';
}
Second, Twilio webhooks are POST requests by default. So, you should either turn your route into a POST:
Route::post('outbound', 'TwilioController#outboundMultiCall');
Or, you can pass a method parameter when you create the call:
$call = $client->account->calls->create($visitor_phone, $twilio_number,
array(
"url" => $url,
"method" => "GET"
)
);
Finally, to record who answers the call you can use a statusCallback URL attribute on the <Number>. Twilio will send a webhook when the call transitions into a new state. The events are "initiated", "ringing", "answered" and "completed". The webhook will include all the normal voice call parameters so you can tell who the call was made to with the To parameter. There are extra parameters too, which might be useful.

Send automatical email after save to database

I am new here.
I have a project in Laravel. I have one textarea and data from it is save in datavase. It works good. Now I would like to send automatical email to one specific email address with this data. It must be sent only one time with save to database.
I have no problem with sending email to customer with data but now I need to send email with data from this textarea to one specific email. It is a textarea what we have to buy for customer. It must be sent to our cooperation company.
Is it possible?
Ofcourse this is possible!
You should take a look at the following resources :
Observers
https://laravel.com/docs/6.0/eloquent#observers
Notifications
https://laravel.com/docs/6.0/notifications
-> specifically : https://laravel.com/docs/6.0/notifications#mail-notifications
yes, you can just trigger your function after saving: for example, after saving in controller.
public function store(Request $request){
$var = new Property; //your model
$var->title=$request->title; // the input that being save to database.
$var ->save();
// Send email to that input
Mail::send('email',['email'=>$request->title],function ($mail) use($request){
$mail->from('info#sth.com');
$mail->to($request->title);
});
return redirect()->back()->with('message','Email Successfully Sent!');
}

Why can't this method access the session?

I have a session containing some data that I access throughout several methods in my controller with no trouble. But one method in particular has problems.
I have made a little booking system. On completion of a booking, I call a function to send an e-mail to myself and the customer:
public function complete(Request $request)
{
$details = Session::get('details');
// send emails: call sendConfirmationEmail(to address, using this view)
$this->sendConfirmationEmail(env('EMAIL'), 'emails.ourconfirmation');
$this->sendConfirmationEmail($details->booker_email, 'emails.bookerconfirmation');
return view('booking/complete');
}
private function sendConfirmationEmail($to,$view)
{
$from = env('OFFICE_EMAIL');
$to_address = $to;
$details = Session::get('details');
$instance = Session::get('instance');
Mail::queue($view, compact(['details','instance']), function($message) use ($to){
$message->from(env('OFFICE_EMAIL'))
->to($to)
->subject('Thanks for booking');
});
}
First I got an error accessing a non-object in my e-mail view. So to test it I just set the sendConfirmationEmail function to return $instance - blank page. Then I tested it by commenting out the function call in complete() and returning $instance there. No problem, there's a nice shiny session full of data. Then I tried passing $instance from complete() to sendConfirmationEmail() and returning it: again, blank page. Why can't sendConfirmationEmail 'see' my session?!
To my knowledge, Sessions are for using across HTTP requests, not across functions in PHP. You are trying the use Sessions as global variables.
You can simply capture details and instance session data in the complete function, and then pass them along as parameters for the sendConfirmationEmail() function.

Laravel - Check for new message inside conversation

I created application in Laravel where users can communicate using Facebook-like messages. Now I have problem when I check for new messages. I created function which needs to query all conversations and all messages inside those conversations to find new (unopened) messages.
So I'm asking if there is different way for achiving this - without stressing too much the server with all those queries.
This is my function:
function newMessage(){
if(Auth::check()){
$conversations = User::find(Auth::user()->id)->conversations;
$new = false;
foreach ($conversations as $key => $value) {
if(count(Conversation::find($value->id)->messages()->where("user_id", "!=", Auth::user()->id)->where("opened", "=", 0)->get()) > 0){
$new = true;
}
}
return $new;
}else{
return false;
}
}
Relationship between conversation and message is one to many.
Conversation table consists only of id and message table has id and opened (I'm giving you only relevant columns).
This is how I solved it:
created opened column in conversation_user table
when user opens a message opened column updates to 1
when user sends message, opened column updates to 0 for every user in that conversation except for the user who sends the message
And I wrote this function which will check if user has new messages (inside User model):
public function hasUnread(){
return (bool)$this->conversations()->whereOpened(0)->count();
}

Adding unsubscribe link in custom email magento

How to add unsubscribe link in custom email notification i am sending an email through zend mail function i follow this function sending mail in magento in body part i want to add unsubscribe link how can we implement that?
In my e mail notification i am using this function.
public function sendMail()
{
$post = $this->getRequest()->getPost();
if ($post){
$random=rand(1234,2343);
$to_email = $this->getRequest()->getParam("email");
$to_name = 'Hello User';
$subject = ' Test Mail- CS';
$Body="Test Mail Code : ";
$sender_email = "sender#sender.com";
$sender_name = "sender name";
$mail = new Zend_Mail(); //class for mail
$mail->setBodyHtml($Body); //for sending message containing html code
$mail->setFrom($sender_email, $sender_name);
$mail->addTo($to_email, $to_name);
//$mail->addCc($cc, $ccname); //can set cc
//$mail->addBCc($bcc, $bccname); //can set bcc
$mail->setSubject($subject);
$msg ='';
try {
if($mail->send())
{
$msg = true;
}
}
catch(Exception $ex) {
$msg = false;
//die("Error sending mail to $to,$error_msg");
}
$this->getResponse()->setBody(Mage::helper('core')->jsonEncode($msg));
}
}
If you have a custom module use this code:
Mage::getModel('newsletter/subscriber')->loadByEmail($email)->getUnsubscriptionLink();
Explanation:
first part is the model for the subscriber.
If you want to see al the available methods within the model just use this code:
$myModel = Mage::getModel('newsletter/subscriber');
foreach (get_class_methods(get_class($myModel)) as $cMethod) {
echo '<li>' . $cMethod . '</li>';
}
the second part of the code loadByEmail($email) is to get 1 specific subscriber object. $email should be a string of the emailaddress.
The last part of the code is a selfexplaning method. It will generate a link to unsubscribe. This is a method that is given by Magento.
In my Magento version I get the following code by default when creating a new newsletter template:
Follow this link to unsubscribe <!-- This tag is for unsubscribe link -->{{var subscriber.getUnsubscriptionLink()}}
I expect it to work in any Magento version.
I am using Magento 1.9.
To add newsletter unsubscribe link in newsletter template here are following steps:
Override the core file
/app/code/core/Mage/Newsletter/Model/Subscriber.php
by copy in local directory
/app/code/local/Mage/Newsletter/Model/Subscriber.php
Open in editor to edit the code and seacrh the function sendConfirmationSuccessEmail()
replace the code
$email->sendTransactional(
Mage::getStoreConfig(self::XML_PATH_SUCCESS_EMAIL_TEMPLATE),
Mage::getStoreConfig(self::XML_PATH_SUCCESS_EMAIL_IDENTITY),
$this->getEmail(),
$this->getName(),
array('subscriber'=>$this)
);
with this
$email->sendTransactional(
Mage::getStoreConfig(self::XML_PATH_SUCCESS_EMAIL_TEMPLATE),
Mage::getStoreConfig(self::XML_PATH_SUCCESS_EMAIL_IDENTITY),
$this->getEmail(),
$this->getName(),
array('subscriber'=>$this, 'unsubscribe' =>$this->getUnsubscriptionLink())
);
and place this code in email template where you want to use unsubscribe link:
Unsubscribe here
That's it!
Hope this helps someone.

Resources