Skip to content

RajnishKMehta/Scream2Wish

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

74 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

What Is This?

Scream2Wish is a completely 100% usefulπŸ‘€, mildly chaotic Android app that forces you to scream as loud as you can to break a genie's lamp and only then lets you make a wish.

Your wish gets sent to the internet via a Cloudflare Worker β†’ GitHub Actions pipeline and lives forever in a public repo. In return, you get to read a random stranger's note. Whether that's comforting or unsettling is entirely up to you.

It is a fun project made for timepass and learn.


Download

Download APK

Install on Android 10+ devices (sideloading required enable "Install from unknown sources" in settings).


The Full Experience

Step 1 β€” Permissions Gate

The app opens with an animated permission screen asking for microphone access (to detect your screams) and vibration (to annoy you while you're idle). You cannot proceed without granting both. The back button is "defective."

Step 2 β€” Joke Login

A suspiciously serious login screen asks for your real name and a password. The name is used throughout the experience. The password has a specific validation rule β€” figure it out yourself.

  • 1 wrong attempt β€” a video overlay starts playing in the background.
  • 4 wrong attempts β€” a roast panel slides up from the bottom. It picks & shows one messages mocking your inability to read placeholder/input box name text, reveals the correct password with a copy button, After the roast panel appears, the math effect overlay video and sound cut out entirely. Subsequent wrong attempts trigger text-to-speech - a random insult from a pool of eight, delivered in English, no repeat guaranteed.

Step 3 β€” The Lamp

A countdown from 5. Then the main event.

A genie lamp sits in the center of the screen. A vertical amplitude meter in the top right corner reflects your scream in real time. The louder you scream, the faster the lamp breaks. Stop screaming for even a second and the lamp fully resets to normal. The phone vibrates at you constantly while you're silent encouragement.

  • 25% progress β€” the lamp starts cracking. The genie speaks to you via text-to-speech.
  • 55% progress β€” the lamp is half destroyed.
  • 100% progress β€” the lamp shatters and one of three characters emerges:
Value Character Probability
0 Red Mermaid Red Mermaid (yes, from genie lamp😁) 30%
1 Genie Genie 35%
2 Blue Mermaid Blue Mermaid 35%

Step 4 β€” Make Your Wish

The character that emerged from the lamp greets you via text-to-speech and asks you to type your wish. Then it asks you to leave a note for the world. Both steps have a skip option, but after all that screaming, why would you?

Step 5 β€” The End

The end screen shows two tabs: Random Note (default) and My Note.

Random Note fetches a stranger's message from the public wishes repo β€” their name, their note, and when they screamed. If the fetch fails, you see the error reason and a retry button.

My Note shows the note you left, plus the live send status. The app automatically retries sending up to 6 times per session (immediate β†’ 3 s β†’ 5 s β†’ 5 s β†’ …). The attempt counter lives in memory and resets on every app open, so you always get 6 fresh auto-retries. If all 6 fail, a Retry send button appears. A 401/403 auth error stops auto-retries for the session (but manual retry still works and auto-retry resumes on next open). Once sent, a green indicator confirms your note is out in the world.

You can share your wish at any point.

Below the notes a creator card shows: a link to the public Scream2Wish website (where all wishes and notes are visible), and a short about section for the creator. The profile picture alternates between a local photo and the GitHub avatar β€” fetched only once a random note has loaded. The switch animation is a crossfade, and which image appears first is randomised on every app open.

That's it. There is no restart button. The app is done with you.


Architecture

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                        Android App (Expo)                        β”‚
β”‚                                                                  β”‚
β”‚  Permission Gate β†’ Fake Login β†’ Scream Main β†’ End Screen        β”‚
β”‚                                                                  β”‚
β”‚  On every open:  trySendWish() runs in background               β”‚
β”‚  On end screen:  fetchAndStoreRandomWish() runs in background    β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                               β”‚ POST  (wish + note + name)
                               β”‚ Header: x-api-key
                               β–Ό
              β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
              β”‚   Cloudflare Worker             β”‚
              β”‚   scream2wish.rajnishkmehta     β”‚
              β”‚   .workers.dev                  β”‚
              β”‚                                 β”‚
              β”‚  Validates API key              β”‚
              β”‚  Forwards repository_dispatch   β”‚
              β”‚  to GitHub API                  β”‚
              β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                               β”‚ repository_dispatch event
                               β–Ό
              β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
              β”‚   GitHub Actions               β”‚
              β”‚   (Scream2Wish-wishes repo)    β”‚
              β”‚                                β”‚
              β”‚  wish-handler.yml              β”‚
              β”‚  Generates a unique ID         β”‚
              β”‚  Saves wish JSON to repo       β”‚
              β”‚  Updates index.json            β”‚
              β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                               β”‚ committed to main branch
                               β–Ό
              β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
              β”‚   Public JSON Store             β”‚
              β”‚   /wishes/index.json           β”‚  ← array of all IDs
              β”‚   /wishes/{id}.json            β”‚  ← individual wish
              β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                         β”‚
           β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
           β”‚             β”‚             β”‚
           β–Ό             β–Ό             β–Ό
      App reads     Website reads  Anyone can
      random wish   all wishes     read the raw
      on end screen publicly       GitHub JSON

Why a Cloudflare Worker in the middle?

You cannot safely embed a GitHub token inside a mobile APK it would be publicly extractable. The Cloudflare Worker holds the GitHub token securely as an environment secret. The app only needs a rotating API key to talk to the Worker, which is far easier to rotate without a new app release.

Why still use an API key if it can be extracted from the APK?

Yes, an API key inside an APK isn’t fully secure and can be extracted with enough knowledge. But it still adds a useful layer of protection. Without any key, the API would be completely open and anyone could spam it easily. Requiring a key creates a basic barrier that prevents casual misuse and automated abuse. It’s not perfect security, but it’s a practical way to reduce spam and keep things under control.


Tech Stack

App

Tech Purpose
Expo + React Native Core framework
expo-audio Real-time microphone metering for scream detection
expo-speech Text-to-speech for the genie / mermaid character
expo-video Punishing video overlay on the login screen
expo-router File-based navigation
expo-updates OTA updates β€” no store release required for fixes
expo-clipboard Clipboard access for copying the password from the roast panel
react-native-mmkv Fast local key-value storage
react-native-reanimated Smooth animations
lucide-react-native Icons

Infrastructure

Tech Purpose
Cloudflare Workers Secure API proxy between app and GitHub
GitHub Actions Wish persistence pipeline
GitHub Pages + Vite Public wishes board website
EAS Build Automated APK builds via GitHub Actions

Local Storage Reference

Key Type Description
name string User's real name from login.
ginie number Character ID: 0 (Red Mermaid), 1 (Genie), 2 (Blue Mermaid).
isginiereleased boolean true if lamp was fully broken; gates re-entry logic.
mywish string The wish text typed by the user.
mynote string The user's personal note (required).
iscompleted boolean true if the wish + note flow is finished.
issent boolean true if successfully sent to the server.
rnote string Random stranger's note fetched from repo.
rnotefrom string Name of the stranger who wrote the random note.
rnoteat number Unix timestamp (ms) of the stranger's scream.

Running Locally

Prerequisites: Node.js, pnpm, an Android device (emulators won't work β€” no real mic metering)

# Clone the repo
git clone https://github.com/RajnishKMehta/Scream2Wish.git
cd Scream2Wish

# Install dependencies
pnpm install

# Set environment variables
# Create a .env file:
# EXPO_PUBLIC_WISH_WORKER_URL=https://scream2wish.rajnishkmehta.workers.dev
# EXPO_PUBLIC_WISH_WORKER_API=your_api_key_here

# Start Expo dev server
pnpm dlx expo start

To build a standalone APK:

# Requires EAS CLI and an Expo account
eas build --platform android --profile preview

About the Worker

Read here


Related Repos

Repo Description
Scream2Wish This repo: app + worker
Scream2Wish-wishes Public JSON store of all submitted wishes

Why Does This Exist?

The DEV April Fools Challenge 2026 prompt was simple: build something completely useless or silly. Something that makes people ask "why on earth did they build this?"

The answer here is: because it required a scream-detection algorithm, a Cloudflare Worker, a GitHub Actions pipeline, three different characters (two of which are mermaids coming out of a lamp), text-to-speech, real-time vibration feedback, fake login validation, OTA updates, and a public wishes board all in service of letting someone type a wish into their phone.

It is overengineered on purpose. It is useless on purpose. And it absolutely works.


License

MIT - free to use, fork, or scream at.


Made with chaos and questionable priorities by Rajnish Mehta

GitHub Dev.to LinkedIn Twitter Instagram

About

An Android app where you scream to break a genie lamp and send your wish to GitHub

Topics

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors