I am attempting to build a discord bot, and one of its features is that it will be able to recognize whether a user has interacted with the bot before by using a json array database. What is instead happening is that it does not read the array, and writes the username into the file even if it is already in the database.
const Discord = require('discord.js');
const fs = require('fs');
const { json } = require('stream/consumers');
const {prefix, token} = require('./config.json');
const {recognizedusers} = require('./database.json');
//Read File
let db = fs.readFileSync('./database.json');
db = JSON.parse(db);
// New discord client
const client = new Discord.Client({ intents: ["GUILDS", "GUILD_MESSAGES"] });
//Client run once
client.once('ready', () => {
console.log('Ready!');
});
//Client always run code
client.on('message', message => {
let msg_content = message.content.toLowerCase()
// Mixed message content response
if (msg_content.includes('test 1') && msg_content.includes('test 2')) {
message.channel.send('test 2: electric boogaloo')
}
if (msg_content.includes('test') && !message.author.username.includes(db.recognizedusers)) {
message.channel.send('unrecognized name')
//Edit Variable
db.recognizedusers.push(message.author.username)
// write file
fs.writeFileSync('./database.json', JSON.stringify(db));
}
});
client.login(token);
Elitezen fixed my problem.
I think you ment !db.recognizedusers.includes(message.author.username)
Related
I am trying to sign a message with wallet connect using ethers, but I am facing an issue when verifying the message with ambire wallet, it's not returning any response.
const signMessage = async () => {
try {
console.log("started");
// 1.] create a provider
const walletConnectProvider = new WalletConnectProvider({
infuraId: "3cd774e14cf34ff78167908f8377051c", // Required
// qrcode: true
});
// 2.] enable provider
await walletConnectProvider.enable();
// console.log(walletConnectProvider.wc.accounts[0]);
let rawMessage = "Hello World";
let rawMessageLength = new Blob([rawMessage]).size;
let message = ethers.utils.toUtf8Bytes(
"\x19Ethereum Signed Message:\n" + rawMessageLength + rawMessage
);
message = ethers.utils.keccak256(message);
var params = [
walletConnectProvider.wc.accounts[0],
message,
];
// 3.] sign message
const provider = new providers.Web3Provider(walletConnectProvider);
const signer = provider.getSigner();
let signature = await signer.signMessage(message);
console.log("signature", signature);
// 4.] verify message
let verified = await ethers.utils.verifyMessage(message, signature);
console.log("verified", verified);
} catch (err) {}
};
there are a couple of things you additionally need:
You need to pass the original message (before prefix) to signer.signMessage, in other words the rawMessage: await signer.signMessage(rawMessage) - because the wallet (no matter if it's Ambire or not) will add the prefix
In order to support smart wallets like Ambire, Gnosis Safe, Argent and others, you need to implement EIP 1271.
In JS (warning: not tested), this will look somewhat like this:
const signerAddr = await signer.getAddress();
if (provider.getCode(signerAddr) === '0x') {
// Regular RSV sig verification
verified = signerAddr === (await ethers.utils.verifyMessage(message, signature));
} else {
// Smart contract wallet (EIP 1271) verification: see https://eips.ethereum.org/EIPS/eip-1271 for more info
const EIP1271ABI = ['function isValidSignature(bytes32 _hash, bytes memory _signature) public view returns (bytes4 magicValue)'];
const EIP1271MagicValue = '0x1626ba7e';
const signerEIP1271Contract = new ethers.Contract(signerAddr, EIP1271ABI, provider);
const rawMessageLength = new Blob([rawMessage]).size;
const message = ethers.utils.toUtf8Bytes(
"\x19Ethereum Signed Message:\n" + rawMessageLength + rawMessage
);
const messageHash = ethers.utils.keccak256(message);
verified = EIP1271MagicValue === (await signerEIP1271Contract.isValidSignature(messageHash, signature));
}
NOTE: We, the Ambire team, are currently working on a comprehensive guide on how to verify all styles of signature (EIP1271, EIP712, 712+1271, regular), which will hopefully be linked by the ethers.js documentation.
EDIT: We've published a library that makes this a whole lot easier, please check it out: https://github.com/AmbireTech/signature-validator/ - we recommend that you use that
I am using forge-apis package on Node.js and I want to translate a .fbx file in SVF2. When I do so and load the model, size and GPU memory used is the same as normal translate to SVF and when I check viewer.model.isSVF2() it return false.
const {
DerivativesApi,
JobPayload,
JobPayloadInput,
JobPayloadOutput,
JobSvfOutputPayload} = require('forge-apis');
and
router.post('/jobs', async (req, res, next) => {
const xAdsForce = (req.body.xAdsForce === true);
let job = new JobPayload();
job.input = new JobPayloadInput();
job.input.urn = req.body.objectName;
if(req.body.rootFilename && req.body.compressedUrn) {
job.input.rootFilename = req.body.rootFilename;
job.input.compressedUrn = req.body.compressedUrn;
}
job.output = new JobPayloadOutput([
new JobSvfOutputPayload()
]);
job.output.formats[0].type = 'svf2' ;
job.output.formats[0].views = ['2d', '3d'];
try {
// Submit a translation job using [DerivativesApi](https://github.com/Autodesk-Forge/forge-api-nodejs-client/blob/master/docs/DerivativesApi.md#translate).
const result = await new DerivativesApi().translate(job, { xAdsForce: xAdsForce }, req.oauth_client, req.oauth_token);
res.status(200).end();
} catch(err) {
next(err);
}});
How can I handle this problem? Thanks a lot.
I have been working on a React Native project with Expo that uses a json file to store local data. I am importing the data like so
import data from '../database.json'
I am making changes (adding and removing) to the imported JSON by using data.push(new_data). These changes are not persistent when I close the app because I cannot figure out how to save them. I have looked at using the expo-file-system library as so:
import * as FileSystem from 'expo-file-system';
...
FileSystem.writeAsStringAsync(FileSystem.documentDirectory + 'database.json', data);
This is from looking at examples in the API documentations. This however always throws promise rejections and doesn't end up writing the file. Can you point me in the right direction?
Also, should I import the database.json in a different way so I will already have the uri to save it to?
The documentation doesn't give an example of it's returned props in promises, so I was overlooking it for longer than I care to admit 😅. I was really dedicated to figuring this out so I could use the Expo solution, and totally missed the return Promise for createFileAsync, so hopefully this saves someone a significant amount of time in the future.
import * as FileSystem from 'expo-file-system';
const { StorageAccessFramework } = FileSystem;
const saveFile = async () => {
const permissions = await StorageAccessFramework.requestDirectoryPermissionsAsync();
// Check if permission granted
if (permissions.granted) {
// Get the directory uri that was approved
let directoryUri = permissions.directoryUri;
let data = "Hello World";
// Create file and pass it's SAF URI
await StorageAccessFramework.createFileAsync(directoryUri, "filename", "application/json").then(async(fileUri) => {
// Save data to newly created file
await FileSystem.writeAsStringAsync(fileUri, data, { encoding: FileSystem.EncodingType.UTF8 });
})
.catch((e) => {
console.log(e);
});
} else {
alert("You must allow permission to save.")
}
}
Use AsyncStorage instead. The react native package is deprecated but working, or use #react-native-community/async-storage and convert json to string (AsyncStorage can only store strings)
Set item
import AsyncStorage from '#react-native-community/async-storage';
...
await AsyncStorage.setItem('myData', JSON.stringify(data))
Get item
const data = await AsyncStorage.getItem('myData')
I found #JayMax answer very helpful however it's only for Android.
On iOS all you need to do is use Sharing.shareAsync and then you can save data to the file. Check this example:
const fileUri = FileSystem.documentDirectory + 'data.txt';
FileSystem.writeAsStringAsync(fileUri, 'here goes your data from JSON. You can stringify it :)', {
encoding: FileSystem.EncodingType.UTF8,
});
const UTI = 'public.text';
Sharing.shareAsync(fileUri, {UTI}).catch((error) => {
console.log(error);
});
If you using AsyncStorage, it only store for small data. Maybe 6mb or 10 mb.
You can use expo fileSystem
import * as FileSystem from 'expo-file-system';
...
FileSystem.writeAsStringAsync(FileSystem.documentDirectory + 'database.json', data);
Convert your data (Type json to string) Such as this:
writeData = async () => {
var persons = ''
await axios.get(`http://192.168.0.48:4000/api/sql/student`)
.then(res => {
persons = res.data
})
await FileSystem.writeAsStringAsync(FileSystem.documentDirectory + `offline_queue_stored.json`, JSON.stringify(persons));
}
#1.If the JSON File is in your Project Folder (PC/Laptop)
import data from './database.json';
#2. If the JSON File is in your Phone
import * as FileSystem from 'expo-file-system';
import * as DocumentPicker from 'expo-document-picker';
this.state = {
fileURI: null,
};
componentDidMount = () =>{
this._pickDocument();
}
_pickDocument = async () => {
let result = await DocumentPicker.getDocumentAsync({});
this.setState({
fileURI: result.uri
})
let fileData = await FileSystem.readAsStringAsync(this.state.fileURI)
console.log(fileData)
};
Two part quersion.
Part 1:
Im uploading an image to my server and want to save it to my database.
So far:
table:
resolver:
registerPhoto: inSequence([
async (obj, { file }) => {
const { filename, mimetype, createReadStream } = await file;
const stream = createReadStream();
const t = await db.images.create({
Name: 'test',
imageData: stream ,
});
},
])
executing query:
Executing (default): INSERT INTO `images` (`Id`,`imageData`,`Name`) VALUES (DEFAULT,?,?);
But nothing is saved.
Im new to this and im probably missing something but dont know what.
Part2:
This is followed by part 1, lets say I manage to save the image, how do I read it and send it back to my FE?
An edit: Ive read alot of guides saving the an image name to the db and then tha actuall image in a folder. This is NOT what im after, want to save the image to the DB and then be able to fetch it from the DB abd present it.
This took me some time but I finaly figured it out.
First step (saving to the db):
Have to get the entire stream data and read it like this:
export const readStream = async (stream, encoding = 'utf8') => {
stream.setEncoding('base64');
return new Promise((resolve, reject) => {
let data = '';
// eslint-disable-next-line no-return-assign
stream.on('data', chunk => (data += chunk));
stream.on('end', () => resolve(data));
stream.on('error', error => reject(error));
});
};
use like this:
const streamData = await readStream(stream);
Before saving I tur the stream into a buffer:
const buff = Buffer.from(streamData);
Finaly the save part:
db.images.create(
{
Name: filename,
imageData: buff,
Length: stream.bytesRead,
Type: mimetype,
},
{ transaction: param }
);
Note that I added Length and Type parameter, this is needed if you like to return a stream when you return the image.
Step 2 (Retrieving the image).
As #xadm said multiple times you can not return an image from GRAPHQL and after some time I had to accept that fact, hopefully graphql will remedy this in the future.
S What I needed to do is set up a route on my fastify backend, send a image Id to this route, fetch the image and then return it.
I had a few diffirent approaches to this but in the end I simpy returned a binary and on the fronted I encoded it to base64.
Backend part:
const handler = async (req, reply) => {
const p: postParams = req.params;
const parser = uuIdParserT();
const img = await db.images.findByPk(parser.setValueAsBIN(p.id));
const binary = img.dataValues.imageData.toString('binary');
const b = Buffer.from(binary);
const myStream = new Readable({
read() {
this.push(Buffer.from(binary));
this.push(null);
},
});
reply.send(myStream);
};
export default (server: FastifyInstance) =>
server.get<null, any>('/:id', opts, handler);
Frontend part:
useEffect(() => {
// axiosState is the obj that holds the image
if (!axiosState.loading && axiosState.data) {
// #ts-ignore
const b64toBlob = (b64Data, contentType = '', sliceSize = 512) => {
const byteCharacters = atob(b64Data);
const byteArrays = [];
for (let offset = 0; offset < byteCharacters.length; offset += sliceSize) {
const slice = byteCharacters.slice(offset, offset + sliceSize);
const byteNumbers = new Array(slice.length);
// #ts-ignore
// eslint-disable-next-line no-plusplus
for (let i = 0; i < slice.length; i++) {
byteNumbers[i] = slice.charCodeAt(i);
}
const byteArray = new Uint8Array(byteNumbers);
byteArrays.push(byteArray);
}
const blob = new Blob(byteArrays, { type: contentType });
return blob;
};
const blob = b64toBlob(axiosState.data, 'image/jpg');
const urlCreator = window.URL || window.webkitURL;
const imageUrl = urlCreator.createObjectURL(blob);
setimgUpl(imageUrl);
}
}, [axiosState]);
and finaly in the html:
<img src={imgUpl} alt="NO" className="imageUpload" />
OTHER:
For anyone who is attempting the same NOTE that this is not a best practice thing to do.
Almost every article I found saved the images on the sever and save an image Id and other metadata in the datbase. For the exact pros and cons for this I have found the following helpful:
Storing Images in DB - Yea or Nay?
I was focusing on finding out how to do it if for some reason I want to save an image in the datbase and finaly solved it.
There are two ways to store images in your SQL database. You either store the actual image on your server and save the image path inside your mySql db OR you create a BLOB using the image and store it in db.
Here is a handy read https://www.technicalkeeda.com/nodejs-tutorials/nodejs-store-image-into-mysql-database
you should save the image in a directory and save the link of this image in the database
I am a new to koa2, and I trying to GET the contents of a JSON file with koa2
app.use( async ( ctx ) => {
let url = ctx.request.url;
if (url == "list") {
let res = ctx.request.get('http://domain/hello.json');
ctx.body = res.body;
}
})
The JSON file hello.json looks like the following:
{"da": "1212", "dad": "12addsf12"}
I want the route /list to return the contents of hello.json, however, the response is empty. What do I do?
Update:
Change the following lines of code:
let res = ctx.request.get('http://domain/hello.json');
ctx.body = res.body;
to:
let res = ctx.get('http://domain/hello.json');
ctx.body = res;
You should get the content now.
Koa by itself does not support routing, only middleware, you need to have a router middleware for that, try koa-router.
Your app would look something like
const route = require('koa-route')
app.use(route.get('/list', ctx => {
// Route handling logic
});
Also note that ctx.get is an alias for ctx.request.get which returns header information.
This may not be Koa's way of doing things, but this is what I tried and worked for me (complete code for noobs like me):
// jshint ignore: start
const koa2 = require("koa2");
const router = require('koa-simple-router');
const app = new koa2();
const request = require('request-promise-native');
// response
app.use(router(_ => {
_.get('/list', async (ctx) => {
const options = {
method: 'GET',
uri: 'http://www.mocky.io/v2/5af077a1310000540096c672'
}
await request(options, function (error, response, body) {
// I am leaving out error handling on purpose,
// for brevity's sake. You must in your code.
ctx.body = body;
})
});
}));
app.listen(3000);
And, like what J Pichardo's answer points out, Koa by itself does not support routing. You need to use some routing middleware.