We are getting automated calls coming to twillio. We do have openvbx installed. I am trying to figure out how I can block calls with incoming DID that have 111, 110, or 101 in the beginning. I know how to input static numbers in openvbx and I can successfully block them.
Any help would be appreciated.
Hi Twilio Customer Support here.
Have you thought about using the Twilio verb? It will allow you to build a list of numbers you do not wish to receive calls from:
https://www.twilio.com/docs/api/twiml/reject
https://www.twilio.com/docs/howto/reject
Regards,
Tom
I guess there is no support for openvbx on here and from twilio. To post a question here on stackoverflow and tag it openvbx it said I needed to have a certain number of points. I am new to this so my account has no points.
Anyways I solved my own question. Here is the explanation to other users looking for a similar solution.
You need to edit plugins/standard/applets/start/twiml.php in your openvbx installation and make it the code below. I hope there is more support out there for openvbx.
<?php
$ci =& get_instance();
$list = AppletInstance::getValue('list');
$direction = isset($_REQUEST['Direction']) ? $_REQUEST['Direction'] : 'inbound';
// block calls
$caller = normalize_phone_to_E164(isset($_REQUEST['From'])? $ci->input->get_post('From') : '');
$response = new TwimlResponse;
// Update this list of numbers
$block_list = array('+112345678910');
//pattern analysis to block DIDs
$patterns = array('111','110','101','+111','+110','+101');
$position = 0;
foreach ($patterns as $pattern) {
if( $position = strpos(' ' . $caller, $pattern)) {
if( $position == 1 ) $response->reject(array('reason' => 'busy'));
}
}
if (in_array($caller, $block_list)) {
$response->reject(array('reason' => 'busy'));
}else{
$next = AppletInstance::getDropZoneUrl('next');
if (!empty($next)) {
$response->redirect($next);
}
}
$response->respond();
?>
Related
Solved the problem earlier today. In the 2nd line of code global $db,$tags; was overwriting if($this->has_lead_type_selected($person['ID'],$tags)) which caused the global $tags to overwrite $tags at the lower portion of code. So the global var was empty because it was before the actual $tags var was given a function.
When an HTML form is submitted to our REST API it sends data called 'lead_type' which are simply tags to identify the lead being sent.
User select these tags from a tag cloud. If a form is submitted to the API with one of these tags (lead_type) and any of our users profiles match those tags (they selected in their tag cloud). The user is sent a SMS to notify them.
Everything posts to the database tables, the API works but everyone of the users still gets a SMS even if they don't have matching tags. If I comment out the line (i'll show the rest of the code below) an SMS is sent to everyone. If I leave it uncommented no SMS is sent to anyone.
if($this->has_lead_type_selected($person['ID'],$tags))
Here is how the code flows.
}
private function has_lead_type_selected($user_id,$tags){
global $db,$tags;
$lead_types = explode(',',$tags);
$user_lead_types = $db
->where('user_id',$user_id)
->where('lead_type_id', $lead_types, 'IN')
->get('user_lead_types');
return sizeof($user_lead_types) > 0;
}
//Get lead types from API post and create $tags
$lead_types = $this->request['leadData']['lead_types'];
$strTags = array();
if(!empty($lead_types))
$strTags = explode(',',$lead_types);
$tags = '';
$lead_types_objects = $db->where('lead_type', $strTags,'IN')->get('lead_types');
foreach($lead_types_objects as $l)
{
if($tags=='')
$tags = $l['id'];
else
$tags.=',' .$l['id'];
}
We then send them a SMS if the form tags matched the users cloud tags.
global $sid,$token;
$client = new Twilio\Rest\Client($sid, $token);
$content_data = [
"leadname" => $posted_name,
"leadzipcode" => $posted_zipcode,
"leadphone" => $posted_phone,
"leademail" => $posted_email,
"leadtags" => $lead_types
];
//Replace Content
foreach($content_data as $index => $value){
$lead_sms_template = str_replace("|".$index."|", $value, $lead_sms_template);
}
// Step 5: Loop over all our friends. $number is a phone number above, and
// $name is the name next to it
foreach ($people as $person) {
try{
//commented temporarily -- uncommented below to try to solve issue of texting everyone still
if($this->has_lead_type_selected($person['ID'],$tags))
{
$number = $person['phone_no'];
$name = $person['first_name']. ' '. $person['last_name'];
Thank you for the help.
In the 2nd line of code global $db,$tags; was overwriting if($this->has_lead_type_selected($person['ID'],$tags)) which caused the global $tags to overwrite $tags at the lower portion of code. So the global var was empty because it was before the actual $tags var was given a function.
I am looking for a way to fix a certain piece of coding I have, it's probably simple to solve but I'm reall stuck. I haven't created this code myself
The code is triggered by a user entering his details, and the next piece of code filters out 2 parts of an URL based on the login of the user.
$regex = "/ranking.asp\?Group=(([A-Za-z]+) - ([0-9]+))/";
if (preg_match_all($regex, $str, $matches_out)) {
$data->groupLevel = $matches_out[2][0];
$data->groupNumber = $matches_out[3][0];
}
$matches_out[2][0] provides a letter
$matches_out[3][0] provides a number
When a user hits the top tier, the url is not ranking.php?group=A - 1 anymore (for example) but just ranking.php. This will obviously return an error, because it's looking for something else.
Now what I want to do is something like
if(code doesnt provide error){
execute the code;
}else{
$data->groupLevel = 'toptier';
$data->groupNumber = 1;
}
Or something similar which practically does the same. I hope someone can help me with this, it's very much appreciated! :)
If I understand correctly, when the code you posted causes an error, i.e. preg_match_all, you want to default to hard coded values?
I would think you should add an else statement like this.
$regex = "/ranking.asp\?Group=(([A-Za-z]+) - ([0-9]+))/";
if (preg_match_all($regex, $str, $matches_out)) {
$data->groupLevel = $matches_out[2][0];
$data->groupNumber = $matches_out[3][0];
}else{ //if the regex throws error, do this
$data->groupLevel = 'toptier';
$data->groupNumber = 1;
}
I'm using JSN Uniform plugin for Joomla to receive emails, but it's not accepting the .company domain as a valid domain. It accepts the usual domains (com, net, org, info, biz,...), but domains like .company aren't accepted.
Now, I'm really not experienced in PHP, as I'm more into JavaScript, but according to my poor knowledge the solution to my problem could be in the form.php file so here is the part of a code.
PHP:
private function _fieldEmail($post, $fieldIdentifier, $fieldTitle, &$validationForm)
{
$postFieldIdentifier = isset($post[$fieldIdentifier]) ? $post[$fieldIdentifier] : '';
$postFieldIdentifier = (get_magic_quotes_gpc() == true || get_magic_quotes_runtime() == true) ? stripslashes($postFieldIdentifier) : $postFieldIdentifier;
$postEmail = $postFieldIdentifier;
if ($postEmail)
{
$regex = '/^[_a-zA-Z0-9-]+(\.[_a-zA-Z0-9-]+)*#[a-zA-Z0-9-]+(\.[a-zA-Z0-9-]+)*(\.[a-zA-Z]{2,6})$/';
if (!preg_match($regex, $postEmail))
{
$validationForm[$fieldIdentifier] = JText::sprintf('JSN_UNIFORM_FIELD_EMAIL', $fieldTitle);
}
else
{
return $postFieldIdentifier ? $postFieldIdentifier : "";
}
}
else
{
return $postFieldIdentifier ? $postFieldIdentifier : "";
}
}
Could someone help me please with this?
Thanks.
EDIT: I have tried to change regex value from 2,6 to 2, but still no change.
Please see php fiddler here: http://viper-7.com/CqxAMZ
You should replace the regex like this:
$regex = '/^[_a-zA-Z0-9-]+(\.[_a-zA-Z0-9-]+)*#[a-zA-Z0-9-]+(\.[a-zA-Z0-9-]+)*(\.[a-zA-Z]{2,})$/';
to accept a domain of any size bigger than one. Now it is restricted to sizes between 2 and 6. More on the subject in http://www.regular-expressions.info/repeat.html
Change {2,6} to {2,7} at the end.
That indicates the last part of the regex should contain between 2 and 7 characters ("company" exceeds the limit of 6).
Replace:
$regex = '/^[_a-zA-Z0-9-]+(\.[_a-zA-Z0-9-]+)*#[a-zA-Z0-9-]+(\.[a-zA-Z0-9-]+)*(\.[a-zA-Z]{2,6})$/';
if (!preg_match($regex, $postEmail))
{
$validationForm[$fieldIdentifier] = JText::sprintf('JSN_UNIFORM_FIELD_EMAIL', $fieldTitle);
}
with:
if (!filter_var($postEmail, FILTER_VALIDATE_EMAIL)) {
$validationForm[$fieldIdentifier] = JText::sprintf('JSN_UNIFORM_FIELD_EMAIL', $fieldTitle);
}
Email validate is more complicated that a one-line regex.
Are the names of profiles on Facebook publicly accessible, as if I would NOT need to log into Facebook to access them?
I am intending to store a large amount of names as a small piece of a larger project. I feel as if scraping Facebook for names would be a relatively simple task using the Facebook Graph API, but I am a little confused.
I found another tutorial online at http://jilltxt.net/?p=2810 which described an easy way of finding any Facebook profile picture using one simple line:
https://graph.facebook.com/USER-ID/picture?type=large
This was very helpful because I am able to use a range of ID numbers and a small amount of PHP to gather large amounts of profile pictures as seen on my test page here: http://www.joshiefishbein.com/fi/photobook.php
But what I am unfamiliar with is how I go from collecting pictures to names in this one simple line. Is it possible? Is there another (better) way?
Here's the code I am working with. The range of ID's are just an example.
function gen_pix($min, $max, $quantity) {
$numbers = range($min, $max);
shuffle($numbers);
$x_arr = array_slice($numbers, 0, $quantity);
foreach ($x_arr as $key => $value) {
$username = "https://graph.facebook.com/" . $value . "/";
$json = json_decode(file_get_contents($username), true);
echo $json["name"];
}
}
$x = 337800042;
$y = 337800382;
$z = 1;
gen_pix($x,$y,$z);
I've gotten a little farther with this code, I can echo $username and I get the URL that I am looking for (for example https://graph.facebook.com/337800382/) but I do not get anything after that. json_decode isn't working seemingly.
In the same way you are pulling the profile picture, you can get the basic information of a user with their ID.
This page provides a list of data that is always publicly accessible.
So you need to make a GET request to pull back the JSON, like so...
https://graph.facebook.com/{user-id}/
For example https://graph.facebook.com/586207189/ pulls back my basic information. So your PHP would look like this
$json = json_decode(file_get_contents("https://graph.facebook.com/$user_id/"), true);
echo $json["name"];
PHP fiddle here
Update: Based on the code above, it's worth adding an IF to catch invalid Facebook IDs. Facebook IDs may not be sequential so not every one will return a name or image.
Updated code:
<?php
function gen_pix($min, $max, $quantity) {
$numbers = range($min, $max);
shuffle($numbers);
$x_arr = array_slice($numbers, 0, $quantity);
foreach ($x_arr as $key => $value) {
$username = "https://graph.facebook.com/" . $value . "/";
$json = json_decode(file_get_contents($username), true);
if (!isset($json['name'])) {
echo "Invalid ID<br />";
}
else {
echo $json["name"]. '<br />';
}
}
}
$x = 337800042;
$y = 337800382;
$z = 50;
gen_pix($x,$y,$z);
?>
PHP Fiddle here
It's also worth noting that pulling that much data from the graph is going to take a while. Have a look at doing batch requests to speed things up a bit. More info here
UPDATE:
Thank you all for your input. Some additional information.
It's really just a small chunk of markup (20 lines) I'm working with and had aimed to to leverage a regex to do the work.
I also do have the ability to hack up the script (an ecommerce one) to insert the classes as the navigation is built. I wanted to limit the number of hacks I have in place to keep things easier on myself when I go to update to the latest version of the software.
With that said, I'm pretty aware of my situation and the various options available to me. The first part of my regex works as expected. I posted really more or less to see if someone would say, "hey dummy, this is easy just change this....."
After coming close with a few of my efforts, it's more of the principle at this point. To just know (and learn) a solution exists for this problem. I also hate being beaten by a piece of code.
ORIGINAL:
I'm trying to leverage regular expressions to add a CSS a class to the first and last list items within an ordered list. I've tried a bunch of different ways but can't produce the results I'm looking for.
I've got a regular expression for the first list item but can't seem to figure a correct one out for the last. Here is what I'm working with:
$patterns = array('/<ul+([^<]*)<li/m', '/<([^<]*)(?<=<li)(.*)<\/ul>/s');
$replace = array('<ul$1<li class="first"','<li class="last"$2$3</ul>');
$navigation = preg_replace($patterns, $replace, $navigation);
Any help would be greatly appreciated.
Jamie Zawinski would have something to say about this...
Do you have a proper HTML parser? I don't know if there's anything like hpricot available for PHP, but that's the right way to deal with it. You could at least employ hpricot to do the first cleanup for you.
If you're actually generating the HTML -- do it there. It looks like you want to generate some navigation and have a .first and .last kind of thing on it. Take a step back and try that.
+1 to generating the right html as the best option.
But a completely different approach, which may or may not be acceptable to you: you could use javascript.
This uses jquery to make it easy ...
$(document).ready(
function() {
$('#id-of-ul:firstChild').addClass('first');
$('#id-of-ul:lastChild').addClass('last');
}
);
As I say, may or may not be any use in this case, but I think its a valid solution to the problem in some cases.
PS: You say ordered list, then give ul in your example. ol = ordered list, ul = unordered list
You wrote:
$patterns = array('/<ul+([^<]*)<li/m','/<([^<]*)(?<=<li)(.*)<\/ul>/s');
First pattern:
ul+ => you search something like ullll...
The m modifier is useless here, since you don't use ^ nor $.
Second pattern:
Using .* along with s is "dangerous", because you might select the whole document up to the last /ul of the page...
And well, I would just drop s modifier and use: (<li\s)(.*?</li>\s*</ul>) with replace: '$1class="last" $2'
In view of above remarks, I would write the first expression: <ul.*?>\s*<li
Although I am tired of seeing the Jamie Zawinski quote each time there is a regex question, Dustin is right in pointing you to a HTML parser (or just generating the right HTML from the start!): regexes and HTML doesn't mix well, because HTML syntax is complex, and unless you act on a well known machine generated output with very predictable result, you are prone to get something breaking in some cases.
I don't know if anyone cares any longer, but I have a solution that works in my simple test case (and I believe it should work in the general case).
First, let me point out two things: While PhiLho is right in that the s is "dangerous", since dots may match everything up to the final of the document, this may very well be what you want. It only becomes a problem with not well formed pages. Be careful with any such regex on large, manually written pages.
Second, php has a special meaning of backslashes, even in single quotes. Most regexen will perform well either way, but you should always double-escape them, just in case.
Now, here's my code:
<?php
$navigation='<ul>
<li>Coffee</li>
<li>Tea</li>
<li>Milk</li>
<li>Beer</li>
<li>Water</li>
</ul>';
$patterns = array('/<ul.*?>\\s*<li/',
'/<li((.(?<!<li))*?<\\/ul>)/s');
$replace = array('$0 class="first"',
'<li class="last"$1');
$navigation = preg_replace($patterns, $replace, $navigation);
echo $navigation;
?>
This will output
<ul>
<li class="first">Coffee</li>
<li>Tea</li>
<li>Milk</li>
<li>Beer</li>
<li class="last">Water</li>
</ul>
This assumes no line feeds inside the opening <ul...> tag. If there are any, use the s modifier on the first expression too.
The magic happens in (.(?<!<li))*?. This will match any character (the dot) that is not the beginning of the string <li, repeated any amount of times (the *) in a non-greedy fashion (the ?).
Of course, the whole thing would have to be expanded if there is a chance the list items already have the class attribute set. Also, if there is only one list item, it will match twice, giving it two such attributes. At least for xhtml, this would break validation.
You could load the navigation in a SimpleXML object and work with that. This prevents you from breaking your markup with some crazy regex :)
As a preface .. this is waaay over-complicating things in most use-cases. Please see other answers for more sanity :)
Here is a little PHP class I wrote to solve a similar problem. It adds 'first', 'last' and any other classes you want. It will handle li's with no "class" attribute as well as those that already have some class(es).
<?php
/**
* Modify list items in pre-rendered html.
*
* Usage Example:
* $replaced_text = ListAlter::addClasses($original_html, array('cool', 'awsome'));
*/
class ListAlter {
private $classes = array();
private $classes_found = FALSE;
private $count = 0;
private $total = 0;
// No public instances.
private function __construct() {}
/**
* Adds 'first', 'last', and any extra classes you want.
*/
static function addClasses($html, $extra_classes = array()) {
$instance = new self();
$instance->classes = $extra_classes;
$total = preg_match_all('~<li([^>]*?)>~', $html, $matches);
$instance->total = $total ? $total : 0;
return preg_replace_callback('~<li([^>]*?)>~', array($instance, 'processListItem'), $html);
}
private function processListItem($matches) {
$this->count++;
$this->classes_found = FALSE;
$processed = preg_replace_callback('~(\w+)="(.*?)"~', array($this, 'appendClasses'), $matches[0]);
if (!$this->classes_found) {
$classes = $this->classes;
if ($this->count == 1) {
$classes[] = 'first';
}
if ($this->count == $this->total) {
$classes[] = 'last';
}
if (!empty($classes)) {
$processed = rtrim($matches[0], '>') . ' class="' . implode(' ', $classes) . '">';
}
}
return $processed;
}
private function appendClasses($matches) {
array_shift($matches);
list($name, $value) = $matches;
if ($name == 'class') {
$value = array_filter(explode(' ', $value));
$value = array_merge($value, $this->classes);
if ($this->count == 1) {
$value[] = 'first';
}
if ($this->count == $this->total) {
$value[] = 'last';
}
$value = implode(' ', $value);
$this->classes_found = TRUE;
}
return sprintf('%s="%s"', $name, $value);
}
}