Picking random image from array 60+ choices javascript - javascript

I understand this question has tons of answers already, but I am trying to figure out how to do this in the most efficient way. I have a website that sends an image with a button click to a phone number, but I want to choose between 60 or so photos and manually entering all of these image locations into an array does not seem ideal.
Here is my js file that performs the email action, this is all hosted on a free hosting service.
// server.js
const express = require("express")
const app = express()
app.use(express.static("public"))
app.get("/", (req, res) => {
res.sendFile(__dirname + "/index.html")
/* this sends the "index.html" file when people go to app.glitch.me/ */
})
app.get("/send", (req, res) => {
// where node app starts
var nodemailer = require('nodemailer');
var transporter = nodemailer.createTransport({
service: 'gmail',
auth: {
user: process.env.USER,
pass: process.env.PASS,
}
});
var mailOptions = {
from: process.env.USER,
to: process.env.RECIP,
subject: "As you requested",
text: '',
attachments: [
{
/*image location*/
path: 'https://post.healthline.com/wp-content/uploads/sites/3/2020/02/322868_1100-1100x628.jpg',
}
]
};
transporter.sendMail(mailOptions, function(error, info){
if (error) {
console.log(error);
} else {
console.log('Email sent: ' + info.response);
}
});
res.redirect("/sent.html") // after sending the email, redirect back to "index.html" at app.glitch.me/
})
app.listen(3000); //open for traffic
Here is my HTMl if its even relevant to my question
<!DOCTYPE html>
<html lang="en">
<head>
<title>Hello!</title>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- import the webpage's stylesheet -->
<link rel="stylesheet" href="/style_index.css">
click me for snazzy pics<!-- script to ping --!>
<!-- import the webpage's javascript file -->
<script src="/script.js" defer></script>
</head>
<body>
<h1>hello</h1>
<p>
I made this.
</p>
</body>
</html>

Try first logging all of your images from where they are hosted. If it is not a database you can call upon then you may need to create an array of them manually. Once they are in an object, you can simply use a variable to determine which position in the array that image link should come from. I hope the below helps.
For example:
imageChoices = ["https://post.healthline.com/wp-content/uploads/sites/3/2020/02/322868_1100-1100x628.jpg", "https://post.healthline.com/wp-content/uploads/sites/3/2020/02/322868_1100-1100x628.jpg", etc.]
randomIndexChooser = Math.floor(Math.random() * 60) + 1;
var mailOptions = {
from: process.env.USER,
to: process.env.RECIP,
subject: "As you requested",
text: '',
attachments: [
{
/*image location*/
path: imageChoices[randomIndexChooser],
}
]
};

you need to make an ajax service that calls an api, the api loops through all the files that are in the specified folder and returns the list of file paths. after you get the list from the api, you append them to the wanted array in your javascript code.
I will provide you a sample in asp.net c# , you may be working on another framework, but you can benefit from the idea at least.
here is a function in an api
[HttpGet]
public List<string> GetImageFilesPaths()
{
//getfiles returns all found files' paths in a specified directory
List<string> imageFilePaths = Directory.GetFiles("folderpath", "*.png", SearchOption.AllDirectories).ToList();
}
ajax service that calls the API
$.ajax({
url:'hostname/apiname/GetImageFilesPaths'
contentType: "application/json",
dataType: 'json',
success: function(result){
//here you append the result which is the list of file path
//into your wanted array, you can also loop
result.forEach((imagePath)=>{
arrayOfImages.push(imagePath)
})
}
})

Related

What next when the user is logged?

