Pusher - with Wix HTTP Functions - pusher

I am trying to integrate Pusher with the Wix HTTP Functions
For example:
A GET request is made to the Wix site ( path: '/findItems' ). After the request is made, I want to check for new insertion of items in the database. This, I found, I could do with the afterInsert hook. When the hook is hooked, I want to trigger the Pusher.
This is the code I am currently using http-functions.js:
import { ok, created, notFound, serverError } from 'wix-http-functions';
import wixData from 'wix-data';
import Pusher from "pusher";
const pusher = new Pusher({
appId: "xxxxx",
key: "xxxxxxxxxxxxxxx",
secret: "xxxxxxxxxxxx",
cluster: "xxxx",
useTLS: true
});
export function get_findItems(request) {
let options = {
"headers": {
"Content-Type": "application/json"
}
};
return wixData.query("users")
.eq("firstName", request.path[0])
.eq("lastName", request.path[1])
.find()
.then((results) => {
if (results.items.length > 0) {
options.body = {
"items": results.items
};
return ok(options);
}
options.body = {
"error": `'${request.path[0]} ${request.path[1]}' was not found`
};
return notFound(options);
})
.catch((error) => {
options.body = {
"error": error
};
return serverError(options);
});
}
export function post_newItem(request) {
let options = {
"headers": {
"Content-Type": "application/json"
}
};
return request.body.text()
.then( (body) => {
return wixData.insert("users", JSON.parse(body));
} )
.then( (results) => {
options.body = {
"inserted": results
};
return created(options);
} )
.catch( (error) => {
options.body = {
"error": error
};
return serverError(options);
} );
}
export function users_afterInsert(item, context) {
let hookContext = context;
pusher.trigger("channel", "action", {
firstName: item.firstName,
lastName: item.lastName
});
return item;
}
But unfortunately, Pusher does not get triggered. After Debugging, I found that the Pusher package is installed and working but not triggering only in the afterInsert hook!
Any help is greatly appreciated!
Thanks !

The code for the afterInsert hook needs to be in a backend file named data.js, not in the http-functions.js file as you have it now.

Related

createAysncThunk in Redux Toolkit catching error when making fetch request

I'm working on the user registration functionality of an application using Typescript and Redux Toolkit. When I make the fetch request to the signup endpoint, a new user is saved to the database I've connected, but I keep entering the catch error block.
export const registerUser = createAsyncThunk(
"user/registerUser",
async (form: { username:string, password:string }, thunkAPI) => {
try {
const response = await fetch('/api/auth/signup', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
userInfo: {
username: form.username,
password: form.password
}
}),
});
if (response.status === 200) return 200;
else return 400;
} catch (e) {
console.log('Error')
}
}
);
I've tried logging the response to the console a number of ways
const data = await response.json() console.log(data)
But have had no luck. I think this is an error with how I've done my fetch request using createAsyncThunk but haven't been able to figure out what I've missed.
This is the code for the initial state and slice:
interface UserState {
userProfile: {
id: number | null;
},
registration: {
status: 'loaded' | 'loading'
}
}
const initialState : UserState = {
userProfile: {
id: null,
},
registration: {
status: 'loaded'
}
};
export const userSlice = createSlice({
name: 'user',
initialState,
reducers: {
},
extraReducers: (builder) => {
builder.addCase(registerUser.fulfilled, (state) => { state.registration.status = 'loaded' }),
builder.addCase(registerUser.rejected, (state) => { state.registration.status = 'loaded' }),
builder.addCase(registerUser.pending, (state) => { state.registration.status = 'loading' })
}
})
And here is the code for the function where the action is dispatched on the UI
const handleRegister= async () => {
if (!username) return alert('Username field was left empty');
if (!password) return alert('Password field was left empty');
const {payload} : any = await dispatch(registerUser({ username: username, password: password}));
if (payload === 200) {
alert('Successfully registered. Redirecting to dashboard');
return navigate('/dashboard');
} else { return alert('User creation unsuccessful'); }
}
Appreciate any help as I've looked through many other posts but haven't been able to resolve my issue.

One signal push notification node js API

