Clickatell alternative SMS-Gateway? [closed] - sms

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking us to recommend or find a tool, library or favorite off-site resource are off-topic for Stack Overflow as they tend to attract opinionated answers and spam. Instead, describe the problem and what has been done so far to solve it.
Closed 8 years ago.
Improve this question
We're just about to go live but Clickatell seems to be problematic. Billing AND Server issues!!
A quick google search shows a long record of problems.
They did however made good impression at first but now we're simply not sure - they don't seem to be stable!
So, which reliable SMS gateway would allow me to send simple English SMS to Israel (programmatically through an HTTP API)?
Saw so far:
http://www.bulksms.com/

Disclaimer, I do developer evangelism part time at Nexmo.
If you're looking for an API to send SMS with a large global reach and high deliverability, you should check out Nexmo.
I don't recall the exact number, but for outgoing SMS over 200 countries/800 carriers (I think that's more like 1K now) are supported. It doesn't seem like you'll need incoming, but if you do, you can get inbound numbers in 14 (that number is also growing) countries.
As to reliability, I believe Nexmo is the only SMS provider that publishes delivery stats. I've pasted the delivery status for Israel here:
Network | Success Ratio | DLR Ratio
42503 Pelephone | 91.47 | 99.99
42502 Cellcom | 92.01 | 99.95
42501 Orange | 93.14 | 99.97
Success ratio is messages delivered to handsets, DLR ratio is messages that resulted in a delivery receipt - so for Pelephone, 99.99% of the time, your application will be sent a report notifying of the message status, even when it's not part of the 91.47% of the time the message is successful delivered to the handset.

For high quality SMS services you should check out my employer´s website. Consider enabling delivery report callbacks. This will trigger a script at your server with information about if and when a message was successfully delivered to the users phone.
PHP example:
<?php
// Register here to get a username and password:
// http://www.vianett.com/en/free-demonstration-account
if (vianett_sendsms('username', 'password', 'example', '+4412345678', 'Hello world', $error)) {
echo 'Success!';
} else {
echo $error;
}
function vianett_sendsms($username, $password, $from, $to, $msg, &$response=null) {
$url = 'https://smsc.vianett.no/v3/send.ashx';
$data = array(
'user' => $username,
'pass' => $password,
'src' => $from,
'dst' => $to,
'msg' => $msg
);
$qs = http_build_query($data);
$response = file_get_contents($url.'?'.$qs);
return $response == '200|OK';
}

Related

CPU is utilizing 100% resource and therefore Queue failed

My code is like below.
for($i = 0; $i <= 100; $i++) {
$objUser = [
"UserName" => $request["UserName"] . $i,
"EmailAddress" => $request["EmailAddress"] . $i,
"RoleID" => RoleEnum::ProjectManager,
"Password" => $request["Password"],
];
$RegisterResponse = $this->Register->Register($objUser);
$Data = $RegisterResponse["Data"];
$job = (new AccountActivationJob($Data));
dispatch($job);
}
Above code is creating 100 users and Each time a queue is being created to send email notification. I am using database default queue.
I have shared hosting account on GoDaddy. Due to some reasons the CPU usage reaches 100. Here is the screenshot.
Finally loop stops in between. Below is the screenshot after 5 mins.
Here, My problem is: It is not able to continue creating 100 users. I am doing this to test the sample queue implementation where multiple users send request for registration. Am I doing anything wrong?
As stated above, GoDaddy has a lot of resource limitations. You can only send 100 Emails an hour is what I have heard.
That also not at a single time. If it detects you are sending a lot of emails, your process is blocked.
Instead, you can queue up the messages to be sent 1 per 20 seconds or 30 seconds. It will help keep the resources in limits, and your emails are sent to the customers without any problem.
You can use the sleep function for this.
Godaddy does have a limit of resources you can use. If you go over it, it will kill the processes on ssh.
The limits are avaiable here
Try running the php process with a different nice parameter.
That's what I do when i need to use an artisan command that does use a lot of resources..
I did the findings and found that I should move to VPS instead of Shared hosting. here are the nice and cheap plans by GoDaddy. https://in.godaddy.com/hosting/vps-hosting

How to parallelize downloads across hostnames on WordPress?