I am trying to integrate google auth from Firebase into my web app (on GAS), and i am having a hard time. I am new to it and have few experience in developing so excuse my lack of precision.
I managed to implement several steps but fail to come back to navigate the app normally once the user has logged.
First, here are the steps that are working fine (at least they seem to):
doGet() returns HtmlService.createHtmlOutputFromFile('auth') which contains all the necessary code for the authentication.
'auth.html' calls necessary stuff from firebase via CDN and the behaviour is correct: if i am not logged: UI shows and if i am logged: user details show on screen.
Since i need the userID to go on with the server-side scripts, i pass the userID which for now is just used to check i have the value on server side (is that correct to use userID this way?);
EDITED QUESTION:
Now what i would like to understand is the best practice for the steps
User opens app
doGet() is run and loads 'auth.html'
client-side authentication runs and collects user data
userID is set as a variable to be passed to server
then in order to run the rest of the scripts (the real app content user needs to see) what is the way to go? Should some function be run through google.script.run.someFunction(userID) when user is logged that would run the 'normal' app content (as it was before i integrated any authentication to be clear)?
last question: Does the authentication needs to be run on every page before loading content?
Here is my code:
.gs
function doGet(e) {
return HtmlService.createHtmlOutputFromFile('auth2')
.setXFrameOptionsMode(HtmlService.XFrameOptionsMode.ALLOWALL)
.setTitle('FirebaseUI | Firebase Authentication');
}
auth.html
<base target="_top">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/css/materialize.min.css">
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
<script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/js/materialize.min.js"></script>
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<script src="https://www.gstatic.com/firebasejs/7.14.2/firebase-app.js"></script>
<script src="https://www.gstatic.com/firebasejs/7.14.2/firebase-auth.js"></script>
<script src="https://cdn.firebase.com/libs/firebaseui/3.5.2/firebaseui.js"></script>
<link type="text/css" rel="stylesheet" href="https://cdn.firebase.com/libs/firebaseui/3.5.2/firebaseui.css" />
<script>
var firebaseConfig = {
apiKey: "stackoverflow",
authDomain: "stackoverflow.firebaseapp.com",
databaseURL: "https://stackoverflow-default-rtdb.europe-west1.firebasedatabase.app",
projectId: "stackoverflow",
storageBucket: "stackoverflow.appspot.com",
messagingSenderId: "267227785525",
appId: "1:stackoverflow:web:stackoverflow",
measurementId: "G-stackoverflow"
};
firebase.initializeApp(firebaseConfig);
</script>
<script>
google.script.run.withSuccessHandler(function(url) {
var uiConfig = {
signInFlow: 'redirect',
signInSuccessUrl: url,
signInOptions: [
firebase.auth.GoogleAuthProvider.PROVIDER_ID
],
};
var ui = new firebaseui.auth.AuthUI(firebase.auth());
var user = firebase.auth().currentUser;
console.log(user);
if (user) {
document.getElementById("signOut").style.display = "inline-block";
} else {
ui.start('#firebaseui-auth-container', uiConfig);
}
})
.webAppUrl();
</script>
<script>
initApp = function() {
firebase.auth().onAuthStateChanged(function(user) {
if (user) {
user.getIdToken().then(function(accessToken) {
document.getElementById('account-details').textContent = JSON.stringify({
displayName: user.displayName,
email: user.email,
custom: user.email,
emailVerified: user.emailVerified,
phoneNumber: user.phoneNumber,
photoURL: user.photoURL, // remove quotes to get the photoURL
uid: user.uid,
accessToken: "hidden", // replace "hidden" with accessToken
providerData: user.providerData // remove quotes to get the photoURL
}, null, ' ');
});
const userID = user.email;
google.script.run.someFunction(userID);
} else {
document.getElementById('account-details').textContent = '';
}
});
};
window.addEventListener('load', function() {
initApp();
});
</script>
</head>
Here the documentation i read:
https://developers.google.com/apps-script/guides/html/communication
https://firebase.google.com/docs/auth/web/google-signin

How do I display value(s) of fetch function?

