Google search API wrapper for Node.js - node.js

I am looking for a Google search API wrapper to be used in Node.js, I have searched around but haven't found something updated and fully baked. Can anyone please recommend something working?
Thanks

Why aren't you using node client lib for Google APIs? https://github.com/google/google-api-nodejs-client
var googleapis = require('googleapis');
googleapis.discover('customsearch', 'v1').execute(function(err, client) {
// set api key
client.withApiKey('...');
client.search.cse.list({ q: '...' }).execute(console.log);
});

I'm assuming you are not referring to the deprecated Google Web Search API...
The Google Custom Search API is a RESTful API. This means that you can easily access it without a specialized wrapper.
There are a couple of modules that make this easier. The one I usually use is the request module, which lets you make HTTP requests very simply.

I just used node-google-images and it worked right away in less than 2 minutes:
https://github.com/vdemedes/node-google-images
Just call
npm install google-images
and then
client = require( 'google-images' );
client.search( 'Chicken Teriyaki', function (err, images) {
console.log(images)
});
will return
[ { width: '1920',
height: '1280',
url: 'http://www.springkitchenrestaurant.com/Chicken_Teriyaki.jpg',
writeTo: [Function] }]
(actually, it will return 4 results but stackoverflow prevents me from posting more than 2 links... - you get the gist!)

You can use jsearch module. Install with:
npm install jsearch
Usage:
js.google('queryStringYouWant',10,function(response){
console.log(response) // for Google results
})

You can use a third-party service like SerpApi with its Node.js library to scrape Google and get back structured JSON.
To install it:
npm install google-search-results-nodejs
Code example:
var gsr = require('GoogleSearchResults')
let serp = new gsr.GoogleSearchResults()
query_params = {
q: "query",
google_domain: "Google Domain",
location: "Location Requested",
device: device,
hl: "Google UI Language",
gl: "Google Country",
safe: "Safe Search Flag",
num: "Number of Results",
start: "Pagination Offset",
serp_api_key: "demo"
}
callback = function(data) {
console.log(data)
}
// Show result as JSON
serp.json(query_params, callback)
// Show results as JSON with Images
serp.jsonWithImages(query_params, callback)
// Show result as HTML file
serp.html(query_params, callback)

Related

Mailchimp and Node.js with typescript noob question: Import vs Require

I am creating an app that sends certain transactional emails using Mailchimp.
They have great docs here: https://mailchimp.com/developer/api/transactional/messages/send-using-message-template/
But Im using typescript, so the line:
var mailchimp = require("mailchimp_transactional")("API_KEY");
Doesn't work, I get the following error:
Error: Cannot find module 'mailchimp_transactional'
I know this is something small, but I am not sure how to get around it at all. I found an article that describes creating your own types file here: #mailchimp/mailchimp_marketing/types.d.ts' is not a module in nodeJs
But there has to be a quicker simpler solution. It also doesn't make it clear how to set the API key in that case.
I have tried to import the module which is #mailchimp/mailchimp_transactional which did not work.
I have ofcourse also run npm install #mailchimp/mailchimp_transactional
Any help would be appreciated, here is a full sample just incase it helps.
var mailchimp = require("mailchimp_transactional")("API_KEY");
export const testSendEmailFromTemplate = async () => {
let mcbody = {
template_name: "my-template",
template_content: [{
name:"firstname",
content:"INJECTED.BY.TEMPLATE.CONT.firstname"
},
{
name:"surname",
content:"INJECTED.BY.TEMPLATE.CONT.surname"
}],
message: {
to:{
email:"email#gmail.com",
name: "Test",
type: "to"
}
},
async:true
};
return await mailchimp.messages.sendTemplate(mcbody);
}
If anyone is unfortunate enough to face this issue because Mailchip's docs don't cater to the typescript setup, and you aren't sure how to make it 'just work' here is the answer:
const mailchimpFactory = require("#mailchimp/mailchimp_transactional/src/index.js");
const mailchimp = mailchimpFactory("PUTKEYHERE");
This pulls in the javascript file directly and then the second line initialises the object.
Good luck all!
As of March 2022 the types have been added to DefinitelyTyped and can be accessed by running
npm install --save-dev #types/mailchimp__mailchimp_transactional
I had the same problem in a node/Typescript project, but this is working for me:
const mailchimp = require('#mailchimp/mailchimp_marketing')
export class MailchimpServices {
constructor() {
mailchimp.setConfig({
apiKey: '...',
server: 'us5',
});
}
async ping() {
console.log('Start mailchimp ping!')
const response = await mailchimp.ping.get();
console.log(response);
}
}

