Posting to Twitter through OAuthSimple.js - javascript

I've been stuck on this one for a while. I'm trying to use OAuthSimple.js to interact with Twitter in a Chrome extension I've written.
The signing process seems to work fine for requests to retrieve a user's statuses, but I can't seem to construct a request that will successfully authenticate when I try to retweet, reply, or mark a tweet as favorite.
I'm following the guides here. I have also tried numerous ways of structuring the request, and comparing the request contents against the output of the OAuth tool provided by Twitter ( which seems to check out ), but I'm still getting 401 errors and generic "We couldn't authenticate you" responses.
Here's how I'm trying to form the request:
var sendTwitterRequest = function(url, params, method, callback) {
var request = null;
if ( localStorage.twitterAuthToken ) {
OAuthSimple().reset();
request = OAuthSimple(TwitterConsumerKey,TwitterConsumerSecret).sign({
action:method,
method:"HMAC-SHA1",
dataType:"JSON",
path:url,
parameters:params,
signatures:{
oauth_version:'1.0',
oauth_token:localStorage.twitterAuthToken,
oauth_secret:localStorage.twitterAuthVerifier
}
});
console.log(request);
$j.ajax({
url:request.signed_url,
type:method,
data:request.parameters,
success:callback
});
}
};
Then, making calls into this method like this:
// this works, I get the data and can do stuff with it
sendTwitterRequest('http://api.twitter.com/1/statuses/user_timeline.json?user_id=',null,'GET',someMethod());
// this fails and throws a 401 error every time
sendTwitterRequest("https://api.twitter.com/1/statuses/retweet/"+tweetKey+".json",null,'POST',someOtherMethod());
Am I missing something? Thanks in advance!

It turns out the requests I am creating are fine, I just needed a final one to exchange request tokens for OAuth tokens. I thought this step was covered when the user was prompted for input, but turns out I was wrong.
I also ended up switching from OAuthSimple.js to just OAuth.js, on account of the fact that I could only get OAuth.js to process both the token requests and the timeline requests.
Some of this is pretty specific to what my application is doing, so you will probably need to modify it.
The new sendTwitterRequest method:
var sendTwitterRequest = function(options){
var accessor={
consumerSecret:TwitterConsumerSecret
};
var message={
action:options.url,
method:options.method||"GET",
parameters:[
["oauth_consumer_key",TwitterConsumerKey],
["oauth_signature_method","HMAC-SHA1"],
["oauth_version","1.0"]
]
};
if(options.token){
message.parameters.push(["oauth_token",options.token])
}
if(options.tokenSecret){
accessor.tokenSecret=options.tokenSecret
}
for(var a in options.parameters) {
message.parameters.push(options.parameters[a])
}
OAuth.setTimestampAndNonce(message);
OAuth.SignatureMethod.sign(message,accessor);
try {
$j.ajax({
url:message.action,
async:options.async||true,
type:message.method||'GET',
data:OAuth.getParameterMap(message.parameters),
dataType:options.format||'JSON',
success:function(data) {
if (options.success) {options.success(data);}
}
});
} catch ( e ) {
}
};
And the methods that depend on it:
// asks Twitter for an oauth request token. User authorizes and the request token is provided
requestTwitterToken = function() {
// this is semi-specific to what my extension is doing, your callback string may need
// to be slightly different.
var callbackString = window.top.location + "?t=" + Date.now();
var params = [
[ 'oauth_callback', callbackString ]
];
sendTwitterRequest({
url: "https://api.twitter.com/oauth/request_token",
method: 'POST',
parameters: params,
format: 'TEXT',
success: function(data) {
var returnedParams = getCallbackParams(data);
if ( returnedParams.oauth_token ) {
chrome.tabs.create({
url:"https://api.twitter.com/oauth/authorize?oauth_token=" + returnedParams.oauth_token
});
}
},error:function( e ) {
console.log( 'error' );
console.log( e );
}
});
};
// exchanges the Twitter request token for an actual access token.
signIntoTwitter = function(token, secret, callback) {
var auth_url = "https://api.twitter.com/oauth/access_token";
var authCallback = function(data) {
var tokens = getCallbackParams(data);
localStorage.twitterAuthToken = tokens.oauth_token || null;
localStorage.twitterAuthTokenSecret = tokens.oauth_token_secret || null;
callback();
};
try {
sendTwitterRequest({url:auth_url, method:'POST', async:true, format:'TEXT', token:token, tokenSecret:secret, success:authCallback});
} catch ( e ) {
console.log(e);
}
};
With this, the steps are as follows:
ask Twitter for a token ( requestTwitterToken() ) and provide a callback
in the callback, check to see if a token is provided. If so, it's an initial token
pass the token back to Twitter and open the Twitter auth page, which allows the user to grant access
in the callback to this call, see if an access token was provided
exchange the request token for an access token ( signIntoTwitter() )
After that, I simply use the sendTwitterRequest() method to hit Twitter's API to fetch the timeline and post Tweets.

