I am really struggling with Meteor and the NPM package node-linkedin.
I understand how NPM integration is supposed to work. I added NPM using Meteorite and node-linkedin to packages.js. I am then calling the NPM package through Meteor.require().
Here is my server/linkedin.js file:
function Linkedin(accessToken) {
this.linkedin = Meteor.require('node-linkedin')('api', 'secret', 'callback');
this.accessToken = accessToken;
this.linkedin.init(this.accessToken);
}
Linkedin.prototype.company = function() {
var self = this;
var data = Meteor.sync(function(done) {
self.linkedin.companies.company('162479', function(err, res) {
done(null, res);
});
});
return data.result;
}
Meteor.methods({
getCompanyInfo: function () {
var linkedin = new Linkedin(Meteor.user().services.linkedin.accessToken);
var data = linkedin.company();
return data;
}
});
Unfortunately, it does not work when I call getCompanyInfo()... I get the following error: "Cannot call method 'company' of undefined".
Linkedin Auth works fine (thanks to accounts-linkedin). But I also need to connect to Linkedin API.
I had previously followed this article to play with FB Graph API in Meteor. Everything was fine.
Maybe the problem comes from Metheor.require(). I am wondering what I am supposed to do with the second set of parameters in Metheor.require(). Should I add these npm packages to packages.json as well? Does Method.require() handle this second set of parameters correctly?
Thank you for your help!
Related
I am trying to make a script that takes input from the user, runs it through Dialogflow, then returns it back to the user. The platform I am taking input from only supports Node.js. I am hosting the bot through glitch.com, but I don't think that's what's causing the issue. I wanted to check on here before I submit a bug report onto the GitHub repo.
var bot = 'the platform i use to accept inputs and send outputs'
bot.on("message", async message => {
console.log(message.content); // Log chat to console for debugging/testing
if (message.content.indexOf(config.prefix) === 0) { // Message starts with your prefix
let msg = message.content.slice(config.prefix.length); // slice of the prefix on the message
let args = msg.split(" "); // break the message into part by spaces
let cmd = args[0].toLowerCase(); // set the first word as the command in lowercase just in case
args.shift(); // delete the first word from the args
// You can find your project ID in your Dialogflow agent settings
const projectId = process.env.PROJECT_ID; //https://dialogflow.com/docs/agents#settings
const sessionId = 'quickstart-session-id';
var query = msg;
const languageCode = 'en-US';
// Instantiate a DialogFlow client.
const dialogflow = require('dialogflow');
const sessionClient = new dialogflow.SessionsClient();
// Define session path
const sessionPath = sessionClient.sessionPath(projectId, sessionId);
// The text query request.
const request = {
session: sessionPath,
queryInput: {
text: {
text: query,
languageCode: languageCode,
},
},
};
// Send request and log result
sessionClient
.detectIntent(request)
.then(responses => {
console.log('Detected intent');
const result = responses[0].queryResult;
console.log(` Query: ${result.queryText}`);
console.log(` Response: ${result.fulfillmentText}`);
if (result.intent) {
console.log(` Intent: ${result.intent.displayName}`);
} else {
console.log(` No intent matched.`);
}
})
.catch(err => {
console.error('ERROR:', err);
});
}
return;
});
That is the relevant part of the code. For those wondering, the process.env.PROJECT_ID is something glitch.com uses for anything private. Because I don't want random people getting their hands on my project id, I hide it in there and glitch hides it from anyone I don't explicitly invite.
Every time I execute this and try to query the bot, it returns an error Uncaught Promise Error: TypeError: dialogflow.SessionsClient is not a constructor.
If someone can direct me to what I'm missing, or what the problem is, that would be great!
As per #google-cloud/dialogflow - npm
IMPORTANT NOTE
Version 2.0.0 renames dialogflow to #google-cloud/dialogflow on npm, along with introducing TypeScript types.
So to update the dialogflow to use latest version, first uninstall dialogflow and then install with following command:
npm uninstall dialogflow
npm i #google-cloud/dialogflow
Also, if you were using older version 1.2.0 of dialogflow before then in code, make following changes as per their sample or refer the sample from above link (in require and to get the sessionPath):
const dialogflow = require('#google-cloud/dialogflow');
const sessionPath = sessionClient.projectAgentSessionPath(
projectId,
sessionId
);
It worked fine for me after doing this without any errors.
I figured it out. After many many refreshes, I decided to look at the npm documentation for it. Turns out some idiot listed the earliest version as 4.0.3, and the latest version as 0.7.0. I needed to explicitly tell it to use version 0.7.0 in order for it to work. Thank goodness!
Mine worked by reinstalling the dialogflow package
npm uninstall dialogflow
npm install dialogflow --save
put the code inside try and catch block. In my case by doing this, this error was removed.
Scenario :
I'm trying to create a Firebase Function to add a subscriber to a Mailchimp list using the Mailchimp API but after three days of trying different methods I've had little luck.
Currently my function resembles:
exports.addSubscriber = functions.https.onRequest((req, res) => {
const Mailchimp = require('mailchimp-api-v3')
const mailchimp = new Mailchimp('MY_API_KEY');
mailchimp.post('/lists/'MY_LIST_ID'/members', {
"email_address": 'test#gmail.com',
"status": 'pending'
}).then(function(results) {
console.log('added new user to mailchimp list');
})
.catch(function(err) {
console.log(err);
})
return null
});
When I try to trigger the function it results in a 'crash' with Error: Cannot find module 'mailchimp-api-v3' in the logs.
I've already ran npm install mailchimp-api-v3 in my local Firebase
directory so the module should be available.
Where am I going wrong?
Is there a simpler way to use the Mailchimp API with Javascript?
Try to run
npm install mailchimp-api-v3 --save
It seams the above package is missing.
I downloaded and installed the google apis with npm install googleapis and now i'm trying to access the api in my node js file with this code:
var google = require('googleapis')
var youtube = google.youtube({version: 'v3', auth: API_KEY})
However, when I try to access the videos object, I always get back null. Apparently, the youtube object is corrupted because when I stringify it I get this back:
{"_options":{"auth":"*********"},"activities":{},"captions":{},"channelBanners":{},"channelSections":{},"channels":{},"commentThreads":{},"comments":{},"guideCategories":{},"i18nLanguages":{},"i18nRegions":{},"liveBroadcasts":{},"liveStreams":{},"playlistItems":{},"playlists":{},"search":{},"subscriptions":{},"thumbnails":{},"videoAbuseReportReasons":{},"videoCategories":{},"videos":{},"watermarks":{},"google":{"_options":{},"auth":{"_cachedCredential":null}}}
So all of the little "subobjects" are empty. How do I fix this?
Did you check if the dependency is listed in your package.json file ? If not try npm install --save googleapis which directly adds it to your dependency list
There's nothing worrying in the fact that your youtube variable shows empty objects when stringified, because JSON representation of that object only contains properties that are primitive types. youtube.videos object contains only methods, which are ommited by JSON.stringify.
Try this:
var google = require('googleapis');
var youtube = google.youtube({version: 'v3', auth: API_KEY});
var queryOptions = {
'part': 'id,snippet',
'maxResults': 5,
'id': 'dQw4w9WgXcQ,HL1UzIK-flA'
};
youtube.videos.list(queryOptions, function(err, data) {
if(err) {
console.error(err);
return;
}
console.log(data);
});
For youtube api I use youtube-node and it works fine: https://github.com/nodenica/youtube-node
I'm interested in being able to use the Breeze.js EntityManager and query capabilities within a node console service to access a remote Data Service that exposes an BreezeJS/OData compliant RESTful endpoint.
We currently have a Data Service implemented using Node.js, MongoDB and the Breeze.js breeze-mongodb module.
We have web browser hosted clients that access the MondgoDB using the Breeze.js client API (EntityManager) and the Data Service described above.
I need to create another Node.js service that can access the same MongoDB database that the web browser hosted clients do, and for consistency/simplicity I would like to use the same data acceess API as I am using in the web browser.
Has anyone experimented with this configuration?
I experimented with loading Breeze and its dependencies using the Node.js module infrastructure, but am getting errors when Breeze tries to initialize Angular as an ajax handler. Angular is installed and configured as a node module dependency, but I am getting an error thrown:
Error: [$injector:nomod] http://errors.angularjs.org/1.2.2/$injector/nomod?p0=ngLocale
In theory I shouldn't need angular, but I get additional errors if Angular is not present.
I may be able to debug this particular issue, but it will require stepping through Breeze.js code in detail and possibly modifying it to fix. Was curious if anyone else has gotten this working.
I'm running Breeze in Node at the moment. It used to work just fine without any modification, but a few versions ago they added a check that it's running in the browser... so now I manually remove that check :-)
My use-case is a little bit different: I'm running breeze on the server so that I can use the same business logic as in the client, and just have a really really thin layer between breezejs and the DB.
The only thing I needed to change to get it to run in the browser is add a fake ajax handler that delegates to my skinny DB wrapper - you could equally delegate to anything else, including your existing API.
var ctor = function () {
this.name = 'node';
this.defaultSettings = { };
};
ctor.prototype.initialize = function () {
};
var query = require('../../../../server/db/query');
ctor.prototype.ajax = function (config) {
if (config.url === '/api/all') {
query.get()
.then(function (result) {
var httpResponse = {
data: result,
status: '400',
getHeaders: undefined,
config: config
};
config.success(httpResponse);
})
.otherwise(function (error) {
var httpResponse = {
data: '',
status: '500',
getHeaders: undefined,
error: error,
config: config
};
config.error(httpResponse);
});
} else if (config.url === '/api/SaveChanges') {
query.save(JSON.parse(config.data))
.then(function (result) {
var httpResponse = {
data: result,
status: '400',
getHeaders: undefined,
config: config
};
config.success(httpResponse);
})
.otherwise(function (error) {
var httpResponse = {
data: '',
status: '500',
getHeaders: undefined,
error: error,
config: config
};
config.error(httpResponse);
});
}
};
breezejs.config.registerAdapter('ajax', ctor);
breezejs.config.initializeAdapterInstance('ajax', 'node', true);
It's a good question. We haven't actually tried running Breeze within Node but your use case is interesting. This sounds like a perfect item for the Breeze User Voice. We take these suggestions seriously.
I'm trying to login to my meteor site via a third party library like this one:
https://gist.github.com/gabrielhpugliese/4188927
In my server.js i have:
Meteor.methods({
facebook_login: function (fbUser, accessToken) {
var options, serviceData, userId;
serviceData = {
id: fbUser.id,
accessToken: accessToken,
email: fbUser.email
};
options = {
profile: {
name: fbUser.name
}
};
userId = Accounts.updateOrCreateUserFromExternalService('facebook', serviceData, options);
return userId;
}, ......
In my client.js I have:
facebookLogin: function () {
if (Meteor.user())
return;
if (!Session.equals("deviceready", true))
return;
if (!Session.equals("meteorLoggingIn", false))
return;
// Do not run if plugin not available
if (typeof window.plugins === 'undefined')
return;
if (typeof window.plugins.facebookConnect === 'undefined')
return;
// After device ready, create a local alias
var facebookConnect = window.plugins.facebookConnect;
console.log('Begin activity');
Session.equals("meteorLoggingIn", true);
Accounts._setLoggingIn(true);
facebookConnect.login({
permissions: ["email", "user_about_me"],
appId: "123456789012345"
}, function (result) {
console.log("FacebookConnect.login:" + JSON.stringify(result));
// Check for cancellation/error
if (result.cancelled || result.error) {
console.log("FacebookConnect.login:failedWithError:" + result.message);
Accounts._setLoggingIn(false);
Session.equals("meteorLoggingIn", false);
return;
}
var access_token = result.accessToken;
Meteor.call('facebook_login', result, access_token, function (error, user) {
Accounts._setLoggingIn(false);
Session.equals("meteorLoggingIn", false);
if (!error) {
var id = Accounts._makeClientLoggedIn(user.id, user.token);
console.log("FacebookConnect.login: Account activated " + JSON.stringify(Meteor.user()));
} else {
// Accounts._makeClientLoggedOut();
}
});
});
}, // login
facebookLogout: function () {
Meteor.logout();
// var facebookConnect = window.plugins.facebookConnect;
// facebookConnect.logout();
},
The third party library (Facebook Android SDK in my case) works fine. My problem is after the "var id = Accounts._makeClientLoggedIn(user.id, user.token);" the Meteor.user() returns Undefined. However If I do a page refresh in the browser works fine and the template renders as a logged in user.
Anyone knows how to fix the 'Undefined' on client ??
PS. On server side the users collection looks fine. The meteor token and everything else are there.
Solved. I had to add : this.setUserId(userId.id);
after userId = Accounts.updateOrCreateUserFromExternalService('facebook', serviceData, options); at server.js
Meteor's client side javascript can't run fibers. Fibers allows synchronous code to be used with javascript since by design js is asynchronous. This means there are callbacks that need to be used to let you know when the task is complete.
From what it looks like Accounts._makeClientLoggedIn doesn't take a callback & unfortunately and doesn't return any data looking at its source. I can't say i've tried this myself because I can't test your code without the android sdk but have you tried using Deps.flush to do a reactive flush?
Also Meteor also has very clean and easy facbeook integration. If you simply add the facebook meteor package
meteor add accounts-facebook
You can get access to a lovely Meteor.loginWithFacebook method that can make everything reactive and your code simpler and really easy. If you need to modify it to use the Android SDK Dialog instead you can easily modify the code out as the code for the module is out there for you to hack up to your spec
Edit: If you're using an external SDK such as the java SDK/cordova plugin
Set your plugin so that it redirects to the following URL (set up for meteor.com hosting):
http://yourmeteorapp.meteor.com/_oauth/facebook?display=touch&scope=your_scope_request_params&state=state&code=yourOAuthCodeFromJava&redirect=YourAPP
So in the querystring we have:
scope= Contains your facebook scope params (for permissions)
code= Your OAuth code from the java sdk
redirect=Where to redirect to after once logged in instead of the window.close
state= A cros site forgery state value, any random value will do
This url is basically used to mimic would what be given to the REDIRECT_URI at : https://developers.facebook.com/docs/reference/dialogs/oauth/
This will redirect to meteor's OAuth helper (at https://github.com/meteor/meteor/blob/master/packages/accounts-oauth-helper/oauth_server.js)
So what would happen is you give the OAuth code from Java to meteor, it fetches the OAuth token and the user's data, then redirect the user to a URL in your app