How to get API for TargetingIdeaSelector (Google API to get keyword search data) in Node.JS?

This API is available in other languages, but I want the code in Node.JS.
From this source : https://developers.google.com/adwords/api/docs/guides/targeting-idea-service#python_4
It looks like you have to send a POST request, the problem is the request is build from targetingIdeaService.get function:
targetingIdeaService.get(selector)
The selector itself can be guessed from the docs :
offset = 0
PAGE_SIZE = 10
selector = {
'ideaType': 'KEYWORD',
'requestType': 'IDEAS',
'requestedAttributeTypes':[
'KEYWORD_TEXT',
'SEARCH_VOLUME',
'CATEGORY_PRODUCTS_AND_SERVICES'
],
'paging':{
'startIndex': str(offset),
'numberResults': str(PAGE_SIZE)
},
'searchParameters':[{
'xsi_type': 'RelatedToQuerySearchParameter',
'queries': ['space cruise']
}]
}
But you do not have access to the way the request is constructed from this object.
I would suggest you to use this unofficial googleads node library since it seems to handle targetingIdeaService. Or even this npm package since it has more recent developments.

Google Cloud HTTP function by webhook: Request body is missing data

Im integrating the Zoom API with my Firebase app, and to do so I'm relying on Zooms pre-made webhooks to run an HTTP function on my Firebase for various events like "meeting started" and "meeting ended". Zoom API reference: https://marketplace.zoom.us/docs/guides/webhooks
This is the Google Cloud function that the Zoom API is calling:
exports.zoomTestA = functions.https.onCall((req, res) => {
console.log(req);
let data = req.body;
var xmlData = data.toString();
console.log(xmlData);
});
Here is the payload sent by Zoom:
{
"event": "meeting.ended",
"payload": {
"account_id": "LTf-KjgUTR2df-knT8BVEw",
"object": {
"duration": 0,
"start_time": "2019-05-07T14:02:51Z",
"timezone": "",
"topic": "Alexander Zoom Meeting",
"id": "864370042",
"type": 1,
"uuid": "2h/SWVrrQMu7fcbpLUly3g==",
"host_id": "Ty6ykNolSU2k1N4oc0NRcQ"
}
}
This causes this error to appear in my Google Cloud console:
Request body is missing data. { event: 'meeting.ended',
payload:
{ account_id: 'LTf-KjgUTR2df-knT8BVEw',
object:
{ duration: 0,
start_time: '2019-04-30T14:23:44Z',
timezone: '',
topic: 'Alexander\'s Zoom Meeting',
id: '837578313',
type: 1,
uuid: 'WotbHO3RRpSviETStKEGYA==',
host_id: 'Ty6ykNolSU2k1N4oc0NRcQ' } } }
The request body that Zoom sends is not wrapped in in a "data: {}" tag as required by Google Cloud functions. I've found solutions to this problem if you can control the payload here: Dart json.encode is not encoding as needed by Firebase Function .
My problem is that I am unable to alter the request that the Zoom API sends. Is there any way I can still accept the request in my Google Cloud function? Or is there any way to alter the format of the request sent by Zoom? I'm unable to find references for either.
One potential solution would be to set up another server that receives the request by Zoom, format it to Google Cloud functions specifications, and then pass it on to my Google Cloud function. I would however like to avoid stepping out of the Google Cloud eco-system.
Is this problem solvable on the Google Cloud platform?
So I figured it out. In Firebase / Google Cloud functions you can either make HTTP-functions with
functions.https.onCall((req, res) => {
var data = req.body;
and
functions.https.onRequest((req, res) => {
var data = req.body;
The difference seems to be that onCall is made for being used within the Firebase/ Google Cloud functions environment. However if you wan external functions you need to use onRequest as this does not require specific formatting of the payload.
Using onRequest instead solved all my problems.

Google analytics steps to get number of views per page from an API

I want to start somewhere.
This is my use case.
I have a restAPI written in node.js express framework.
I have a mobile application written in the react native.
Also I have a web application for the administration purpose of the mobile app, written in Vue.js
Mobile app is food app. Where you can search restaurants or dishes of a restaurant.
I want to pass the restaurant id and get the restaurant views of the app with in the last 7 days.
Pretty straight forward requirement. But hard to implement. Since I don't know where to start from.
I went through the docs and have found there are 7 APIs.
Core reporting API
Management API
Embed API
User deletion API
Multi channel reporting API
Real time API
Meta data API
End of the day, I would love to do something similar to this with the API.
showMeTheView(restaurant_id)
Also If I want to pass additional parameter to say get only last month views count.
showMeTheViews(restaurant_id, last_month)
I can't figure out what are the essential steps to achieve my requirement?
What need to be done in the react-native app?
What need to be done in the vue.js web app?
What need to be done in between these two?
First off you should be using the Core reporting api this is the api that can be used to extract data from Google analytics. The Json object used to extract data form Google analytics is quite extensive batch get
It will make your life a lot easier if you use the Google apis node.js client libray
code ripped from sample found here
'use strict';
const {google} = require('googleapis');
const sampleClient = require('../sampleclient');
const analyticsreporting = google.analyticsreporting({
version: 'v4',
auth: sampleClient.oAuth2Client,
});
async function runSample() {
const res = await analyticsreporting.reports.batchGet({
requestBody: {
reportRequests: [
{
viewId: '65704806',
dateRanges: [
{
startDate: '2018-03-17',
endDate: '2018-03-24',
},
{
startDate: '14daysAgo',
endDate: '7daysAgo',
},
],
metrics: [
{
expression: 'ga:users',
},
],
},
],
},
});
console.log(res.data);
return res.data;
}
// if invoked directly (not tests), authenticate and run the samples
if (module === require.main) {
const scopes = ['https://www.googleapis.com/auth/analytics'];
sampleClient
.authenticate(scopes)
.then(runSample)
.catch(console.error);
}
// export functions for testing purposes
module.exports = {
runSample,
client: sampleClient.oAuth2Client,
};

Google+ insert moment with nodejs client

Has anyone been able to get the google-api-nodejs-client to successfully insert a moment?
Whatever I try, I get a generic 400 "Invalid value" error but am unable to narrow down the invalid value because the API Explorer doesn't work either.
Would it be because of the missing data-requestvisibleactions parameter? I'm using passport.js's require('passport-google-oauth').OAuth2Strategy for handling oauth access, and that part is working fine, but I have no idea how to incorporate requestvisibleactions into the oauth request flow since this is definitely not originating from a clientside form.
Here's a snippet of what I'm trying to do (using the latest version of googleapis, v1.0.2):
var google = require('googleapis')
var auth = new google.auth.OAuth2()
auth.setCredentials({
'access_token': user.token
})
google.plus('v1').moments.insert({
collection: 'vault',
userId: 'me',
debug: true,
resource: {
type: "http://schemas.google.com/AddActivity",
target: {
type: "http://schema.org/CreativeWork",
url: "...omitted...",
image: "...omitted...",
description: "test",
name: "test"
}
},
auth: auth
}, function (err, response) {
if (err) {
console.error(err)
res.send(err.code, err)
} else {
console.log(response)
res.send(200)
}
})
ref 1 (out-of-date w.r.t. an older version of googleapis)
ref 2 (client-side, where the use of data-requestvisibleactions is more obvious)
As you speculated, you need the request_visible_actions parameter as part of the URL calling the oauth endpoint.
It looks like the current version of passport-google-oauth doesn't support this parameter. Judging by several of the open issues and pull requests, it isn't clear that the author will respond to requests to add it either. You have two possible options:
Switch to using the OAuth support that is included in google-api-nodejs-client
Patch the passport-google-oauth code. (And possibly submit a pull request in the hopes it will be useful to someone else.)
I don't use passport.js or the passport module in question, so I can't test this, but based on the github repository, I think you can insert the following in lib/passport-google-oauth/oauth2.js after line 136 and before the return statement:
if (options.requestVisibleActions) {
// Space separated list of allowed app actions
// as documented at:
// https://developers.google.com/+/web/app-activities/#writing_an_app_activity_using_the_google_apis_client_libraries
// https://developers.google.com/+/api/moment-types/
params['request_visible_actions'] = options.requestVisibleActions;
}

Resources