Push notification node js API using One signal
Hello guys, I've watched a tutorial to implement push notifications on flutter app project.
the code I'll show is how to set up a push notification on node js API using one signal.
I need help to know how to view the notification using One Signal API.
here is the notification service folder
notification.services.js
const { ONE_SIGNAL_API_KEY } = require('../utils/config')
const { info } = require('../utils/logger')
const sendNotification = async (data, callback) => {
const headers = {
'Content-Type': 'application/json; charset=utf-8',
Authorization: 'Basic ' + ONE_SIGNAL_API_KEY,
}
const options = {
host: 'onesignal.com',
port: 443,
path: '/api/v1/notifications',
method: 'POST',
headers: headers,
}
const https = require('https')
const req = https.request(options, res => {
res.on('data', data => {
info(JSON.parse(data))
return callback(null, JSON.parse(data))
})
})
req.on('error', e => {
return callback({
message: e,
})
})
req.write(JSON.stringify(data))
req.end()
}
here is the notification controller folder
notification.controller.js
const { ONE_SIGNAL_APP_ID } = require('../utils/config')
const notificationsService = require('../services/notifications.services')
const sendNotification = (req, res, next) => {
const message = {
app_id: ONE_SIGNAL_APP_ID,
headings: { en: 'All Devices' },
contents: { en: 'Send push notifications to all devices' },
included_segments: ['All'],
content_available: true,
small_icon: 'ic_notification_icon',
data: {
// eslint-disable-next-line quotes
PushTitle: "Porc'Ivoire",
},
}
notificationsService.sendNotification(message, (error, results) => {
if (error) {
next(error)
}
return res.status(200).send({
message: 'Success',
data: results,
})
})
}
const sendNotificationToDevice = (req, res, next) => {
var message = {
app_id: ONE_SIGNAL_APP_ID,
headings: { en: '🤑 Paiement accepté' },
contents: {
en: 'Votre paiment a été effrctué avec succès',
},
included_segments: ['included_player_ids'],
include_player_ids: req.body.devices,
content_available: true,
small_icon: 'ic_notification_icon',
data: {
// eslint-disable-next-line quotes
PushTitle: "Porc'Ivoire",
},
}
notificationsService.sendNotification(message, (error, results) => {
if (error) {
next(error)
}
return res.status(200).send({
message: 'Success',
data: results,
})
})
}
module.exports = {
sendNotification,
sendNotificationToDevice,
}

Return from module is undefined

Hi I made a module and when I try to return the song name it is just undefined, the console.log just before it works though so I'm a little confused. The line after console.log(`"${songName}" by ${artistsList}`) is where the issue is, I try to return "${songName}" by ${artistsList} but the return is just undefined so I am a little stuck on why
Code: (This is the spotify.js module)
I call it with const Spotify = require("./spotify.js"), everything works up until I need to just return the song name using the Spotify.request() function
const axios = require("axios");
module.exports = {
token: "",
ref: "",
refresh: function () {
axios({
method: "post", //you can set what request you want to be
url: "https://accounts.spotify.com/api/token",
data:
`grant_type=refresh_token&refresh_token=${this.ref}`,
headers: {
Authorization:
"Basic ",
"Content-Type": "application/x-www-form-urlencoded"
}
}).then(response => {
this.token = response.data.access_token
console.log(`Successfully refreshed token ${module.exports.token}`);
});
},
analyseSong: function (data) {
console.log(data)
const x = data;
//console.log(x)
if (x.is_playing) {
const songNameMatch = x.item.name.split("(");
var songName = x.item.name;
try {
const letter = songNameMatch[1].charAt(0);
letter.toLowerCase() == "f" ||
songNameMatch[1].toLowerCase().match(/^with/)
? (songName = songNameMatch[0].trim())
: false;
} catch (err) {
false;
}
var artistArray = [];
var artist;
const artists = x.item.artists;
//console.log(token)
for (artist in artists) {
artistArray.push(x.item.artists[artist].name);
}
//console.log(artistArray)
const artistsList = artistArray.join(", ");
//console.log(artistsList)
//console.log(`Currently playing: ${songName} - ${artistsList}`);
console.log(`"${songName}" by ${artistsList}`)
return `"${songName}" by ${artistsList}`;
} else {
return `Not currently listening to a song`;
}
},
request: function () {
axios
.get("https://api.spotify.com/v1/me/player/currently-playing", {
headers: { Authorization: `Bearer ${this.token}` }
})
.then(function (response) {
module.exports.analyseSong(response.data);
})
},
}
So I'm doing X=Spotify.request() trying to get the song name as X so I can output using IRC chat
There are a couple problems. .request() has no return value at all. So, it will never return anything other than undefined. You can fix that like this by adding two return statements, the first to return the promise itself and the second to make the return value from analyseSong() be the resolved value of that promise:
request: function () {
return axios
.get("https://api.spotify.com/v1/me/player/currently-playing", {
headers: { Authorization: `Bearer ${this.token}` }
})
.then(function (response) {
return module.exports.analyseSong(response.data);
})
},
Now Spotify.request() will return a promise that will resolve with the value returned from .analyseSong(response.data). You would use that promise like this:
Spotify.request().then(result => {
console.log(result);
}).catch(err => {
console.log(err);
});

Set Mock Response for JWT Module NodeJS

