I have a simple bot (I am using webhook) that responds to a command and goes to the database and sends a sticker and a simple html message for every record found.
If there are many records (20 or more AND took more than 2 minutes to finish the while bucle) bot goes crazy and display the results 4 times (finish one time and then starts again 3 more times), I tried to add a sleep() timer to avoid the loop but have no luck. Not sure what I am missing or doing wrong.
Here's my code:
$update = json_decode(file_get_contents('php://input'));
if (isset($update->message)){
//Fetching update
$message = $update->message;
$message_id = $update->message->message_id;
$text = $message->text;
$chat_id = $message->chat->id;
switch($text){
case "read":
$age = 18;
read_fields($age, $chat_id);
break;
default:
bot('SendMessage',[
'chat_id' => $chat_id,
'text' => "This is a test"
]);
}
}
function read_fields($age, $chat_id){
include("conexion.inc");
$i = 0;
$sticker = "";
$id = "";
$name = "";
$sql = "SELECT id, name, sticker FROM Persons WHERE age = ".$age;
$php = mysql_query($sql, $con);
while($row=mysql_fetch_assoc($php)){
$sticker = $row['id_sticker'];
$id = $row['id'];
$name = $row['name'];
bot('sendSticker',[
'chat_id' => $chat_id,
'sticker' => $id_sticker
]);
$message = $id."-<b>".$name."</b>";
bot('SendMessage',[
'chat_id' => $chat_id,
'parse_mode' => "HTML",
'text' => $mensaje
]);
sleep(3);
$i++;
}
bot('SendMessage',[
'chat_id' => $chat_id,
'text' => "### ".$i." total ### "
]);
}
Telegram Bot API will retry webhook request when server-side consider there are dropped, so you need to reduce response time.
One solution is process them quickly, but it seems not easy.
If you know how to close HTTP connection before timeout, just do that, since it's implement is different from your HTTP server, try to search like NginX fastcgi close upstream connection.
Related
Moodle 3, developing a block
I'm getting the following error: 'A required parameter (id) was missing'.
It happens in $mform, only when I'm using the array('id' => $instance->id) in the 'Else if' statement in the redirect($url).
Surprisingly, because when I'm using the same code in a button with a redirect url, the code works correct.
I've tried several things, but nothing helps. What could be the problem?
Here is some code:
$id = required_param('id', PARAM_INT);
$instance = $DB->get_record('block_instances', array('id' => $id), '*', MUST_EXIST);
$context = \context_block::instance($instance->id);
$mform = new newlink();
if ($mform->is_cancelled()) {
$url = new moodle_url('/my');
redirect($url);
} else if ($fromform = $mform->get_data()) {
// data from form
....
$url = new moodle_url('/blocks/name_of_block/links.php', array('id' => $instance->id)); // HERE IS THE PROBLEM
(Note: when I'm using here the block instance id number 123 directly, the redirect is working correct:
$url = new moodle_url('/blocks/name_of_block/links.php?id=123';)
redirect ($url);
} else {
//Set default data (if any)
$mform->set_data($toform);
//displays the form
$mform->display();
}
$url = new moodle_url('/blocks/name_of_block/links.php', array('id' => $instance->id))
echo $OUTPUT->single_button($url, get_string('button:links', 'block_name_of_block')); // THIS IS WORKING CORRECT
Is it when you submit the form rather than the redirect?
In your form do you have:
$mform->addElement('hidden', 'id');
$mform->setType('id', PARAM_INT);
and in the code above do you have:
$toform->id = $id;
$mform->set_data($toform);
My code is working fine but take so much time for show result because i have above 1500 products.
So any one modify my code or best way to show results
$results = $proxy->catalogProductList($sessionId);
$productData = new stdClass();
$productData->additional_attributes = array('short_description','cost');
foreach($results as $value){
$results_product = $proxy->catalogProductInfo($sessionId,$value->product_id,null,$productData);
$pro_imag = $proxy->catalogProductAttributeMediaList($sessionId, $value->product_id);
echo "";
echo "".$sno++."".$value->product_id."".$value->sku."".$value->name."".$results_product->additional_attributes[0]->value."".abs($results_product->additional_attributes[1]->value)."".abs($results_product->price)." url."' width='80px' height='80px'> ";
echo "";
}
Try the following code and use magento site for easy api examples like following, example SOAP V2 (Complex Filter)
<?php
$client = new SoapClient('http://magentohost/api/v2_soap/?wsdl');
$session = $client->login('apiUser', 'apiKey');
$complexFilter = array(
'complex_filter' => array(
array(
'key' => 'type',
'value' => array('key' => 'in', 'value' => 'simple,configurable')
)
)
);
$result = $client->catalogProductList($session, $complexFilter);
var_dump ($result);
I'm trying to implement the PayPal API function for SetExpressCheckout. Below I put a part of my code that I am using to call the payment process on the PayPal side. Everything looks fine. At the last step of the checkout, i push the "Pay Now" button and the payment is processed. After that user is returnet to my original site and i got the Transaction ID, success message and token. It looks like evrything was finished fine, but in my PayPal account i dont see any transactions and I don’t get any money at all.
$returnUrl = home_url("/wp-login.php?checkemail=registered&ppayment=done&price=".$package_price."&code=".$paypal_price_unit."&package=".$package_name."&pid=".$incomingpost);
$requestParams = array(
'RETURNURL' => $returnUrl,
'CANCELURL' => home_url('/wp-login.php?checkemail=registered&ppayment=cancel')
);
// Sent item info
$orderParams = array(
'PAYMENTREQUEST_0_AMT' => $package_price,
'PAYMENTREQUEST_0_SHIPPINGAMT' => '0',
'PAYMENTREQUEST_0_CURRENCYCODE' => $paypal_price_unit,
'PAYMENTREQUEST_0_ITEMAMT' => $package_price
);
//send package info
$item = array(
'L_PAYMENTREQUEST_0_NAME0' => $paymentName,
'L_PAYMENTREQUEST_0_DESC0' => $package_name,
'L_PAYMENTREQUEST_0_AMT0' => $package_price,
'L_PAYMENTREQUEST_0_QTY0' => '1'
);
//Call payment process
$infos = array();
$infos['USER'] = $paypal_api_user;
$infos['PWD'] = $paypal_api_pwd;
$infos['SIGNATURE'] = $paypal_api_signature;
if($paypal_sandbox == 1){$sandstatus = true;}else{$sandstatus = false;}
$paypal = new Paypal($infos,$sandstatus);
$response = $paypal -> request('SetExpressCheckout',$requestParams + $orderParams + $item);
if(is_array($response) && $response['ACK'] == 'Success') {
// We will redirecting now.
$token = $response['TOKEN'];
//Save DB before redirect.
$trans_post = array(
'post_status' => 'pending',
'post_type' => 'retransactions',
'post_title' => $token,
);
$new_post_id = wp_insert_post( $trans_post );
add_post_meta($new_post_id, 'webburemap_payment_user', $user_id);
add_post_meta($new_post_id, 'webburemap_payment_amount', $package_price);
add_post_meta($new_post_id, 'webburemap_payment_package_id', $package_IDNO);
add_post_meta($new_post_id, 'webburemap_payment_package_transtype', 'NewPackage');
if($paypal_sandbox == 0){
$commit = '&useraction=commit';
header( 'Location: https://www.paypal.com/webscr?cmd=_express-checkout&token=' . urlencode($token) . $commit ); //PayPal Pay Now
}else{
header( 'Location: https://www.sandbox.paypal.com/webscr?cmd=_express-checkout&token=' . urlencode($token) );
}
die();
}
Can you provide the Express Checkout Token and the Transaction ID that you are getting back and I will take a look at it on my side to see what may be happening. Also make sure that you are pointing to the correct endpoint. If you are trying to process a live payment, make sure you are pointing towards the live site and not the sandbox.
I'm using the Twitter API 1.1 Get statuses method to return the latest tweet from an account on the client's website. This is working fine but I can't find any clear documentation on how to render any links that may be included (Both included usernames and included links) as clickable links?
I can see in the JSON response that any included links are in the XML but it's not clear to me how to go about adding clickable links into the rendered output. The documentation around the new API seems to be lacking practical examples.
Can anyone advise?
The code I'm using the pull out the latest tweet is as follows:
$token = 'TOKEN HERE';
$token_secret = 'TOKEN SECRET HERE';
$consumer_key = 'CONSUMER KEY HERE';
$consumer_secret = 'CONSUMER SECRET HERE';
$host = 'api.twitter.com';
$method = 'GET';
$path = '/1.1/statuses/user_timeline.json'; // api call path
$query = array( // query parameters
'screen_name' => 'SCREEN NAME HERE',
'count' => '1'
);
$oauth = array(
'oauth_consumer_key' => $consumer_key,
'oauth_token' => $token,
'oauth_nonce' => (string)mt_rand(), // a stronger nonce is recommended
'oauth_timestamp' => time(),
'oauth_signature_method' => 'HMAC-SHA1',
'oauth_version' => '1.0'
);
$oauth = array_map("rawurlencode", $oauth); // must be encoded before sorting
$query = array_map("rawurlencode", $query);
$arr = array_merge($oauth, $query); // combine the values THEN sort
asort($arr); // secondary sort (value)
ksort($arr); // primary sort (key)
// http_build_query automatically encodes, but our parameters
// are already encoded, and must be by this point, so we undo
// the encoding step
$querystring = urldecode(http_build_query($arr, '', '&'));
$url = "https://$host$path";
// mash everything together for the text to hash
$base_string = $method."&".rawurlencode($url)."&".rawurlencode($querystring);
// same with the key
$key = rawurlencode($consumer_secret)."&".rawurlencode($token_secret);
// generate the hash
$signature = rawurlencode(base64_encode(hash_hmac('sha1', $base_string, $key, true)));
// this time we're using a normal GET query, and we're only encoding the query params
// (without the oauth params)
$url .= "?".http_build_query($query);
$oauth['oauth_signature'] = $signature; // don't want to abandon all that work!
ksort($oauth); // probably not necessary, but twitter's demo does it
// also not necessary, but twitter's demo does this too
function add_quotes($str) { return '"'.$str.'"'; }
$oauth = array_map("add_quotes", $oauth);
// this is the full value of the Authorization line
$auth = "OAuth " . urldecode(http_build_query($oauth, '', ', '));
// if you're doing post, you need to skip the GET building above
// and instead supply query parameters to CURLOPT_POSTFIELDS
$options = array( CURLOPT_HTTPHEADER => array("Authorization: $auth"),
//CURLOPT_POSTFIELDS => $postfields,
CURLOPT_HEADER => false,
CURLOPT_URL => $url,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_SSL_VERIFYPEER => false);
// do our business
$feed = curl_init();
curl_setopt_array($feed, $options);
$json = curl_exec($feed);
curl_close($feed);
$twitter_data = json_decode($json);
Thanks a lot for your response. I actually found a solution thanks to this blog post from the guys at Asheville - http://www.appliedtns.com/blog/tag/twitter/
It works fine for me.
// Parse any links found in our tweet
$formatted_text = preg_replace('/(\b(www\.|http\:\/\/)\S+\b)/', "<a target='_blank' href='$1'>$1</a>", $post->text);
$formatted_text = preg_replace('/\#(\w+)/', "<a target='_blank' href='http://search.twitter.com/search?q=$1'>#$1</a>", $formatted_text);
$formatted_text = preg_replace('/\#(\w+)/', "<a target='_blank' href='http://twitter.com/$1'>#$1</a>", $formatted_text);
Not sure if this exactly what you need but I am using the tmhOAuth library for my application, see https://github.com/themattharris/tmhOAuth-examples. Using code from Matt Harris' examples I loop through the response and build the output as in the code below. The links in the tweets are created by the library function entify_with_options($tweet).
// Decode response
$timeline = json_decode($this->tmhOAuth->response['response'], true);
if(!$timeline){
throw new Exception('Error: No response was found.');
}
else{
// Start building the output
foreach ($timeline as $tweet) :
... start of response processing
// Format and set tweet text
$tw_entified_tweet = tmhUtilities::entify_with_options($tweet);
// Format and set creation date for permalink
$tw_created_at_formatted = is_twitterlist_format_date($tweet['created_at']);
// Format and set permalink
$tw_permalink = str_replace(
array(
'%screen_name%',
'%id%',
'%created_at%'
),
array(
$tweet['user']['screen_name'],
$tweet['id_str'],
$tw_created_at_formatted,
),
'%created_at%'
);
... end response processing
endforeach;
}
The date format function is:
function is_twitterlist_format_date($created_date)
{
if ( is_null($created_date)) {
return '';
}
else{
// Format: March 4th, 9:19 am
return date('F jS, g:i a', strtotime($created_date));
}
}
Hope this is useful.
Hi I have searched the site for my question but haven't found an easy solution and I think the issue is so basic.
I'm using Api V2 so maybe there's a solution now. Here I go, this is my code:
$api_soap_url = 'http://localhost/magento/api/v2_soap?wsdl=1';
$client = new SoapClient($api_soap_url);
$session_id = $client->__soapCall('login',array($user, $pw));
$data = array($session_id);
$result = $client->__soapCall('customerCustomerList', $data);
This returns all results, I need to limit number of result so I have tried using filters and other solutions found here but no luck.
The only one I haven't tried is this one:
Control the number of results from a Magento API call
But filtering by date doesn't solve my problem and rewriting classes is a ver complex solution for such a simple need.
Thanks in advance
I'm not sure the filter can limit number of result but you can try this:
$complexFilter = array(
'complex_filter' => array(
array(
'key' => 'created_at',
'value' => array('key' => 'gt', 'value' => '2012-05-13 06:11:00')
// where created_at is greater than 2012-05-13 06:11:00
// For example: eq (equals), neq (not equals), gt (greater than), lt (less than), etc.
)
)
);
$result = $client->customerCustomerList($session, $complexFilter);
I ended up overriding app/code/core/Mage/Sales/Model/Order/Api.php, adding a "special magic" field called "collection.limit". Your mileage may vary; I have tight controls on both the Magento installation and the programs (in this case, a set of C# programs) accessing the Magento installation.
My caller simply uses the "magic field" as a key/ value pair, something like this (please test, again, I was calling from C#, so this php should be considered suspect):
$collectionLimitClause = array (
'key' => 'collection.limit',
'value' => array('key' => 'eq', 'value' => '10')
);
In my Magento installation (this part is tested, live and running), I created a Sales/Model/Order/Api.php in my local namespace and over-rode the items function. Around the 32nd or so line of that function, you'll see this:
$apiHelper = Mage::helper('api');
$filters = $apiHelper->parseFilters($filters, $this->_attributesMap['order']);
try {
foreach ($filters as $field => $value) {
$orderCollection->addFieldToFilter($field, $value);
}
} catch (Mage_Core_Exception $e) {
$this->_fault('filters_invalid', $e->getMessage());
}
Instead, I "catch" my own magic limiter with the strncmp here, with an if-else inside the foreach:
$apiHelper = Mage::helper('api');
$filters = $apiHelper->parseFilters($filters, $this->_attributesMap['order']);
try {
foreach ($filters as $field => $value) {
if( !strncmp($field,"collection.limit",16) ) {
$orderCollection->getSelect()->limit($value['eq']);
}
else {
$orderCollection->addFieldToFilter($field, $value);
}
}
} catch (Mage_Core_Exception $e) {
$this->_fault('filters_invalid', $e->getMessage());
}
I'm not overly excited by this, but, I think it's pretty safe and it works.