Running a function in the background in Codeigniter 3 - php

I am trying to send a message to all my telegram bot subscribers. However, due to their large number curl_exec inside a loop of thousands users take lots of time to finish the function.
This is a problem, because if users send some request from my bot during the loop, they have to wait untill telegram api answers to my previous loop requests and then only to their requests. There will be confusion to TELEGRAM API also, and it may repeat same message to the users 2-3 times at this stage.
So I want to do it in the background, so that users keep working with the bot and not wait, and also I will not care how long it will take to send message to all subscribers.
I would be very grateful if you could help.

check this out
function broadcast($message) {
$url = 'https://api.telegram.org/bot' . getenv('TELEGRAM_BOT_TOKEN') . '/sendMessage';
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, 'chat_id=' . getenv('TELEGRAM_CHAT_ID') . '&text=' . $message);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_TIMEOUT, 10);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10);
$result = curl_exec($ch);
curl_close($ch);
return $result;
}

Related

PHP Telegram Bot sends same message many times

I have a Telegram Bot which worked fine for a few months. About 3-4 weeks ago the Telegram Bot sends sometimes (!) the same messages a few times - not just one time!
I have already tried many things to fix that:
I save the update_id in the database. If the new update_id is higher than the saved one, the bot sends the message. If not, an error occurs. (Found out yesterday that every duplicate message has got a new (higher) update_id - so this method is useless)
I tried to add exit(); to every PHP Function - didn't work.
I checked the whole code, if there is a not closed loop. But everything is fine.
I added a ?limit=1 to the function, but also no chance.
Slowly I am at the end of my ideas. Maybe someone has got a good answer for that.
I have always the $update and the chat ID:
define('api', 'https://api.telegram.org/bot'.token.'/');
$data = file_get_contents("php://input");
$update = json_decode($data, true);
$cbid = $update["callback_query"]["from"]["id"];
My function looks like this:
function callback($up){
return $up["callback_query"];
}
function tg_send_message($id, $text) {
$params=[
'chat_id' => $id,
'text' => $text,
'parse_mode' => 'Markdown',
];
$ch = curl_init('https://api.telegram.org/bot'.token.'/sendMessage?limit=1');
curl_setopt($ch, CURLOPT_HEADER, false);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT_MS, 3500);
curl_setopt($ch, CURLOPT_TIMEOUT_MS, 3500);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, ($params));
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
$result = curl_exec($ch);
curl_close($ch);
}
If I want to send a message if someone clicks on the inline button Top 10:
if(callback($update) and $cbdata == "top_10"){
tg_send_message($cbid, "This is my message!");
}
Everything worked fine and is working now as well - the bot just sends sometime a message multiple times.
The extra messages have always a new update_id! And if there is a variable value from another API (like Bitcoin price), it is also changing. It's like you clicked 22 times on the button (but you just clicked once)
I am very thankful for every helpful answer! Thank you very much.
Best regards.
EDIT: I have also tried the following:
function tg_btn_click_send_message($id, $text) {
$response = $update["callback_query"];
$botUrl = "https://api.telegram.org/bot" . BOT_TOKEN . "/answerCallbackQuery";
$postFields = array('callback_query_id' => $callback_query_id, 'text' => $response);
$ch = curl_init();
curl_setopt($ch, CURLOPT_HTTPHEADER, array("Content-Type:multipart/form-data"));
curl_setopt($ch, CURLOPT_URL, $botUrl);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $postFields);
$output = curl_exec($ch);
//send Text
header("Content-Type: application/json");
$parameters = array('chat_id' => $id, "text" => $text);
$parameters["method"] = "sendMessage";
echo json_encode($parameters);
}
Like suggested here: php telegram answercallbackquery sendmessage
But also not working.
If someone has the same problem, here the solution:
function tg_answer_callback_query($cbq_id) {
$params=[
'callback_query_id' => $cbq_id
];
$ch = curl_init('https://api.telegram.org/bot'.token.'/answerCallbackQuery');
curl_setopt($ch, CURLOPT_HEADER, false);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT_MS, 3500);
curl_setopt($ch, CURLOPT_TIMEOUT_MS, 3500);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, ($params));
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
$result = curl_exec($ch);
curl_close($ch);
}
Run this code at the end of if(callback($update)) (not after it!) and it works!

