Samarth Jajoo
hacker

content creator
@jajoosam (382)
15 y/o maker of things! sam.jajoo.fun
โ–ฒ
30
๐Ÿ•ต๏ธโ€โ™‚๏ธ A scavenger hunt with image classification ๐Ÿ–ผ๏ธ
hey hey hey hey hey I'm back with something I think y'all will find interesting! I built a game based on image classification - you have to get objects from around your house - whatever the app tells you to get, you fetch! ## [Play here](https://hunt.4ty2.fun?ref=repltalk) ๐ŸŽฎ Check out [this demo video](https://youtu.be/kdGipA-VDj4) I made ๐ŸŽฅ - I go over using the app, and the tools I used to make it! ![demo gif](https://storage.googleapis.com/replit/images/1548248878277_61c6e20eadf9da4da8e8967685a61f08.gi) ### How does this work? 4ty2 hunt has two main dependencies - [ml5](https://ml5js.org) and [p5](https://p5js.org) - p5 lets you do cool things with graphics (like getting the video stream from the webcam, super easily) - but ml5 is the real core of this app! ml5.js lets us run machine learning models, and train them as well, right in our browser. But the reason it exists is to make ML projects, like this mindblowingly simple ๐Ÿคฏ The whole of my game comes down to me writing about `150` lines of JS - that's it. ml5 allows me to pass the webcam's video stream as a parameter, and keeps telling me what it sees. I'm using the mobile-net model for this, which uses the [image-net](http://image-net.org/index) dataset - around 15 million labelled images. Besed on that huge chunk of data, this model predicts what it sees! ### Challenging you Image Net has 1000 different labels through which objects are classified - some of them include things like `Komodo Dragon`s, `Great White Shark`s, and `Ostrich`es - you know, things that can't be found in *most* homes ๐Ÿ˜› So, I manually went through loads of the labels, trying to label things most of us could find. ![me going whaaaaaat?](https://storage.googleapis.com/replit/images/1548250013223_d4e633164513cafa87953e8e9e755ae1.pn) Clearly, I was a little sleep deprived - and I probably made some mistakes. Let me know if you find some weird labels - I'm @jajoosam on the Discord ๐Ÿ’ฌ ### Easy machine learning with JS Machine Learning is pretty complex, but that doesn't mean making projects with it has to be too! I have gained a lot of appreciation for [ml5.js](https://ml5js.org) - it's an amazing way to integrate ML into your projects. I learnt all the tech behind making this project from [Dan Shiffman's videos on ml5 ](https://www.youtube.com/watch?v=jmznx0Q1fP0)- and I highly recommend you check them out if you found this interesting! He's a great, super energetic teacher ๐Ÿ‘จโ€๐Ÿซ ![SelfassuredScrawnyKusimanse-small](https://storage.googleapis.com/replit/images/1548250591304_1f59b29dfc20b7f8c93d6323da1a4c72.gi) Before building this project, I followed the [first video](https://www.youtube.com/watch?v=yNkAuWz5lnY) of the series to build [this](https://ml5-mobilenet.jajoosam.repl.co) Super excited to hear what y'all think about this!
8
posted to Challenge by jajoosam (382) 29 days ago
โ–ฒ
16
Build an ML app, with just a little JavaScript ๐Ÿค–
## Making a feature extractor with ml5.js and p5.js ![](https://ecstatic-rosalind-da34e4.netlify.com/main.gif) [Demo](https://feature-extractor--jajoosam.repl.co) โฏ๏ธ [Code](https://repl.it/@jajoosam/feature-extractor) ๐Ÿ‘จโ€๐Ÿ’ป [Video Walkthrough](https://ecstatic-rosalind-da34e4.netlify.com/feature-extractor-demo-compressed-3e7aac1a-1c37-4448-92ab-140b5dd84056.mp4) ๐ŸŽฆ Machine Learning is a super cool way to build AI apps - but I won't lie, it is a lot of math. Luckily, thanks to [ml5.js](https://ml5js.org) - we don't need to spend months understanding ML, we can apply it and develop some cool uses in our app within just a few hours ๐Ÿ˜„ This is a guide to build a feature extractor - something that can get a video stream from your webcam and predict what it sees, once it is trained with a little bit of data - just like in the video above! ## ๐Ÿด Forking the frontend I don't want to waste too much of your time with the frontend I used for this app - I think it'd be much better if I skipped right to the JavaScript, and logic. You should fork this repl - [https://repl.it/@jajoosam/feature-extractor-start](https://repl.it/@jajoosam/feature-extractor-start) - so that you have the HTML already there! It's essentially just a few `div`s for holding the video and some other text, along with some buttons to control our app! I've commented everything (except the CSS ๐Ÿ˜›) - so you should be able to go through the frontend and understand the basic layout of the app in a few minutes. Once you're done, head over to `script.js` ![](https://ecstatic-rosalind-da34e4.netlify.com/Untitled-8e918105-6ae0-4591-8362-7ed6e7068460.png) ## โœ๏ธ Declaring the variables We're going to have quite a few variables to declare, so the first thing we're going to do is create them. Our app is going to have a lot of functions, and it's important that all of them can access the variables - which is why we shall declare right at the start of our code ```javascript var featureExtractor, classifier, video, loss, redCount, blueCount; redCount = blueCount = 0; ``` I'll give you an overview of what these are for, but you'll understand them much better as we continue building our app. `featureExtractor` and `classifier` are variables we're going to store and initialize machine learning models in. `video` is where we're storing the webcam stream, while `loss` lets us know the progress of how far our on feature extractor has been trained. Finally, `blueCount` and `redCount` are counters for how many images there are in each category - and we initalize both of them with a value of `0`, in the next line. ## ๐Ÿ› ๏ธ The `setup()` `setup()` is a function which shall fire up as soon as our code is ready to run. Bacause of using [p5.js](https://p5js.org), our code is pretty readable and easy to understand here. ```javascript function setup() { // Tells p5 to not automatically create a canvas element. noCanvas(); // Starts capturing a video feed from the webcam video = createCapture(VIDEO); // Puts the video stream into the div in our html, with ID `video` video.parent('video'); // Initializes a feature extractor, yet to be trained - from ml5.js featureExtractor = ml5.featureExtractor('MobileNet'); classifier = featureExtractor.classification(video); // What we're doing next - setting up buttons! setupButtons(); } ``` This code goes in your `script.js` file right after you declare variables - essentially, it gets a video stream and displays it on our page, inside a `div` with the ID `video`. We also make some functions using the ml5.js library here, and pass the captured video as a parameter - you'll see what we do with these soon, but there's still a little more setup left! As you can see, at the end of `setup()`, we call `setupButtons()` - the function we're going to make next. Here, we're adding event listeners to buttons in our HTML - so we can run functions when they're clicked. Here's all the code we write for the `setupButtons()` function ๐Ÿ‘‡ ```javascript // A function to create the buttons function setupButtons() { buttonA = select('#red'); buttonB = select('#blue'); โ€‹ โ€‹ buttonA.mousePressed(function() { โ€‹ redCount++; โ€‹ classifier.addImage('red'); โ€‹ select('#redCount').html(redCount); โ€‹ }); โ€‹ โ€‹ buttonB.mousePressed(function() { โ€‹ blueCount++; โ€‹ classifier.addImage('blue'); โ€‹ select('#blueCount').html(blueCount); โ€‹ }); โ€‹ train = select('#train'); train.mousePressed(function() { classifier.train(function(lossValue) { // This is where we're actually training our model if (lossValue) { loss = lossValue; select('#info').html('Loss: ' + loss); } else { select('#info').html('Done Training! Final Loss: ' + loss); select('#train').style("display", "none"); select('#predict').style("display", "inline"); } }); }); // Predict Button buttonPredict = select('#predict'); buttonPredict.mousePressed(classify); } ``` That's the largest art of our app, and I'm going to break it up into several parts to make it easier to explain! ## ๐Ÿง™โ€โ™‚๏ธbUt wHaT Do tHeSe bUtToNs dO?!?!?! DON'T PANIC. Let's start off with this block: ```javascript buttonA = select('#red'); buttonB = select('#blue'); buttonA.mousePressed(function() { redCount++; classifier.addImage('red'); select('#redCount').html(redCount); }); buttonB.mousePressed(function() { blueCount++; classifier.addImage('blue'); select('#blueCount').html(blueCount); }); ``` `buttonA` and `buttonB` are nothing but the two different buttons we have in our app! ![](https://ecstatic-rosalind-da34e4.netlify.com/Untitled-c85ebc09-ab40-4060-a9ce-98966a9fe021.png) With `.mousePressed()` we're defining what happens when any of these buttons are pressed - which is: - Increase the count by 1, using the `++` operator - Capture the current frame from the webcam videom and add it to the classifier, with `classifier.addImage()` - Update the count on our app by changing the button's text, with `.html()` Next up, we have this whole block - where we train the classifer itself: ```javascript train = select('#train'); train.mousePressed(function() { classifier.train(function(lossValue) { // This is where we're actually training our model if (lossValue) { loss = lossValue; select('#info').html('Loss: ' + loss); } else { select('#info').html('Done Training! Final Loss: ' + loss); select('#train').style("display", "none"); select('#predict').style("display", "inline"); } }); }); ``` When the `Train ๐Ÿš‹` button on our app is pressed, we call `classifier.train()` - and with each iteration, the function we supply there is called - which is why we see the *[Loss](https://ml-cheatsheet.readthedocs.io/en/latest/loss_functions.html)* value keep changing. ![](https://ecstatic-rosalind-da34e4.netlify.com/CleanShot-2019-01-26-at-18-6a9809c8-75a3-4b88-b1ee-3931aa15d08c.04.57.gif) When the *Loss* value is `0`, then we hid the `Train ๐Ÿš‹` button, and show the previously hidden `Predict ๐Ÿ”ฎ` button! The last 2 lines of the `setupButtons()` function are about the predict button: ```javascript buttonPredict = select('#predict'); buttonPredict.mousePressed(classify); ``` It seems like we're calling this `classify` function - which is what we're going to build next! Keep going, we're almost done ๐Ÿ’ฏ ## ๐Ÿ”ฎ Predictions, and showing results Our `classifier()` function is pretty straightforward - this is all we do: ```javascript function classify() { classifier.classify(gotResults); } ``` We're just telling the ml5 `classifier` to classify the current frame in either of the categories (๐Ÿ”ด or ๐Ÿ”ต), and send the results to the `gotResults` function - which brings us to the final part of our app! As long as the classifier doesn't send us an error, we change the entire page's background color to either `red` or `blue` - and then call `classify()` again, which keeps our code running forever, and the predictions keep coming! ```javascript function gotResults(err, result) { if (err) { console.log(err); } select("body").style("background", result); classify(); } ``` That's all the code we have to write to build the example feature extractor. I highly recommend going through the final code so that you can see how everything fits together well - I know there are quite a few functions too keep track of, but I've commented everything to make it easier ๐Ÿ˜… https://repl.it/@jajoosam/feature-extractor Now go ahead, try it out! Here are some things I did to see if the feature extractor would work (it did!) ๐Ÿ‘‡ - Keep my head in the left in ๐Ÿ”ด, and right in ๐Ÿ”ต - Make a โœŒ๏ธ in ๐Ÿ”ด, and a โœ‹ in ๐Ÿ”ต - Wear different colored ๐Ÿ‘•s in ๐Ÿ”ด and ๐Ÿ”ต Let me know other cool things it worked with ๐Ÿ‘€ ## โœจ okay, but what do I **MAKE** with this? There are SOOOOO MANY THINGS you could do! A feature extractor gives you the ability to add this whole other, mysterious way of controlling, and getting input in your app! Here are a few ideas ๐Ÿ’ก - A gesture controlled game, right in the browser ๐ŸŽฎ - A mood tracker - leave the tab open all day, and train it with different face expressions ๐Ÿค” - Build your own **[hotdog or not](https://www.youtube.com/watch?v=pqTntG1RXSY)** app ๐ŸŒญ - Build an app which only lets you message others with gestures ๐Ÿ’ฌ ## ๐Ÿ‘จโ€๐Ÿซ what else is there? ml5.js can do crazy things! You can integrate image classification into your own app [like I did](https://repl.it/talk/challenge/male-A-scavenger-hunt-with-image-classification/10185), find similar words which fit into a text, get a precise skeleton of human bodies and even transfer the styles in images - look at what my picture looks like, when composed with the style of a cool painting ๐Ÿ–Œ๏ธ ![mepaint](https://ecstatic-rosalind-da34e4.netlify.com/mepaint.png) You should take a look at the many [examples on the ml5.js website](https://ml5js.org/docs/quick-start) - or take a look at [Dan Shiffman's videos on ml5.js](https://www.youtube.com/playlist?list=PLRqwX-V7Uu6YPSwT06y_AEYTqIwbeam3y), he covers loads of things you can do with it - and explains everything with a ton of energy. I highly recommend watching his videos on the [Coding Train](https://www.youtube.com/user/shiffman) YouTube! You have over 2 weeks left to submit something to the [Repl.it AI Challenge](https://repl.it/talk/challenge/Artificial-Intelligence-Competition/10058) ๐Ÿ“† If you have any questions or need any help with your ml5 submission, feel free to ping me @jajoosam on the Discord, or leave something in the comments :)
1
posted to Learn by jajoosam (382) 23 days ago
โ–ฒ
23
A smart background removal tool ๐ŸŽจ
[colorSpace](https://color.4ty2.fun/?ref=repltalk) is a smart background removal tool based completely on the front end, so your pictures never leave your computer. ![demo](https://storage.googleapis.com/replit/images/1547265356292_3848cfe46c9f10fb81ef0a1e7e97417d.gi) It gets colors in an image through the HTML canvas, converts them to the [L*a*b](https://en.wikipedia.org/wiki/CIELAB_color_space) colorspace (makes difference measures intuitive to human vision) - and measures the euclidian difference between colors, and purges them from an image based on the threshold. More in [this tweet](https://twitter.com/jajoosam/status/1083764001375346688)!
8
posted to Share by jajoosam (382) 1 month ago
โ–ฒ
27
Build your very own URL shortener ๐Ÿ”—๐Ÿš€
## Build a tiny URL shortener, using a remote database ![](https://boring-lamport-1b901a.netlify.com/2018-12-2214-5f2c1bbe-59a2-4ba7-9544-438b1ab5e1dd.39.01.gif) [Demo](https://l.4ty2.fun) โฏ๏ธ [Code](https://repl.it/@jajoosam/tyni) ๐Ÿ‘จโ€๐Ÿ’ป Setting up a URL shortener is a lot of work - either you have to pay, or spend hours setting up your own server. This is a guide to making your own URL shortener with [repl.it](http://repl.it) - using `express`, and a remote database - all on `node.js` ## ๐Ÿ› ๏ธ Getting our environment running First up, fork the [https://repl.it/@jajoosam/tyni-starter](https://repl.it/@jajoosam/tyni-starter) repl, so that you have a running project. Next, create a new file - `.env` ![](https://boring-lamport-1b901a.netlify.com/Untitled-675a864b-7c8c-487d-8ca7-595eb8af67ba.png) A `.env` file can store secrets for you, that no one else will be able to see. This is where we want to store our token for accessing the remote database. ## ๐Ÿ“ Making our database We're going to be using [jsonstore.io](http://jsonstore.io) for storing all our URLs. Head over to [jsonstore.io/get-token](https://www.jsonstore.io/get-token) - and copy the token you see - this is the secret we want to store in our `.env` file. Open up your `.env` file, and set `KEY` to your token, like this ๐Ÿ‘‡ ```bash KEY=yourTokenGoesHere ``` Remember to keep **no whitespace**, or your token might not be recognized right! When you open `index.js` you'll see that I've already initialized the database, and a small web server for you. Now let's get to making our API so we can shorten them URLs ๐Ÿš€ ## ๐Ÿ‘จโ€๐Ÿ’ป The API There are two parts to our URL shortener: 1. Storing the short link, corresponding to the long URL - in our database. 2. Redirecting visitors from the short link to the long link Both of these are super simple to implement, thanks to the `express` server we're using - we'll just be collecting `get` requests for both of the tasks. For adding links to our database, we have a special endpoint - requests to it have two parts: the long URL, and the short path. ```javascript app.get('/shorten', (req, res) => { db.write(req.query.key, {"url": req.query.url}); res.status(200); }); ``` Adding this to our code lets us correspond the short path (`key`) to the long `url`, and then we finally send a successful response. For the second task, we'll just be collecting the short path (`key`) from a request, finding the corresponding URL in our database, and then redirecting our visitor โฌ‡๏ธ ```javascript app.get('/:key', (req, res) => { db.read(req.params.key + "/url").then( (url) => { res.redirect(url); }); }); ``` That's prety much it - we have a fully functional URL shortener ๐Ÿคฏ - check it out for yourself, open a new URL which looks like this ๐Ÿ”— ``` https://tyni.jajoosam.repl.co/shorten?key=yay&url=https://dsh.re/50854 ``` Now, going to [`http://tyni.jajoosam.repl.co/yay`](http://tyni.jajoosam.repl.co/yay) will be nice to see ๐Ÿ‘‡ ![](https://boring-lamport-1b901a.netlify.com/1-8380b52f-92c2-4acc-87dc-64011c6fd502.jpg) Of course, you'll be replacing `tyni.jajoosam` in those URLs with your own repl! ## โœจ The Frontend Our URL shortener does work, but it's tedious, having to type out a huge URL before shortening it - we can make the whole process much simpler with a simple frontend. I've already created this - and gone for a neat and minimal look using [wing.css](https://github.com/kbrsh/wing) ![](https://boring-lamport-1b901a.netlify.com/Untitled-0fa3af54-ddae-46ca-abdf-4fcbcb218f8b.png) You just have to add code to send visitors to the hompage in the `static` folder ๐Ÿ  ```javascript app.get('/', (req, res) => { res.sendFile("static/index.html", {root: __dirname});; }); ``` If you browse through the `static` folder, you'll find a simple `HTML` file with a form, `CSS` to style our page, and most importantly, `JS` to send requests to our URL shortening API. The `HTML` is quite straightforward, we're asking for the long URL, and *optionally* a short path. Open up `script.js` and you'll see the `shorten()` function. Here's what the JS file does (*I've also annotated the code with comments*) ๐Ÿ‘‡ ๐Ÿ” Getting the path(`key`) and the long `url` from the form. ๐Ÿ“ Possibly generating a random 5 character hash as our path (in case there's no path entered) ๐Ÿ”— Sending a get request to our API, with our `key` and `url` as parameters ๐Ÿ–ฅ๏ธ Displaying the shortened URL on our page ## ๐ŸŒ Getting our custom domain Sure, our links are shorter - but we still don't have them on our own domain, and the `repl.co` links can be pretty long ๐Ÿ‘€ Luckily for us, the folks at [repl.it](http://repl.it) recently allowed custom domains to be used! That means this project could be something you actually use all the time ๐Ÿ˜„ Check out `dotcomboom`'s guide on [using custom domains](https://repl.it/talk/learn/How-to-use-a-custom-domain/8834), it should only take a few minutes. It also teaches you about getting free domains ๐Ÿ’ธ Be sure to put down any questions or improvements down in the comments ๐Ÿ’ฌ - and here's all the code for you to go over again ๐Ÿค– https://repl.it/@jajoosam/tyni
10
posted to Learn by jajoosam (382) 2 months ago
โ–ฒ
81
Build a WhatsApp bot in 30 minutes ๐Ÿ•
A few months ago, I'd started making chatbots on [Telegram](https://t.me) - I'd seen APIs for WhatsApp but they were unoffical and there was a chance for getting your number blocked ๐Ÿ“ฑ โŒ A while ago, I saw that [Twilio](https://twilio.com) had an official WhatsApp API. 30 minutes later, I made a [Wikipedia bot on WhatsApp](https://wikibot.4ty2.fun) ๐Ÿ‘‡ ![](https://wikibot.surge.sh/Untitled-b9da3f92-94c0-4f97-8afb-787110d8a9d3.png) This is a tutorial to help you make a something like this, your own chatbots on WhatsApp - these bots are immediately available to 2 billion users, and there are so many things possible ๐ŸŽ“ I can't wait to see what you make! Now, let's get started ๐Ÿƒโ€โ™‚๏ธ ## ๐Ÿ”‘ Accounts and Keys First, Sign up for [Twilio](https://www.twilio.com/try-twilio) - it's free and you won't need a credit card ๐Ÿ’ณ ![](https://wikibot.surge.sh/screely-1535885763017-fc654067-9557-4bf7-98b5-4337911ff4ba.png) Once you're done verifying your phone number, select Procuts > Programmable SMS and then continue to name your project. ![](https://wikibot.surge.sh/screely-1535885937977-c5a924ec-8cc3-4430-9345-9b5e1dc74ef3.png) Feel free to skip steps for adding teammates - you won't need that for now. You must now take note of some authentication keys you'll need for building the WhatsApp bot ๐Ÿ‘‡ ![](https://wikibot.surge.sh/screely-1535886250966-f68b6cfb-c104-4adf-80e7-4e3f9bd15b5b.png) The final step - setup your WhatsApp Sandbox [here](https://www.twilio.com/console/sms/whatsapp/sandbox) - choose any number, and join your sandbox following instructions on the page. ![](https://wikibot.surge.sh/screely-1535886798623-1dac1ba9-c362-4e49-87ab-7bbb6138e8c7.png) Aaaaaand you're done with credential setup! Don't worry, that was the toughest part of this tutorial ๐Ÿ˜› ## ๐Ÿš€ Getting Started So that we don't spend too much time on setup, I've created an environment (with repl.it!) you can use within your browser. Head over [here](https://repl.it/@jajoosam/wikibot-start), and wait for a couple of seconds to fork it. Next, open up `server.js` and put in your Account SID and Auth Token, on lines `7` and `8` ```javascript const accountSid ="XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"; //Account SID const authToken ="XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"; // Auth Token ``` You can see, this environment already has dependencies installed, and an `express` server set up. We still need to give Twilio a URL to send incoming messages to, though ๐Ÿ”— Let's go back to the [WhatsApp Sandbox](https://www.twilio.com/console/sms/whatsapp/sandbox), and put in a webhook URL for incoming messages. ![](https://wikibot.surge.sh/Untitled-3ed5263b-c6d8-492b-ba08-b4644ab502cf.png) This URL must be what you see on the preview panel of your [repl.it](http://repl.it) project + `/incoming` ![](https://wikibot.surge.sh/Untitled-1779b21f-9100-4942-b732-320dc48c5f76.png) We can now finally read messages that are sent to the bot. Add a simple `console.log()` in your webhook handler ๐Ÿ‘‡ ```javascript app.post('/incoming', (req, res) => { console.log(req.body) }); ``` When you send a message to your bot, you should be able to see something like this in your repl console ๐Ÿ‘จโ€๐Ÿ’ป ![](https://wikibot.surge.sh/Untitled-163eb09e-e6ab-4910-badb-d8aa0aa789f7.png) Building an echo bot would look something like this, using `twiml` to write a message ๐Ÿ‘‡ ```javascript app.post('/incoming', (req, res) => { const twiml = new MessagingResponse(); twiml.message(req.body.Body); res.writeHead(200, {'Content-Type': 'text/xml'}); res.end(twiml.toString()); }); ``` But, since we're actually trying to build a useful bot - let's use informative APIs! ## ๐ŸŒ Fetching Information DuckDuckGo has an amazing, free instant answer API. It takes in a query and returns back a summary from WikiPedia and more. A few examples ๐Ÿ‘‰ [WikiPedia](https://api.duckduckgo.com/?skip_disambig=1&format=json&pretty=1&q=WikiPedia), [Macbook Air](https://api.duckduckgo.com/?skip_disambig=1&format=json&pretty=1&q=MacBook%20Air), [Twilio](https://api.duckduckgo.com/?skip_disambig=1&format=json&pretty=1&q=Twilio) I spent some time creating a decent parser which usually returns information from this API. Try pasting this code in your [repl.it](http://repl.it) project, and your [console](https://dsh.re/f7477c) should have stuff about Trump in it ๐Ÿ˜› ```javascript var base = 'https://api.duckduckgo.com/?skip_disambig=1&format=json&pretty=1&q='; var query = 'Donald Trump'; request(base + query, function (error, response, body) { body = JSON.parse(body) if(body["Abstract"] == ""){ body["Abstract"]= body["RelatedTopics"][0]["Text"] } var msg = body["Heading"]+"\n\n"+body["Abstract"]; console.log(msg) }); ``` Pretty straight forward, right? ๐Ÿ˜„ ## ๐Ÿ› ๏ธ Putting it all together To make our actual bot, all we need to do is get the query from our request - which we can get as `req.body.Body` - and use `twmil` to send across the data we collected in `msg` ```javascript app.post('/incoming', (req, res) => { const twiml = new MessagingResponse(); var base = 'https://api.duckduckgo.com/?skip_disambig=1&format=json&pretty=1&q='; var query = req.body.Body; request(base + query, function (error, response, body) { body = JSON.parse(body) if(body["Abstract"] == ""){ body["Abstract"]= body["RelatedTopics"][0]["Text"] } var msg = twiml.message(body["Heading"]+"\n\n"+body["Abstract"]); res.writeHead(200, {'Content-Type': 'text/xml'}); res.end(twiml.toString()); }); }); ``` You now have a fully functionaing WhatsApp bot! Send anything you want to know about your bot ๐Ÿค– and you should see it respond super fast ๐Ÿ’ฌ โšก Adding welcome messages and a little formatting is quite simple, look at the final [repl](https://repl.it/@jajoosam/wikibot) to see how I did it ๐Ÿ‘จโ€๐Ÿ’ป ## ๐Ÿ”— Sharing the bot For others to use this bot, they'll need to join your sandbox first - and send a message just like you did earlier ๐Ÿ‘‰ `join <two-words>` You can create links with this text too - For example this link lets you join my bot ๐Ÿ‘‡ ``` https://wa.me/14155238886?text=join ultramarine-tapir ``` `14155238886` is my bot's number, while `ultramarine-tapir` is the sandbox phrase. ## โšก What's next? Now that you know how to build a bot on WhatsApp, try sending notifications to yourself, and building more useful tools! Twilio has loads of [other mediums](https://www.twilio.com/channels) to message through too! All code for my WikiBot is on [Github](https://github.com/jajoosam/wikibot)! I'm a 15 year old maker ๐Ÿ‘จโ€๐Ÿ’ป For more cool things to make and to stay update with my progress, sign up for [my newsletter ๐Ÿ“ง](https://buttondown.email/jajoosam)
14
posted to Learn by jajoosam (382) 4 months ago
โ–ฒ
47
Starbot
Starbot adds support for appreciation in a discord community! You can give people who helped you stars, and the bot will note it - also creating a leaderboard, and some sort of karma points in the community. When you give a star - it reduces the number you have by one. But everyone starts off with `20` ๐Ÿ˜„ Here's a demo ๐Ÿ‘‡ ![](https://i.imgur.com/suV9ooj.gif) Send a message tagging user(s) like this: `Thanks @amasad and @hayaodeh for creating repl.it โญ` And send only a โญ to see the count ๐Ÿ† Try it out now in the [#bot-usage channel](https://discordapp.com/channels/437048931827056642/439586718681792552) ๐Ÿ’ฌ There's a full API to access the star count available - send `โญ API` - and to see help in the Discord, send `โญ Help` Starbot can also work in other Discord communities - add it to your own for $5: https://bmc.xyz/l/starbot
10
posted to Share by jajoosam (382) 3 months ago
โ–ฒ
16
Santafy your images ๐ŸŽ…
![ezgif.com-video-to-gif](https://storage.googleapis.com/replit/images/1545801167135_cb49d8067df821702ed38ed513ac1811.gi) Santafy automatically adds santa hats to people in your pictures! All processing is done front end - your images remain on your computer at all times ๐Ÿ˜„ I hope it is still Xmas somewhere ๐ŸŽ„ https://santa.4ty2.fun
15
posted to Share by jajoosam (382) 2 months ago
โ–ฒ
10
Make an instrumental version of your Spotify playlist!
[wordLess](https://wordless.4ty2.fun?ref=repltalk) finds instrumentals for songs from your spotify playlist, and loads them up into a shareable page. More in [this](https://twitter.com/jajoosam/status/1086299965247242240) tweet! Check it out ๐Ÿ‘‰ [https://wordless.4ty2.fun](https://wordless.4ty2.fun?ref=repltalk) [Demo ๐ŸŽฅ](https://dsc.cloud/Jajoosam/wl-demo.mp4)
2
posted to Share by jajoosam (382) 1 month ago
โ–ฒ
14
Chat on the terminal
# Chat on the terminal ## Build a realtime chat in your terminal ๐Ÿ’ฌ ![](https://i.imgur.com/OqMNLC2.gif) [Demo](https://chat.jajoosam.repl.run) โฏ๏ธ [Code](https://repl.it/@jajoosam/chat) ๐Ÿ‘จโ€๐Ÿ’ป This is a quick tutorial which helps you build a realtime chat on your terminal - using [socket.io](https://socket.io) - we can build and test super quick thanks to [repl.it](https://repl.it)'s [repl.run](http://repl.run) platform - which displays a terminal on the web ๐ŸŒ ๐Ÿ‘จโ€๐Ÿ’ป ## โš™๏ธ Dependencies We're only using one external dependency in this project - [socket.io](http://socket.io), which helps us communicate realtime between several clients and a server. Along with this, we'll be using node's built in `readline` which lets us collect input from the terminal. ## ๐Ÿ’ Setting up the server Because we're using [socket.io](http://socket.io) - we need to spin up a small server to relay messages too! Just fork this, and you'll be all set ๐Ÿ‘‰ [repl.it/@jajoosam/chat-server](https://repl.it/@jajoosam/chat-server) ```javascript io.on('connection', function (socket) { socket.on('message', function(data) { io.emit("msg", data); }); }); ``` This small block of code listens for any `message`s from any user, and then broadcasts that message to all the users - that simple โœจ ## ๐Ÿ’ฌ Let's get chatting Let's start off by forking [this repl](https://repl.it/@jajoosam/chat-starter) - I've already declared dependencies to make things simple. On `line 3`, replace the `url` with that of the server you just created. Whenever a user connects, let's ask them for their name. Put this code inside the `socket.connect` block. ```javascript rl.question(`What's your name? `, (answer) => { socket.emit("message", `๐Ÿ‘ค : ${answer} has joined the chat`); id = answer; chat(); }); ``` We're sending a message which says a new user has joined the chat, and storing their name for later reference. As you can see - we're also calling the `chat` function, which is currently empty - let's change that! ```javascript rl.question("ยป ", (answer) => { // "ยป " Gives a prompt for the user socket.emit("message", `${id}: ${answer}`); chat(); }); ``` We're prompting for a user to type out a message, then sending it back to the server - also at the end - we're calling `chat` again in case they want to send more messages โŒจ๏ธ ## ๐Ÿ–จ๏ธ Printing out messages If you try running this code now, you'll see that no message you type is printed in the terminal. Let's create a new event listener inside `socket.connect` to listen for messages ๐Ÿ‘‡ ```javascript socket.on('msg', function(data){ console.log("\n" + data); chat(); }); ``` Whenever the server broadcasts a new message to us, we print it out to the `console` - and call `chat` again - so that our user can keep sending messages! ## ๐Ÿ› ๏ธ Hacking this It was pretty simple to build this chat - but it doesn't seem like a conventional one in many ways. Luckily, you can change that ๐Ÿ˜„ **Here are some ideas to tinker with this project ๐Ÿ‘‡** - Let everyone know when a user is typing โŒจ๏ธ - Don't print out messages sent by the same user repeatedly ๐Ÿ”„ - Add color + formatting to the chat with [chalk](https://github.com/chalk/chalk) ๐ŸŒˆ - Take realtime to the next level by broadcasting every character as it's typed ๐Ÿ’ก Check out [this](https://github.com/aviaryan/chattt) open source project for more ideas! Here's the code for the completed project (with a few tweaks!) - feel free to refer to it ๐Ÿ‘จโ€๐Ÿ’ป [https://repl.it/@jajoosam/chat](https://repl.it/@jajoosam/chat) Now, go ahead and share what you've built on [repl talk](https://repl.it/talk/share), and tag me - [@jajoosam](https://repl.it/@jajoosam) ๐Ÿ‘ค
3
posted to Learn by jajoosam (382) 3 months ago
โ–ฒ
13
A blog on the terminal
I tried to build the most hacker like blog possible - let me know what you think! Check it out at [repl.run](https://blog.jajoosam.repl.run/) Guide to building your own is dropping soon :)
6
posted to Share by jajoosam (382) 4 months ago
โ–ฒ
7
An e-book downloader, with repl.run ๐Ÿ“–
Check out the repl.run page [here](https://libert-cli.jajoosam.repl.run/)! Scraping content from libgen, and matching to information from google books for accuracy! So cool that I can share apps that run on the terminal! BTW, this is how [libert.ml](https://libert-cli.jajoosam.repl.run/) started!
0
posted to Share by jajoosam (382) 4 months ago
โ–ฒ
3
Get started with Web Scraping ๐Ÿค–
## Learn to scrape the web by creating your own quotes website ๐Ÿค– ๐Ÿค” ![](https://dsc.cloud/Jajoosam/Ece4h5VzbOGNas2PsmkDr2hD23DCJwOm6b7zUeNt3S7jit1pK8MXoHGenIrPDpVNFUtbaMBivWbLFJuHq5WgnNRM9xZS4djo8TnD.gif) [Demo](https://quote-scraper.jajoosam.repl.co) โฏ๏ธ [Code](https://repl.it/@jajoosam/quote-scraper) ๐Ÿ‘จโ€๐Ÿ’ป There's so much information on the web, but so few APIs ๐Ÿ˜• Web Scraping lets you get content from any webpage, extracting information from `HTML` selectors. This is a super simple guide to help you scrape the web with `Node.js` , in less than 20 minutes ๐Ÿ•’ We'll learn to use developer tools to see `HTML` selectors, extract the content in `Node.js` with `x-ray` - and use `pug` to render quotes we get! ## ๐Ÿ› ๏ธ Setup Um, there's none really. Just load up this repl - [repl.it/@jajoosam/quote-scraper-starter](https://repl.it/@jajoosam/quote-scraper-starter) โœจ ![](https://dsc.cloud/Jajoosam/oeCd23rkkJ1pvV0hrCioQJlzUw3dCHBTodyhvq0g8AjxC9GAUmEbVUBKRs194SHrOyccgcDxcwPgj3cSDp2J3ddfk6aNoAETKNBb.png) We'll talk about all the tools and dependencies we use as we continue! ## ๐Ÿ“Š Understanding Structure [Quotesondesign.com](http://quotesondesign.com) has some nice quotes - and is an easy introduction to scraping stuff on the web. Another great part - it loads up a random quote each time! Open the website up, right click on the quote, and then hit `Inspect` ๐Ÿ‘‡ !()[(https://dsc.cloud/Jajoosam/gnFthrFnWt45BA1AtRUTTzOEr1PdUwIM4RODxVWydpLZAeVDXkgkw6JCtbTF0EYXUpA6ypZ0eZPNkqt18WN7A2TbiFojxRYd9GnY.gif) You can now see a view of the entire document ๐Ÿ“œ Go ahead and click all the small triangles to expand this view. You'll be able to see that the quote itself is inside a paragraph, in a `div` with id `quote-content`, while the author's name has an id of `quote-title`. ![](https://dsc.cloud/Jajoosam/NRMd90XWrYqR38kgs1EgPmlTlJ77jwxduW5bkBce6BRHkd8qjumaKzRQnNwRL5BVLC3IDnGydTAAx3yH5r2y2faJIyP2p9wB1y7L.png) ## โฌ‡๏ธ Getting the quotes To scrape information from a web page, you generally request its `HTML`, and then extract the content you want with selctors, like `id`s, `classes`, and `HTML tags`. When we inspected [Quotesondesign.com](http://quotesondesign.com), we saw that the quote itself was in a `div`, with `id=quote-content`, nested inside a `<p>` (Paragraph element) - while the author's name was inside an element with `id=quote-title`. Having this information makes scraping super easy ๐Ÿ™Œ - we'll use a library called [x-ray](https://github.com/matthewmueller/x-ray) - which makes our job very straightforward! It's already installed in the repl you're using. Try adding this code to your `index.js` file ๐Ÿ‘‡ ``` x('https://quotesondesign.com', { quote: "#quote-content p", author: "#quote-title" } )(function(err, result){ console.log(result) }); ``` Run your code, and the console on the bottom right will look something like this ๐Ÿ‘€ ![](https://dsc.cloud/Jajoosam/lIGAkvplrgDFKSO4zs9JQMJDi2k62rMb2avtZ0vKWR0o1CyBDOxKnln0HGNG9pLenZmjjYiI6gWYuBvGVraFG8BjSHlwxIJFHJ8H.png) `x-ray` gives you a nice `json` object, which you can now render! You've now successfully scraped the web ๐ŸŽ‰ ## ๐Ÿ“œ Render those quotes If you see the file tree in the sidebar, you'll see `quotes.pug` - a template which can render quotes passed to it. We're using the [pug](https://pugjs.org/api/getting-started.html) templating engine to do this - which we've initialized on line `6` One thing to note is that `pug` is whitespace sensitive: `HTML` tags are nested inside each other with tabs โŒจ๏ธ ![](https://dsc.cloud/Jajoosam/9jGShYBQ9zFliv41bjmwWfHHZJCeU0jxph9ISkihBWby28iyasRysT7IrEHgYAlgJyW1qQvgH0kR6liVNVDua2zjYHGtnxL9I80X.png) All we have to do now is pass the quote we get from `x-ray` to `pug`! This is very easy to do on our `express` server, just change your `app.get` block to this ๐Ÿ‘จโ€๐Ÿ’ป ``` app.get('/', (req, res) => { x('https://quotesondesign.com', { quote: "#quote-content p", author: "#quote-title" } )(function(err, result){ res.render('quote', result) console.log(result) }); }); ``` Run your repl, and this is what you'll see ๐Ÿ˜ฎ ![](https://dsc.cloud/Jajoosam/6O4MLq9QgQ4gbz69cYamgIEpqUwnoDEsU88pLw0MIZKZLSo6Mceup0RYh6VApkzXJeZpqIRb6ktnx3YLPMjqWOHSdr97FH4KZ4QS.png) Pretty neat, huh? We've not written any css of my own, the page looks readable just because of the simple [sakura.css](https://oxal.org/projects/sakura/) library. Remove line `4` in `quote.pug` and get ready for ugly ๐Ÿคฎ ## โšก Putting your skill to use There is a lot you can do with web scraping - and this guide has given you all the basic knowledge you need. I'm excited to see what you do with this ๐Ÿ˜„ **Here are a few cool things to try ๐Ÿ‘‡** - Scrape different data points - weather, latest news, bitcoin price ๐Ÿ˜› - and make a dashboard for yourself - Scrape [IMDb](https://imdb.com) to get a list of all movies currently in theatres ๐ŸŽฆ - Scrape [Repl Talk](https://repl.it/talk) and make an API for it ๐Ÿ‘จโ€๐Ÿ’ป Whatever you build, be sure to share it in the comments ๐Ÿ’ฌ [Here](https://blog.jajoosam.repl.run)'s what the final code looks like, feel free to refer to it ๐Ÿ‘‡ [https://repl.it/@jajoosam/quote-scraper](https://repl.it/@jajoosam/quote-scraper)
0
posted to Learn by jajoosam (382) 3 months ago
โ–ฒ
1
Bruteforce method to approximate Pi!
I created an interactive demo of a simple monte carlo integration in order to derive ฯ€ - let me know what you think ๐Ÿ˜„ https://pi.4ty2.fun ![mc demo](https://storage.googleapis.com/replit/images/1540660616027_a55a418f1d82f2f062b1224d1337d4cf.gi)
0
posted to Share by jajoosam (382) 4 months ago
โ–ฒ
1
Search for rhymes, but with your voice ๐Ÿ—ฃ๏ธ
I tried exploring the annyang library to experiment with speech recognition in a very simple web app! Let me know if you think this is cool - I'd love to create a tutorial :) You gotta open the repl on an external page, with https ๐Ÿ‘‰ https://rhyme.4ty2.fun
0
posted to Share by jajoosam (382) 4 months ago