Validate that Skype username is in use - validation

Is there a way to validate that a Skype username is valid in a web app? (form validation upon account creation)
By valid, I do not mean by using regular expressions. We can easily check to see if it is 6-22 characters, starts with a letter, etc. I want to verify that either:
the username entered actually calls the user inputting it, similar to when we validate email by sending an email with a link to verify it or
verify that there exists in the Skype database a user with that username.

This may not be very reliable, but the following endpoint will give you different responses based on the availability of a Skype username: https://login.skype.com/json/validator. Here are two examples of (at the time of this writing) an unavailable and available username:
# Request (unavailable):
curl -iX POST -H" Application/json" https://login.skype.com/json/validator?new_username=borist
# Response:
{
"status": 406,
"status_text": "valid",
"data": {
"markup": "Skype Name not available",
"alternatives": true,
"fieldDetails": "<label>Suggestions<\/label><ul><li><label><input class=\"skypeNameSuggestion\" type=\"radio\" name=\"selectSkypeName\" value=\"borist92\"\/>borist92<\/label> <\/li><li><label><input class=\"skypeNameSuggestion\" type=\"radio\" name=\"selectSkypeName\" value=\"borist176\"\/>borist176<\/label> <\/li><li><label><input class=\"skypeNameSuggestion\" type=\"radio\" name=\"selectSkypeName\" value=\"borist417\"\/>borist417<\/label> <\/li><\/ul>"
}
}
# Request (available)
curl -iX POST -H" Application/json" https://login.skype.com/json/validator?new_username=boris3294a
# Response
{
"status":200,
"status_text":"valid",
"data":{"markup":"",
"alternatives":false,
"fieldDetails":""}
}

I guess you'll have to do exactly what you said: “similar to when we validate email by sending an email with a link to verify it”
I'd dig into Skype4py, you'll find an example of searching for someone.
So you can do:
some kind of early validation by searching for that person
sending him/her a txt message with a key/link to verify your user
See: need an python script that uses skype4py to send an instant message

Building off of pho79's answer, I have made a gist. The code simply checks to see if the message returned says that the name is unavailable meaning that it is in use. There are some other messages it sends back for other errors, so this is what I went with.
import requests
def checkName(name):
values = { "new_username" : name }
r = requests.post("https://login.skype.com/json/validator", values)
return "not available" in r.json()[u'data'][u'markup']

Related

Ruby YouTube Data API v3 insert caption always returns error

