Discovering and editing a specific line in Sheets: An in-depth look at the Message Counter

Currently, the bot checks if your ID already exists in the sheet list and adds you if it doesn't when someone writes a message in the chat.

Now, I want the bot to implement a message counter in the sheet list. What would be the most effective way to achieve this with the existing code?

In short: The bot verifies your presence in the list and increments the message counter by +1 (where "Nachrichten" signifies Messages).

You can think of it as a database that records the number of messages from each user.

Below is the current code:

const fs = require('fs').promises;
const path = require('path');
const process = require('process');
const {authenticate} = require('@google-cloud/local-auth');
const {google} = require('googleapis');
const axios = require('axios');
const moment = require('moment');
const SCOPES = ['https://www.googleapis.com/auth/spreadsheets.readonly'];

// The file token.json stores the user's access and refresh tokens, and is
// created automatically when the authorization flow completes for the first
// time.

const TOKEN_PATH = path.join(process.cwd(), 'token.json');
const CREDENTIALS_PATH = path.join(process.cwd(), 'credentials.json');

module.exports = client => {

client.on('messageCreate', async message => {
  const member = message.member

  async function loadSavedCredentialsIfExist() {
    try {
      const content = await fs.readFile(TOKEN_PATH);
      const credentials = JSON.parse(content);
      return google.auth.fromJSON(credentials);
    } catch (err) {
      return null;
    }
  }
  
  /**
   * Serializes credentials to a file compatible with GoogleAuth.fromJSON.
   *
   * @param {OAuth2Client} client
   * @return {Promise<void>}
   */
  async function saveCredentials(client) {
    const content = await fs.readFile(CREDENTIALS_PATH);
    const keys = JSON.parse(content);
    const key = keys.installed || keys.web;
    const payload = JSON.stringify({
      type: 'authorized_user',
      client_id: key.client_id,
      client_secret: key.client_secret,
      refresh_token: client.credentials.refresh_token,
    });
    await fs.writeFile(TOKEN_PATH, payload);
  }
  
  /**
   * Load or request authorization to call APIs.
   *
   */
  async function authorize() {
    let client = await loadSavedCredentialsIfExist();
    if (client) {
      return client;
    }
    client = await authenticate({
      scopes: SCOPES,
      keyfilePath: CREDENTIALS_PATH,
    });
    if (client.credentials) {
      await saveCredentials(client);
    }
    return client;
  }
  
  /**
   * 
   * @see https://docs.google.com/spreadsheets/d/12e_460eFvxYS5m8AMRg17uBlfEEzjpOfPqgbX0YIeEE/edit
   * @param {google.auth.OAuth2} auth The authenticated Google OAuth client.
   */
  async function listMajors(auth) {
    const sheets = google.sheets({version: 'v4', auth});
    const res = await sheets.spreadsheets.values.get({
      spreadsheetId: '12e_460eFvxYS5m8AMRg17uBlfEEzjpOfPqgbX0YIeEE',
      range: 'Liste!B2:B',
    });
    const rows = res.data.values;
     const rowsdata = res.data.values.join(', ');
    if (rowsdata.includes(`${member.id}`)) {
      // Here, I need the bot to edit the Message Line
     return;
    } else 
    axios.post('https://sheetdb.io/api/v1/gfycyawty283n', {
      data: {
        Name: `${member.user.tag}`,
        ID: `${member.id}`,
        Nachrichten: `1`,
        VoiceTime: "00:00:00:00",
        ServerBeigetreten: moment.utc(member.joinedAt).format('DD/MM/YY HH:MM:SS')
      }
    })
    
    
  }
  
  authorize().then(listMajors).catch(console.error);
  

  })  


};
https://i.sstatic.net/jPpdy.png

Sheet after modification:

"Nachrichten" represents Messages.

