shopify app development changing graphql API version - node.js

I am trying to change the version of the graphql API the app is using.
setup:
shopify CLI ver 2.15.6
type node.js
in code I cannot see the URL the app is calling, is there an ENV or some server side
settings to change to the latest API version?
on next.js I see this on the server/client.js
export const createClient = (shop, accessToken) => {
return new ApolloClient({
uri: `https://${shop}/admin/api/2019-10/graphql.json`,
but this is not used in embedded app bridge calls.
I would like to use the 2022-04 (latest) version

I think you need to initialise it using the context, according to the docs
While setting up Context, you'll be able to set which version of the
Admin API your app will be using.
Shopify.Context.initialize({
API_KEY,
API_SECRET_KEY,
SCOPES: [SCOPES],
HOST_NAME: HOST.replace(/https:\/\//, ""),
IS_EMBEDDED_APP: {boolean},
API_VERSION: ApiVersion.{version} // all supported versions are available, as well as "unstable" and "unversioned"
});

Related

Datastax Astra netlify and react-app, should I use nodejs client or REST API for serverless functions?

I built a simple react app with "create-react-app" and I want to use serverless functions with netlify.
I use DataStax Astra Cassandra DB for that purpose, and created a netlify.toml config and .env variables (for the Database) inside my react project.
I set up a serverless functions folder for netlify:
const { createClient } = require('#astrajs/collections')
// create an Astra client
exports.handler = async function (event, context) {
try {
const astraClient = await createClient({
astraDatabaseId: process.env.ASTRA_DB_ID,
astraDatabaseRegion: process.env.ASTRA_DB_REGION,
applicationToken: process.env.ASTRA_DB_APPLICATION_TOKEN,
})
// const basePath = `/api/rest/v2/KEYSPACES/${process.env.ASTRA_DB_KEYSPACE}/collections/messages`
const messagesCollection = astraClient
.namespace(process.env.ASTRA_DB_KEYSPACE)
.collection('messages')
const message = await messagesCollection.create('msg1', {
text: 'hello my name is Marc!',
})
return {
statusCode: 200,
body: JSON.stringify(message),
}
} catch (e) {
console.error(e)
return {
statusCode: 500,
body: JSON.stringify(e),
}
}
it works when I run netlify dev , then my .env variables are injected into the .js file.
However, I am wondering if I should use the nodejs datastax collections here, or the REST API functions from datastax (https://docs.datastax.com/en/astra/docs/astra-collection-client.html)? Because with react, it's essentially running in the browser or not? I am wondering why this still works with nodejs (because its not a nodejs environment with react, or is it?)
I am getting access to my functions via localhost:8888/.netlify/functions/functionName is this served from a nodejs server or is it browser stuff?
it works when I run netlify dev , then my .env variables are injected into the .js file. However, I am wondering if I should use the nodejs datastax collections here, or the REST API functions from datastax (https://docs.datastax.com/en/astra/docs/astra-collection-client.html)? Because with react, it's essentially running in the browser or not?
Correct - you would expose your Astra credentials to the world if you connect to your database directly from your React app.
I am wondering why this still works with nodejs (because its not a nodejs environment with react, or is it?) I am getting access to my functions via localhost:8888/.netlify/functions/functionName is this served from a nodejs server or is it browser stuff?
Netlify functions run serverside so it is safe to connect to Astra in your function code. Here's an example: https://github.com/DataStax-Examples/todo-astra-jamstack-netlify/blob/master/functions/createTodo.js

How to make a post using WATSON and Node js?

I want to make a POST (add a new task) through chatting with Watson.
I have the POST function which works very well, I tested it on Postman. And I have the Watson nodes created.
Here is my endpoint from the POST in Node js:
MainRouter.post('/welcome', (req, res) => {
TaskPost.postTask(req.body).then(message => {
return res.json(message);
}).catch((error) => {
return res.status(404).json(error);
});
});
Here is my conversation with Watson (is working very well):
I also included this in the main.js and changed the password and url:
const AssistantV2 = require('ibm-watson/assistant/v2');
const { IamAuthenticator } = require('ibm-watson/auth');
const assistant = new AssistantV2({
authenticator: new IamAuthenticator({ apikey: '<apikey>' }),
serviceUrl: 'https://api.us-south.assistant.watson.cloud.ibm.com',
version: '2018-09-19'
});
How do I make this connection ? What do I have to include?
I would recommend the official Node.js SDK for the IBM Watson services. It includes support for Watson Assistant and is easy to use.
If you still want to use the V2 API directly, then take a look at how the SDK utilizes the API. As alternative, the API docs for Watson Assistant have code snippets for Node.js.
The basic flow is that you authenticate, then establish a session, and finally send messages with the user input to Watson Assistant.
To get to your dialog node with the task, the user (or your code) would need to send the right intents and entities for navigating from the root node to that specific subnode.

React native and IBM Watson

I have been using expo to build a react native app and would like to integrate an IBM Watson chatbot onto my platform. When I import the module however I receive a lot of error messages as core node modules such as os and fs seem to be missing, but aren't downloaded with node.js for some reason. When I try and add these manually, the HTTPS module is missing the index.js file. Is there any way for me to find this file or resolve this problem another way?
It's not completely clear from your question but I shall assume that you are using the Node SDK for Watson Assistant. This is designed to be run in a Node.js environment which a react native JavaScript bundle is not (with or without expo). That's why you are missing key libraries like os and fs which the Node SDK expects. Installing fs won't resolve your problem because it also expects a Node.js environment to work, hence why there are react native specific fs libraries that are able to use ios and android code to interact with the file system of the phone.
What you should be attempting is running the Node SDK on an independent server and running simple api requests using libraries like axios or for more robust production systems graphql so that your architecture will approximate this high level design.
a high level architecture diagram which shows a phone connected by an arrow reading axios api request to another box labelled cloud hosted server. From this box another arrow labelled Node SDK is pointing to another box labelled Watson Assistant
Web applications are similarly limited. The code run on the user's browsers can't directly use the Watson Assistant SDK, these requests to Watson Assistant need to be run by a server. There is an example starter Watson Assistant web application that does this. If you run or host this application you can use the same server for your requests (although bear in mind this simple app and shared traffic probably isn't scalable for anything but a proof of concept).
So rather than running the api requests to Watson Assistant directly you run them to this domain of the server and then the necessary endpoint. The server in the example app is set up to accept requests to start the session at <your domain>/api/session and to send messages at <your domain>/api/message
You optionally can run direct api calls to Watson Assistant from a react native app without the SDK. It's not advisable because you would need to store your private keys on the device where they could be viewed by anyone.
Here is a functional component that is able to complete api calls direct to Watson Assistant using the v1 of the message tool without the SDK. BUT IT IS NOT ADVISED BECAUSE I MUST STORE MY KEYS INSECURELY.
import React, { useState } from 'react';
import { View, Text, TouchableOpacity } from 'react-native';
import axios from 'axios';
import base64 from 'react-native-base64';
const workspace = ''; //replace with your own workspace id
const key = ''; //replace with your own key
const encodedKey = base64.encode(`apikey:${key}`);
// the following url will be different depending on where you host your Watson Assistant
// this is for Frankfurt as an example hence eu-de in the domain name
const assistantInstance =
'https://api.eu-de.assistant.watson.cloud.ibm.com/instances/<This is your own>/v1'; //replace with your own
const ExampleComponent = () => {
const [response, setResponse] = useState('');
const sendMessage = () => {
axios
.post(
`${assistantInstance}/workspaces/${workspace}/message?version=2018-09-20`,
{
input: { text: 'This is the message' },
},
{
headers: {
Authorization: `Basic ${encodedKey}`,
'Content-Type': 'application/json',
},
},
)
.then((data: any) => {
console.log(data);
setResponse('Got response');
})
.catch((err: any) => {
console.log(err);
setResponse('Got an error');
});
};
return (
<View>
<Text>{response}</Text>
<TouchableOpacity
onPress={() => {
sendMessage();
}}
>
Send message
</TouchableOpacity>
</View>
);
};
export default ExampleComponent;
The next complication you will find is that you will need to add code to store the context returned in the response otherwise your state is lost. Your body would end up looking something like
{
input: { text: 'This is the message' },
context: savedContextObject
},
The newer version of the API has a stateful version which you may want to use instead. You can use this axios as a pattern for constructing whatever requests your prefer.
For the third and final time PLEASE DO NOT SAVE TO THE JS FILE YOUR API KEY as I do here. This is just as an example and for proof of concepts. Anyone who downloads your app will be able to unzip your apk and read these strings in your generated JS bundle unencrypted!

How to fix TypeError when using signInWithCredential on node.js? [EDIT: bug in Firebase 6.2.2]

I am trying to sign in to firebase using a Google Id Token, as I'm developing an app that will be running on a raspberry pi, but when trying to sign in using the received token firebase crashes when using signInWithCredential. Here's my minimal reproducible example
var firebase = require("firebase/app");
require("firebase/auth");
const firebaseConfig = {
...
};
// Initialize Firebase
firebase.initializeApp(firebaseConfig);
const id_token = "A_GOOGLE_ID_TOKEN";
var credential = firebase.auth.GoogleAuthProvider.credential(id_token);
firebase.auth().signInWithCredential(credential);
and it crashes with
TypeError: this.f is not a constructor
at ai.a (C:\Dev\Crashing\node_modules\#firebase\auth\dist\auth.js:188:361)
at yh (C:\Dev\Crashing\node_modules\#firebase\auth\dist\auth.js:171:191)
at bi.o (C:\Dev\Crashing\node_modules\#firebase\auth\dist\auth.js:193:175)
at ji (C:\Dev\Crashing\node_modules\#firebase\auth\dist\auth.js:191:239)
at C:\Dev\Crashing\node_modules\#firebase\auth\dist\auth.js:197:181
at new C (C:\Dev\Crashing\node_modules\#firebase\auth\dist\auth.js:18:736)
at pi (C:\Dev\Crashing\node_modules\#firebase\auth\dist\auth.js:197:161)
at C:\Dev\Crashing\node_modules\#firebase\auth\dist\auth.js:209:203
at e.g (C:\Dev\Crashing\node_modules\#firebase\auth\dist\auth.js:22:101)
at Kb (C:\Dev\Crashing\node_modules\#firebase\auth\dist\auth.js:25:195)
I tried it with several valid ID Tokens, but it seems that part is actually not broken, the credential itself appears to be fine, because signInWithCredential dies the same way even when I pass an arbitrary string as the id_token.
What am I doing wrong? Or could it possibly be an issue with Firebase JS SDK itself?
I am working on Windows 10, ver. 1809, running Node v10.15.3 and firebase JS SDK 6.2.2 (npm firebase package).
EDIT: I tried Firebase JS SDK version 6.2.0 and the code worked as expected! There is a bug in version 6.2.2 though.
Firebase JS SDK 6.2.3 was just released today, and it fixes this bug:
https://firebase.google.com/support/release-notes/js#authentication
Look like this is the git commit that fixes it:
https://github.com/firebase/firebase-js-sdk/commit/728f4f54b4589c07a2d474deb94328a332c8fe39
I verified it with this mocha unit test:
const firebase = require('../../firebaseApp')
const chai = require('chai')
describe('firebase javascript sdk', () => {
// This unit test verifies that the error message is as expected,
// and not the error "this.f is not a constructor", which was caused
// by a bug in version 6.2.1, and fixed in versin 6.2.3.
// https://stackoverflow.com/questions/56716255/how-to-fix-typeerror-when-using-signinwithcredential-on-node-js-edit-bug-in-f
it('should be able to checkActionCode', () => {
return firebase.auth().checkActionCode('xyz')
.catch(error => {
// https://stackoverflow.com/questions/56716255/how-to-fix-typeerror-when-using-signinwithcredential-on-node-js-edit-bug-in-f
chai.assert.equal(error.message,
"The action code is invalid. This can happen if the code is malformed, expired, or has already been used.")
})
})
})
The Firebase client SDKs generally do not work with nodejs. Firebase Authentication depends heavily on running inside a web browser in order to work correctly.
If you're running node, you might want to consider just using the Firebase Admin SDK to access your project without having to sign in.

Calling Watson Conversation API from behind a Proxy server using Node.js

I am using Watson Node.js SDK https://www.npmjs.com/package/watson-developer-cloud to send a message to Watson Conversation service, but I'm behind a http proxy and not able to reach to the Watson service. How might we configure proxy details (either inside or outside of Node.js) so that the the outbound API call can be made?
var Watson = require( 'watson-developer-cloud/conversation/v1' ); // watson sdk
// Create the service wrapper
var conversation = new Watson( {
username: '<username>',
password: '<password>',
url: 'https://gateway.watsonplatform.net/conversation/api',
version_date: '2016-09-20',
version: 'v1'
});
conversation.message( payload, function(err, data) {
...
});
Not completely sure about this but can you set the environment variable for http_proxy? I believe that this should force the use of the proxy regardless of the what the developer cloud module does.
process.env.http_proxy = "https://YOUR_PROXY_HOST:YOUR_PROXY_PORT";
If that works you should set the variable using:
npm set <key> <value>

Resources