I'm struggling to extract certain data values and put them in my website. I'm getting data from an API in JSON format. This is then handled by the handleResponse function. Now I wish to display one or more of these received values on my website. Any clues on how to properly do this? I've tried just about everything to the best of my ability. I am also aware that {dataList} is currently not a used variable. This is just to state where i want my data to be. Thanks.
<meta charset='utf-8'>
<meta name='viewport' content='width=device-width,initial-scale=1'>
<title>Sollicitatie Opdracht Volcano</title>
<link rel='icon' type='image/png' href='/favicon.png'>
<link rel='stylesheet' href='/global.css'>
<link rel='stylesheet' href='/build/bundle.css'>
<script defer src='/build/bundle.js'>
import { onMount } from "svelte";
// Here we define our query as a multi-line string
// Storing it in a separate .graphql/.gql file is also possible
var query = `
query ($id: Int) { # Define which variables will be used in the query (id)
Media (id: $id, type: ANIME) { # Insert our variables into the query arguments (id) (type: ANIME is hard-coded in the query)
id
title {
romaji
english
native
}
}
}
`;
var dataList;
// Define our query variables and values that will be used in the query request
var variables = {
id: 15125
};
// Define the config we'll need for our Api request
var url = 'https://graphql.anilist.co',
options = {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json',
},
body: JSON.stringify({
query: query,
variables: variables
})
};
// Make the HTTP Api request
fetch(url, options).then(handleResponse)
.then(handleData)
.catch(handleError);
function handleResponse(response) {
return response.json().then(function (json) {
return response.ok ? json : Promise.reject(json);
});
}
function handleData(data) {
console.log(data);
}
function handleError(error) {
alert('Error, check console');
console.error(error);
}
</script>
<h1>API Fetching System</h1>
<main>
<h2>{dataList}</h2>
</main>
<svelte:head>
<title>aniAPI Test App</title>
</svelte:head>
<style>
main {
background-color: lavenderblush;
font-size: 15px;
}
h1 {
font-size: 25px;
}
</style>
Data to display:
I fixed the issue.
By declaring a var dataString = ''; in the beginning, and in the HandleData function, I stringify the data using dataString = JSON.stringify(data);
then down below where dataList used to be:
{#await dataString}
{:then dataString}
<h2>{dataString}</h2>
{/await}

NodeJS + Socket.IO : Problem accessing room variables

I am new to the technologies NodeJS and Socket.io and i am facing a problem with the variables stored in io.sockets.adapter.rooms.
I have my app.js :
var app = require('express')();
var http = require('http').createServer(app);
var io = require('socket.io')(http);
app.get('/', (req, res) => {
res.sendFile(__dirname + '/index.html');
});
io.on('connection', (socket) => {
console.log('a user connected');
socket.on('message', function (room) {
socket.join(room);
console.log(io.sockets.adapter.rooms);
io.sockets.adapter.rooms[room].variable = "This is a test";
})
});
http.listen(3000, () => {
console.log('listening on *:3000');
});
The index.html :
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<input type="button" value="Press me" id="test">
<body>
<script src="/socket.io/socket.io.js"></script>
<script>
var socket = io();
document.getElementById('test').addEventListener('click', function () {
socket.emit('message', 'room1');
})
</script>
</body>
</html>
And the server return this error :
TypeError: Cannot set property 'variable' of undefined
It means that "io.sockets.adapter.rooms[room].variable" is undefined but i do not understant how i can define it otherwise.
By the way I am using NodeJS 12.8.3 and express 4.17.1
Maybe I need a specific module ?
Thanks a lot to everyone who will take the time to answer this
In their changelog for v3.0.0 they mention the following
Socket#rooms is now a Set instead of an object
Which means it's now a Map object instead of a normal js object
So with v3.0.3 you get the following output when logging the rooms, which you can't access by key like a normal js object, and .set() has to be used instead.
Map(2) {
'II-OqYrpZYtv2bKrAAAD' => Set(1) { 'II-OqYrpZYtv2bKrAAAD' },
'room1' => Set(1) { 'II-OqYrpZYtv2bKrAAAD' }
}
Although I have no idea how to add an additional variable to the room. Since if you run the following code:
io.sockets.adapter.rooms.set(room, {
variable: "Test variable"
})
it replaces the socket id with the new variable. I can't find anything on how they want us to store variables using this new structure.
Map(2) {
'Xv6vbxuOgDuqp6dmAAAB' => Set(1) { 'Xv6vbxuOgDuqp6dmAAAB' },
'room1' => { variable: 'Test variable' }
}
When logging the rooms with v2.0.3 you get a normal object output which you can access with [key].
{
'tVnQpZyKDglSf4J-AAAA': Room { sockets: { 'tVnQpZyKDglSf4J-AAAA': true }, length: 1 },
room1: Room { sockets: { 'tVnQpZyKDglSf4J-AAAA': true }, length: 1 }
}
So if you revert socket.io back to v2.0.3 (the latest 2.x.x version) your code works fine.
You can revert socket.io by running the following
npm i socket.io#2.0.3
Or by changing the version number in package.json and then running
npm install

Create pdf from HTML elements

What I want to do, is have a user dynamically create an image, like a nametag and then I want to save the image to the server as a pdf, then send the pdf via emil, to myself or someone else.
So far, I am able to dynamically create the nametag, and I am able to send an email when a button is pressed. Now what I can't seem to find is how to save the element as a pdf.
My code:
The endpoint that handles sending the email
let cors = require('cors');
let express = require('express');
let app = express();
app.use(cors());
let nodemailer = require('nodemailer');
/**
*
* Function to hopefully send an email :)
*/
app.post("/sendMail", function (req, res) {
console.log(req);
let transporter = nodemailer.createTransport({
service: 'gmail',
auth: {
user: 'user#gmail.com',
pass: 'Password'
}
});
let mailOptions = {
from: 'user#gmail.com',
to: 'recipient#alphagraphics.com',
subject: 'Test',
text: 'It works!'
};
transporter.sendMail(mailOptions, function(error, info) {
if (error) {
console.log(error);
} else {
console.log('Email sent: ' + info.response);
}
});
});
app.listen(8080);
The javascript that handles the button click to send the email
$('#some-long-stupid-unique-name').click(function(){
$.ajax({
type: 'POST',
url: 'http://192.168.1.23:8080/sendMail'
});
});
The html before editing
<div>
<div id="name"></div>
<div id="title></div>
</div>
Now the user will have some text boxees they cna type into and when they click "Update" whatever they typed into the text boxes (respectivly named Name and Title) the html will look like the following
<div>
<div id="name">My Name Here></div>
<div id="title">My Title Here</div>
</div>
How can I turn this element into a pdf and save it to my server, so I can then send it over from my mailing client?
Edit: I have seen other posts on how to "Save as pdf" but it seemed to me that they all save to the clients machine, but for me and the clients, it doesn't matter so much if they can save it on their machine, it is more important to save it to the server
Edit: Note that the format (pdf) doesn't matter so much I just thought it would be the easiest and most versatile?
If you would only save it as png, I would just say you to create a foreignObject inside an svg and render it on canvas, but since you want to convert that to pdf, I will do something that I rarely like doing. Try jsPDF, it should come in handy:
https://parall.ax/products/jspdf

Spotify web player gives Websocket error on raspberry pi

I am trying to set up spotify player to my raspberry pi. I have codes that work's like a charm on my macbook/chrome but the same codes wont work on raspbian/chromium.
I am getting following errors:
Error while parsing the 'allow' attribute: 'encrypted-media' is an invalid feature name.
{message: "Failed to initialize player"} script.js:44
WebSocket connection to 'wss://gew-dealer.spotify.com/?access_token=removed_my_token'
failed: Error in connection establishment: net:: ERR_NOT_IMPLEMENTED
{message: "Authentication failed"} script.js:45
Here is my script.js:
const hash = window.location.hash
.substring(1)
.split('&')
.reduce(function (initial, item) {
if (item) {
var parts = item.split('=');
initial[parts[0]] = decodeURIComponent(parts[1]);
}
return initial;
}, {});
window.location.hash = '';
// Set token
let _token = hash.access_token;
const authEndpoint = 'https://accounts.spotify.com/authorize';
// Replace with your app's client ID, redirect URI and desired scopes
const clientId = 'removed_my_client_id';
const redirectUri = 'http://localhost:1337';
const scopes = [
'streaming',
'user-read-birthdate',
'user-read-private',
'user-read-email',
'user-modify-playback-state'
];
// If there is no token, redirect to Spotify authorization
if (!_token) {
window.location = `${authEndpoint}?client_id=${clientId}&redirect_uri=${redirectUri}&scope=${scopes.join('%20')}&response_type=token&show_dialog=true`;
}
// Set up the Web Playback SDK
window.onSpotifyPlayerAPIReady = () => {
const player = new Spotify.Player({
name: 'Web Playback SDK Template',
getOAuthToken: cb => { cb(_token); }
});
// Error handling
player.on('initialization_error', e => console.error(e));
player.on('authentication_error', e => console.error(e));
player.on('account_error', e => console.error(e));
player.on('playback_error', e => console.error(e));
// Playback status updates
player.on('player_state_changed', state => {
console.log(state)
$('#current-track').attr('src', state.track_window.current_track.album.images[0].url);
$('#current-track-name').text(state.track_window.current_track.name);
});
// Ready
player.on('ready', data => {
console.log('Ready with Device ID', data.device_id);
// Play a track using our new device ID
play(data.device_id);
});
// Connect to the player!
player.connect();
}
// Play a specified track on the Web Playback SDK's device ID
function play(device_id) {
$.ajax({
url: "https://api.spotify.com/v1/me/player/play?device_id=" + device_id,
type: "PUT",
data: '{"uris": ["spotify:track:5ya2gsaIhTkAuWYEMB0nw5"]}',
beforeSend: function(xhr){xhr.setRequestHeader('Authorization', 'Bearer ' + _token );},
success: function(data) {
console.log(data)
}
});
}
Index.html
<!DOCTYPE html>
<html>
<head>
<title>Spotify Web Playback SDK Template</title>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href="https://sp-bootstrap.global.ssl.fastly.net/8.0.0/sp-bootstrap.min.css" rel="stylesheet" />
<script
src="https://code.jquery.com/jquery-3.2.1.min.js"
integrity="sha256-hwg4gsxgFZhOsEEamdOYGBf13FyQuiTwlAQgxVSNgt4="
crossorigin="anonymous"></script>
<!-- Include the Web Playback SDK -->
<script src="https://sdk.scdn.co/spotify-player.js"></script>
<!-- Include our Javascript -->
<script src="script.js" defer></script>
</head>
<body class="container">
<h1 class="text-salmon">Spotify Web Playback SDK Template</h1>
<h4>This app uses the implicit grant authorization flow to get an access token and initialise the Web Playback SDK. It then uses the Spotify Connect Web API to play a song.</h4>
<p>If everything is set up properly, you should hear some music!</p>
<img id="current-track"/>
<h3 id="current-track-name"></h3>
<a class="btn btn-salmon btn-lg" href="https://glitch.com/edit/#!/spotify-web-playback">Get started!</a>
</body>
</html>
This code should do:
Initialize the web player
Select one hard coded song
Play the song
Show the image
I have absolutely no idea what could be the problem here. I have been trying a lot of things to fix this but the problem is that i don't know what causes this so i have been just doing stuff without any idea is it going to help. So my question is how i can make this work on raspberry?

Categories