Related

How to get response from Paynet.js load form?

I was trying to integrate Paynet.js for payment Integration They are having few custom HTML on page Load they are invoking below API on response I am getting session ID.
export function getPaymentSessionId(data) {
data = JSON.stringify(data);
let url = "/paynetj/auth?type=CF"
let BASE = "https://pts-api.paynet.com.tr/v1"
let actualurl = BASE + url;
Api._callAPI(actualurl, 'POST', data, (type, dt) => {
if (type == 'success') {
dispatcher.dispatch({
type: 'SessionId',
data: dt,
})
}else{
}
});
}
ON page Load getting Session ID
How to get that Session Id.
In the component I was calling action
let data1 = {
token:"pbk_pcs_wCtr5nd31EhNm7DhjUarQpgxQasTb2pa",
amount:150000,
add_commission:false,
pos_type:5,
domain:"https://www.paynet.com.tr",
tds_required:false,
show_tds_error:true,
merge_option:false,
save_card:false
}
UserAction.getPaymentSessionId(data1);
Showing in response unAuthorized what ever the keys and values given in API doc the same i was sending, do i need to send that token from my end and what is that token, can anyone please explain.
Else Do i need to call same API from my Application, Is there any alternate to get Session Id from the API that is getting Invoked on Page Load

AWS Lambda Node.js HTTP GET Request never executed

I have the following intent. When intent is entered I want to perform a GET request to an external API. The intent is entered, however my http.get requested is not. If you look below I added a log statement within the request and it is never executed. Any ideas what the problem may be?
'BlogEntrySlugIntent': function () {
var url = 'http://jsonplaceholder.typicode.com/posts/1';
http.get( url, function( response ) {
console.log('In get request');
response.on( 'data', function( data ) {
var text = 'Data returned is: ' + data;
this.emit(':tell', 'hellloooo');
});
});
},

Get intents, entities, contexts and all data

In the case, the actually conversation-simple have one function with all the values, but the function update every time if flows conversation.
I want create one function or other form to be able to capture all that data that is currently on the data.
In the case have Intents, context, entities, etc.
conversation.message(payload, function(err, data) {
if (err) {
return res.status(err.code || 500).json(err);
}
return res.json(updateMessage(payload, data));
});
});
The data inside updateMessage parameter have all I need, but if I create other function and try get this values, does not work.
In the case I use the values and get with app.js for open some REST webservice.
I try it:
function login (req, res) {
numberOrigin = null;
sessionid = null;
var dataLogin = {
data: { "userName":"xxxxx","password":"xxxxx","platform":"MyPlatform" },
headers: { "Content-Type": "application/json" }
};
client.registerMethod("postMethod", "xxxxxxxxxxxxxxx/services/login", "POST");
client.methods.postMethod(dataLogin, function (data, response) {
if(Buffer.isBuffer(data)){
data = data.toString('utf8');
console.log(data);
var re = /(sessionID: )([^,}]*)/g;
var match = re.exec(data);
var sessionid = match[2]
console.log(sessionid);
}
});
}
function openRequest(data, sessionid, numberOrigin ){
//console.log(data); dont show the values.. show the data response of login
var dataRequest = {
data: {"sessionID": sessionid,
"synchronize":false,
"sourceRequest":{
"numberOrigin":numberOrigin,
"description": JSON.stringify(data.context.email) } },
headers: { "Content-Type": "application/json" }
};
numberOrigin +=1;
client.post("xxxxxxxxxxxxxxxxxx/services/request/create", dataRequest, function (data, response) {
if(Buffer.isBuffer(data)){
data = data.toString('utf8');
console.log(data);
}
});
}
function updateMessage(res, input, data, numberOrigin) {
var email = data.context.email; // this recognize but this function is responsible for other thing
if (email === 'xxxxxxxxxxxx#test.com') {
console.log(data);
login(data);
openRequest(data, sessionid, numberOrigin)
}
}
In case, I just want get the values with my app.js for use inside REST. I got it with ajax but everything on the client side (index.html), and that made me show my credentials, so I decided to do it in REST for security my code..
If have some form to solved this, please let me know.
If have other form to do it, I'll be happy to know.
Thanks advance.
The issue is likely that you need to write to the response object res.. In the updateMessage function the response is passed in. In order for data to be sent back to the browser you need to write to the response. I have a demo app which calls the weather channel to get the weather based on an intent, similar to what you are trying to do with your login function. Please take a look at this code
https://github.com/doconnor78/conversation-simple-weather/blob/master/app.js#L130
You will need to pass the original res (response) object into the appropriate function and then write data to the response (res) once you get it from the third party service.