I am trying to use the Ruby SDK to upload videos to YouTube automatically. Inserting a video, deleting a video, and setting the thumbnail for a video works fine, but for some reason trying to add captions results in an invalid metadata client error regardless of the parameters I use.
I wrote code based on the documentation and code samples in other languages (I can't find any examples of doing this in Ruby with the current gem). I am using the google-apis-youtube_v3 gem, version 0.22.0.
Here is the relevant part of my code (assuming I have uploaded a video with id 'XYZ123'):
require 'googleauth'
require 'googleauth/stores/file_token_store'
require 'google-apis-youtube_v3'
def authorize [... auth code omitted ...] end
def get_service
service = Google::Apis::YoutubeV3::YouTubeService.new
service.key = API_KEY
service.client_options.application_name = APPLICATION_NAME
service.authorization = authorize
service
end
body = {
"snippet": {
"videoId": 'XYZ123',
"language": 'en',
"name": 'English'
}
}
s = get_service
s.insert_caption('snippet', body, upload_source: '/path/to/my-captions.vtt')
I have tried many different combinations, but the result is always the same:
Google::Apis::ClientError: invalidMetadata: The request contains invalid metadata values, which prevent the track from being created. Confirm that the request specifies valid values for the snippet.language, snippet.name, and snippet.videoId properties. The snippet.isDraft property can also be included, but it is not required. status_code: 400
It seems that there really is not much choice for the language and video ID values, and there is nothing remarkable about naming the captions as "English". I am really at a loss as to what could be wrong with the values I am passing in.
Incidentally, I get exactly the same response even if I just pass in nil as the body.
I looked at the OVERVIEW.md file included with the google-apis-youtube_v3 gem, and it referred to the Google simple REST client Usage Guide, which in turn mentions that most object properties do not use camel case (which is what the underlying JSON representation uses). Instead, in most cases properties must be sent using Ruby's "snake_case" convention.
Thus it turns out that the snippet should specify video_id and not videoId.
That seems to have let the request go through, so this resolves this issue.
The response I'm getting now has a status of "failed" and a failure reason of "processingFailed", but that may be the subject of another question if I can't figure it out.

How to send to multiple recipients (WITHOUT LOOPING) while using variable alphanumeric sender ID?

I was wondering if there is a way to set multiple recipients WITHOUT looping over the list of recipients at my end?! Also most importantly while using variable alphanumeric sender ID and NOT buying a twilio number?
I can do all this for single recipient like this:
$twilio_client->messages->create(
'+64*******', //to
[
'from'=> 'foo',
'body' => 'bar'
]);
Works perfectly fine. However, doesnt work with multiple receivers.
Also note, it was bloody-1-step easy to implement smsbroadcast.com.au and pass all this in a simple call (simple call, quick fast, super easy documentation - unlike twilio which has like a billion lines of confusing documentation, 200 similar products and YET no direct api to check balance, or do a simple thing such as multiple recipients!!)
After a lot of back and through with the support, plus reading all the over-written-essay (so-called documentations), finally I found a way to get all that done.
[Step 1: Configuration]
You have to implement Notify product which is a separate product than the Message product.
So from left menu Notify> Service> add New. Here you need to add a Messaging Service and have it selected here for Notify.
On the Messaging Services page, it will ask you to buy a twilio number. Instead just click on Configure from the left menu and put in all the details you need.
Specifically and importantly, make sure you have Alpha Sender ID checked and a default Alpha Sender text entered there. This will be the default fallback in case if your api call fails to accept the from param.
.
[Step 2: API Call]
//$notify_service_SID = the SID from the Notify Service you added in step 1
$client = new Client($this->Account_SID, $this->auth_token);
$notify_obj = $client->notify->services($notify_service_SID);
//you need receivers in a JSON object such as the following, plus make sure numbers are starting with country code to ensure alpha sender works correctly
$receivers_json = [0=>'{"binding_type":"sms","address":"+614********"}']+[1=>'{"binding_type":"sms","address":"+614*******"}']
$call_ret = $notify_obj->notifications->create([
'toBinding'=> $receivers_json,
'body' => $msg, //actual message goes here
'sms' => [
'from'=> $sender //alphanumeric variable sender
],
]);
.
[Step 3: Check for errors]
There is no direct way to check all errors in twilio when implementing Notify. Here is my mixed approach.
Exception handling to the notifications->create call
$call_ret will have err if the Notify fails, but not when the Message fails. because Notify just passes the call to Message and there is no direct way to check Message errors over Notify call. So you would check for $call_ret['err']
Call the Alerts API; fetch all recent alerts, and match against the Notification SID you received from the last call.
--
Here is how to do the Alerts check:
$alerts = #$client->monitor->v1->alerts->read();
if(is_array($alerts))
foreach($alerts as $av)
{
$t = #$av->toArray();
#parse_str($t['alertText'], $alert_details);
if(isset($alert_details['notificationSid']) && $alert_details['notificationSid'] == $call_retx['sid'])
{
$alert_err = $alert_details['description'];
break;
}
}
$alert_err will carry an error if there was an error. Apart from this there is no direct way to do it. You can fetch these Alerts via crons or you can setup a webhook for them to do a call back. Or simply implement a one call simple api that does it all in super simple way such assmsbroadcast.

Google Service Account "Invalid JWT Signature"

I am attempting to write some code in webDNA to connect to the google drive api. Using the service account seems to be the best solution for the given problem. From what I have read the process is... create the JWT, send the JWT to google to get a token response, then send the taken response to call api methods.I believe my issue is with the private key.
I build and encrypt the header:
[text]header={"alg":"RS256","typ":"JWT"}[/text]
[text]header=[encrypt method=Base64][header][/encrypt][/text]
[text]header=[db_base64URL varName=header][/text][!]custom function to deal with special characters[/!]
Next build and encrypt the claim(added white space for readability):
[text]claim={
"iss":"xxx",
"scope":"https://www.googleapis.com/auth/drive",
"aud":"https://www.googleapis.com/oauth2/v4/token",
"exp":[Math][cTime]+3600[/Math],
"iat":[cTime]
}[/text]
[text]claim=[encrypt method=Base64][claim][/encrypt][/text]
[text]claim=[db_base64URL varName=claim][/text]
Those sections seem to be correct, now to build the signature:
[text]p_key=-----BEGIN PRIVATE KEY-----xxxx-----END PRIVATE KEY-----\n[/text]
[text]sig=[encrypt method=SHA256][header].[claim].[p_key][/encrypt][/text]
[text]sig=[encrypt method=Base64][sig][/encrypt][/text]
[text]sig=[db_base64URL varName=sig][/text]
I have tried moving the [p_key] around, outside the sha256 encryption and inside, with and without the '.', I don't get an error till I try to send it to google using [TCPConnect] and [TCPSend] here:
[text show=T]response=[!]
[/!][TCPconnect host=accounts.google.com&SSL=T&port=443][!]
[/!][TCPsend skipheader=T]POST /o/oauth2/token HTTP/1.1[crlf][!]
[/!]Host: accounts.google.com[crlf][!]
[/!]Content-Type: application/x-www-form-urlencoded[crlf][!]
[/!]Content-Length: [countchars][sendData][/countChars][crlf][!]
[/!]Connection: close[crlf][!]
[/!][crlf][!]
[/!][sendData][crlf][!]
[/!][/TCPsend][!]
[/!][/TCPconnect][/text]
When the response is shown it is displayed as:
{
"error": "invalid_grant",
"error_description": "Invalid JWT Signature."
}
This error message is less that helpful, from what I have read it could mean one(or more) of any number of things and google's documentation on this is not exactly helpful. If anyone has any experience using the google apis through webDNA I would appreciate any help you could give!

Zapier CLI Trigger - How to use defined sample data when no results returned during setup

I am trying to prototype a trigger using the Zapier CLI and I am running to an issue with the 'Pull In Samples' section when setting up the trigger in the UI.
This tries to pull in a live sample of data to use, however the documentation states that if no results are returned it will use the sample data that is configured for the trigger.
In most cases there will be no live data and so ideally would actually prefer the sample data to be used in the first instance, however my trigger does not seem to ever use the sample and I have not been able to find a concrete example of a 'no results' response.
The API I am using returns XML so I am manipulating the result into JSON which works fine if there is data.
If there are no results so far I have tried returning '[]', but that just hangs and if I check the zapier http logs it's looping http requests until I cancel the sample check.
Returning '[{}]' returns an error that I need an 'id' field.
The definition I am using is:
module.exports = {
key: 'getsmsinbound',
noun: 'GetSMSInbound',
display: {
label: 'Get Inbound SMS',
description: 'Check for inbound SMS'
},
operation: {
inputFields: [
{ key: 'number', required: true, type: 'string', helpText: 'Enter the inbound number' },
{ key: 'keyword', required: false, type: 'string', helpText: 'Optional if you have configured a keyword and you wish to check for specific keyword messages.' },
],
perform: getsmsinbound,
sample: {
id: 1,
originator: '+447980123456',
destination: '+447781484146',
keyword: '',
date: '2009-07-08',
time: '10:38:55',
body: 'hello world',
network: 'Orange'
}
}
};
I'm hoping it's something obvious as on scouring the web and Zapier documentation I've not had any luck!
Sample data must be provided from your app and the sample payload is not used for this poll specifically. From the docs:
Sample results will NOT be used for a user's Zap testing step. That
step requires data to be received by an event or returned from a
polling URL. If a user chooses to "Skip Test", then the sample result,
if provided, will be used.
Personally, I have never seen "Skip Test" show up. A while back I asked support about this:
That's a great question! It's definitely one of those "chicken and
egg" situations when using REST Hooks - if there isn't a sample
available, then everything just stalls.
When the Zap editor tries to obtain a "sample result", there are three
places where it's going to look:
The Polling endpoint (in Step #3 of your trigger's setup) is invoked for the current user. If that returns "nothing", then the Zap
editor will try the next step.
The "most recent record/data" in the Zap's history. Since this is a brand new Zap, there won't be anything present.
The Sample result (in Step #4 of your trigger's setup). The Zap editor will tell the user that there's "nothing to show", and will
give the user the option to "skip test and continue", which will use
the sample JSON that you've provided here.
In reality, it will just continue to retry the request over and over and never provide the user with a "skip test and continue" option. I just emailed again asking if anything has changed since then, but it looks like existing sample data is a requirement.
Perhaps create a record in your API by default and hide it from normal use and just send back that one?
Or send back dummy data even though Zapier says not to. Not sure, but I don't know how people can set up a zap when no data has been created yet (and Zapier says not many of their apps have this issue, but nearly every trigger I've created and ever use case for other applications would hint to me otherwise).

Bing translator HTTP API throws bad request error, how to solve this?

Whenever I call Bing Translation API [HTTP] to translate some text, first time it works fine, and second time onwards it gives me 'bad request' [status code 400] error. If I wait for 10 or so minutes and then try again, then first request is successful, but second one onwards same story. I have a free account [2million chars translation] with Bing Translation APIs, are there any other limitations calling this API?
Thanks, Madhu
Answer:
hi, i missed to subscribing to Microsoft Translator DATA set subscription. Once i get the same, then things have solved. i.e; once i have signed up for https://datamarket.azure.com/dataset/bing/microsofttranslator then things are working.
i was generating the access_token correctly, so that is not an issue.
thanks, madhu
i missed to subscribing to Microsoft Translator DATA set subscription. Once i get the same, then things have solved. i.e; once i have signed up for https://datamarket.azure.com/dataset/bing/microsofttranslator then things are working.
i was
thanks, madhu
As a note to anyone else having problems, I figured out that the service only allows the token to be used once when using the free subscription. You have to have a paid subscription to call the Translate service more than once with each token. This limitation is, of course, undocumented.
I don't know if you can simply keep getting new tokens -- I suspect not.
And regardless of subscription, the tokens do expire every 10 minutes, so ensure you track when you receive a token and get a new one if needed, e.g. (not thread-safe):
private string _headerValue;
private DateTime _headerValueCreated = DateTime.MinValue;
public string headerValue {
get {
if(_headerValueCreated < DateTime.Now.AddMinutes(-9)) {
var admAuth = new AdmAuthentication("myclientid", "mysecret");
_headerValue = "Bearer " + admAuth.GetAccessToken();
_headerValueCreated = DateTime.Now;
}
return _headerValue;
}
}

Resources