Twitter Search API- How to implement premium access keys in NODE.JS? - javascript

I am using npm-twit in node.js to get tweets with the twitter search api.
I am totally new to programming but need it for my master thesis. I therefore got the premium account with full archive access to the search requests.
With the standard free api access my code worked without any problems. But now I do not know how to correctly implement access tokens etc.
I tried putting product and label in different places and changed q to query and data.statues to data.results but anything I tried gives me several error codes - like
'code: 195, message: 'Missing or invalid url parameter.'
'code: 25, message: 'Query parameters are missing.'
'message: 'Sorry, that page does not exist', code: 34'.
Or tells me that tweets.length does not exist (even though it worked before).
Or a simple 'null'
(when I use this code snipped :
T.get('search/tweets/fullarchive/:dev', params , gotData); function gotData(err, data, response){console.log(data)}
)
//This is the current code which is not working
var Twit = require('twit');
var config = require('./config');
var T = new Twit({
consumer_key: 'XXX',
consumer_secret: 'XXX',
access_token: 'XXX',
access_token_secret: 'XXX',
timeout_ms: 60*1000,
strictSSL: true,
app_only_auth: true,
PRODUCT: 'fullarchive',
LABEL: 'dev',});
var params = {
query: 'VW',
fromDate:'201801010000',
toDate:'201901010000',
followers_count:1000,
maxResults: 500,
result_type: 'popular',
lang: 'en'
//next: ''
}
T.get('search/tweets/fullarchive/:dev', params , gotData);
//T.get('search/tweets', params , gotData); - gives me all results in standard api
function gotData(err, data, response)
{
var tweets = data.results; //var tweets = data.statuses - gives me what I need in standard api
for (var i = 0; i < tweets.length; i++)
console.log(tweets[i].text, tweets[i].retweet_count,tweets[i].created_at,tweets[i].id_str,tweets[i].favorite_count,);
With this code I get an error 'Unhandled rejection TypeError: Cannot read property 'results' of null'
Ideally I want to get information about the tweet containing its text, creation date, retweet count, tweet id, favorite count - and if possible the "next" token when needed.
I would really appreciate any help!

Related

Filters in Power BI embed report

I developed a few months ago a NodeJS API to get embed reports from Power BI (using a tenant). I consume this API from an Angular app. Now I want to get the report filtered, and I don't know if this is possible with my actual code.
I used the PowerBI rest API to get the embed report. Reading the docs of microsoft, I see lots of docs like this one, where says that I should create an object with the filters that I want. This is not a problem, but I don't know if this is compatible with mi actual Node API or I should develop a new solution.
My API follows the sample provided by Microsoft, and the code is:
async function getEmbedParamsForSingleReport(
workspaceId,
reportId,
additionalDatasetId
) {
const reportInGroupApi = `https://api.powerbi.com/v1.0/myorg/groups/${workspaceId}/reports/${reportId}`;
const headers = await getRequestHeader();
// Get report info by calling the PowerBI REST API
const result = await axios.get(reportInGroupApi, { headers });
if (result.status !== 200) {
throw result;
}
// Convert result in json to retrieve values
const resultJson = result.data;
// Add report data for embedding
const reportDetails = new PowerBiReportDetails(
resultJson.id,
resultJson.name,
resultJson.embedUrl
);
const reportEmbedConfig = new EmbedConfig();
// Create mapping for report and Embed URL
reportEmbedConfig.reportsDetail = [reportDetails];
// Create list of datasets
let datasetIds = [resultJson.datasetId];
// Append additional dataset to the list to achieve dynamic binding later
if (additionalDatasetId) {
datasetIds.push(additionalDatasetId);
}
// Get Embed token multiple resources
reportEmbedConfig.embedToken =
await getEmbedTokenForSingleReportSingleWorkspace(
reportId,
datasetIds,
workspaceId
);
return reportEmbedConfig;
}
With this I obtain the embed report and send back to my app. Is this solution compatible with filters?
Thanks in advance!
Finally, I came out with a solution. In mi Angular app, I use the library powerbi-client-angular. That allows me to define some configuration in the embed report:
basicFilter: models.IBasicFilter = {
$schema: 'http://powerbi.com/product/schema#basic',
target: {
table: 'items',
column: 'id',
},
operator: 'In',
values: [1,2,3],
filterType: models.FilterType.Basic,
requireSingleSelection: true,
displaySettings: {
/** Hiding filter pane */
isLockedInViewMode: true,
isHiddenInViewMode: true,
},
};
reportConfig: IReportEmbedConfiguration = {
type: 'report',
id: cuantitativeReportID,
embedUrl: undefined,
tokenType: models.TokenType.Embed,
filters: [this.basicFilter],
accessToken: undefined,
settings: undefined,
};
With this, I can avoid passing information to the NodeJS API
Yes, It will work fine with this solution. Please find the relevant code below:
Create a filter object:
const filter = {
$schema: "http://powerbi.com/product/schema#basic",
target: {
table: "Geo",
column: "Region"
},
operator: "In",
values: ["West", "Central"]
};
Add the filter to the report's filters:
await report.updateFilters(models.FiltersOperations.Add, [filter]);
You can refer sample NodeJS application to get embed reports from Power BI.
Please find the the reference here:
https://github.com/microsoft/PowerBI-Developer-Samples/tree/master/NodeJS

AngularJS (500 Internal Server Error) for http put

I want to update the record to the api.
In my firebug it shows:
500 internal server error,
XML Parsing Error: no element found Location: moz-nullprincipal:{f514f16e-f3d3-49f1-99e6-105b2b80f26c} Line Number 1, Column 1:
and also under put it shows:
There are no child objects
Here is my code
$scope.EditUser = function(){
$scope.ApplicationId = '7bg67898ewnbqjq65e';
$http.put("mydomain.com/api/Users/UpdateUser", {}, {
params: { _id: $scope.selectedItem._id, ApplicationId: $scope.ApplicationId, User_Name : $scope.selectedItem.UserName, IsActive: $scope.selectedItem.IsActive }
});
This is solved using this
$scope.EditUser = function(){
$scope.ApplicationId = '7bg67898ewnbqjq65e';
$http.put("mydomain.com/api/Users/UpdateUser", {
_id: $scope.selectedItem._id, ApplicationId: $scope.ApplicationId, User_Name : $scope.selectedItem.UserName, IsActive: $scope.selectedItem.IsActive
});
The shortcut method to perform PUT request is: $http.put(url, data, [config]);
#user3055606 your Answer is correct.

Creating an envelope from a template returning "UNSPECIFIED_ERROR"

When I try to create an envelope from a template I get a response of:
{ errorCode: 'UNSPECIFIED_ERROR',
message: 'Non-static method requires a target.' }
Here's what I'm doing so far:
First I login, which returns
{ loginAccounts:
[ { name: '*****',
accountId: '*****',
baseUrl: 'https://demo.docusign.net/restapi/v2/accounts/******',
isDefault: 'true',
userName: '***** ********',
userId: '*******-*****-*****-*****-*********',
email: '********#*******.com',
siteDescription: '' } ] }
So then I take the baseUrl out of that response and I attempt to create the envelope. I'm using the hapi framework and async.waterfall of the async library, so for anyone unfamiliar with either of these my use of the async library uses the next callback to call the next function which in this case would be to get the url for the iframe, and with our usage of the hapi framework AppServer.Wreck is roughy equivalent to request:
function prepareEnvelope(baseUrl, next) {
var createEntitlementTemplateId = "99C44F50-2C97-4074-896B-2454969CAEF7";
var getEnvelopeUrl = baseUrl + "/envelopes";
var options = {
headers: {
"X-DocuSign-Authentication": JSON.stringify(authHeader),
"Content-Type": "application/json",
"Accept": "application/json",
"Content-Disposition": "form-data"
},
body : JSON.stringify({
status: "sent",
emailSubject: "Test email subject",
emailBlurb: "My email blurb",
templateId: createEntitlementTemplateId,
templateRoles: [
{
email: "anemailaddress#gmail.com",
name: "Recipient Name",
roleName: "Signer1",
clientUserId: "1099", // TODO: replace with the user's id
tabs : {
textTabs : [
{
tabLabel : "acct_nmbr",
value : "123456"
},
{
tabLabel : "hm_phn_nmbr",
value : "8005882300"
},
{
tabLabel : "nm",
value : "Mr Foo Bar"
}
]
}
}
]
})
};
console.log("--------> options: ", options); // REMOVE THIS ====
AppServer.Wreck.post(getEnvelopeUrl, options, function(err, res, body) {
console.log("Request Envelope Result: \r\n", JSON.parse(body));
next(null, body, baseUrl);
});
}
And what I get back is:
{ errorCode: 'UNSPECIFIED_ERROR',
message: 'Non-static method requires a target.' }
From a little googling it look like 'Non-static method requires a target.' is a C# error and doesn't really give me much indication of what part of my configuration object is wrong.
I've tried a simpler version of this call stripping out all of the tabs and clientUserId and I get the same response.
I created my template on the Docusign website and I haven't ruled out that something is set up incorrectly there. I created a template, confirmed that Docusign noticed the named form fields, and created a 'placeholder' templateRole.
Here's the templateRole placeholder:
Here's one of the named fields that I want to populate and corresponding data label:
As a side note, I was able to get the basic vanilla example working without named fields nor using a template using the docusign node package just fine but I didn't see any way to use tabs with named form fields with the library and decided that I'd rather have more fine-grained control over what I'm doing anyway and so I opted for just hitting the APIs.
Surprisingly when I search SO for the errorCode and message I'm getting I could only find one post without a resolution :/
Of course any help will be greatly appreciated. Please don't hesitate to let me know if you need any additional information.
Once I received feedback from Docusign that my api call had an empty body it didn't take but a couple minutes for me to realize that the issue was my options object containing a body property rather than a payload property, as is done in the hapi framework.

correct way to use Stripe's stripe_account header from oauth with meteor

I'm trying to build a platform based on Meteor that uses Stripe Connect. I want to use the "preferred" authentication method from Stripe (Authentication via the Stripe-Account header, https://stripe.com/docs/connect/authentication) so that I can create plans and subscribe customers on behalf of my users. I cannot get it to work. I tried with a second params object, similar to the exemple in the documentation:
var stripeplancreate = Meteor.wrapAsync(Stripe.plans.create, Stripe.plans);
var plan = stripeplancreate({
amount: prod.price,
interval: prod.interv,
name: prod.name,
currency: prod.curr,
id: prod.id+"-"+prod.price+"-"+prod.curr+"-"+prod.interv,
metadata: { prodId: prod._id, orgId: org._id },
statement_descriptor: prod.descr
},{stripe_account: org.stripe_user_id});
but I get "Exception while invoking method 'createStripeProduct' Error: Stripe: Unknown arguments ([object Object]). Did you mean to pass an options object? See https://github.com/stripe/stripe-node/wiki/Passing-Options." which does not seem to accurately reflect the issue but prompted me to try adding stripe_account in the params object itself:
var stripeplancreate = Meteor.wrapAsync(Stripe.plans.create, Stripe.plans);
var plan = stripeplancreate({
amount: prod.price,
(...)
statement_descriptor: prod.descr,
stripe_account: org.stripe_user_id
});
I then get the following error: "Exception while invoking method 'createStripeProduct' Error: Received unknown parameter: stripe_account"
Any ideas? Has anybody managed to have Stripe Connect stripe_account authentication work with Meteor, especially with Meteor.wrapAsync(...)?
This should work for wrapAsync, HOWEVER check out my answer here for possible issues with wrapAsync - Wrapping Stripe create customer callbacks in Fibers in Meteor:
Here is also a great video on wrapAsync: https://www.eventedmind.com/feed/meteor-meteor-wrapasync
var createStripePlanAsync = function(shoppingCartObject, callback){
stripe.plans.create({
amount: shoppingCartObject.plan.totalPrice,
interval: shoppingCartObject.plan.interval,
name: shoppingCartObject.plan.planName,
currency: "usd",
id: shoppingCartObject.plan.sku //this ID needs to be unique!
}, function(err, plan) {
// asynchronously called
callback(err, plan);
});
};
var createStripePlanSync = Meteor.wrapAsync(createStripePlanAsync);
var myShoppingCart = {
customerInfo: {
name: "Igor Trout"
},
plan: {
totalPrice: 5000,
interval: "month",
name: "Set Sail For Fail Plan",
sku: "062015SSFF"
}
};
// Creates the plan in your Stripe Account
createStripePlanSync(myShoppingCart);
Later when you subscribe a customer to a plan you just refer to the plan via the id that you gave the plan when you first created it.
After much trying multiple things, for now, I just managed to get it working using the stripe-sync package instead of the "normal" one + wrapAsync.
try{
var plan = Stripe.plans.create({
amount: prod.price,
...
},{stripe_account: org.stripe_user_id});
}catch(error){
// ... process error
}

Twitter update-status with media

I have a requirement to update twitter status with media . I am using following Twitter API for it.
https://dev.twitter.com/docs/api/1.1/post/statuses/update_with_media.
Doing this with nodejs twit library "https://github.com/ttezel/twit"
twit = new Twit({
consumer_key: TWITTER_OAUTH_KEY
, consumer_secret: TWITTER_OAUTH_SECRET
, access_token: 'access token'
, access_token_secret: 'secret'
});
wallpost = {};
wallpost.status = 'media upload1 deliverdfd\nhttp://www.animalplanet.com/';
wallpost.media = [{
"media_url": "http:\/\/pbs.twimg.com\/media\/A7EiDWcCYAAZT1D.jpg",
"media_url_https": "https:\/\/pbs.twimg.com\/media\/A7EiDWcCYAAZT1D.jpg",
"url": "http:\/\/t.co\/bAJE6Vom",
"display_url": "pic.twitter.com\/bAJE6Vom",
"expanded_url": "http:\/\/twitter.com\/BarackObama\/status\/266031293945503744\/photo\/1",
"type": "photo",
}];
My post request
twit.post( "update_with_media", wallpost, function(err, res2) {
if (err) {
return next(err);
}
console.info(res2);
// returns the post id
res.json({
status: 200,
info: "OK",
id: res2.id
});
});
Am getting an error message [{"code":195,"message":"Missing or invalid url parameter"}]}.
I have googled it found some threads some of them mentioning about set content type multipar form data. But i don't know how to set content type.
I have tried
var multipart = [{
"Content-Type": "multipart/form-data"
}];
wallpost.content_type = multipart;
not working for me. Please help me to solve this issue. Thank you
From the documentation you linked to
Supported image formats are PNG, JPG and GIF, including animated GIFs of up to 3MB . This data must be either the raw image bytes or encoded as base64.
You can only upload images - not links to images. Save an image locally and add it to media as a base64 encoded string.
You can not send links - even to Twitter images.

Categories

Resources