Insert action after Woocomerce Completed Order Email is sent out - filter

I want to accomplish the following:
With the Woocomerce Completed Order Email a pdf is generated and sent out as attachment. After the Email is sent, the pdf is deleted on the server.
I achieved the first part with the woocommerce_email_attachments Filter like this.
add_filter('woocommerce_email_attachments', 'attach_ticket_pdf_to_email', 10, 3);
Now for security reasons I want to delete the pdf that was generated on the server AFTER the Email is sent out.
I found the Action 'woocommerce_order_status_completed’ that could be hooked into, but this is not called if I resend the Completed Order Email from the admin backend.
Is there some hook or filter or action that is called to send out the Emails in Woocomerce. Or after the emails are sent?
There I would like to call a function that deletes those pdfs again.
Any ideas?

The emails are triggered with a default priority of 10. Therefore, I presume that you could call your function with a higher/later priority and it would be fired after the email was sent.
If you re-send an order email from the admin you can use the woocommerce_after_resend_order_email hook. This gets passed an $order object so you can't quite attach the exact same function to both.
Here's how I would start:
add_action( 'woocommerce_order_status_completed', 'delete_pdf', 20 );
function delete_pdf( $order_id ){
// do your thing to delete the file
}
add_action( 'woocommerce_after_resend_order_email', 'after_resend', 10, 2 );
function after_resend( $order, $action ){
if( $action == 'customer_completed_order' ){
delete_pdf( $order->id );
}
}

Related

when we send email with job and queue error occur

[when send emails shows these error][1]ReflectionException Method App\Mail\Newsletter::__invoke() does not exist
these is my controlledispatch(new Newsletter($emailSubject,$emailBody,$arrayEmails));
these is my email classpublic function build() { return $this->view('emails.newsletter')->subject($this->emailSubject)->with(['msg'=> $this->emailBody]); }
these is my jobs public function handle() { $email = new Newsletter($this->emailSubject,$this->emailBody,$this->arrayEmails); Mail::to($this->arrayEmails)->send($email); }
As I understand, you create a job that in turn create and send the email object.
However, in the controller, you are not dispatching the job, you are dispatch the email object. And the email object doesn't contain either a handle or __invoke method so you see the error message.
The solution is to dispatch the job instead of the email.
This design is indeed unnecessary. Pls have a look at Mailables, create a queued mailable, and just send it.

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!');
}

virtuemart 2 - how to send invoice as email attachment on confirm order

I want to send invoice as email attachment on order confirmation ,how to go about sending the invoice.
searched a lot ,not relevant data found.
The VM Order Confirmation Email work flow is as follows,
Check the function notifyCustomer() inside orders.php in administrator/components/com_virtuemart/models/
There is a section like shopFunctionsF::renderMail() It calls a function from shopefunctionsf helper file in /components/com_virtuemart/helpers/shopfunctionsf.php
renderMail() calls sendVmMail() in the same file there you can find option for attaching media or anything you want .
if (isset($view->mediaToSend)) {
foreach ((array)$view->mediaToSend as $media) {
//Todo test and such things.
$mailer->addAttachment($media);
}
}
Hope its helps..

sending email to all newsletter members with 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.

Resources