Send JSONP data to Google Apps script from javascript

I am trying to send data to a google app script, to create and insert data into a sheet. What I would like to happen is that the person using the page, will be the one asked to authorize the app (only allowed within the organization). So when authorized, the javascript on the page will send data via jsonp to an app script, which will process and generate a sheet, and then save it to the users drive, and show them the link (or open it up in a new tab).
But when I try this I am running into issues. Here is javascript in my app (not in googles html, my own app).
var foo = function(data) {
console.log('foo')
console.log(data)
}
var url = "https://script.google.com/a/macros/viedu.org/s/AKfycbzF6g9dAC5DI7Qtl0VD3QeYGsDbo43XxuVtoEYSHEA5_4yibYFN/exec"
console.log(url)
var data = {
"foo": "bar"
}
$.ajax({
"url": url,
// The name of the callback parameter
jsonp: "callback",
// Tell jQuery we're expecting JSONP
dataType: "json",
jsonpCallback: foo,
"data": data
})
.done(function(response) {
console.log('success')
console.log(response)
})
.fail(function(response) {
console.log('fail')
console.log(response)
})
and my app script:
function doGet(e) {
var cb = e.parameter.callback;
var data = JSON.stringify({"data":"bar"});
var outputStr = cb + "(" + data + ")";
return ContentService
.createTextOutput(outputStr)
.setMimeType(ContentService.MimeType.JAVASCRIPT);
}
and my response in chrome console:
fail
script.html:39 Object {readyState: 0, responseJSON: undefined, status: 0, statusText: "error"}
the response from the app script seems to be coming back as undefined. but im not sure why. If I try almost anything else in the jquery, I get errors stating it is trying to parse html/text and is invalid javascript. But I don't see what has to change in the app script as it looks fairly straight forward.
Replace this:
return ContentService.createTextOutput(outputStr).setMimeType(ContentService.MimeType.JAVASCRIPT);
with this:
var params = JSON.stringify(getr);
return ContentService.createTextOutput(params);

Difference in $http response and Api response [AngularJs]

I have an issue on my application when I get an API request from members belongs to a particulary group.
GET /api/organizations/1234/members?group=4321
If I start my navigation with this request, I have the right members but if I navigate in other page with other groupe before, the $http response is full of parasite members whereas the response form API is right (check from network tab in Chrome developper tools).
I think about some cache but I can not find it ! For info, I use jsData for mounting my data but it's not seems to be the problem.
Here the code of my function to send Api Request :
var loadGroupMembers = function() {
return $q(function(resolve, reject) {
var callParams = {
organizationId: $stateParams.OrganizationId,
groupId: $stateParams.groupId
};
sendApiCall('groupMembers', 'get', callParams)
.success(function(data) {
resolve(data);
})
.error(function(data) {
});
});
};
var sendApiCall = function(requestId, method, params, data, queryStringParams) {
params = params || {};
data = data || {};
var apiCallConfig = {
params: config.params,
method: config.method,
url: "/api/organizations/1234/members?group=4321",
data: data,
cache : false
};
$rootScope.fn.setHistory($state.current.name, 'apiCall', 'sendManualApiCall:' + requestId);
return $http(apiCallConfig);
};
Please tell me if you have questions or need more details.
Thanks for your help ! :)
Edit : I add the function that call sendApiCall and I made a little apiary to show you how the data from api are : http://private-52326-groupmember.apiary-mock.com/organization/1234/members?group=4321
It was kind of link with Jsdata and an interceptor created by an other developer. For each api request, the interceptor add some data on the response with the same type ... So the issue is closed.
Thanks for your help anyway :)

Categories