Skip to content

Commit

Permalink
Uses localstorage
Browse files Browse the repository at this point in the history
  • Loading branch information
SomajitDey committed Sep 19, 2024
1 parent 76c1016 commit fb23079
Show file tree
Hide file tree
Showing 3 changed files with 98 additions and 74 deletions.
58 changes: 44 additions & 14 deletions app/server.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
// Main entry point for the server. Deploys background worker in "bg-worker.js" for handling networking.

spaHide("jsAlert");

let myWorker = null;
let getFrom, postTo, TGchatID;
let numReadMsgs = 0;
let numTotalMsgs = 0;
const logs = document.getElementById("logs");
Expand Down Expand Up @@ -70,8 +71,8 @@ function genUUID() {
}

const fetchChatID = async () => {
logThis("Fetching Telegram chat ID")
const apiEndpoint = 'https://api.telegram.org/bot' + document.getElementById("apiKey").value + '/getUpdates';
logThis("Fetching Telegram chat ID");
const apiEndpoint = 'https://api.telegram.org/bot' + document.getElementById("TGbotKey").value + '/getUpdates';
const response = await fetch(apiEndpoint); // Make request
if (! response.ok) {
logThis(`Telegram API status code: ${response.status}. Is Bot API Token ok?`);
Expand All @@ -80,7 +81,9 @@ const fetchChatID = async () => {
}
const data = await response.json();
try {
TGchatID = data.result[0].message.chat.id;
const TGchatID = data.result[0].message.chat.id;
document.getElementById("chatID").value = TGchatID;
localStorage.setItem("TGchatID", TGchatID);
} catch (e) {
alert("Failed to fetch chat ID. Send any text to the Telegram Bot then try again.");
}
Expand All @@ -91,19 +94,18 @@ function config() {
const uuid = document.getElementById("uuid").value;
// Choose a random index in [0, relayList.length]. Use first two nibbles of uuid as random number in range [0,256].
const randomIdx = Math.floor(parseInt(uuid.substr(0,2),16)*relayList.length/256);
getFrom = relayList[randomIdx] + '/' + uuid;
postTo = 'https://api.telegram.org/bot' + document.getElementById("apiKey").value + '/sendMessage';
document.getElementById("config").innerHTML = `<p class="alert alert-success">HTML Form Action URL: <u>${getFrom}</u></p>`;
document.getElementById("testFormBtn").setAttribute("formaction", getFrom);
spaShowHide("testForm");
document.getElementById("config").scrollIntoView();
const getFrom = relayList[randomIdx] + '/' + uuid;
localStorage.setItem("getFrom", getFrom);
const postTo = 'https://api.telegram.org/bot' + document.getElementById("TGbotKey").value + '/sendMessage';
localStorage.setItem("postTo", postTo);
spaGoTo("server");
localStorage.setItem("loggedIn", "true");
}

function startWorker() {
if (getFrom === undefined) {
config();
if (myWorker) {
return;
}

myWorker = new Worker("app/bg-worker.js");

// Register handler for messages from the background worker
Expand All @@ -122,17 +124,26 @@ function startWorker() {
}
}

const getFrom = localStorage.getItem("getFrom");

// Communicate key data to the background worker
myWorker.postMessage([getFrom, postTo, TGchatID]);
myWorker.postMessage([getFrom, localStorage.getItem("postTo"), localStorage.getItem("TGchatID")]);

toggleServer.value = "Kill Server";
toggleServer.disabled = false;

logThis("Server started");
document.getElementById("serverStatus").innerHTML = 'Live <span class="spinner-grow spinner-grow-sm"></span>';

document.getElementById("formActionURL").innerHTML = `<p class="alert alert-success">HTML Form Action URL: <u>${getFrom}</u></p>`;
document.getElementById("testFormBtn").setAttribute("formaction", getFrom);
spaShow("testForm");
}

function stopWorker() {
if (! myWorker) {
return;
}
myWorker.terminate();
myWorker = null;
console.log("Worker terminated");
Expand All @@ -148,3 +159,22 @@ function toggleWorker() {
startWorker();
}
}

function signout() {
stopWorker();
localStorage.clear();
location.reload();
}

function main() {
// Enable config if no prior settings found in localStorage
if (localStorage.getItem("loggedIn")) {
startWorker();
spaGoTo("server");
} else {
spaGoTo("setup");
}

}

spaHide("jsAlert");
44 changes: 23 additions & 21 deletions app/spa.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,30 @@
const spaHomePageID = document.querySelector(".spa-page").id; // Assuming first spa-page class is the home / hero page
let spaCurrentPageID = spaHomePageID;

{
const jsAlerts = document.getElementsByClassName("spa-js");

for (let el of jsAlerts) {
el.style.display = 'none';
}
function spaShow(id) {
document.getElementById(id).style.display = 'block';
}

const pages = document.getElementsByClassName("spa-page");
function spaHide(id) {
document.getElementById(id).style.display = 'none';
}

for (let el of pages) {
el.style.display = 'none';
function spaToggle(id) {
let x = document.getElementById(id);
if (x.style.display === "none") {
x.style.display = "block";
} else {
x.style.display = "none";
}
}

function spaGoTo(id) {
document.getElementById(spaCurrentPageID).style.display = 'none';
spaShow(id);
spaCurrentPageID = id;
spaTop();
}

function spaTop(){
document.getElementById(spaCurrentPageID).scrollIntoView();
}
Expand All @@ -27,19 +37,11 @@ function spaBottom(){
document.getElementById(spaCurrentPageID).scrollIntoView(false);
}

function spaGoTo(id) {
document.getElementById(spaCurrentPageID).style.display = 'none';
document.getElementById(id).style.display = 'block';
spaCurrentPageID = id;
spaTop();
}
{
const pages = document.getElementsByClassName("spa-page");

function spaShowHide(id) {
let x = document.getElementById(id);
if (x.style.display === "none") {
x.style.display = "block";
} else {
x.style.display = "none";
for (let el of pages) {
el.style.display = 'none';
}
}

Expand Down
70 changes: 31 additions & 39 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,9 @@ <h1>Welcome to EasyForm</h1>
<div class="row">
<div class="col-sm-2 text-bg-secondary text-center pt-5">
<div class="sticky-top">
<h3>Menu</h3>
<div class="d-flex flex-column justify-content-center align-items-center mt-2 mb-3 pb-3">
<button type="button" class="btn btn-primary mt-5" onclick="spaGoTo('about');">About</button>
<button type="button" class="btn btn-primary mt-4" onclick="spaGoTo('server');">Server</button>
<button type="button" class="btn btn-primary mt-4" onclick="spaGoTo('inbox'); updateUnreadCount();">Inbox <span id ="unread" class="badge bg-danger">0</span></button>
<button type="button" class="btn btn-primary mt-4" onclick="spaGoTo('server');">Server</button>
<a href="https://github.com/somajitdey/easyform" class="btn btn-primary mt-4">Source</a>
<a href="https://buymeacoffee.com/SomajitDey" class="btn btn-primary mt-4">Donate</a>
<a href="https://github.com/SomajitDey/EasyForm/discussions/1" class="btn btn-primary mt-4">Contact</a>
Expand All @@ -41,45 +39,31 @@ <h3>Menu</h3>
</div>


<p class="alert alert-danger spa-js">You don't have JavaScript enabled! This page cannot function without it.</p>
<p class="alert alert-danger" id="jsAlert">You don't have JavaScript enabled! This page cannot function without it.</p>

<div class="spa-page" id="about">
<section>
<h3>About</h3>
<p>EasyForm gives you a free and easy, self-hosted form backend solution for adding (contact) forms to your static website(s). You don't, however, need
to configure any server or install anything. Your browser becomes your server!
</p>
<p>Your smartphone or PC is perhaps always connected to the internet, even on the move. So, if you keep your browser open there, and a very
light-weight JavaScript server runs in it, you are essentially "self-hosting" for free. EasyForm capitalizes on this. Also, the ability to run in a
browser makes EasyForm platform-independent!
<p>EasyForm gives you a free and easy, self-hosted form backend solution that runs in your browser! Just sign up and then embed the following HTML
form in your website. Therefrom, as long as this Tab is open in your browser, whenever your users submit the form in your website, your Inbox here
will be populated. You will also be notified via Telegram.
</p>
Working with EasyForm is dead simple. All you need to do is the following:
<ul>
<li>Create a Telegram Bot and store its API token. This is easy. Just open a chat with <a href="https://t.me/botfather">@BotFather</a> in Telegram
and send: /newbot
</li>
<li>Follow instructions in the <b>Config:</b> section below. You will be required to choose a Form Action URL there</li>
<li>Use your chosen Form Action URL in your (contact) form</li>
</ul>
Whenever your users submit the form, you will get a Telegram text containing the users' form data from the Telegram Bot you created.
<p>Here is an HTML code snippet you can readily embed as a basic contact form in your website. Just replace FormActionURL with the actual URL.</p>
<pre><code class="language-html">
&lt;form action=&quot;FormActionURL&quot; method=&quot;POST&quot; target=&quot;hidden_iframe&quot; autocomplete=&quot;on&quot;&gt;
&lt;!-- Replace XXXXX with the form action URL given by this app upon sign up` --&gt;
&lt;form action=&quot;XXXXX&quot; method=&quot;POST&quot; target=&quot;hidden_iframe&quot; autocomplete=&quot;on&quot;&gt;
&lt;input type=&quot;hidden&quot; name=&quot;From&quot; value=&quot;sample&quot;&gt;
&lt;input type=&quot;email&quot; name=&quot;Email&quot; placeholder=&quot;Your Email&quot;&gt;
&lt;input type=&quot;text&quot; name=&quot;Name&quot; placeholder=&quot;Your Name&quot;&gt;
&lt;input type=&quot;text&quot; name=&quot;Message&quot; placeholder=&quot;Your Message&quot; autocomplete=&quot;off&quot;&gt;
&lt;input type=&quot;submit&quot; value=&quot;Submit&quot;&gt;
&lt;input type=&quot;reset&quot; value=&quot;Reset&quot;&gt;
&lt;button type=&quot;submit&quot;&gt;Submit&lt;button&gt;
&lt;input type=&quot;reset&quot;&gt;Reset&lt;button&gt;
&lt;/form&gt;
&lt;!-- when the form is submitted, the server response will appear in this iframe, hidden from view --&gt;
&lt;iframe name=&quot;hidden_iframe&quot; src=&quot;about:blank&quot; hidden&gt;&lt;/iframe&gt;
</code></pre>
<strong>Tips:</strong>
<ul>
<li>Securely store your Bot API token and Form Action URL for future reference.</li>
<li>For reproducibility upon page reload/refresh, reuse the previous values, often suggested by the browser, during config.</li>
</ul>

<p><button class="btn btn-primary mt-4" onclick="main();">Let's get started</button></p>

<h3>Powered by</h3>
<ul class="nav nav-pills nav-justified">
<li class="nav-item"><a class="nav-link" href="https://github.com/nwtgck/piping-server">piping-server</a></li>
Expand All @@ -93,26 +77,31 @@ <h3>Powered by</h3>
</ul>
</section>
</div>
<div class="spa-page" id="server">
<div class="spa-page" id="setup">
<section>
<h3>Server</h3>
<div id="config">
<form onsubmit="startWorker(); return false;" autocomplete="on">
<h3>Setup</h3>
<form id="config" onsubmit="config(); startWorker(); return false;" target="hidden_iframe">
<p>Setup in just 3 easy steps.</p>
<label for="apiKey" class="form-label">1. Enter your Telegram Bot API Token (available from <a href="https://t.me/botfather">@BotFather</a>):</label>
<input type="text" id="apiKey" class="form-control" required>
<label for="TGbotKey" class="form-label">1. Enter your Telegram Bot API Token (available from <a href="https://t.me/botfather">@BotFather</a>):</label>
<input type="text" id="TGbotKey" class="form-control" autocomplete="on" required>
<br>
<p>2. Send any text to the Bot. Then, click Fetch Chat ID. Or, enter your chat ID if you know what you're doing :-)</p>
<p>2. Send any text to the Bot. Then, click Fetch Chat ID. Do not enter your chat ID by hand.</p>
<button onclick="fetchChatID();">Fetch Chat ID</button>
<input type="text" id="chatID" placeholder="Chat ID" required>
<br><br>
<p>3. Generate or enter your EasyForm API Key:</p>
<button onclick="genUUID();">Generate API Key</button>
<input type="text" id="uuid" size="8" placeholder="Enter API Key" required>
<br><br>
<button type="submit" class="btn btn-success">Use the above to launch server</button>
<button type="submit" class="btn btn-success">Sign in</button>
</form>
</div>
<div id="testForm" style="display:none">
</section>
</div>
<div class="spa-page" id="server">
<section>
<h3>Server</h3>
<div id="formActionURL"></div>
<div id="testForm">
<p>Test if everything is working properly with the following sample form. You should get a Telegram message upon clicking Post! Your posted data should also be logged below.</p>
<form method="POST" target="hidden_iframe">
<input type="hidden" name="From" value="tester">
Expand All @@ -132,11 +121,14 @@ <h3>Server</h3>
</div>
<br><br>
<h3>Log</h3>
<input type="button" id="toggleServer" value="Kill Server" disabled=true; onclick="toggleWorker();">
<button onclick="signout();">Sign out</button>
<button onclick="spaBottom();">Bottom</button>
<br><br>
<div id="logs" class="text-bg-info">
<p>Server logs will be shown here</p>
</div>
<br><br>
<input type="button" id="toggleServer" value="Kill Server" disabled=true; onclick="toggleWorker();">
<button onclick="spaTop();">Top</button>
</section>
</div>
Expand Down

0 comments on commit fb23079

Please sign in to comment.