The bot needs to locate the user ID and increment the "Nachrichten" Value by +1 for every message sent (https://i.sstatic.net/MVsZB.png).

Answer №1

I successfully resolved the issue on my own and here is the finalized code.

const fs = require('fs').promises;
const path = require('path');
const process = require('process');
const {authenticate} = require('@google-cloud/local-auth');
const {google} = require('googleapis');
const axios = require('axios');
const moment = require('moment');
const SCOPES = ['https://www.googleapis.com/auth/spreadsheets.readonly'];

// The token.json file contains the user's access and refresh tokens, generated automatically during the initial authorization flow.

const TOKEN_PATH = path.join(process.cwd(), 'token.json');
const CREDENTIALS_PATH = path.join(process.cwd(), 'credentials.json');

let channelblacklist = ['1084311032228479047','1084310095170637845']

module.exports = client => {

client.on('messageCreate', async message => {
  const member = message.member

  async function loadSavedCredentialsIfExist() {
    try {
      const content = await fs.readFile(TOKEN_PATH);
      const credentials = JSON.parse(content);
      return google.auth.fromJSON(credentials);
    } catch (err) {
      return null;
    }
  }

  /**
   * Serializes credentials to a file compatible with GoogleAuth.fromJSON.
   *
   * @param {OAuth2Client} client
   * @return {Promise<void>}
   */
  async function saveCredentials(client) {
    const content = await fs.readFile(CREDENTIALS_PATH);
    const keys = JSON.parse(content);
    const key = keys.installed || keys.web;
    const payload = JSON.stringify({
      type: 'authorized_user',
      client_id: key.client_id,
      client_secret: key.client_secret,
      refresh_token: client.credentials.refresh_token,
    });
    await fs.writeFile(TOKEN_PATH, payload);
  }

  /**
   * Load or request authorization to call APIs.
   *
   */
  async function authorize() {
    let client = await loadSavedCredentialsIfExist();
    if (client) {
      return client;
    }
    client = await authenticate({
      scopes: SCOPES,
      keyfilePath: CREDENTIALS_PATH,
    });
    if (client.credentials) {
      await saveCredentials(client);
    }
    return client;
  }

  /**
   * 
   * @see https://docs.google.com/spreadsheets/d/12e_460eFvxYS5m8AMRg17uBlfEEzjpOfPqgbX0YIeEE/edit
   * @param {google.auth.OAuth2} auth The authenticated Google OAuth client.
   */
  async function listMajors(auth) {
    const sheets = google.sheets({version: 'v4', auth});
    const res = await sheets.spreadsheets.values.get({
      spreadsheetId: '12e_460eFvxYS5m8AMRg17uBlfEEzjpOfPqgbX0YIeEE',
      range: 'Liste!A2:E', // A2:E includes all columns where we have data
    });
    const rows = res.data.values;
     const rowsdata = res.data.values.join(', ');
    if (rowsdata.includes(`${member.id}`)) {
      if (channelblacklist.includes(message.channel.id)) return;
      const index = rows.findIndex(row => row[1] === member.id);
      const row = rows[index];
      const messages = parseInt(row[2], 10) + 1;
      const updateRange = `Liste!C${index + 2}`; // We add 2 to skip the header row
      await sheets.spreadsheets.values.update({
        spreadsheetId: '12e_460eFvxYS5m8AMRg17uBlfEEzjpOfPqgbX0YIeEE',
        range: updateRange,
        valueInputOption: 'RAW',
        requestBody: {
          values: [[messages]],
        },
      });
     return;
    } else 
    axios.post('https://sheetdb.io/api/v1/gfycyawty283n', {
      data: {
        Name: `${member.user.tag}`,
        ID: `${member.id}`,
        Messages: `1`,
        VoiceTime: "00:00:00:00",
        ServerJoined: moment.utc(member.joinedAt).format('DD/MM/YY HH:MM:SS')
      }
    })
    
    
  }
  
  authorize().then(listMajors).catch(console.error);

  })  


};

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

I am having difficulty retrieving information from the Laravel API

I am struggling to retrieve data from my Laravel application and display it in Vue CLI. While I can see the response, I am encountering difficulties when trying to show it in the Vue application. https://i.stack.imgur.com/tCgrd.png Whenever I attempt to f ...

Obtain the content enclosed within parentheses using JavaScript

const str = "(c) (d)"; I need to separate the given string into an array The result should be [0] => 'c' [1] => 'd' ...

I am encountering issues with my THREE.js RawShaderMaterial

I haven't encountered any issues when loading shaders created by others into THREE.js, but I've hit a roadblock when trying to create and run my own shader. The shader works perfectly on the platform where I designed it (), but it doesn't fu ...

Is it possible to launch a Nextjs app on Vercel for production purposes? How well does it handle high volumes of traffic?

As a newcomer to Nextjs, I am looking to deploy my app to production. I'm curious about whether Vercel can effectively handle heavy traffic on the site. Should I consider utilizing platforms such as AWS or GCP for deployment instead? Any advice would ...

Python responding to an Ajax request using jQuery

Currently, I am experimenting with integrating a pre-built inline editor from the following source: https://github.com/wbotelhos/inplace Regrettably, the available support documentation is lacking and my expertise in Javascript, jQuery, or Ajax is limited ...

Is it possible to create a compound editor within a cell in SlickGrid that contains two date fields

Currently, I am implementing SlickGrid with jQuery and I am interested in incorporating a compound editor within a cell similar to example 3a mentioned here. However, instead of two text fields, I would like to have two date fields. Although Example 3 dem ...

Utilize Next.js and GSAP to dynamically showcase images upon hovering over the title

I have a dynamic list of titles that I want to enhance by displaying images when hovering over each title. The issue I'm facing is that when I hover over one title, all the images display at once. As a React beginner, I believe the solution should be ...

Is there a way to rotate label text on a radar chart using chart js?

I am working with a Chart js radar diagram that contains 24 labels. My goal is to rotate each label text by 15 degrees clockwise from the previous one: starting with 'Label 1' at the top in a vertical position, then rotating 'Label 2' ...

Potential memory leak detected in EventEmitter by Discord.js

One night while my bot was running on auto-pilot as I drifted off to sleep, a warning popped up out of the blue: MaxListenersExceededWarning: Possible EventEmitter memory leak detected. 11 guildMembersChunk listeners added to [Client]. Use emitter.setMaxLi ...

Update the ngView content on the fly

My project requires dynamic routes to be generated when specific URLs are requested in order to customize the view and display corresponding data uniformly. While adding manual routes with the same templateUrl and controller would have made this task simpl ...

Convert a comma-delimited string containing a numerical value into a floating point number, for example, 3.00

I need to extract a number from a value that is returned with commas around it. My goal is to convert this value into a number so that I can compare it against another number in my code later on. However, I'm facing difficulties in reliably extracting ...

Revise a function that locates an object with a corresponding id in an array, modifies a property, and updates a React component's state

Here is a function that takes in a rating value within an object. The ID and Question properties remain unchanged, but the rating value can be updated. This will result in updating a React state value. Is there a method to improve the readability and con ...

What steps can you take to convert your current menu into a responsive design?

I am currently developing a website using PHP, HTML, and CSS. The site is not responsive, and I want to make the menu responsive. My global navigation and admin interface are not adapting properly as they are designed using tables. Is there a method I can ...

The datetimepicker is not functioning properly

I'm experiencing an issue with the datetimepicker where it doesn't display a calendar when I click the icon. Interestingly, the Chrome browser isn't showing any errors in the development console. <script src="Scripts/jquery-2.1.1.min.js ...

Is there a better approach to verifying an error code in a `Response` body without relying on `clone()` in a Cloudflare proxy worker?

I am currently implementing a similar process in a Cloudflare worker const response = await fetch(...); const json = await response.clone().json<any>(); if (json.errorCode) { console.log(json.errorCode, json.message); return new Response('An ...

Using Symfony 4.3 to submit a form via Ajax and store data in a database

As a beginner in the world of Ajax, I am currently trying to use Ajax to submit a register form with Symfony but seem to be facing some challenges in understanding the process: Within my Controller: /** * @Route("/inscription", name="security_re ...

Updating certain fields in AngularJS with fresh data

I am facing a challenge with the following code snippet: <div ng-controller="postsController"> <div id = "post_id_{{post.postid}}" class = "post" ng-repeat="post in posts"> ...... <div class="comments"> < ...

What is the reason behind the content of a div tag not hiding while the content of a p tag does

<html> <head> <title>How to make a div content disappear when clicked?</title> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <scrip ...

The active link for pagination in CodeIgniter is malfunctioning

Even though there might be similar posts on StackOverflow, my situation is unique. Hence, I have decided to ask this question with a specific title. Let me break down my issue into smaller parts: Part - 1: I have a regular view page where I can select a ...

Retrieve the variable declared within the event

How can I access a variable set in an event? Here is the code snippet: $scope.$on('event_detail', function (event, args) { $scope.id = args; console.log($scope.id); // This prints the correct value }); console.log($scope.id); // ...