I've been experimenting with creating an AngularJS service that can be called from the controller and send text messages based on particular events in the application. The implementation is based on this, and works as follows:
Firstly, we have the service:
function BusinessService($http) {
this.twilioSMS = {
sendMessage: function(to, from, body) {
var accountSid = 'xxx';
var authToken = 'xxx';
var testEndpoint = 'https://api.twilio.com/2010-04-01/Accounts/' + accountSid + '/SMS/Messages.json';
var liveEndpoint = 'https://api.twilio.com/2010-04-01/Accounts/' + accountSid + '/Messages.json';
var data = {
To: to,
From: from,
Body: body
};
$http({
method: 'POST',
url: testEndpoint,
data: data,
dataType: 'json',
contentType: 'application/x-www-form-urlencoded',
beforeSend: function(xhr) {
xhr.setRequestHeader("Authorization",
"Basic " + btoa(accountSid + ":" + authToken) // !
);
},
success: function(data) {
console.log("Got response: %o", data);
if (typeof successCallback == 'function')
successCallback(data);
},
error: function(jqXHR, textStatus, errorThrown) {
console.log("Request failed: " + textStatus + ", " + errorThrown);
if (typeof failCallback == 'function')
failCallback(jqXHR, textStatus, errorThrown);
}
})
}
}
}
Then setting it up in the controller:
function ConsumerBusinessProfileCtrl($scope, BusinessService) {
$scope.sendMessage = function(to, from, body) {
return BusinessService.twilioSMS.sendMessage(to, from, body)
}
}
And then calling it from the view:
<a ng-click="sendMessage('+12345678901', '+15005550006', 'Hey Jenny! Good luck on the bar exam!')">Send Message</a>
I've tested the jsfiddle example with my accountSid, authToken, and phone numbers and it is working fine. But my implementation fails with a 401 (UNAUTHORIZED) error. A part of me thinks that this is because $http does not support beforeSend or afterSend. But I am not sure? Can anybody here guide me in the right direction?
Changed $http to the following to fix things:
$http({
method: 'POST',
url: testEndpoint,
data: data,
transformRequest: function(obj) {
var str = [];
for (var p in obj)
str.push(encodeURIComponent(p) + "=" + encodeURIComponent(obj[p]));
return str.join("&");
},
headers: {
'Authorization': 'Basic ' + btoa(accountSid + ':' + authToken),
'Content-Type': 'application/x-www-form-urlencoded'
},
}).success(function(response) {
console.log(response);
}).error(function(error) {
console.log(error);
});
}
Related
I just want to make a PUT request with jQuery in Jira.
I've tried it before with SoapUI and there it works, but in my JS file it's not working... It's always giving me an error back (alert with "no" in my case).
Here's my code:
var issueKey = this.JIRA.Issue.getIssueKey();
var username = "admin";
var password = "admin";
var encodedLoginData = btoa(username + ":" + password);
AJS.$.ajax({
type: 'PUT',
contentType: 'application/json',
url: '/jira/rest/api/2/issue/' + issueKey,
dataType: 'json',
async: false,
headers: { 'Authorization': 'Basic ' + encodedLoginData },
data: JSON.stringify('{"update":{"timetracking":[{"edit":{"originalEstimate":"4m","remainingEstimate":"3m"}}]}}'),
success: function(response){ alert("yes"); },
error: function(error){ alert("no"); }
});
As mentioned, the JSON data phrase works in SoapUI, also the login information and the base64 encryption. That's all correct.
But I can't find my fault... Any ideas?
EDIT:
PUT http://localhost:2990/jira/rest/api/2/issue/TEST-3 400
XMLHttpRequest.send # batch.js?devtoolbar=…logged-in=true:5461
send # batch.js?locale=en-US:197
ajax # batch.js?locale=en-US:191
calculate # batch.js?devtoolbar=…logged-in=true:5620
prepareCalculation # batch.js?devtoolbar=…logged-in=true:5620
(anonymous) # batch.js?devtoolbar=…logged-in=true:5620
dispatch # batch.js?locale=en-US:104
h # batch.js?locale=en-US:96
trigger # batch.js?locale=en-US:101
simulate # batch.js?locale=en-US:108
e # batch.js?locale=en-US:114
I think your problem is that the parameter of your JSON.stringify shouldn't be a String. Try to save that into a variable and then make a JSON.stringify of that.
Take into account the result of JSON.stringify. For instance:
JSON.stringify("{}"); //""{}""
JSON.stringify({}); //"{}"
Now your code should be like this For example:
var issueKey = this.JIRA.Issue.getIssueKey();
var username = "admin";
var password = "admin";
var encodedLoginData = btoa(username + ":" + password);
var dataObject = {"update":{"timetracking":[{"edit":{"originalEstimate":"4m","remainingEstimate":"3m"}}]}};
AJS.$.ajax({
type: 'PUT',
contentType: 'application/json',
url: '/jira/rest/api/2/issue/' + issueKey,
dataType: 'json',
async: false,
headers: { 'Authorization': 'Basic ' + encodedLoginData },
data: JSON.stringify(dataObject),
success: function(response){ alert("yes"); },
error: function(error){ alert("no"); }
});
If this is an IIS server, you may need to disable WebDAV, as that grabs all PUT requests.
Happens to be your error is that you're trying to stringify a string
data: JSON.stringify('{update...}')
Nowadays, you don't need jQuery to do HTTP in the browser. All modern browsers come with the Fetch API built in
const issueKey = this.JIRA.Issue.getIssueKey();
const username = "admin";
const password = "admin";
const encodedLoginData = btoa(username + ":" + password);
const body = {
update: {
timetracking: [{
edit: {
originalEstimate: "4m"
remainingEstimate: "3m"
}
}]
}
}
fetch(`/jira/rest/api/2/issue/${issueKey}`, {
method: 'PUT',
body: JSON.stringify(body),
headers: {
'Authorization': 'Basic ' + encodedLoginData
'Content-Type': 'application/json',
},
})
.then(response => alert('yes'))
.catch(error => alert('no'));
I'm accessing Twitter Search api into my Angular application getting following error. Implemented this change into https. Still getting same error
{"errors":[{"code":215,"message":"Bad Authentication data."}]}
twitter-service.js
angular.module('TwitterServices', [], function ($provide) {
$provide.factory('$twitter', function ($http, $log) {
var consumerKey = encodeURIComponent('<consumerKey from twitter api>');
var consumerSecret = encodeURIComponent('<consumerSecret from twitter api>');
var credentials = Base64.encode(consumerKey + ':' + consumerSecret);
var twitterOauthEndpoint = $http.post(
'https://api.twitter.com/oauth2/token'
, "grant_type=client_credentials"
, {
headers: {
'Authorization': 'Basic ' + credentials, 'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8',
'Access-Control-Allow-Origin': '*'
}
}
);
twitterOauthEndpoint.success(function (response) {
serviceModule.$httpProvider.defaults.headers.common['Authorization'] = "Bearer " + response.access_token
}).error(function (response) {
});
So I am using the JavaScript port of RiveScript which uses ajax and of course I don't want to use jQuery anymore. There is only one line ajax and I want to change it to the new Fetch API.
**FYI: You can see the ajax code in line 1795 of the CDN.**
So here's the original code:
return $.ajax({
url: file,
dataType: "text",
success: (function(_this) {
return function(data, textStatus, xhr) {
_this.say("Loading file " + file + " complete.");
_this.parse(file, data, onError);
delete _this._pending[loadCount][file];
if (Object.keys(_this._pending[loadCount]).length === 0) {
if (typeof onSuccess === "function") {
return onSuccess.call(void 0, loadCount);
}
}
};
})(this),
error: (function(_this) {
return function(xhr, textStatus, errorThrown) {
_this.say("Ajax error! " + textStatus + "; " + errorThrown);
if (typeof onError === "function") {
return onError.call(void 0, textStatus, loadCount);
}
};
})(this)
});
and here's what I tried so far using the Fetch API:
return fetch(file, {
dataType: "text"
})
.then(function(_this) {
return function(data, textStatus, xhr) {
_this.say("Loading file " + file + " complete.");
_this.parse(file, data, onError);
delete _this._pending[loadCount][file];
if (Object.keys(_this._pending[loadCount]).length === 0) {
if (typeof onSuccess === "function") {
return onSuccess.call(void 0, loadCount);
}
}
};
})
.catch(function(_this) {
return function(xhr, textStatus, errorThrown) {
_this.say("Ajax error! " + textStatus + "; " + errorThrown);
if (typeof onError === "function") {
return onError.call(void 0, textStatus, loadCount);
}
};
})
The app code:
var bot = new RiveScript();
bot.loadFile("./brain.rive", loading_done, loading_error);
function loading_done (batch_num) {
console.log("Batch #" + batch_num + " has finished loading!");
bot.sortReplies();
var reply = bot.reply("local-user", "Hello, bot!");
console.log("The bot says: " + reply);
}
function loading_error (error) {
console.log("Error when loading files: " + error);
}
Using the Fetch API, I'm not seeing any error now though I'm also not seeing any error or success messages.
Am I missing something here?
The fetch init object doesn’t have a dataType key.
To indicate you want plain text back, add an Accept: text/plain header to the request:
fetch(file, {
headers: {
"Accept": "text/plain"
},
})
And the fetch call returns a promise that resolves with a Response object, and that Response object provides methods that resolve with text, JSON data, or a Blob — which means the basic form for handling the response from your fetch(…) call is like this:
fetch(file, {
headers: {
"Accept": "text/plain"
},
})
.then(response => response.text())
.then(text => {
// Do something with the text
})
So you need to take the existing code in the question and fit it into that form.
I want to create ajax call with authorization headears only when user writes username and password. When this vars are empty I need to create ajax call without authorization headers. How can I do this? Can I make it with one ajax or I need to create two ajax every for one situation?
var username = "user123";
var password = "pass123";
//var username = "";
//var password = "";
$.ajax({
type: "GET",
url: url_survey,
dataType: "json",
headers: {
'Authorization': "Basic " + btoa(username + ":" + password)
},
success:
function (data) {
alert("SUCCESS");
},
error:
function (data) {
alert("ERROR");
}
});
Try this:
var username = "user123";
var password = "pass123";
//var username = "";
//var password = "";
var headers = {}; //list of headers
if(username && password) //user and pass exists
headers['Authorization'] = "Basic " + btoa(username + ":" + password);
$.ajax({
type: "GET",
url: url_survey,
dataType: "json",
headers: headers, //use our headers
success:
function (data) {
alert("SUCCESS");
},
error:
function (data) {
alert("ERROR");
}
});
The parameter passed to $.ajax is just an object. Just simply create it, add properties as needed, then send it to `$.ajax.
var ajaxData = {
type: "GET",
url: url_survey,
dataType: "json",
success:
function (data) {
alert("SUCCESS");
},
error:
function (data) {
alert("ERROR");
}
};
if(username && password){
ajaxData.headers = {
'Authorization': "Basic " + btoa(username + ":" + password)
};
}
$.ajax(ajaxData);
I have a RESTful web service (hosted on a different server via IIS) that returns JSON. The strange thing is the following NodeJS command line test application (not via the web browser, but via the command line) is working fine and returning the JSON:
Working NodeJS App:
var request = require("request");
var btoa = require("btoa");
var uname = "corp\\user.name";
var pword = "password123"
var options = {
url: "http://192.168.3.142/v1/foo?format=json",
headers: {
"Authorization": "Basic " + btoa(uname + ":" + pword)
}
};
request(options, function(err, response, body) {
console.log(body);
});
However the following AJAX request fails with:
OPTIONS http://192.168.3.142/v1/foo?format=json 401 (Unauthorized) jquery-1.11.0.min.js:4
XMLHttpRequest cannot load http://192.168.3.142/v1/foo?format=json. Invalid HTTP status code 401
This is the response header from the server:
Response Headers:
Access-Control-Allow-Headers:Authorization
Access-Control-Allow-Methods:GET, POST, PUT, DELETE, OPTIONS
Access-Control-Allow-Origin:*
Content-Length:1293
Content-Type:text/html
Date:Thu, 06 Mar 2014 05:41:24 GMT
Server:Microsoft-IIS/7.5
WWW-Authenticate:Basic realm="192.168.3.142"
X-Powered-By:ASP.NET
AJAX code:
$.ajaxSetup({
beforeSend: function (xhr, settings) {
var creds = {
username: "corp\\user.name",
password: "password123"
};
xhr.setRequestHeader("Authorization", "Basic " + btoa(creds.username + ":" + creds.password));
return true;
}
});
$.ajax({
type: "GET",
url: "http://192.168.3.142/v1/foo?format=json",
success: function (data, text) {
console.log(data);
}
});
UPDATE:
Throws the same 401 (Unauthorized):
var creds = {
username: "corp\\user.name",
password: "password123"
};
var credentials = btoa(creds.username + ":" + creds.password);
$.ajax({
type: "GET",
dataType: "text/json",
url: "http://192.168.3.142/v1/foo?format=json",
beforeSend: function (xhr) {
xhr.setRequestHeader("Authorization", "Basic " + credentials);
return true;
},
success: function (data, text) {
console.log(data);
}
});
Once I added xhrFields: { withCredentials: true } to the $.ajaxSetup({}); the error was returning:
Credentials flag is 'true', but the 'Access-Control-Allow-Credentials' header is ''. It must be 'true' to allow credentials.
I added Access-Control-Allow-Credentials: true on the server-side and it's now working correctly.
var creds = {
username: "username",
password: "password"
};
var credentials = btoa(creds.username + ":" + creds.password);
$.ajaxSetup({
xhrFields: { withCredentials: true },
beforeSend: function (xhr, settings) {
xhr.setRequestHeader("Authorization", "Basic " + credentials);
return true;
}
});
$.ajax({
type: "GET",
url: "http://localhost/v1/service",
async: true,
success: function (data, text) {
console.log(data);
}
});