I'm getting this message "Parallelize downloads across hostnames" when checking my WordPress site on GTmetrix > https://gtmetrix.com
Here are the details > https://gtmetrix.com/parallelize-downloads-across-hostnames.html
How do I fix that ?
Details
Web browsers put a limit on the number of concurrent connections they will make to a host. When there are many resources that need to be downloaded, a backlog of resources waiting to be downloaded will form. The browser will make up as many simultaneous connections to the server as the browser allows in order to download these resources, but then will queue the rest and wait for the requests to finish.
The time spent waiting for a connection to finish is referred to as blocking and reducing this blocking time can result in a faster loading page. The waterfall diagram below shows a page which loads 45 resources from the same host. Notice how long the resources are blocked (the brown segments), before they are downloaded (the purple segments) as they wait for a free connection.
So here is a hack to implement it on WordPress.
In order to work properly, all subdomains/hostnames MUST have the same structure/path. Ex:
example.com/wp-content/uploads/2015/11/myimage.jpg
media1.example.com/wp-content/uploads/2015/11/myimage.jpg
media2.example.com/wp-content/uploads/2015/11/myimage.jpg
Add to functions.php
function parallelize_hostnames($url, $id) {
$hostname = par_get_hostname($url);
$url = str_replace(parse_url(get_bloginfo('url'), PHP_URL_HOST), $hostname, $url);
return $url;
}
function par_get_hostname($name) {
//add your subdomains below, as many as you want.
$subdomains = array('media1.mydomain.com','media2.mydomain.com');
$host = abs(crc32(basename($name)) % count($subdomains));
$hostname = $subdomains[$host];
return $hostname;
}
add_filter('wp_get_attachment_url', 'parallelize_hostnames', 10, 2);
This is mainly due do HTTP/1.1 in which browsers open on average 6 connections per hostname.
If you are running over HTTPS with a provider that supports HTTP/2, this warning can usually be safely ignored now. With HTTP/2 multiple resources can now be loaded in parallel over a single connection.
--
However, if you need to fix it, you can follow the below steps:
Create additional subdomains such as:
domain.com static1.domain.com static2.domain.com
Simply add the following code to your WordPress theme’s functions.php file. And replace the $subdomains values with your subdomains.
All subdomains/hostnames MUST have the same structure/path.
function parallelize_hostnames($url, $id) {
$hostname = par_get_hostname($url); //call supplemental function
$url = str_replace(parse_url(get_bloginfo('url'), PHP_URL_HOST), $hostname, $url);
return $url;
}
function par_get_hostname($name) {
$subdomains = array('static1.domain.com','static2.domain.com');
$host = abs(crc32(basename($name)) % count($subdomains));
$hostname = $subdomains[$host];
return $hostname;
}
add_filter('wp_get_attachment_url', 'parallelize_hostnames', 10, 2);
Read more about the parallelize downloads across hostnames warning and why you probably don't need to worry about this anymore.

Random (403) User Rate Limit Exceeded

I am using translate API to translate some texts in my page, those texts are large html formated texts, so I had to develop a function that splits these texts into smaller pieces less than 4500 characters (including html tags) to avoid the limit of 5000 characters per request, also I had to modify the Google PHP API to allow send requests via POST.
I have enabled the paid version of the api in Goole Developers Console, and changed the total quota to 50M of characters per day and 500 requests/second/urser.
Now I am translating the whole database of texts with a script, it works fine but at some random points I revive the error "(403) User Rate Limit Exceeded", and I have to wait some minutes to re-run the script because when reached the error the api is returning the same error over and over until I wait some time.
I don't know why it keeps returning the error if I don't pass the number of requests, it's like it has some kind of maximum chaaracters per each interval of time or something...
You probably exceed the quota limits you set before: this is either the daily billable or the limit on the request characters per second.
To change the usage limits or request an increase to your quota, do the following:
1. Go to the Google Developers Console "https://console.developers.google.com/".
2. Select a project.
3. On the left sidebar, expand APIs & auth.
4. Click APIs.
5. Click the name of an activated API you're interested in "i.e. The Translate API".
6. Near the top of the info page for the API, click Quota.
If you have the billing enabled, just click Quota and it will take you to the quota page where you can view and change the quota-related settings.
If not, clicking Quota shows information about any free quota and limits that apply to the Translate API.
Google Developer Console has a rate limit of 10 requests per second, regardless of the settings or limits you may have changed.
You may be exceeding this limit.
I was unable to find any documentation around this, but could verify it myself with various API requests.
You control the characters limitation but not the concurrency
You are either making more than 500 concurrent request/second or you are using another Google API that is hitting such concurrency limitation.
The referer header is not set by default, but it is possible to add the headers to a request like so:
$result = $t->translate('Hola Mundo', [
'restOptions' => [
'headers' => [
'referer' => 'https://your-uri.com'
]
]
]);
If it makes more sense for you to set the referer at the client level (so all requests flowing through the client receive the header), this is possible as well:
$client = new TranslateClient([
'key' => 'my-api-key',
'restOptions' => [
'headers' => [
'referer' => 'https://your-uri.com'
]
]
]);
This worked for me!
Reference
In my case, this error was caused by my invalid payment information. Go to Billing area and make sure everything is ok.

How does API signature authentication work as implemented by Mashery?