Cannot send SMS through PHP API when hosted on OpenShift by Redhat

I have the following script which I used to send mobile verification sms through a third party sms gateway.
<?
$code = rand(100000, 999999);
$mobilenum = "+919898989898";
$data = '{"accountId": "xxxxxxxxxx","apiKey": "xxxxxxxxx","dndType": "transactional","smsType":"normal","senderId": "xxxxxx","to": "' . $mobilenum . '","templateId": "xxxxxxxx","placeholders": {"code": "' . $code . '"}}';
// Create a curl handle to domain 2
$url = "https://api.smsowl.in/v1/sms";
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_HEADER, false);
//we want to get result as a string
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
//if servers support is and you want result faster, allow compressed response
//curl_setopt($ch, CURLOPT_ENCODING, 'gzip,deflate');
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
"Content-type: application/json"
));
//configure a POST request with some options
curl_setopt($ch, CURLOPT_POST, true);
//put data to send
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
echo "status code :" . $status;
//execute request
$result = curl_exec($ch);
curl_close($ch);
//show response form domain 2 to client if needed
//echo $code;
//print_r(apache_response_headers());
?>
The script used to work fine when it was hosted on hostgator server 2 months ago. But recently I started working on the application again and hosted it on OpenShift by RedHat since the hostgator service period ended. This script doesn;t work there. status code returns 0. curl_error() returns null and $result also returns null.
Please help.

CURL login & submit another post

In order to learn PHP my boss asked me to do some sort of project. I've done so far a To Do List & Reminder (www.frontpagewebdesign.com/newfolder) but what I'm trying to do right now is sending SMS notifications.
Because I cannot afford to buy a SMS gateway for such a small project, I decided to use my account on this website: www.sms-gratuite.ro. My trouble is the automatic Login and SMS sending with CURL.
I followed a tutorial and this is what I've done so far:
<?php
$form_vars = array();
//array for SMS sending form values
$username = '****#****.com';
$password = '********';
$loginUrl = 'http://sms-gratuite.ro/page/autentificare';
$postUrl='http://sms-gratuite.ro/page/acasa';
$form_vars['to'] = "076xxxxxxx";
//my own phone number
$form_vars['mesaj'] = "test";
//SMS text
$encoded_form_vars = http_build_query($form_vars);
$user_agent="Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0)";
//init curl
$ch = curl_init();
//Set the URL to work with
curl_setopt($ch, CURLOPT_URL, $loginUrl);
// ENABLE HTTP POST
curl_setopt($ch, CURLOPT_POST, 1);
//Set the post parameters (mail and parola are the IDs of the form input fields)
curl_setopt($ch, CURLOPT_POSTFIELDS, 'mail='.$username.'&parola='.$password);
//Handle cookies for the login
curl_setopt($ch, CURLOPT_COOKIEJAR, 'cookie.txt');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt ($ch, CURLOPT_USERAGENT, $user_agent);
//execute the request (the login)
$store = curl_exec($ch);
//check if the Login was succcesful by finding a string on the resulting page
if(strpos($store, "Trimite mesaj")===FALSE)
echo "logged in";
else
echo "not logged";
//set the landing url
curl_setopt($ch, CURLOPT_URL, 'http://sms-gratuite.ro/page/autentificare');
$referer='';
curl_setopt($ch, CURLOPT_URL, $postUrl);
//curl_setopt($ch, CURLOPT_HTTPHEADER,array("Expect:"));
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_REFERER, $referer);
curl_setopt($ch, CURLOPT_POSTFIELDS, 'to='.$form_vars['to'].'&mesaj='.$form_vars['mesaj']);
curl_setopt($ch, CURLOPT_COOKIEJAR, 'cookie.txt');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_USERAGENT, $user_agent);
$result = curl_exec($ch);
if(strpos($result, "Mesajul a fost trimis")===FALSE)
echo "<br>sms sent";
else
echo "<br>sms not sent";
curl_close($ch);
?>
I don't have any errors but it surely doesn't work. First of all the login fails. Is this form a particular one and the curl cannot handle it?
You could to put every curl request result into a different file, say page1.html, page2.html, etc. This way you can open then in browser and see what's the exact page you got in return for your request
You need to make exactly same request, as browser would do. There are browser addons like HttpFox (if you are using FireFox) that can show you all fields that were sent, all cookies and everything else related. You can compare that lists to what your curl is forming to find lacking pieces
Try theese steps and comment with further errors that you got, preferably detailed.

