Skocz do zawartości

OD ZERA DO BOTmastera, czyli jak pisać boty na Discorda


wiktorm12
 Udostępnij

Rekomendowane odpowiedzi

OD ZERA DO BOT-MASTERA

 

Discord to platforma społecznościowa, na której standardowy użytkownik może wysyłać wiadomości, uczestniczyć w rozmowach, dodawać do znajomych tworzyć własne serwery, rozpowszechniać zdjęcia i korzystać z rozmaitych botów, a właśnie na tym temacie zatrzymamy się na dłużej…

Kto z was nie zna MEE6, Tatsumaki, Carl-bota, Dyno, Rythm? (jeżeli serio ktoś nie wie o czym gadam to są to jedne z czołowych botów discordowych) Posiadają one wiele funkcji od warnowania, mutowania, banowania przez puszczanie muzyki, losowania, ekonomie skończywszy na dodawaniu rang po kliknięciu w emotki, tworzenie kolorowych wiadomości i wiele wiele innych.

W tym poradniku nauczymy właśnie pisać takiego boty. Poradnik podzielony będzie na części, które będą się pojawiały co 2 dni. Każda z nich będzie pojawiała się w komentarzu. Poniżej znajduje się spis treści, który będzie aktualizowany z dodaniem każdej kolejnej części i będzie zawierał temat kolejnej lekcji.
 

Spis treści:

[NodeJS #1] – Opis i podstawy języka oraz podstawowe wyrażenia, [ Zarejestruj się lub zaloguj, aby zobaczyć ukrytą treść! ]

[NodeJS #2] – Przygotowania środowiska oraz pierwsza komenda (podstawy języka w praktyce) [ Zarejestruj się lub zaloguj, aby zobaczyć ukrytą treść!]

[NodeJS #3] – Stworzenie pliku configu, command handler i komenda pomocy [Zarejestruj się lub zaloguj, aby zobaczyć ukrytą treść!]

 

 

Odnośnik do komentarza
Udostępnij na innych stronach

 
qKQIB5D.png

Podczas lekcji:

  •  poznasz informacje o języku JavaScript,
  •  poznacz podstawowe słówka, które przydadzą Ci się podczas kolejnych lekcji jak i będą występować w dokumentacji i w większości innych języka programowania.

Mam nadzieje, że przygotowany przeze mnie materiał uda Ci się przyswoić w najlepszym dla ciebie stopniu i wspomoże Cię on na drodze do budowania swojego programistycznego imperium.


Pierwszym krokiem podczas poznawania nowego języka programowania jest poznanie jego podstawowych zasad, możliwości i użyteczności.

JavaScript to skryptowy jeżyk programowania w dużej mierze przeznaczony do tworzenia niestatycznych stron internetowy. Dzisiaj jest od niezbędny do stworzenia większego serwisu internetowego, a sama jego znajomość otwiera nam bardzo dużą bramę do świata IT.

Jak znamy już najważniejsze (i te mniej ważne) informacje o języku, w którym będziemy pisać powinniśmy poznać jeszcze silnik naszego przyszłego bota czyli NodeJS.

NodeJS jak podaje jego strona (Zarejestruj się lub zaloguj, aby zobaczyć ukrytą treść! jest to asynchroniczne środowisko JavaScript do tworzenia skalowalnych aplikacji sieciowych, co oznacza, że zamiast otwierania skryptu w przeglądarce internetowej możemy użyć takiego wizualizatora, który dodatkowo udostępnia nam dodatkowe wbudowane w niego ułatwienia. Wraz z silnikiem instalowany manager pakietów - npm, z którego kilkukrotnie będziemy korzystać podczas kursu. 

Znając już podstawowe informacje na temat technicznego zaplecza bota poznajmy kilka podstawowych słówek, które przydadzą się w dalszych częściach kursu:

  • Edytor tekstowy – aplikacja pozwalająca na edycje plików tekstowych (przykładowo jest to windowsowy notatnik, ja podczas prowadzenia tego kursu będę używał Visual Studio Code),
  • Plik tekstowy – plik zawierający ciąg znaków,
  • Flow projektu – zbór zasad i zaleceń dotyczący danego projektu,
  • Repozytorum – lokalizacja pliku źródłowego (podczas tego projektu będzie to najczęściej GitHub),
  • Folder – lokalizacja pozwalająca do grupowanie plików.

To tyle jeżeli chodzi o słowa programowano podobne, teraz czas na słowa typowo związane z kodem.

  • zmienna – wartość przypisana do danego wyrażenia, której można używać nieskończenie wiele razy ale tylko w obszarze jej działania,
  • tablica – przez wiele osób nazywana jest to „szufladka na dane” i w sumie coś w tym jest, ponieważ przypisywane do niej wartości najczęściej nie mają konkretnych nazw, a jedynie identyfikatory, które można porównać do piętek w komodzie z szufladami.
  • obiekt – zbiór zmiennych i funkcji połączony wspólną nazwą, najczęściej powiązany ze sobą znaczeniowo,
  • funkcja – zapis zdarzeń wykonywany w ustalonej wcześniej kolejności zwracający dany efekt,
  • komentarz – oznaczenie widoczne tylko dla człowieka, wyłączone z logicznego działania programu

Poznaliśmy już większość trudnych i wartych po poznania słówek przed kursem. Teraz czas na poznanie ich w praktyce w języku JavaScript. Każdy z powyżej wymienionych elementów można stworzyć i używać na kilka sposobów ja spróbuje przedstawić większość, a na pewno wszystkie najczęściej używane sposoby.

 

 

9nHGL42.png
 

Pierwszym elementem, którym się zajmiemy są zmienne. W JS w przeciwieństwie do większości innych języków programowania nie wymagane jest ustalenie typu zmiennej (chodzi tu o definiowanie, że w zmiennej będą występować liczby, tekst czy wartości prawda/fałsz) dzielą się one na 3 rodzaje:

Zmienna const – zmienna ta jest preferowana do najczęstszego używania. Jej minusem, a zarazem zaletą jest fakt, że raz zdefiniowanej nie można ponownie zdefiniować, ani zmienić jej wartości. Aby używa się jej tak:

const zmienna = wartość”;

Zmienna let – zmienna ta preferowana jest wszędzie gdzie zmienna const jest niewystarczająca i potrzeba w środku kodu zmieniać wartość zmiennej. Oto sposoby jej użycia:

let zmienna = wartość”;

 

let zmienna;
zmienna = wartość”;

Zmienna var – dwa powyższe rodzaje zmiennych są zmiennymi tak zwanymi obszarowymi, czyli działają jedynie na obszarze obiektu, w przypadku gdy będziemy próbowali ich użyć poza tym obiektem będzie występowa błąd undefined co oznacza że zmienna ta jest po prostu niezdefiniowania, lecz w przypadku zmiennej var użycie jej przed jej poza obszarem będzie skutkowało otrzymaniem wartości null co oznacza, że zmienna nie ma wartości, dodatkową różnicą jest również redeklarowalność co oznacza, że zmienne var pod tą samą nazwą można zdefiniować kilka razy i nie będzie żadnego błędu logicznego w przeciwieństwie co zmiennej cost i let, lecz jest to odradzane, ponieważ tworzy to nieład w projekcie. Zmiennej tej powinno używać się jak najmniej, a tak naprawdę w projektach podstawowych najlepiej jej nie używać. Definiowanie jej wygląda tak samo jak zmiennej let:

var zmienna = wartość”;

 

var zmienna;
zmienna = wartość”;

Aby pobrać dane z każdej z powyższych zmiennych wystarczy w kodzie wpisać ich nazwe:

zmienna

 

 

wGKxaaP.png

 

Kolejnym poznanym przez nas elementem będzie tablica. W JS tablice definiuje się tak:

["item1", "item2", "item3"]

Można ją przypisać do wybranej zmiennej.
Aby pobrać określoną daną z tablicy należy tą tablice przypisać do zmiennej oto przykład:

const items = ["kot", "pies", "słoń", "żyrafa"];

Następnie należy wpisać nazwę zmiennej i w nawias kwadratowych określić miejsce wartości, pamiętając, że w programowaniu liczymy od 0:

items[0]

Powyższy zapis zwróci nam wartość kot.

 

 

5PdXDW3.png

Po tablicach przyszedł czas na obiekty. Stanowią one najczęściej zapis wartości. Można je zdefiniować w taki sposób:

{
Nazwa1: wartość1”,
Nazwa2: wartość2
};

 

const nazwa1 = wartość1”;
let nazwa2 = wartość2”;
{
nazwa1,
nazwa2
};


Oczywiście obiekty tak samo jak tablice można przypisać do obiektów, a robi to się tak:

const obj = {
  Nazwa1: wartość1”,
  Nazwa2: wartość2
};

 

const nazwa1 = wartość1”;
let nazwa2 = wartość2”;
const obj = {
  nazwa1,
  nazwa2
};

 

Aby wyciągnąć wartość z obiektu należy przypisać dany obiekt do zmiennej, a następnie zrobić to tak:

obj.nazwa1

w tym momencie otrzymaliśmy wartość wartość1.

 

 

TIRfqg4.png

 

Ostatnim logicznym elementem z naszej listy są funkcje. Są to dokładnie obiekty, lecz zamiast nazw i wartości mają one odpowiednie wyrażenia logiczne. Aby zdefiniować podstawową funkcje należy napisać taki fragment kodu:

() => {
    return 1;
};

 

function() {
    return 1;
};

Powyżej napisane funkcje zwracają wartość 1, ponieważ zwrot return w ciele funkcji oznacza, że dana funkcje zwraca wartość (może być również sytuacja gdzie funkcje nie zwraca żadnej wartości, wtedy return służy jako element przerwania dalszego działania funkcji).

Funkcje tak jak tablice i obiekty można przypisać do nazw, a robi się to w taki sposób:

const func =  () => {
    return 1;
};

 

const func = function() {
  return 1;
};

 

function func() => {
  return 1;
};

 

Funkcje mogą otrzymywać przy wywoływaniu kodu argumenty, które tworzą wewnętrzne zmienne w funkcji wygląda to tak:

const func =  (arg1, arg2) => {
  return arg1 + arg2;
};

 

const func = function(arg1, arg2) {
    return arg1 + arg2;
};

 

function func(arg1, arg2) => {
    return arg1 + arg2;
};


Aby wywołać funkcje musi posiadać ona nazwę. Można to zrobić w taki sposób:

func(1, 2);

 

 

vgtB8FI.png

Ostatnim elementem, którego będę najczęściej używał jest komentarz. W JS wygląda to tak:

//ten komentarz jest tekstem jedno linijkowym

 

/*
Ten komentarz
mogę rozciągnąć na kilka
linijek i nadal będą to linijki nieingerujące w kod
*/


 

To już koniec tej lekcji, mam nadzieje, że taka forma nauki Ci się spodoba!
(Z powodu, że ta lekcja jest bardzo mocno teoretyczna kolejna z wersją praktyczną pojawi się już jutro!)

A jeżeli chcesz zgłębić temat JavaScripta odsyłam cię do jego kilku dokumentacji:
Zarejestruj się lub zaloguj, aby zobaczyć ukrytą treść!
Zarejestruj się lub zaloguj, aby zobaczyć ukrytą treść!
Zarejestruj się lub zaloguj, aby zobaczyć ukrytą treść!

Coś nie tak, a może wręcz przeciwnie spodobało ci się coś i chcesz bym o czymś pisał więcej?
Napisz to w komentarzu poniżej na pewno rozważę wszelkie wasze propozycje!

Do zobaczenia o/     
 

 

Odnośnik do komentarza
Udostępnij na innych stronach

O! I właśnie to jest dobry poradnik! Poprzedni, pod którym dyskutowaliśmy był kozacki pod względem tego, że było na nim wiele gifów dobrze obrazujących co i gdzie trzeba kliknąć :D 

Ode mnie masz lajki pod postami, smutne jest jednak to, że na tym forum raczej kariery mentora nie zrobisz, bo większość ludzi nie przychodzi tutaj czegoś się nauczyć, tylko wyżebrać kilka skryptów, żeby odpalić serwer i dopisać AUTORSKIE PLUGINY!!!11

Odnośnik do komentarza
Udostępnij na innych stronach

3 godziny temu, LeviBoyPL napisał:

Poprzedni, pod którym dyskutowaliśmy był kozacki pod względem tego, że było na nim wiele gifów dobrze obrazujących co i gdzie trzeba kliknąć :D

W kolejnej części która pojawi się jutro (mam nadzieje) o 15 też będzie sporo takich elementów się pojawi

Spoiler

image.png

 

4 godziny temu, LeviBoyPL napisał:

smutne jest jednak to, że na tym forum raczej kariery mentora nie zrobisz, bo większość ludzi nie przychodzi tutaj czegoś się nauczyć, tylko wyżebrać kilka skryptów, żeby odpalić serwer i dopisać AUTORSKIE PLUGINY!!!11

To jest jeden z powodów dla których pisze ten poradnik, by pokazać ludziom, że tworzyć można na różne sposoby, a rzecz zrobiona samemu bawi jeszcze bardziej niż ta pod którą tylko się podpisaliśmy
 

2 godziny temu, jhgggg napisał:

jeden z lepszych poradników dotyczący jak zrobić/napisać bota discordowego..

Plan całego kursu tworzyłem przez kilka dni więc bardzo mnie ciszy że mi wyszło (mimo, że w miedzy czasie z 5 razy się poddawałem)
 

2 godziny temu, jhgggg napisał:

I czekam na więcej!!!

Cytując nazwę polskiego kanału na YouTube "to już jutro"

Odnośnik do komentarza
Udostępnij na innych stronach

 DvfIoIZ.png

Podczas lekcji:

  • poznasz sposób przygotowania środowiska i miejsca pracy od strony technicznej do pisania bota,
  • poznasz poprawny sposób uruchamiania bota,
  • poznasz pierwszy sposób reagowania przez bota na wpisane komendy.

Mam nadzieje, że przygotowany przeze mnie materiał uda Ci się przyswoić w najlepszym dla ciebie stopniu i wspomoże Cię on na drodze do budowania swojego programistycznego imperium.

 

Pierwszym etapem dzisiejszej lekcji będzie zainstalowanie silnika NodeJS, aby to wykonać należy:

1. Wejść na stronę Zarejestruj się lub zaloguj, aby zobaczyć ukrytą treść!, która jest oficjalnym źródłem tego silnika

MhDEAiI.png

 

2. Wybrać jedną z wersji, ja polecam tą z dopiskiem Recommended For Most Users - jest to wersja stabilna doskonała dla większości użytkowników pod pisanie bota jest w zupełności wystarczająca. Następnie postępujemy według wskazań instalatora.

8TIpD3C.png

 

3. Aby sprawdzić czy instalacja przebiegła poprawnie należy w konsoli CMD pisać komendę npm -v, jeżeli odpowiedź zawiera wersje waszego silnika wszystko przebiegło poprawnie.

iocNVjO.png

(Zajrzyj poniżej jeżeli nie wiesz jak ją uruchomić)

Spoiler

Wa8sFo1.png

4. Następnie wybieramy miejsce, w którym będzie znajdował się nasz bot. Ja wybrałem folder na pulpicie, Tobie również polecam stworzyć nowy folder, ponieważ bot będzie się składał z dużej ilości plików co jest jednoznaczne z tym, że zrobienie go w folderze, w którym już istnieją pliki będzie mocno utrudniało Ci prace. Następnie musimy uruchomić konsolę cmd z domyślną lokalizacją naszego folderu, który wybraliśmy na miejsce przyszłych plików bota. Robi się naciskając dwukrotnie na ścieżkę do lokalizacji folderu

AqWNm28.gif

 

5. Kolejnym krokiem jest zainicjowanie pliku package.json, w którym będą znajdywały się główne informacje o projekcie. Robimy to poleceniem npm init

dA7lwTM.png

 

6. Wypełniamy następnie odpowiednie wartości. W nawiasach okrągłych znajdują się odpowiedzi domyślne, które zostaną ustawione, jeżeli to pole to zostanie puste.
(jeżeli nie wiesz jak wypełnić dane pole zajrzyj do spojlera poniżej)

Spoiler

package name – jest to nazwa naszego projektu, można ją ustawić jakąkolwiek, lecz zaleca się by nie zawierała polskich znaków, dodatkowo nie może zawierać dużej litery,
version – należy wpisać wersje naszego projektu w formacie x.x.x,
description – jest to opis naszego projektu. Nie trzeba jej wypełniać,
entry point – nazwa pliku startowego, ja jako, że będzie to bot nazwałem je bot.js Ty za to możesz nazwać je jakkolwiek, lecz musi ten plik posiadać rozszerzenie .js określający że jest to plik JavaScripta,
test command – jest to treść komendy testowej, na początku pracy najlepiej zostawić to miejsce puste, ze edytujemy ją ręcznie podczas pisania bota,
git repozytorium – tu możemy wpisać adres URL do repozytorium, które będzie podpięte do projektu, na razie nie używamy żadnego,
keywords – słowa kluczowe, czyli słowa, którymi będzie się dany projekt identyfikowany, na poziomie bota nie jest to nam potrzebne,
author – jest to miejsce, w którym powinniśmy wpisać autora, lecz nadal jest to niewymagane
license – kolejnym polem jest pole licencji, które na naszym poziomie zostawiamy niezmienne, ponieważ nie używamy żadnej zaawansowanej licencji praw autorskich.

plVAa32.png

wDos0rg.png

7. Kolejną wymaganą do odwiedzenia przez nas stroną będzie Zarejestruj się lub zaloguj, aby zobaczyć ukrytą treść!

U1znVfb.png

 

8.     Możemy tam znaleźć komendę do zainstalowanej wcześniej konsoli npm.

hHnTEnm.png

 

9. Wpisujemy ją w tą samą konsole, co wcześniej polecenie npm init

vqpxtK9.png

 

10. Po kilku chwilach menadżer pakietów npm zainstaluje nam bibliotekę DiscordJS, z której będziemy korzystać podczas tworzenia bota. Kolejnym etapem będzie uruchomienie edytora kodu źródłowego, w którym będziemy tworzyć projekt. Ja z doświadczenia polecam VS code, które można pobrać ze strony Zarejestruj się lub zaloguj, aby zobaczyć ukrytą treść!, lecz można również użyć innych takich jak subline, ub nawet notepad++  (lecz w nim będzie dużo trudności)

fylbOTO.png

 

11. Po zainstalowaniu wybranego przez nas edytora należy wpisać komendę code . co oznacza, że folder w którym się znajdujemy zostanie otwarty przez edytor VS code (jeżeli macie inny należy sprawdzić czy daje on możliwość otwarcia pełnego katalogu i jeżeli tak to w jaki sposób i postępujecie według tych wskazówek)

70ax1AV.png

 

QVaMGmE.png

 

Pierwszy punkt naszej lekcji uważam za zaliczony… Dużo teorii? Tak wiem, ale od teraz zaczynamy prawdziwą zabawę z kodem. Naszym dzisiejszym celem będzie stworzenie bota, który będzie podawał nam aktualną godzinne po wpisaniu komendy !czas, ale dość już tego przedłużania i zacznijmy kodowanie!

 Pierwszym krokiem jaki zrobimy to napiszemy podstawowy kod uruchamiający bota:
 

const Discord = require('discord.js');

const bot = new Discord.Client();

bot.login(token);

Ale co to w sumie jest? I skąd wziąć token?
Takie dwa pytanie mogą narodzić się w Twojej głowie podczas patrzenie na ten kod już spieszę z wyjaśnieniami.

Wpierw zajmiemy się pytaniem technicznym co oznaczają poszczególne linijki, a zrobię to w taki sposób:

const Discord = require('discord.js'); /* Pobieramy  domyślny obiekt do pobrania z biblioteki discord.js i przypisujemy je do zmiennej Discord */
const bot = new Discord.Client(); /* Tworzy naszego bota i przypisuje go do zmiennej bot */
bot.login(token); /* przypisuje specjalny tajny kod dostępu do naszego bota */

 

Najważniejszą zasadą przy tokenie jest to, że nie wolno go podawać publicznie ponieważ jest to taki login i hasło dla naszego bota i podając komuś ten token dajemy komuś dostęp do bota.
Ale mówię tu o tym tokenie, a w sumie nie wiadomo jak stworzyć taki token…

1. Należy wejść na stronę Zarejestruj się lub zaloguj, aby zobaczyć ukrytą treść! jest to programistyczny panel platformy Discord, właśnie tam możemy stworzyć naszego bota.

2. Pierwszym krokiem panelu programisty jest utworzenie specjalnej aplikacji Discordowej, jest ona taką naszą strefą, dzięki której możemy programować używając specjalnych API – jest to specjalna bramka umożliwiająca niegraficzne połączenia z daną platformą, aktualnie bez API nie można zrobić poprawnie dużej platformy, zwłaszcza tak zaawansowanej jak Discord.

3. Kolejno musimy wybrać zakładkę BOT, a następnie klikamy Create bot, zostanie wtedy utorzona nam dodatkowa strefa, w której możemy pobrać informacje takie jak token.

4. Aby pozwolić nam podejrzeć token należy kliknąć w tekst Click to Reveal Token

Oto krótki wizualny poradnik jak to zrobić:

kwcBYP1.gif

Okej nasz bot już istnieje możemy wkleić teraz token w odpowiednie miejsce:

const Discord = require('discord.js');
const client = new Discord.Client();

client.login('Nzc1NjcxMDQ4ODEyNjI1OTMw.X6pt9Q.OOkUQp59J918Al274uZxicryBZU'); 
/* Przypisujemy go używając znaku ' odpowiada on w JavaScripcie za tekst,
który ignoruje jakiekolwiek nazwy zmiennych jeżeli przypadkiem pojawiły się w naszym tokenie */


(Tak, wiem udostępniłem właśnie Wam token do mojego bota lecz po opublikowaniu tej lekcji kod ten jest już zmieniony)

Okej mamy już bota, mamy już token, ale jak wygenerować link, którym dodamy naszego bota na serwer?
Już śpieszę z wyjaśnieniami. Najprostszym sposobem jest w panelu aplikacji wejście w zakładkę OAuth2, następnie w pierwszej liście zaznaczamy opcje bot, a na kolejnej pojawionej liście wybieramy permisje, które będą dostępne dla bota po dodaniu go generowanym linkiem. Ja z powodu, że jest to bot poradnikowy wybiorę permisje Administrator, czyli nadam botowi wszelkie permisje, lecz nie zawsze jest to wymagane, czasem wystarczy tylko wysyłanie wiadomości, albo dodawanie reakcji w zależności jakiego bota robimy, kolejno kopiujemy wygenerowany link, a następnie przeklejamy go do paska przeglądarki i postępujemy standardowo jak podczas dodawania bota, czyli wybieramy serwer (musimy na nim mieć dostęp do zarządzania serwerem)
Poradnik graficzny:

node.js26.gif.7ff40f28dfd8c6109f4a5fd91be20be1 (1).gif

 

Nasz bot jest już gotowy do uruchomienia. No właśnie do uruchomienia, ale jak to zrobić? Istnieje wiele różnych sposobów na uruchamianie aplikacji pisanych w nodeJS, ale jeden z nich jest najwygodniejszy (a co najmniej w mojej opini) i właśnie go wam przedstawię, ale wracając do poradnik krok po kroku:
1. Wchodzimy w plik package.json

2. Następnie znajdujemy linijkę

„test”: „echo \”Error: no test specified\” && exit 1”

3. Kolejno zamieniamy jej treść na:

„start”: „node bot.js”

( „Start” w tym miejscu określa nazwę, skryptu możesz ją nazwać jak tylko chcesz, ale musi być ona zawarta w cudzysłowie, w miejscu bot.js powinieneś wpisać nazwę pliku głównego, którego nazwę zdefiniowałeś podczas tworzenia projektu poleceniem npm init)
4. Zapisujemy plik i w lewym dolnym rogu znajdujemy przycisk NPM SCRIPTS, a następnie klikamy w nasz skrypt

SDdieAR.gif


Tym sposobem nasz bot już działa i można zauważyć że jego status jest aktywny, lecz nadal nie mamy od niego żadnego komunikatu. Dlatego teraz dodamy do naszego bota komunikat do konsoli, że został poprawnie uruchomiony.
Oto kilka sposobów na stworzenie takiego kodu:

 

const Discord = require('discord.js');
const client = new Discord.Client();
client.login('Nzc1NjcxMDQ4ODEyNjI1OTMw.X6pt9Q.OOkUQp59J918Al274uZxicryBZU');

function ReadyFunction(){
    console.log("Bot został poprawnie uruchomiony");
};
client.on('ready', ReadyFunction);

 

const Discord = require('discord.js');
const client = new Discord.Client();
client.login('Nzc1NjcxMDQ4ODEyNjI1OTMw.X6pt9Q.OOkUQp59J918Al274uZxicryBZU');

const ReadyFunction = () => {
	console.log("Bot został poprawnie uruchomiony");
};
client.on('ready', ReadyFunction);

 

const Discord = require('discord.js');
const client = new Discord.Client();
client.login('Nzc1NjcxMDQ4ODEyNjI1OTMw.X6pt9Q.OOkUQp59J918Al274uZxicryBZU');

client.on('ready', () => {
    console.log("Bot został poprawnie uruchomiony");
});

 

const Discord = require('discord.js');
const client = new Discord.Client();
client.login('Nzc1NjcxMDQ4ODEyNjI1OTMw.X6pt9Q.OOkUQp59J918Al274uZxicryBZU');

const ReadyFunction = function(){
	console.log("Bot został poprawnie uruchomiony");
};
client.on('ready', ReadyFunction);

 

const Discord = require('discord.js');
const client = new Discord.Client();
client.login('Nzc1NjcxMDQ4ODEyNjI1OTMw.X6pt9Q.OOkUQp59J918Al274uZxicryBZU');

client.on('ready', function(){
	console.log("Bot został poprawnie uruchomiony");
});

 

Ukazałem tu możliwość stworzenia tej akcji używając każdej z poznanych w poprzedniej części wariacji funkcji. Ja jak i większość programistów użyła by funkcji strzałkowej nieprzypisanej, którą ukazałem w środkowym kodzie i właśnie z nią będziemy pracować, lecz w żaden sposób nie zabraniam pisania w inny sposób. Jedną z ważnych zasad kodu JavaScript jest czytelność i jednolitość kodu, dlatego jakiej funkcji użyjecie leży po waszej stronie, lecz powinniście - aby zachować jednolitość składniową kodu - używać tej samej przez cały projekt.
Funkcja wywołuje nam najprostsze, ale jednocześnie nieznane nam jeszcze zadanie czylo console.log("notka") obstawiam trudne nie jest do zgadniecie co to znaczy, jest to dokładnie wypisanie treści notki do konsoli jest to jedna z częstszych metod wyszukiwania błędów w JS czyli wypisywanie wartości do konsoli i szukanie, w którym momencie dzieje się coś co nie powinno się stać.
Ostatnią rzeczą do omówienia w tym krótkim kodzie jest funkcja przypisania do opcji on w naszym bocie. Oznacza ona, że w momencie gdy zostanie wykonana akcja z pierwszego argumentu funkcji, ona sama wykona nam przypisaną w drugim funkcje.
(Listę wszystkich dostępnych nazw akcji znajdziesz tutaj: Zarejestruj się lub zaloguj, aby zobaczyć ukrytą treść!, znajduje się ona w liście events po kliknięciu w daną nazwę zostaniesz przeniesiony do strony opisującej działanie wraz z wypisem możliwych argumentów)

Sprawdźmy czy po uruchomieniu działa:

dn78NnD.png
(Jeżeli twój wynik jest inny sprawdź czy nasz wszystko dobrze zapisane)

Jak mamy już to gotowe wyłączmy naszego bota klikając ten śmietniczek

MYvyiev.png

Przejdźmy teraz do pisania naszej pierwszej komendy, użyjemy do tego eventu o nazwie message, wyglada on tak:

client.on('message', ( msg ) => {
    
});

Możemy zauważyć, że w przeciwieństwie do eventu ready, przekazuje on argument. Najczęściej argument ten jest zapisywany jako zmienna msg, dlatego ja również będę go tak nazywał. Z powodu, że funkcja ta jest funkcją strzałkową z jednym argumentem możemy użyć skróconej wersjii zapisu czyli:

client.on('message', msg => {
    
});

Obie te funkcje będą działały identycznie. Teraz powinniśmy sprawdzić jak tak naprawdę wygląda przekazywany nam obiekt, który widnieje w naszej funkcji pod nazwą msg, najprościej sprawdzimy to tak:

client.on('message', ( msg ) => {
    console.log(msg)
});

Wynik tego kodu jest taki:

Message {
  channel: TextChannel {
    type: 'text',
    deleted: false,
    id: '775668209768071168',
    name: 'kanał1',
    rawPosition: 3,
    parentID: '775667827163004938',
    permissionOverwrites: Collection [Map] {
      '705028390205259886' => [PermissionOverwrites],
      '706164940557385738' => [PermissionOverwrites] 
    },
    topic: null,
    nsfw: false,
    lastMessageID: '775837008224190464',
    rateLimitPerUser: 0,
    lastPinTimestamp: null,
    guild: Guild {
      members: [GuildMemberManager],
      channels: [GuildChannelManager],
      roles: [RoleManager],
      presences: [PresenceManager],
      voiceStates: [VoiceStateManager],
      deleted: false,
      available: true,
      id: '705028390205259886',
      shardID: 0,
      name: 'Boty',
      icon: null,
      splash: null,
      discoverySplash: null,
      region: 'europe',
      memberCount: 6,
      large: false,
      features: [],
      applicationID: null,
      afkTimeout: 300,
      afkChannelID: null,
      systemChannelID: null,
      embedEnabled: undefined,
      premiumTier: 0,
      premiumSubscriptionCount: 0,
      verificationLevel: 'NONE',
      explicitContentFilter: 'DISABLED',
      mfaLevel: 0,
      joinedTimestamp: 1605005303568,
      defaultMessageNotifications: 'ALL',
      systemChannelFlags: [SystemChannelFlags],
      maximumMembers: 250000,
      maximumPresences: null,
      approximateMemberCount: null,
      approximatePresenceCount: null,
      vanityURLCode: null,
      vanityURLUses: null,
      description: null,
      banner: null,
      rulesChannelID: null,
      publicUpdatesChannelID: null,
      preferredLocale: 'en-US',
      ownerID: '319161845220900864',
      emojis: [GuildEmojiManager]
    },
    messages: MessageManager {
      cacheType: [Function: LimitedCollection],
      cache: [LimitedCollection [Map]],
      channel: [Circular]
    },
    _typing: Map {}
  },
  deleted: false,
  id: '775837008224190464',
  type: 'DEFAULT',
  system: false,
  content: 'Wiadomość testowa',
  author: User {
    id: '319161845220900864',
    system: false,
    locale: null,
    flags: UserFlags { bitfield: 64 },
    username: 'wiktoor123',
    bot: false,
    discriminator: '0439',
    avatar: '667ac96c2b090fd60a80a80836c0e5d3',
    lastMessageID: '775837008224190464',
    lastMessageChannelID: '775668209768071168'
  },
  pinned: false,
  tts: false,
  nonce: '775837009607393280',
  embeds: [],
  attachments: Collection [Map] {},
  createdTimestamp: 1605044357115,
  editedTimestamp: 0,
  reactions: ReactionManager {
    cacheType: [Function: Collection],
    cache: Collection [Map] {},
    message: [Circular]
  },
  mentions: MessageMentions {
    everyone: false,
    users: Collection [Map] {},
    roles: Collection [Map] {},
    _members: null,
    _channels: null,
    crosspostedChannels: Collection [Map] {}
  },
  webhookID: null,
  application: null,
  activity: null,
  _edits: [],
  flags: MessageFlags { bitfield: 0 },
  reference: null
}

Możemy z tego wyczytać, że jest to obiekt składający się z wielu innych obiektów, ale niech was to nie przeraża nie jest to trudne i przebrniemy przez to razem. Wiadomość, którą wysłałem wyglądała tak:

oRIIxGF.png

Dlatego wiemy już, że jej treść musi mieć wartość Wiadomość testowa. Odnajdźmy ją teraz w tym dużym obiekcie powyżej... (znajduje się w 74 linijce)
Po chwili poszukiwań uda nam się ją znaleźć. Możemy zauważyć, że nie należy ona do innego obiektu, dlatego wystarczy, że odwołamy się do niej za pomocą msg.NAZWA, a za nazwę wstawimy nazwę tego parametru czyli content, poprawny kod wygląda teraz tak:
 

client.on('message', msg => {
    console.log(msg.content)
});

Dzięki niemu po napisaniu jakiejkolwiek wiadomości otrzymamy jej treść w konsoli:

tJllPYg.png


Teraz musimy użyć wyrażenia warunkowego jakim jest IF, jego składnia wygląda tak:

if(warunek){
    //To co jest wykonywane jeżeli warunek jest prawdą
}

Warunkiem jaki dziś użyjemy jest warunek równa się, czyli będzie on sprawdzał czy obie dane są równe. Taki typ warunku oznacza się dwoma znakami równości. Kod z jego użyciem będzie wyglądać tak:

client.on('message', msg => {
    if(msg.content == "!czas"){
        console.log("Warunek został spełniony")
    }
});

Log w konsoli zostanie wyświetlony tylko w przypadku gdy użytkownik napisze !czas.

6459th2.png8QFULyR.png

Teraz przyszedł czas na odpisywanie wiadomości przez bota. Zrobimy to w taki sposób:

client.on('message', msg => {
    if(msg.content == "!czas"){
        msg.reply("Wykonałeś polecenie")
    }
});

Oto wynik tego kodu:

 

Ostatnim elementem kodu będzie użycie specjalnej funkcji Data, dzięki której w łatwy sposób możemy pobrać godzine. (dokumentacje tej metody dla ciekawskich znajdziesz tutaj: Zarejestruj się lub zaloguj, aby zobaczyć ukrytą treść!) Kod z użyciem tej funkcji wygląda tak:

client.on('message', msg => {
    if(msg.content == "!czas"){
        const data = new Date;
        const godzina = data.getHours;
        const minuta = data.getMinutes;
        const sekunda = data.getSeconds;
        msg.reply(`aktualna godzina: ${godzina}:${minuta}:${sekunda}`);
    }
});

Jak widać aby połączyć te 3 zmienne wraz z tekstem w jeden ciąg użyliśmy znaku ` - Grawis (ten ukośny apostrof znajdujący się na klawiaturze pod klawiszem ESC) - , a same zmienne zdefiniowaliśmy w nawiasach klamrowych poprzedzonych znakiem dolara tym sposobem stworzyliśmy Temple Stringi, w których możemy użyć jakiego chcemy sformułowania z JS i będzie on przekształcony w stringa, a następnie połączony z ciągiem znaków. Użycie tego kodu wygląda tak:

VAD8XQu.png

To koniec na dzisiaj. Mam nadzieje, że dzisiejsza lekcja była łatwa do zrozumienia, a przyswojona dzisiaj wiedza zostanie w waszych umysłach na długo.

Chciałbyś bym omówił coś dokładniej, albo masz inne zastarzenia co do dzisiejszej jak i wcześniejszej lekcji? 
Napisz to w komentarzu poniżej :) 

(Kolejna lekcja już w piątek!)

 

Do zobaczenie o/

Odnośnik do komentarza
Udostępnij na innych stronach

 XUCYzaO.png

Podczas lekcji:

  • poznasz zasadę dołączania pliku .json do projektu, 
  • poznasz sposób stworzenia pliku konfiguracyjnego z rozszerzeniem .json,
  • poznasz działanie prostego handlera komend,
  • poznasz przykładowy wygląd drzewa plików, 
  • stworzysz automatyczną komendę pomocy

Witam, w kolejnej lekcji tworzenia botów do discorda. Dzisiejszy projekt będzie kontynuacją poprzedniej lekcji (kod z niej możesz skopiować z poprzedniego  komentarza bądź z githubowego repozytorium: Zarejestruj się lub zaloguj, aby zobaczyć ukrytą treść!). W tej lekcji czeka nas dużo nauki i dużo zmian w dotychczasowym projekcie dlatego już nie przedłużam i zaczynamy.

Pierwszym krokiem dzisiejszej lekcji będzie stworzenie drzewa plików jakich będziemy potrzebować.
W katalogu głównym tworzymy plik handler.js  to właśnie ten plik będzie odpowiedzialny za aktywowanie kolejnych komend, oraz tworzymy dwa katalogi jeden nazywamy config, w nim będą znajdowały się pliki konfiguracyjne dlatego już teraz umieszczamy w nim pusty plik main.json będą w nim się znajdowały główne dane konfiguracyjne, drugi katalog nazywamy cmds i umieszczamy w nim dwa pliki które będą odpowiadały komendą: czas.js, help.js

TD3SxFF.gif

 

Jeżeli projekt mamy już przygotowany możemy zacząć prace. 

Na początek użyjemy pliku konfiguracyjnego, aby zdefiniować w nim token i prefix bota, aby to zrobić musimy zamieścić w tym pliku dane w formacie JSON. W moim przypadku będzie to wyglądać tak:

{
    "token": "Nzc1NjcxMDQ4ODEyNjI1OTMw.X6pt9Q.CIYWrDB1YWMTt_HL0hd9dSDtmow",
    "prefix": "!"
}

Jak możesz zauważyć format ten to format, w którym tworzy się obiekt, lecz w przeciwieństwie do JavaScripta, nazwy opcji muszą być w cudzysłowie. 
Teraz jak mamy już przygotowany plik konfiguracyjny musimy go użyć w naszym pliku bot.js, robimy to tak samo jak importowaliśmy dane z biblioteki DiscordJS

const Discord = require('discord.js');
const config = require('./config/main.json');

const client = new Discord.Client();
client.login('Nzc1NjcxMDQ4ODEyNjI1OTMw.X6pt9Q.CIYWrDB1YWMTt_HL0hd9dSDtmow');


client.on('ready', () => {
    console.log("Bot został poprawnie uruchomiony");
});


client.on('message', msg => {
    if(msg.content == "!czas"){
        const data = new Date;
        const godzina = data.getHours();
        const minuta = data.getMinutes();
        const sekunda = data.getSeconds();
        msg.reply(`aktualna godzina: ${godzina}:${minuta}:${sekunda}`);
    }
});

Ale co nam po dodaniu pliku konfiguracyjnego, jeżeli go nie używamy, a więc aby zacząć prace z danymi z pliku JSON należy jej użyć jak zwykłego obiektu.

const Discord = require('discord.js');
const config = require('./config/main.json');

const client = new Discord.Client();
client.login(config.token);


client.on('ready', () => {
    console.log("Bot został poprawnie uruchomiony");
});


client.on('message', msg => {
    if(msg.content == "!czas"){
        const data = new Date;
        const godzina = data.getHours();
        const minuta = data.getMinutes();
        const sekunda = data.getSeconds();
        msg.reply(`aktualna godzina: ${godzina}:${minuta}:${sekunda}`);
    }
});

Sprawdźmy teraz czy to działa:

XbmvnU0.png

Jak można było zauważyć prócz tokenu zdefiniowaliśmy także prefix, dlatego zaraz przedstawię sposób jak go użyć w naszym kodzie. 

client.on('message', msg => {
    const MSGcontent = msg.content;
    if(MSGcontent.startsWith(config.prefix)){
        const args = MSGcontent.substr(config.prefix.length).split(" ");
        const cmd = args["0"];
        if(cmd == "czas"){
            const data = new Date;
            const godzina = data.getHours();
            const minuta = data.getMinutes();
            const sekunda = data.getSeconds();
            msg.reply(`aktualna godzina: ${godzina}:${minuta}:${sekunda}`);
        }
    }
});

Dużo nowości prawda? Ale spokojnie już wszystko tłumacze

if(MSGcontent.startsWith(config.prefix)){ }

String.startWith() <- ta metoda zwraca nam prawdę/fałsz w zależności czy dany string (czyli ciąg znaków) zaczyna się od tego co znajduje się w nawiasie w naszym przypadku jest prefix bota

const args = MSGcontent.substr(config.prefix.length).split(" ");

tutaj występują trzy nowe elementy czyli po pierwsze string.substr() co oznacza, że danego stringa odcinana jest dana ilość znaków, kolejne to string.lenght, jest to metoda zwracająca nam długość stringa w tym przypadku ilość znaków, które mają zostać odcięte i trzecią metodą jest string.split() <- tworzy ze stringa tablice, która jest podzielona przez ciąg znaków zawartych w nawiasie, w moim przypadku jest to spacja czyli dzieli wiadomość na poszczególne wyrazy.
 

Sprawdźmy teraz czy to działa:

R1ZWLWp.png

Jak widać wszystko działa. Teraz zrobimy kilka akcji naraz. A dokładnie stworzymy handler – łapacz komend -  będzie on polegał na wykonywaniu poszczególnych komend z odpowiednich plików.

Pierwszą najprostszą czynnością jaką zrobimy będzie przeniesienie działania komendy do innego pliku i nadanie jej nazwy oraz opisu. A dokładnie będzie to wyglądać tak:

module.exports = {

    name: "czas",
    description: "pokazuje aktualną godzine",
    run: msg => {
        const data = new Date;
        const godzina = data.getHours();
        const minuta = data.getMinutes();
        const sekunda = data.getSeconds();
        msg.reply(`aktualna godzina: ${godzina}:${minuta}:${sekunda}`);
    }
}

 

Jak widać przypisaliśmy cały obiekt do tak zwanego obiektu modułowego:

module.exports

 

A opcja export służy do tego by wynosić domyślnie ten obiekt z pliku. Nadaliśmy również nazwę komendzie, która będzie nam potrzebna podczas budowania handlera to właśnie ona będzie wskazywała na komendę (w tym przypadki !czas) oraz opis który przyda nam się podczas tworzenia komendy pomocy.

Kolejną rzeczą którą zrobimy to napiszemy handler, oto on:

 

const czas = require('./cmds/czas.js')
const config = require('./config/main.json');
const { readdirSync } = require("fs");
const { Collection } = require("discord.js");

module.exports = client =>{

    client.commands = new Collection();
  	const commandFiles = readdirSync("./cmds").filter((file) => file.endsWith(".js"));
    for (const file of commandFiles) {
        const command = require(`./cmds/${file}`);
        if (command.name) {
            if (command.run) {
                client.commands.set(command.name, command);
                console.log(`✅ ${file}`);
              } else {
                  console.log(`❌ ${file} - brak zdarzenia`);
              }
        } else {
            console.log(`❌ ${file} - brak nazwy komendy`);
        }
      }

 
    client.on('message', msg => {
		const MSGcontent = msg.content;
        if(!MSGcontent.startsWith(config.prefix)) { return; }
        if(msg.author.bot) { return; }       

        const args = MSGcontent.substr(config.prefix.length).split(" ");
        const cmd = args[0].toLowerCase();

        if (!client.commands.has(cmd)){ return; }


        try {
            client.commands.get(cmd).run(msg);
          } catch (e) {
            console.error(e);
            msg.reply("Wystąpił błąd, zgłoś sytuacje administracji!");
          }
    });
}

 

Dużo, dużo dużo nowości wiem, dlatego już wszystko wyjaśniam:
 

client.commands = new Collection()

 

W tym miejscy tworzymy specjalną kolekcje, w której będziemy zapisywać nazwę naszej komendy i jej plik.

 const commandFiles = readdirSync("./cmds").filter((file) => file.endsWith(".js"))

 

W tym miejscu przeszukujemy katalog z komendami używając filtra który zapisuje tylko te nazwy plików, które kończą się na .js.

for (const file of commandFiles) {

}

 

Tutaj tworzymy specjalną pętle po tablicy wcześniej zapisanych nazw plików i zapisujemy poszczególny je jako zmienna file – będzie ona dostepna tylko na obszarze tej pętli.

if (command.name){}   i   if (command.name){}

Te dwa warunku sprawdzają czy dany obiekt w tym przypadku plik komendy posiada te dwie opcje.

client.commands.set(command.name, command)

 W tym miejscu wykorzystujemy stworzoną wcześniej kolekcje i zapisujemy w niej nazwę komedy i obiekt pliku

if(!MSGcontent.startsWith(config.prefix)) { return; }

 

Tutaj sprawdzamy czy wiadomość nie zaczyna się od prefixu, ! w ifie znaczy zaprzeczenie warunku.

if(msg.author.bot) { return; }

Tutaj spradzamy czy wiadomość nie jest od bota, jeżeli jest zostaje zakończone działanie funkcji przez wyrażenie return;

const cmd = args[0].toLowerCase();

Tutaj prócz wyciągania jak wcześniej po prostu komendy tutaj zamieniamy całą komendę na małe literki.

if (!client.commands.has(cmd)){ return; }

A w tym miejscu sprawdzamy czy dana komenda istnieje.

try {
  client.commands.get(cmd).run(msg);
} catch (e) {
  console.error(e);
  msg.reply("Wystąpił błąd, zgłoś sytuacje administracji!");
}

 

Tutaj za pomocą funkcji try/catch wyłapujemy błędy, czyli jeżeli na przykład kod komedy miał by jakiś błąd to wyrzucamy go do konsoli.

Ostatnim krokiem będzie poousuwanie zbędnych fragmentów kodu z pliku bot.js. Będzie on teraz wyglądał tak:

const Discord = require('discord.js');
const config = require('./config/main.json');
const handler = require('./handler.js');

const client = new Discord.Client();

client.login(config.token);
handler(client);

client.on('ready', () => {
    console.log("Bot został poprawnie uruchomiony");
});

 

Sprawdźmy teraz jak to wszystko działa

 

cgXPKnn.png

 

Jak widać wszystko działa perfekto. Ostanim elementem jaki zrobimy na tym kursie jest automatyczna komenda pomocy (dlaczego ostatnim dowiecie się na końcu). Plan na komendę pomocy jest taki:

1. Wyciągamy z wiadomości która jest przekazywana do komendy clienta, czyli naszego bota, na którym zapisane są wszystkie komendy

2. Następnie tworzymy embed wiadomość.

3. Wpisujemy w tą wiadomość wszystkie komendy wraz z opisami.

4. Jeżeli komenda nie ma opisu to wpisujemy „Brak opisu”\

Plan już mamy no to do dzieła oto kod całego mechanizmu:

 

const Discord = require('discord.js');
module.exports = {

    name: "help",
    description: "Wyświelta informacje o wszystkich komendach",
    run: msg => {
        const client = msg.client;
        const embed = new Discord.MessageEmbed()
        .setColor('#0099ff')
        .setTitle('Lista komend');
   
        client.commands.map(command => embed.addField(command.name, command.description, false));

        msg.channel.send(embed)
    }
}


Tutaj też dużo nowości, dlatego znowu poopisujemy linijka po linijce

const client = msg.client;

Tutaj wyciągamy clienta z wiadomości tak jak pisałem w punkcie 1.

const embed = new Discord.MessageEmbed()
        .setColor('#0099ff')
        .setTitle('Lista komend');

 Tworzymy kolorową wiadomość o tytule Lista komend i kolorze niebieskim zapisanym w systemie hexadecymalnym.

client.commands.map(command => embed.addField(command.name, command.description, false));

Funkcją map przerabiamy wszytskie wartości w kolekcji lub tablicy i przypisujemy ich wartość do argumentu. A następnie w samej funkcji dodajemy nowe pole embeda z wartością opisu komendy i ustawiamy by jedna linia odpowiadała jednej informacji.

msg.channel.send(embed)

I ostatecznie wysyłamy gotową wiadomość do kanału, na którym została wykonana komenda.

A teraz sprawdźmy jak to wygląda:

 

dEq482F.png

Jest idealnie

 

 

 To I to na tyle z podstawowego kursu pisania botów do discoda. To były podstawy teraz została praca z dokumentacją, którą znajdziecie pod tymi linkami:

Zarejestruj się lub zaloguj, aby zobaczyć ukrytą treść!

Zarejestruj się lub zaloguj, aby zobaczyć ukrytą treść!

Lub można napisać do mnie na skryptowym discordzie albo moim, do którego link pojawi się niebawem tylko musze napisać na niego odpowiedniego bota i dobrze dostosować rangi lub po prostu napiszcie pod tym wątkiem jakieś pytanie.

Dziękuje wszystkim osobom, które śledziły na bieżącą jak i tym które przeczytały to później. Mam nadzieje, że tymi 3 lekcjami ukazałem wam, że JavaScript nie jest taki trudny.

 

Trzymam za was kciuki miłego kodowania o/

Odnośnik do komentarza
Udostępnij na innych stronach

  • 1 rok później...

Dołącz do dyskusji

Możesz dodać zawartość już teraz a zarejestrować się później. Jeśli posiadasz już konto, zaloguj się aby dodać zawartość za jego pomocą.

Nieaktywny
Dodaj odpowiedź do tematu...

×   Wklejono zawartość z formatowaniem.   Usuń formatowanie

  Dozwolonych jest tylko 75 emoji.

×   Odnośnik został automatycznie osadzony.   Przywróć wyświetlanie jako odnośnik

×   Przywrócono poprzednią zawartość.   Wyczyść edytor

×   Nie możesz bezpośrednio wkleić grafiki. Dodaj lub załącz grafiki z adresu URL.

 Udostępnij

  • Ostatnio przeglądający   0 użytkowników

    • Brak zarejestrowanych użytkowników przeglądających tę stronę.
×
×
  • Dodaj nową pozycję...