Mashery allows authentication via digital signature as follows:
First, concatenate the following components:
API key
Shared secret
UNIX Timestamp
Then, create an MD5 hash of the concatentated string.
The documentation states that the unix timestamp only needs an accuracy of +/- 5 minutes. Details: http://support.mashery.com/docs/read/mashery_api/20/Authentication .
Assuming this is not a trade-secret, what is the algorithm for performing authentication like this?
Specifically, how is it possible when the unix timestamp can vary by 5 minutes? A "brute-force" technique might be to calculate a signature for every possible timestamp value until finding a match (or not), but that doesn't seem practical for authenticating frequent API calls.
Yes, that appears to be what it does. The documentation link you gave states, " A five-minute wiggle is permitted on either side of the current timestamp on the Mashery server to allow for reasonable clock drift." That means they need to check up to 600 hashes to see if the submitted one is valid. 5 minutes is 300 seconds. Plus or minus makes it 600 checks.
It seems practical to me. 600 MD5s is not a lot of processing to do. In fact, a modern password validator (like something that uses bcrypt) would perform much more work to validate a password.
Amazon give a good example of request signing and in quite alot detail which should make the mechanics obvious (I realise its not mashery - but i think it's what your after, or will at least help on your journey to API security happiness)
http://docs.amazonwebservices.com/AmazonS3/latest/dev/index.html?RESTAuthentication.html
Mashery could also pre-generate the list of valid signatures or cache each sig on demand. The signature is global to all API's that Mashery is protecting for that API Key / Shared Secret, so there is no need to validate the API call uniquely for every request.
sha256 is pretty fast. Even in php, you can calculate 830K sha256's a second, so they very likely just brute force it.
<?php
$COUNT = 6000000;
$start = microtime(true);
for($i = 0; $i < $COUNT; $i++) {
$out = hash('sha256', 'wefjklwfekjlewfjklwefjklfwejkwefjklwfekjl' . $i);
//print("$out\n");
}
$total = microtime(true) - $start;
print("Time: $total\n");
print("sha256's per second: " . ($COUNT / $total) . "\n");
?>

Web based API that can tell me if a number is a landline or cell phone? [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
We don’t allow questions seeking recommendations for books, tools, software libraries, and more. You can edit the question so it can be answered with facts and citations.
Closed 7 years ago.
Improve this question
My application sends SMS messages to people, but the numbers entered in as their cell phone are sometimes land lines (this is user error or the user not really knowing if the contact number they have is a cell phone or landline.)
I found a few websites that can tell me if a number is a landline or cell phone, but they do not offer programatic API's. Is anyone aware of a way a web application can figure out if a number can receive SMS messages?
I guess a test SMS message is one way, but my current SMS gateway fails hard when it gets a landline number and doesn't tell me the landline number it tried to send the SMS to. I'll follow this up with my carrier, but I would love an easy way to let the user entering phone numbers in if they are a landline or cell number.
Update:
There are ways to figure this out. Take a look at http://www.phonevalidator.com, they can query a phone number and figure out if it is a landline or cell phone.
You can have JavaScript open a popup with the url:
"http://www.phonevalidator.com/results.aspx?p=" + phoneNumber
It's not a free service, but a company called Targus (not the bag company) has an API for querying phone information. They can tell if it's landline or cell, even address validation. The charge based on how many queries you do (a few cents a query).
http://www.targusinfo.com/
Followup: I contacted TARGUSinfo on Feb. 24, 2011 and was told by their sales rep that they only work with record sets in the hundreds-of-thousands to millions and generally their customers are plugged into their API for real-time access. Differentiating between cell numbers and land line numbers for smaller record sets is "not something they can assist with."
I am afraid the only real way to find it out is contact SMS gateway service providers. A list of them can be found here for example:
http://en.wikipedia.org/wiki/SMS_gateways
Anyway, instead of that I suggest doing the following:
When user inserts cell phone number into his or her profile, send testing SMS to this number with confirmation code. If number is not verified by user, don't bother sending SMS messages to it later on.
Actually there are land line operators that allow receiving SMS. Either by text2voice gateway or phone terminal with extended capability. Moreover, in Europe cell phone operators have started offering "virtual land lines", which are in fact GSM cell phones assigned to one particular base station. But they do follow land line numbering scheme.
Resuming — not allowing sending SMS to land line number is wrong.
The following script returns
646-826-3879 LANDLINE
for the Stack Overflow hot line.
#!/usr/bin/perl -w
use strict;
use warnings;
use LWP::Simple;
use LWP::Simple::Cookies ( autosave => 1, file => "$ENV{'HOME'}/lwp_cookies.dat" );
my $usage = "Usage: $0 <phone_number>\n\nwhere phone_number is on format XXX-XXX-XXXX or XXXXXXXXX";
die $usage unless scalar #ARGV == 1;
my $number = shift #ARGV;
die $usage unless $number =~ /(\d\d\d)-?(\d\d\d)/;
my $NPA = $1;
my $NXX = $2;
#GET /search.asp?frmNPA=646&frmNXX=826&frmCity=&frmState=&frmZip=&frmCounty=&frmCompany=&search.x=0&search.y=0 HTTP/1.0
my $doc = get 'http://www.area-codes.com/search.asp?frmNPA=' . $NPA . '&frmNXX=' . $NXX . '&frmCity=&frmState=&frmZip=&frmCounty=&frmCompany=&search.x=0&search.y=0';
# html format:
#...
# <td><strong>NXX Use Type:</strong></td>
# <td>LANDLINE</td>
#...
my $next = 0;
my $result = "";
grep {
if (/NXX Use Type:/) {
$next = 1;
} else {
if ($next) {
$next = 0;
$result = $_;
}
}
} split(/\n/, $doc);
$result =~ /<[^>]*>(.*)<[^>]*>/;
print "$number\t$1\n";
I'm not sure if you want to do that really... If you want to tell if a number is reserved by a callphone or landline provider, you should be able to find the ranges in some documents from your country's telco supervising entity (not sure who does that in US - it might be http://www.nanpa.com/). Those documents are usually public.
But the problem is that mobile number != able to receive sms. With number porting and all the "unified communication" ideas nowadays you can easily have local numbers redirecting to mobiles, non-geographical numbers handling smses and local "special" numbers rewriting your incoming smses as facebook messages ;) For example my local "landline" number is redirected to a mobile in another country and couple of other locations.
You shouldn't be charged for a message sent to a nonexisting / otherwise strange number, so it might be a good way to check if someone can receive them. If you have a good control over the SMS gateway, you can send a message with delivery report active and expiry == immediate message (forgot the official name). Just send a test / welcome message - if it's not accepted, you can mark the number as unavailable. Otherwise, you can just ask for a "number that accepts SMSes" instead of a "cellphone number".
Trying to combine some answers here...
Daniel mentioned that
You can have JavaScript open a popup with the url:
"http://www.phonevalidator.com/results.aspx?p=" + phoneNumber
Does this still work? I can't seem to reproduce it. If we can get that to work, then maybe we can use a script like the following...
#!/usr/bin/perl -w
use strict;
use warnings;
use LWP::Simple;
my $usage = "Usage: $0 <phone_number>\n\nwhere phone_number is on format XXX-XXX-XXXX or XXXXXXXXX";
die $usage unless scalar #ARGV == 1;
my $number = shift #ARGV;
die $usage unless $number =~ /(\d\d\d)-?(\d\d\d)/;
my $NPA = $1;
my $NXX = $2;
#GET /search.asp?frmNPA=646&frmNXX=826&frmCity=&frmState=&frmZip=&frmCounty=&frmCompany=&search.x=0&search.y=0 HTTP/1.0
my $doc = get 'http://www.phonevalidator.com/results.aspx?p=' . $NPA . $NXX;
# html format:
#...
# <td class="style16">
# Phone Line Type:
# </td>
# <td class="style13">
# <span id="PhoneTypeLabel">LANDLINE</span>
# </td>
#
#...
my $result = "";
grep {
if (/PhoneTypeLabel/) {
$result = $_;
}
} split(/\n/, $doc);
$result =~ /<[^>]*>(.*)<[^>]*>/;
print "$number\t$1\n";
Another option would be to have the user select their cellphone provider from a list. Just a thought.
Why not make a list of the usual format for the landlines and mobile numbers? For example, where I'm located landlines always follow this format:
9xxxx xxxx
and mobiles are always:
04xx xxx xxx
You can easily make a list of the general format of landline/mobile numbers in the area you are serving. Then, when wanting to find out if a US number is landline or mobile, just compare it and see whether it matches the landline format or the mobile number format.
Another thing that is done often to validate phone numbers, is to send a temporary pin via SMS to the user's mobile, and ask them to enter that pin in order to validate their number.
I can imagine doing this, if I had access to the core mobile network. That's an SS7 API, though, not a Web API. I would bet that any service which offers a Web API acts as a proxy to the SS7 network, instead of relying on databases. The only other alternative would be to query the number porability database. Eventually, to terminate a call, all network operators need to determine which other operator they need to connect to.
we have a service which provides fixed line / cellular detection for USA and Canada, and also detects if the number is Live or Dead, which wireless carrier the number is ported to etc. There's a full web API.
If you sign up for an account at www.hlrcheck.com I'll get it validated and add some free credits for you to test. We're in beta at the moment, but full release candidate is imminent.
All solutions mentioned here are static number pattern lookups but the only reliable way to figure out whether a given cell phone number is valid (and ready to receive SMS) is to perform an HLR Lookup. HLR stands for Home Location Register, which is a mobile network operator database with real time subscriber information. There are several API services for HLR lookups, e.g. www.hlr-lookups.com.

Resources