How can I create a Google Chrome extension to automate WhatsApp web tasks?

I’m trying to create a Google Chrome extension that will automate all the tasks of WhatsApp web, including sending text messages, audio files, and documents. I’m new to Chrome extension development and I’m not sure where to start.
I’ve done some research and found Baileys api (https://github.com/adiwajshing/Baileys#baileys—typescriptjavascript-whatsapp-web-api) but not sure that how it could be used in chrome extension development.

Can someone provide some guidance or a starting point for creating such an extension? Are there any existing libraries or resources I can use to simplify this task?

Any help would be greatly appreciated. Thanks in advance!

** background.js**
chrome.tabs.query({url: "https://web.whatsapp.com/"}, function(tabs) {
  if (tabs.length > 0) {
    // The tab already exists, so activate it
    chrome.tabs.update(tabs[0].id, {active: true});
    
  } else {
    // The tab doesn't exist, so create a new one
    chrome.tabs.create({url: "https://web.whatsapp.com/"});
  }
});

{
**manifest.json**
    "manifest_version": 3,
    "name": "My Extension",
    "version": "1.0.0",
    "icons": {
        "16": "icons/icon16.png",
        "32": "icons/icon32.png",
        "64": "icons/icon64.png",
        "128": "icons/icon128.png"
      },
    "description": "Opens a specific tab URL if it doesn't exist",
    "host_permissions": [
        "https://web.whatsapp.com/**"
      ],
    
    "permissions": [
      "tabs",
      "scripting"
      
    ],
    "background": {
      "service_worker": "background.js"

    },
    "action": {
        "default_popup": "options.html"
      }
  }
  

ASP .NET and JS interface – gauge

I am quite new to making web apps via asp .net using js components. I have this .aspx html code:

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Homepage.aspx.cs" Inherits="BpWeb.Homepage" %>

<!DOCTYPE html>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <meta charset="utf-8" />
    <title>Gauge Example</title>

    <!-- Include the Gauge.js library -->
<!-- Raphael must be included before justgage -->
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/raphael/2.1.4/raphael-min.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/justgage/1.2.9/justgage.min.js"></script>

</head>
<body>
    <form runat="server">
        <div>
            <!-- Container for the gauge -->
            <div id="gauge"></div>
            <button id="ClickMe" runat="server" onclick="Click"></button>
        </div>
    </form>

    <!-- Initialize the gauge on page load -->
    <script>
        var gauge = new JustGage({
            id: "gauge",
            value: 0,
            min: 0,
            max: 10,
            title: "My Gauge",
            label: "Value"
        });
    </script>
</body>
</html>

Which simply creates 1 gauge and one button. I want to implements function Click in my .cs file which set value of this gauge to some value – eg. 20. So it means when I click on button ClickMe, the value of my gauge will change from 0 to 20.
Can anyone help me?

I tried some tips from ChatGPT, but nothing works

Cannot read properties of undefined (reading ‘value’): Todo List

I get back value undefined. I tried to change the code around and make sure the code is working propertly, but can’t figure it out.

//Const, lets, and var

const form = document.getElementById('todoForm');
const todoInput = document.getElementById('todoInput')
//List

let todos = []
//Values


form.addEventListener('submit', event => {
    event.preventDefault()

    saveTodo();
})
//Save todo

function saveTodo() {
    const todoValues = todoInput.add.value;

    let values = {
        value: todoValues,
        checked: false,
        color: '#' + Math.floor(Math.random()*16777215).toString(16)
    }

    todos.push(values)
}

console.log(todos)

How to make a discord bot reply to a new message after the first one is sent

I’m trying to make a math minigame command of some sorts and I I’m trying to make my bot check the newest message sent for the answer if the math problem instead of the message that started the command

I tried using this but it wont check the newest sent message, rather is checks the message with “s!mathMinigame” instead

if(message.content === "s!mathMinigame"){
      var number1 = Math.floor(Math.random() * 100) + 1;
      var number2 = Math.floor(Math.random() * 100) + 1;
      message.reply(`${number1}+${number2}=?`)
      var answer = number1 + number2
      console.log(answer)
      setTimeout(() => { 
        if(message.content.channel === answer){
          return message.reply("Correct!")}
        else{return message.reply(`sorry, either your answer was incorrect, or you ran out of time! the answer is ${answer}, please use __s!mathMinigame__ to try again!`)}}, 5000);

Mapping in subsxribe cause undefined error

I have method to get data from BE

Here is it

 getChartsData(): any {
const documentStyle = getComputedStyle(document.documentElement);
const textColor = documentStyle.getPropertyValue('--text-color');
const textColorSecondary = documentStyle.getPropertyValue(
  '--text-color-secondary'
);
const surfaceBorder = documentStyle.getPropertyValue('--surface-border');

this._testFileService.getFileData().subscribe((result) => {
  console.log(result);
  console.log(
    result.map((obj: any) => {
      obj.city;
    })
  );

}

My problem that console.log(result); return array of 369 objects

But console.log( result.map((obj: any) => { obj.city; }) );

Return undefined

How I can solve this?

My problem that

How can I show the data I get from mongo with js on my web page?

I want to pull data from Mongodb and display it on my web page. To create a button, press this button and the data should appear on the screen.

html :

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css"
        integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
</head>
<style>
    .democlass {
        display: block;
        width: 100%;
        height: 34px;
        padding: 6px 12px;
        font-size: 14px;
        line-height: 1.42857143;
        color: #555;
        background-color: #fff;
        background-image: none;
        border: 1px solid #ccc;
        border-radius: 4px;
        margin-top: 10px;
        margin-bottom: 10px;
    }
</style>

<body>
    <h1>Posting data to mongo</h1>

    <form class="containter" id="container" method="post" action="/">
        <div id="divInputs">
            <div class="form-group">
                <input class="form-control" name="title" id="title1">
            </div>
            <div class="form-group">
                <input class="form-control" name="content" id="title2">
            </div>
        </div>
        <button>add mobgodb</button>
    </form>
    <button type="button" id="btnCreateInput">Yeni Input</button>
    <button type="button" value="Result" onclick="getData()">getData</button>
    <form class="containter" method="post" action="/">
    </form>
    <div>
        {% for doc in details %}
            <p>{{doc['allSentences']}}</p>
            <p>{{doc['time']}}</p>
        {% endfor %}
    </div>
    
    <script>
        let inputCount = 0;
        const divInputs = document.getElementById('divInputs');
        document.getElementById('btnCreateInput').addEventListener("click", function () {
            inputCount++;
            const newInput = document.createElement('input');
            newInput.type = "text";
            newInput.id = "input" + inputCount;
            newInput.className = "form-control";
            newInput.name = "text" + inputCount;
            const newDiv = document.createElement('div');
            newDiv.id = "div" + inputCount;
            newDiv.className = "form-group";
            newDiv.appendChild(newInput);
            divInputs.appendChild(newDiv);

        }) 
    </script>
    <script src="https://cdn.jsdelivr.net/npm/[email protected]/browser.min.js"></script>
    <script src="server.js"></script>
</body>

</html>

js:

const express = require('express');
const mongoose = require('mongoose');
const app = express();
const ejs = require('ejs');
app.set('view engine', 'ejs');
const bodyParser = require("body-parser");

app.use(bodyParser.urlencoded({ extended: true }))

const url = "url";

mongoose.connect(url, { useNewUrlParser: true, useUnifiedTopology: true })
    .then((result) => console.log("Basarili"))
    .catch((err) => console.log(err))

const notesSchema = {
    text1: String,
    text2: String,
    text3: String,
    text4: String,
    text5: String,
    text6: String,
    text7: String,
    text8: String,
    text9: String,
    text10: String,
    text11: String,
    text12: String,
    text13: String,
    text14: String,
    text15: String,


}
const resultsSchema = {
    allSentence: String,
    time: Number
}
const Result = mongoose.model("Result", resultsSchema);
const Note = mongoose.model("Note", notesSchema);

async function getItems(){

    const Items = await Result.find({}).sort({_id:-1}).limit(1);
    return Items;
  
  }

app.get("/", function (req, res) {
    getItems().then(function(FoundItems){
        res.render('index', {resultsList: FoundItems});
      });
})

app.post("/", function(req, res) {
    let newNote = new Note({
        text1: req.body.title,
        text2: req.body.content,
        text3: req.body.text1,
        text4: req.body.text2,
        text5: req.body.text3,
        text6: req.body.text4,
        text7: req.body.text5,
        text8: req.body.text6,
        text9: req.body.text7,
        text10: req.body.text8,
        text11: req.body.text9,
        text12: req.body.text10,
        text13: req.body.text11,
        text14: req.body.text12,
        text15: req.body.text13,


    });
    newNote.save();
    res.redirect('/');
})

app.listen(5500, function(){
    console.log("server is running on 5500");
})


var cumle = "";

async function getData(){
    try {
        const post = await Result.find({}).sort({_id:-1}).limit(1);
        console.log(post);
    } catch (error) {
        console.log(error.message);
    }
}
function display() {
    alert("Hello world!");
 }


getData();

Despite trying many methods, I can’t get any results. Can you help me ?

I create a ejs file and this file moved to view is not working to or i cant do it.

Return the type of an object from an array of objects

How can I type the getFieldsBySlug function so that it returns a typed object

For example:

getFieldsBySlug('price', 'area')

// Return { label: “Price, $”, slug: “price”, type: “checkbox” } but not { label: string, slug: string, type: string, }

const getFieldsBySlug = (...slugs) => {
  return slugs.map((slug) => Fields.find((filed) => filed.slug === slug)) || [];
};

const Fields = [
  {
    label: "Price, $",
    slug: "price",
    type: "checkbox",
  },
  {
    label: "Area",
    slug: "area",
    type: "number",
  },
  {
    label: "Floor",
    slug: "floor",
    type: "grop",
  },
  {
    label: "Finishing",
    slug: "finishing",
    type: "radio",
  },
];

I tried to add “as const”, but it does not return a specific type, but variants

I keep getting the Error “”Cannot read properties of undefined (reading ‘map’)””

I keep getting the Error “”Cannot read properties of undefined (reading ‘map’)””:

import React from "react";

import './TrackList.css';

import Track from "../Track/Track";

class TrackList extends React.Component {
    render() {
      return (
        <div class="TrackList">  
            {      
            this.props.tracks.map(track => {
                return <Track track={track}
                key={track.id} />
            })
        } 
</div>
      ) 
    }
}

export default TrackList;

I have tried removing the .map:

writing on canvas Vs. drawing on a canvas

I have a Canvas on a web page where users can type or draw on a click of a button. below is the web code:

    <input id="btnType" type="button" value="Type" />
                <input id="btnDraw" type="button" value="Draw" />
                <hr />
                <input id="txtType" type="text" placeholder="Type Here" style="width: 500px; height: 200px;" />
                <div id="dvSignature" style="display: none;">
                    <div class="tools">
                        <a href="#colors_sketch" data-tool="marker">Marker</a>
                        <a href="#colors_sketch" data-tool="eraser">Eraser</a>
                    </div>
                    <br />
                    <canvas id="colors_sketch" width="500" height="200" style="border: 1px solid #ccc;"></canvas>
                </div>
<div>
<input style="float: right; margin-bottom:20px" type="submit" id="myBtn1" value="Submit" class="btn btn-primary"  />
</div>

when the user draw, the drawing is done on the canvas, but when they type, the typing is not done on the canvas, it is just done in a text box. How can do the typing part on the canvas. below is the code where users can type and draw:

script type="text/javascript" src="https://cdn.rawgit.com/mobomo/sketch.js/master/lib/sketch.min.js"></script>
    <script type="text/javascript" src=https://cdnjs.cloudflare.com/ajax/libs/signature_pad/1.3.4/signature_pad.min.js></script>

<script type="text/javascript">
        $(function () {
            $('[id*=btnType]').on('click', function () {
                $('[id*=txtType]').attr('style', 'display:block;width: 500px; height: 200px;font-family:Journal;color:blue;font-size:20px');
                $('[id*=dvSignature]').attr('style', 'display:none;');
            });

            $('[id*=btnDraw]').on('click', function () {
               
                $('[id*=dvSignature]').attr('style', 'display:block;');
                $('[id*=txtType]').attr('style', 'display:none;');
                $('[id*=colors_sketch]').sketch();
                $(".tools a").eq(0).attr("style", "color:#000");
                $(".tools a").click(function () {
                    $(".tools a").removeAttr("style");
                    $(this).attr("style", "color:#000");
                });
            });
        });
    </script>

As you can see, in the above code, typing is done in just a text box rather than a canvas. How can I modify the code so that the typing is also done on the canvas.

Why the Authorization header is missing in tus-js-client?

I have a tusd dockerized as follows:

  tusd-addressfull:
    image: my-tusd
    environment:
      - FILE_SERVICE_URL
      - AWS_ACCESS_KEY_ID=${S3_ACCESS_KEY}
      - AWS_SECRET_ACCESS_KEY=${S3_SECRET_KEY}
      - AWS_REGION=${S3_REGION}
      - KEYCLOAK_URI
      - KEYCLOAK_REALM
      - TUSD_CLIENT_ID
      - TUSD_CLIENT_SECRET
      - TUSD_BUCKET=addressfull
      - BASE_HOST
    command: ["-s3-endpoint=${S3_ENDPONINT}", "-s3-bucket=addressfull", "-base-path=/files/addressfull"]
    depends_on:
      - file-service

And I would access it behind Spring Cloud Gateway, by:

        #TUSD
        - id: tusd-addressfull
          uri: http://tusd-addressfull:1080
          predicates:
            - Path=/files/addressfull/**
          filters:
            - name: RequestSize
              args:
                maxSize: 2GB

The Spring Cloud Gateway accepts authenticated requests with Keycloak.

In my front-end example I’m using:

    // Create a new tus upload
    let upload = new tus.Upload(file, {
        // endpoint: "https://mydomain/files/upload",
        endpoint: "http://mydomain/files/addressfull",

        headers: {
            "Authorization": `Bearer ${keycloak.token}`,
        },
        retryDelays: [0, 3000, 5000, 10000, 20000],
        metadata: {
            filename: file.name,
            filetype: file.type,
            test: "test"
        },
        onError: function(error) {
            console.log("Failed because: " + error)
        },
        onProgress: function(bytesUploaded, bytesTotal) {
            let percentage = (bytesUploaded / bytesTotal * 100).toFixed(2)
            console.log(bytesUploaded, bytesTotal, percentage + "%")
        },
        onSuccess: function() {
            console.log("Download %s from %s", upload.file.name, upload.url)
        }
    })

But when I sent the upload request OPTIONS pass with 200 but POST method says 401 Unauthorized and if I check the Authorization: Bearer TOKEN header isn’t present in POST.

Seems as this issue.

Why?

What am I missing out?

Array pf promises return Script Uncaught error before promise.allSettled

I was pushing list of promises into an array, so that later i can use promise.allSettled to get result of promises but once i push promises to an array and after that i make an api call and then use promise.allSettled to get results of it, but it threw Uncaught promise first.

(async function () {
const fakeTimer = (val) => new Promise(res => setTimeout(() => res(val), 2000))
const fakeTimerError = () => new Promise((res, rej) => setTimeout(() => rej('Hello'), 300))
var arr = [1, 2, 4, 6,7, 3]
var promises = []

try {
    for (let val of arr) {
        if (val === 4) {
            promises.push(fakeTimerError())
        } else {
            promises.push(fakeTimer(val))   
        }
    }
    await fakeTimer('test1')
    await fakeTimer('test2')
    const res = await Promise.allSettled(promises)
    console.log(res)
} catch (error) {
    console.log('error', error)
}
})()

Response i am getting

Image of response

How to toggle textinput with react-native?

I have a react-native app. And I try to shwo/hide a textinput with a icon.

So I have this component:

export const CategoryScreen = ({ navigation }) => {
    const { loading, categoryList } = useContext(CategoryContext);
    const [showAccordion, setShowAccordion] = useState(false);

    const toggleAccordion = () => {
        setShowAccordion(!showAccordion);
    };

    //console.log(navigation);
    return (
        <SafeArea>
            {loading && (
                <LoadingContainer>
                    <ActivityIndicator animating={true} color={MD2Colors.green200} />
                </LoadingContainer>
            )}
            <Search />
            <CategoryList
                data={categoryList}
                renderItem={({ item }) => {
                    return (
                        <>
                            <TouchableOpacity
                                onPress={() => navigation.navigate("groepen", { subcategories: item.id })}>
                                <Spacer position="top" size="large">
                                    <CategoryInfoCard category={item} />
                                </Spacer>
                            </TouchableOpacity>

                            <View>
                                <ButtonDetail onPress={toggleAccordion}>
                                    <AntDesign name="twitter" size={24} color="green" />
                                </ButtonDetail>
                                {<TextInput placeholder="Enter some text..." />}
                            </View>
                            
                        </>
                    );
                }}
                keyExtractor={(item) => item.id}
            />
        </SafeArea>
    );
};

And it is about this part:

<View>
    <ButtonDetail onPress={toggleAccordion}>
        <AntDesign name="twitter" size={24} color="green" />
    </ButtonDetail>
    {<TextInput placeholder="Enter some text..." />}
</View>

So when the app is loading the textfield is visible. But it has to be hidden. And when I trigger the icon. Nothing happens.

Question: How to toggle the textinput with the icon?

How to programmatically Download a file from Google Drive, using Javascript and HTML? (NOT Google Drive API)

Goal:

In Chrome Browser, Run a javascript in this Public Google Drive Folder to Select a file from the Google Drive folder (e.g: first file), and Download it.

P.S: I do NOT want to use the GoogleDriveAPI.

Steps:

1. Select file

2. Download file, using one of the following options:

  • Click Download button from page
  • Expand the file options menu and click the Download button

What’s working:

Select the file using:

document.querySelector('div[jsname=LvFR7c]').click()

Expand the file options menu using:

document.getElementsByClassName("pc7nUb I5YcP Dk9rmd").click()

What’s NOT working:

Clicking Download button from page or from file options menu

Conclusion:

I noticed that the Google Drive HTML elements are mostly with aria roles like button, menu, & menuitem. They don’t utilize the tag. Some of these elements have jsaction & jscontroller attributes. When these elements are clicked via code, some of them behave as they do when clicking with the mouse, and others do nothing when clicked via code. So I’m just confused and am not sure what to try next.

I feel like this is a trivial task, but this is my first time working in Javascript & HTML, so I’m sure I might be missing something simple.

Would really appreciate any help. Thanks!

Download Button HTML Elements:

Page Download button HTML:

document.querySelector('div[aria-label=Download]')

File Options Menu Download button HTML:

document.querySelectorAll('div[aria-label=Download]')[3]

Things I’ve tried:

element.click()
element.dispatchEvent(new Event('click'))
element.dispatchEvent(new Event('keydown')) // (with more options in the Event initializer)
element.dispatchEvent(new Event('keyup'))
element.focus()
element.setAttribute('aria-expanded', true)
element.setAttribute('aria-pressed', true)
element.ariaPressed = true

and more…

How do I add a stop process command to my bot, which ends the on-going command? (discord.js)

I want to add a joke command to my Discord bot, something like bt!donotusethis which will then answer with the command itself, causing an infinite spam chain.

Obviously, this needs a command to stop it. I want to add a command such as bt!stop, which will end the spam.

Is there any way to add this?

I tried using this:

   client.on("messageCreate", (message) => {
     if (message.content.startsWith("bt!donotusethis")) {
       message.channel.send("bt!donotusethis");
     }
   });

   client.on("messageCreate", (message) => {
     if (message.content.startsWith("bt!stop")) {
       //this is where the end process command goes
     }
   });

And instead of the //this is where the end process command goes I added client.process.end which did stop the spam, but also crashed the bot itself.

Rock paper scissors bug

I have created a simple rock paper scissors exercise, where the webpage prompts the user “Rock, paper or scissors?:” and then compares their input to a randomized result. Problem is I am getting incorrect results. For instance, I will choose paper and then the computer will prompt “The computer chose scissors. You win!”, which should not be happening. Far as I can tell, only choosing rock is returning accurate results.

If I had to guess, the computer is confusing playerChoice and compChoice somehow, and that rock is working correctly because it is the first option in the loop. Any suggestions on how to fix this would be appreciated.

let roundCount = prompt("How many rounds do you want to play:");

var winCount = 0;
var tieCount = 0;
var lossCount = 0;

for (i = 0; i < parseInt(roundCount); i++) {
    var playerChoice = prompt("Rock, paper or scissors?:");
    var randomNumber = Math.floor(Math.random() * 3);
    if (randomNumber === 0) {
        compChoice = "rock"
    }
    else if (randomNumber === 1) {
        compChoice = "paper"
    }
    else if (randomNumber === 2) {
        compChoice = "scissors";
    }
    if (playerChoice === compChoice) {
        alert("Tie!");
        tieCount++
    }
    else if (playerChoice = "rock" && compChoice === "scissors") {
        alert("The computer chose scissors. You win!");
        winCount++
    }
    else if (playerChoice = "rock" && compChoice === "paper") {
        alert("The computer chose paper. You lose!");
        lossCount++
    }
    else if (playerChoice = "paper" && compChoice === "rock") {
        alert("The computer chose rock. You win!");
        winCount++
    }
    else if (playerChoice = "paper" && compChoice === "scissors") {
        alert("The computer chose scissors. You lose!");
        lossCount++
    }
    else if (playerChoice = "scissors" && compChoice === "paper") {
        alert("The computer chose paper. You win!");
        winCount++
    }
    else if (playerChoice = "scissors" && compChoice === "rock") {
        alert("The computer chose rock. You lose!");
        lossCount++
    }
}

alert("Out of " + roundCount + " rounds, you have accumulated " + winCount + " wins," + tieCount + " ties, and " + lossCount + " losses.");