├── .gitattributes ├── README.md ├── arduino-discord.ino ├── schematic.png └── secrets_sample.h /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Arduino, is my bot online? 2 | 3 | It opens a websocket connection with Discord to receive `PRESENCE_UPDATE` events. Once the target become offline, it makes a red led blinks, and once it comes back online, it turns on the green led. 4 | 5 | ## How to install 6 | 7 | * Set up your project using the schematic below. 8 | * Download the code. 9 | * Rename the `secrets_sample.h` file to `secrets.h` and fill it. 10 | * Upload it to your Arduino. 11 | * You're done! 12 | 13 | Once the watched bot will be offline, the red led will blink. 14 | 15 | ## Used libraries 16 | 17 | * [ArduinoJson](https://arduinojson.org/) (used to deserialize Discord payloads) 18 | * [ArduinoWebsockets](https://github.com/gilmaimon/ArduinoWebsockets) (used to open a ws connection to Discord) 19 | 20 | You will also need to add this link: `http://arduino.esp8266.com/stable/package_esp8266com_index.json` to the Additional boards Manager to be able to select `Node mcu 1.0` as the card type. 21 | 22 | ## Used components 23 | 24 | * [Arduino esp8266 mod (node mcu 1.0)](https://www.amazon.fr/SeeKool-d%C3%A9veloppement-Fonctionne-Parfaitement-Compatible/dp/B07DRF9YTV) 25 | * Breadboard 26 | * x2 color leds (one green, one red) 27 | * x2 resistors (220 ohm 1/4 watt) 28 | * x5 wires 29 | 30 | ## Schematic 31 | 32 | ![schematic](./schematic.png) 33 | -------------------------------------------------------------------------------- /arduino-discord.ino: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | #include 5 | 6 | #include 7 | 8 | #include 9 | 10 | #include 11 | #include 12 | 13 | #include "secrets.h" 14 | 15 | ESP8266WiFiMulti WiFiMulti; 16 | 17 | using namespace websockets; 18 | WebsocketsClient client; 19 | 20 | const char ssid[] = SECRET_SSID; 21 | const char pass[] = SECRET_PASS; 22 | const char token[] = SECRET_TOKEN; 23 | const char watched_user_id[] = WATCHED_USER_ID; 24 | 25 | const uint8_t RED_LED = D1; 26 | const uint8_t GREEN_LED = D0; 27 | 28 | bool connected = false; 29 | int lastHeartbeatTime = -1; 30 | int heartbeatInterval = 60000; 31 | int sequence = -1; 32 | 33 | bool offline = false; 34 | 35 | void onMessageCallback(WebsocketsMessage message) { 36 | DynamicJsonDocument payloadObj(2048); 37 | deserializeJson(payloadObj, message.data()); 38 | if(payloadObj["s"]){ 39 | sequence = payloadObj["s"]; 40 | } 41 | if(payloadObj["op"] == 10){ 42 | heartbeatInterval = payloadObj["d"]["heartbeat_interval"]; 43 | login(); 44 | } 45 | if(payloadObj["t"] == "PRESENCE_UPDATE"){ 46 | if(payloadObj["d"]["user"]["id"] == watched_user_id){ 47 | const String newStatus = payloadObj["d"]["status"]; 48 | Serial.println("Target became "+newStatus); 49 | if(newStatus == "offline"){ 50 | offline = true; 51 | } else { 52 | offline = false; 53 | } 54 | } 55 | } 56 | } 57 | 58 | void login(){ 59 | Serial.println("Logging in..."); 60 | DynamicJsonDocument payloadObj(1024); 61 | payloadObj["op"] = 2; 62 | JsonObject data = payloadObj.createNestedObject("d"); 63 | data["token"] = token; 64 | data["intents"] = 256; 65 | JsonObject properties = data.createNestedObject("properties"); 66 | properties["$os"] = "darwin"; 67 | properties["$browser"] = "discly"; 68 | properties["$device"] = "discly"; 69 | String payload = ""; 70 | serializeJson(payloadObj, payload); 71 | Serial.println(payload); 72 | client.send(payload); 73 | Serial.println("Login payload sent!"); 74 | } 75 | 76 | void sendHeartBeat(){ 77 | Serial.println("Sending heartbeat..."); 78 | DynamicJsonDocument payloadObj(1024); 79 | payloadObj["op"] = 1; 80 | payloadObj["d"] = sequence; 81 | String payload = ""; 82 | serializeJson(payloadObj, payload); 83 | client.send(payload); 84 | lastHeartbeatTime = millis(); 85 | Serial.println("Heartbeat payload sent!"); 86 | } 87 | 88 | void onEventsCallback(WebsocketsEvent event, String data) { 89 | if(event == WebsocketsEvent::ConnectionOpened) { 90 | Serial.println("Websocket Connnection Opened!"); 91 | Serial.println(data); 92 | } else if(event == WebsocketsEvent::ConnectionClosed) { 93 | Serial.println("Websocket Connnection Closed!"); 94 | Serial.println(data); 95 | Serial.println(client.getCloseReason()); 96 | } 97 | } 98 | 99 | void setup() { 100 | 101 | pinMode(D0, OUTPUT); 102 | pinMode(D1, OUTPUT); 103 | 104 | Serial.begin(9600); 105 | 106 | Serial.println(); 107 | Serial.println(); 108 | Serial.println(); 109 | 110 | for (uint8_t t = 4; t > 0; t--) { 111 | Serial.printf("[SETUP] WAIT %d...\n", t); 112 | Serial.flush(); 113 | delay(1000); 114 | } 115 | 116 | connectToWifi(); 117 | 118 | // Setup Callbacks 119 | client.onMessage(onMessageCallback); 120 | client.onEvent(onEventsCallback); 121 | 122 | } 123 | 124 | void connectToWifi(){ 125 | WiFi.mode(WIFI_STA); 126 | WiFiMulti.addAP(ssid, pass); 127 | } 128 | 129 | void loop() { 130 | Serial.println(); 131 | if (int stat = WiFiMulti.run() == WL_CONNECTED && !connected) { 132 | Serial.println("Connected to WiFi network"); 133 | // Connect to server 134 | client.connect("wss://gateway.discord.gg/?v=6&encoding=json"); 135 | connected = true; 136 | } 137 | 138 | if(offline){ 139 | if(digitalRead(RED_LED) == HIGH){ 140 | digitalWrite(RED_LED, LOW); 141 | delay(500); 142 | } 143 | if(digitalRead(GREEN_LED) == HIGH){ 144 | digitalWrite(GREEN_LED, LOW); 145 | } 146 | digitalWrite(RED_LED, HIGH); 147 | delay(500); 148 | digitalWrite(RED_LED, LOW); 149 | delay(500); 150 | } else { 151 | digitalWrite(GREEN_LED, HIGH); 152 | } 153 | delay(1000); 154 | client.poll(); 155 | if (millis() - lastHeartbeatTime >= heartbeatInterval) { 156 | sendHeartBeat(); 157 | } 158 | } 159 | -------------------------------------------------------------------------------- /schematic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Androz2091/arduino-is-mybot-online/e7b7a6e900158976aab7160a5a619e878d254146/schematic.png -------------------------------------------------------------------------------- /secrets_sample.h: -------------------------------------------------------------------------------- 1 | #define SECRET_SSID "WIFI name" 2 | #define SECRET_PASS "WIFI password" 3 | 4 | #define SECRET_TOKEN "Discord bot token" 5 | 6 | #define WATCHED_USER_ID "ID of the discord bot to watch" 7 | --------------------------------------------------------------------------------