Can't track down bug

The following is part of a script which is used to authenticate paypal payments.
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://' . $server . '/cgi-bin/webscr');
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $parameters);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HEADER, false);
curl_setopt($ch, CURLOPT_TIMEOUT, 30);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
$result = curl_exec($ch);
curl_error($ch);
curl_close($ch);
On some rare occasions there is a problem with curl_exec which causes the the script to stop executing at that line.
No errors are recorded in the cpanel error log and after trying a number of different things I am no clearer as to what may be causing this error with curl.
I am not very familiar with curl, so if anyone knows of a good way to obtain error information from this, or what could possibly cause this problem, I'd really appreciate it.
Thanks
It could just take a long time.
curl_setopt($ch, CURLOPT_TIMEOUT, 30);
Set the time out to 30 seconds. Are you sure you waited that long?
Use CURLOPT_TIMEOUT_MS to set the timeout in milliseconds.
curl_error() returns a string, it doesn't do any output/logging of its own. The proper way to detect curl errors is as follows:
$result = curl_exec($curl);
if ($result === FALSE) {
error_log("CURL failed at " . date('c'));
error_log("CURL message: " . curl_error($curl));
}

Using CURL with Google

I want to CURL to Google to see how many results it returns for a certain search.
I've tried this:
$url = "http://www.google.com/search?q=".$strSearch."&hl=en&start=0&sa=N";
$ch = curl_init();
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_VERBOSE, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/4.0 (compatible;)");
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, true);
$response = curl_exec($ch);
curl_close($ch);
But it just returns a 405 Method Allowed google error.
Any ideas?
Thanks
Use a GET request instead of a POST request. That is, get rid of
curl_setopt($ch, CURLOPT_POST, true);
Or even better, use their well defined search API instead of screen-scraping.
Scrapping Google is a very easy thing to do. However, if you don't require more than the first 30 results, then the search API is preferable (as others have suggested). Otherwise, here's some sample code. I've ripped this out of a couple of classes that I'm using so it might not be totally functional as is, but you should get the idea.
function queryToUrl($query, $start=null, $perPage=100, $country="US") {
return "http://www.google.com/search?" . $this->_helpers->url->buildQuery(array(
// Query
"q" => urlencode($query),
// Country (geolocation presumably)
"gl" => $country,
// Start offset
"start" => $start,
// Number of result to a page
"num" => $perPage
), true);
}
// Find first 100 result for "pizza" in Canada
$ch = curl_init(queryToUrl("pizza", 0, 100, "CA"));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_USERAGENT, $this->getUserAgent(/*$proxyIp*/));
curl_setopt($ch, CURLOPT_MAXREDIRS, 4);
curl_setopt($ch, CURLOPT_TIMEOUT, 5);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
$response = curl_exec($ch);
Note: $this->_helpers->url->buildQuery() is identical to http_build_query except that it will drop empty parameters.
Use the Google Ajax API.
http://code.google.com/apis/ajaxsearch/
See this thread for how to get the number of results. While it refers to c# libraries, it might give you some pointers.
Before scrapping data please read https://support.google.com/websearch/answer/86640?rd=1
Against google terms
Automated traffic includes:
Sending searches from a robot, computer program, automated service, or search scraper
Using software that sends searches to Google to see how a website or webpage ranks on Google
CURLOPT_CUSTOMREQUEST => ($post)? "POST" : "GET"

Categories