I am writing Test case using JEST in NodeJs inside AzureFunction.
Im trying to mock JWT module outcome inside my index.test.js , however its not working and getting timedout. I wonder is it the return datatype mismatch? How to set response similar to cb of jwt verify method?
Here is my sample code. Please suggest!
Index.js
const JWT = require('./jwtDecoder')
module.exports = function(context, req) {
try {
JWT(req.body, process.env.jwtsecret, function(err, decoded) {
if (err) {
context.log("Invalid JWT::" + req.body);
context.res = {
headers: {
'Content-Type': 'application/json'
},
status: 400,
body: {
"error": err
}
};
context.done();
} else {
context.log("JWT Authentication Successful:");
context.res = {
headers: {
'Content-Type': 'application/json'
},
status: 200,
body: {
"message": "success"
}
};
context.done();
}
});
} catch (err) {
context.log("Exception in main function, PushHttpFunction:" + err);
context.res = {
headers: {
'Content-Type': 'application/json'
},
status: 500,
body: {
"error": err
}
};
context.done();
}
}
jwtDecoder.js
'use strict';
module.exports = (body, secret, cb) => {
console.log('inside jwtDecoder');
if (!body) {
return cb(new Error('invalid jwt data'));
}
require('jsonwebtoken').verify(body.toString('utf8'), secret, { algorithm: 'HS256' }, cb);
};
index.test.js
let indexTest = require('../index')
const { runStubFunctionFromBindings } = require('stub-azure-function-context')
let JWT = require('../jwtDecoder')
jest.mock("../jwtDecoder.js")
/* verify.mockImplementation(() => () => ({
err: new Error('invalid jwt data'),
decoded: 'ok'
})); */
JWT.mockImplementation(() => new Promise(function(resolve, reject) {
resolve('ok');
}));
beforeAll(() => {
process.env = Object.assign(process.env, {
NODE_ENV: "test",
});
});
describe('Simple Testing', () => {
test('return 200 by mocking simpleFunc response" ', async() => {
let request = {
body: "dummy.jwt.zT5p"
};
const context = await runStubFunctionFromBindings(indexTest, [
{ type: 'httpTrigger', name: 'req', direction: 'in', data: request },
{ type: 'http', name: 'res', direction: 'out' },
], new Date());
console.log('mockedResp::', context);
expect(context.res.status).toEqual(200);
}, 30000);
});
Basically you are mocking wrong, you can keep only this line:
jest.mock('./jwtDecoder.js', () => (res, req, cb) => cb(null, 'ok'))
as you need to mock callback
and remove all this part:
jest.mock("../jwtDecoder.js")
JWT.mockImplementation(() => new Promise(function(resolve, reject) {
resolve('ok');
}));

Using React, NodeJS, and Postgres: Having trouble being able to delete and updating todos

I am creating simple todo app with postgre and react.
The server side the delete and update are defined as below.
app.put("/todos/:id", async (req, res) => {
try {
const { id } = req.params;
const { description } = req.body;
const updateTodo = await pool.query(
"update todo set description = $1 where todo_id = $2",
[description, id]
);
res.json("todo updated !!");
} catch (error) {
console.error(error.message);
}
});
// delete todo
app.delete("/todos/:id", async (req, res) => {
try {
const { id } = req.params;
const deleteTodo = await pool.query("delete from todo where todo_id = $1", [
id,
]);
res.json("todo deleted !!");
} catch (error) {
console.error(error.message);
}
});
On the front end (React) this is how I am calling the update and delete
const updateDescription = async () => {
try {
handleClose();
const body = { description };
const response = fetch(`http://localhost:3000/${todo.todo_id}`, {
method: "PUT",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(body),
});
console.log(response);
} catch (error) {
console.log(error.message);
}
};
Delete todo is in the other component.
const deleteTodo = async (id) => {
try {
const deleteTodo = await fetch(`http://localhost:3000/${id}`, {
method: "DELETE ",
});
console.log(deleteTodo);
setTodods(todos.filter((todo) => todo.todo_id !== id));
} catch (error) {
console.log(error.message);
}
};
So when I am doing delete or put request its not updating it in the DB.
On the browser console I am getting this error.
Failed to execute 'fetch' on 'Window': 'DELETE ' is not a valid HTTP method.
Edited
Response {type: "cors", url: "http://localhost:3000/3", redirected: false, status: 404, ok: false, …}
body: (...)
bodyUsed: false
headers: Headers {}
ok: false
redirected: false
status: 404
statusText: "Not Found"
type: "cors"
url: "http://localhost:3000/3"
__proto__: Response
For insert todo its working but for delete and put request its not updating in the database.
So can somebody tell me whats going wrong here ?
There is a space after DELETE, correct it should work properly. Even if its a simple todo App, its always good practice to create an enum or const when we are dealing with fixed string, i.e., we know the string would not change so that we can have consistency and skip over these kind of issues.
const METHOD = {
GET: "GET",
PUT: "PUT",
POST: "POST",
DELETE: "DELETE"
};

Resources