├── FUNDING.yml ├── LICENSE ├── README.md ├── examples ├── WifiNINA │ ├── setCustomStatus │ │ └── setCustomStatus.ino │ └── setPresence │ │ └── setPresence.ino ├── esp32 │ ├── setCustomStatus │ │ └── setCustomStatus.ino │ └── setPresence │ │ └── setPresence.ino └── esp8266 │ ├── setCustomStatus │ └── setCustomStatus.ino │ └── setPresence │ └── setPresence.ino ├── library.properties └── src ├── ArduinoSlack.cpp ├── ArduinoSlack.h └── ArduinoSlackCert.h /FUNDING.yml: -------------------------------------------------------------------------------- 1 | github: [witnessmenow] -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Brian Lough 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # arduino-slack-api 2 | An arduino library to wrap the Slack API 3 | 4 | Currently the library supports updating your Presence and setting a Custom Status. 5 | 6 | ![img](https://i.imgur.com/UUIQj2P.jpg) 7 | 8 | ## Help support what I do! 9 | 10 | I have created a lot of different Arduino libraries that I hope people can make use of. [If you enjoy my work, please consider becoming a Github sponsor!](https://github.com/sponsors/witnessmenow/) 11 | 12 | ### Getting Auth Token (this may change) 13 | 14 | - Create a new Slack App [here](https://api.slack.com/apps) 15 | - Name your app anything, set the "Development Slack Workspace" to the workspace you want to update your status in 16 | - This will bring you to a new page, on the left hand-side there is a menu. Click "OAuth & Permissions" 17 | - Go down to "Scopes", then under "User Token Scopes", click the "Add an OAuth Scope" button 18 | - Add the scopes you need. Here is a list of supported features in this library and their required scopes: 19 | 20 | | Enpoint | scope | 21 | | ------------- |-------------| 22 | | setPresence | users:write | 23 | | setCustomStatus | users.profile:write | 24 | 25 | - scroll up to the top of the page and click "install app to workspace" 26 | - Click "Allow" on the next page 27 | - You will now have an OAuth Access Token up the top of the page, this is uses as the SLACK_ACCESS_TOKEN 28 | -------------------------------------------------------------------------------- /examples/WifiNINA/setCustomStatus/setCustomStatus.ino: -------------------------------------------------------------------------------- 1 | /******************************************************************* 2 | Sets a custom status on your slack account using 3 | Arduino WifiNINA boards (e.g. Nano IoT) 4 | 5 | It will update every 30 seconds 6 | 7 | You will need a bearer token, see readme for more details 8 | 9 | Parts: 10 | Arduino Nano 33 IOT - https://store.arduino.cc/arduino-nano-33-iot 11 | 12 | * * = Affiliate 13 | 14 | If you find what I do usefuland would like to support me, 15 | please consider becoming a sponsor on Github 16 | https://github.com/sponsors/witnessmenow/ 17 | 18 | 19 | Written by Brian Lough 20 | YouTube: https://www.youtube.com/brianlough 21 | Tindie: https://www.tindie.com/stores/brianlough/ 22 | Twitter: https://twitter.com/witnessmenow 23 | *******************************************************************/ 24 | 25 | // ---------------------------- 26 | // Standard Libraries 27 | // ---------------------------- 28 | #include 29 | 30 | // ---------------------------- 31 | // Additional Libraries - each one of these will need to be installed. 32 | // ---------------------------- 33 | 34 | #include 35 | // Library for using network features of the official Arudino 36 | // Wifi Boards (MKR WiFi 1010, Nano 33 IOT etc) 37 | 38 | // Search for "nina" in the Arduino Library Manager 39 | // https://github.com/arduino-libraries/WiFiNINA 40 | 41 | #include 42 | // Library for connecting to the Slack API 43 | 44 | // Install from Github 45 | // https://github.com/witnessmenow/arduino-slack-api 46 | 47 | #include 48 | // Library used for parsing Json from the API responses 49 | 50 | // Search for "Arduino Json" in the Arduino Library manager 51 | // https://github.com/bblanchon/ArduinoJson 52 | 53 | //------- Replace the following! ------ 54 | 55 | char ssid[] = "SSID"; // your network SSID (name) 56 | char password[] = "password"; // your network password 57 | 58 | #define SLACK_ACCESS_TOKEN "AAAAAAAAAABBBBBBBBBBBCCCCCCCCCCCDDDDDDDDDDD" 59 | 60 | //------- ---------------------- ------ 61 | 62 | int status = WL_IDLE_STATUS; 63 | 64 | WiFiSSLClient client; 65 | ArduinoSlack slack(client, SLACK_ACCESS_TOKEN); 66 | 67 | unsigned long delayBetweenRequests = 30000; // Time between requests (1 minute) 68 | unsigned long requestDueTime; //time when request due 69 | 70 | bool firstStatus = true; 71 | 72 | void setup() 73 | { 74 | //Initialize serial and wait for port to open: 75 | Serial.begin(9600); 76 | while (!Serial) 77 | { 78 | ; // wait for serial port to connect. Needed for native USB port only 79 | } 80 | 81 | // check for the WiFi module: 82 | if (WiFi.status() == WL_NO_MODULE) 83 | { 84 | Serial.println("Communication with WiFi module failed!"); 85 | // don't continue 86 | while (true) 87 | ; 88 | } 89 | 90 | String fv = WiFi.firmwareVersion(); 91 | if (fv < "1.0.0") 92 | { 93 | Serial.println("Please upgrade the firmware"); 94 | } 95 | 96 | // attempt to connect to WiFi network: 97 | while (status != WL_CONNECTED) 98 | { 99 | Serial.print("Attempting to connect to SSID: "); 100 | Serial.println(ssid); 101 | // Connect to WPA/WPA2 network. Change this line if using open or WEP network: 102 | status = WiFi.begin(ssid, password); 103 | 104 | // wait 10 seconds for connection: 105 | delay(10000); 106 | } 107 | Serial.println("Connected to wifi"); 108 | printWiFiStatus(); 109 | 110 | // If you want to enable some extra debugging 111 | // uncomment the "#define SLACK_ENABLE_DEBUG" in ArduinoSlack.h 112 | } 113 | 114 | void displayProfile(SlackProfile profile) 115 | { 116 | if (!profile.error) 117 | { 118 | Serial.println("--------- Profile ---------"); 119 | 120 | Serial.print("Display Name: "); 121 | Serial.println(profile.displayName); 122 | 123 | Serial.print("Status Text: "); 124 | Serial.println(profile.statusText); 125 | 126 | Serial.print("Status Emoji: "); 127 | Serial.println(profile.statusEmoji); 128 | 129 | Serial.print("Status Expiration: "); 130 | Serial.println(profile.statusExpiration); 131 | 132 | Serial.println("------------------------"); 133 | } 134 | else 135 | { 136 | Serial.println("error getting profile"); 137 | } 138 | } 139 | 140 | void loop() 141 | { 142 | if (millis() > requestDueTime) 143 | { 144 | SlackProfile profile; 145 | if (firstStatus) 146 | { 147 | profile = slack.setCustomStatus("I am the first status", ":sparkling_heart:"); 148 | } 149 | else 150 | { 151 | profile = slack.setCustomStatus("I am the second status", ":v:"); 152 | // There is an optional third parameter which takes a Unix timestamp for 153 | // when this custom status expires: 154 | // slack.setCustomStatus("I am the second status", ":v:", 1532627506); 155 | } 156 | firstStatus = !firstStatus; 157 | displayProfile(profile); 158 | requestDueTime = millis() + delayBetweenRequests; 159 | } 160 | } 161 | 162 | void printWiFiStatus() 163 | { 164 | // print the SSID of the network you're attached to: 165 | Serial.print("SSID: "); 166 | Serial.println(WiFi.SSID()); 167 | 168 | // print your board's IP address: 169 | IPAddress ip = WiFi.localIP(); 170 | Serial.print("IP Address: "); 171 | Serial.println(ip); 172 | 173 | // print the received signal strength: 174 | long rssi = WiFi.RSSI(); 175 | Serial.print("signal strength (RSSI):"); 176 | Serial.print(rssi); 177 | Serial.println(" dBm"); 178 | } 179 | -------------------------------------------------------------------------------- /examples/WifiNINA/setPresence/setPresence.ino: -------------------------------------------------------------------------------- 1 | /******************************************************************* 2 | Toggles between a presence of "away" and "auto" on your slack account 3 | using Arduino WifiNINA boards (e.g. Nano IoT) 4 | 5 | It will toggle between the two every 30 seconds 6 | 7 | (FYI: You can't set to "online"- https://api.slack.com/methods/users.setPresence) 8 | 9 | You will need a bearer token, see readme for more details 10 | 11 | Parts: 12 | Arduino Nano 33 IOT - https://store.arduino.cc/arduino-nano-33-iot 13 | 14 | * * = Affilate 15 | 16 | If you find what I do useful and would like to support me, 17 | please consider becoming a sponsor on Github 18 | https://github.com/sponsors/witnessmenow/ 19 | 20 | 21 | Written by Brian Lough 22 | YouTube: https://www.youtube.com/brianlough 23 | Tindie: https://www.tindie.com/stores/brianlough/ 24 | Twitter: https://twitter.com/witnessmenow 25 | *******************************************************************/ 26 | 27 | // ---------------------------- 28 | // Standard Libraries 29 | // ---------------------------- 30 | #include 31 | 32 | // ---------------------------- 33 | // Additional Libraries - each one of these will need to be installed. 34 | // ---------------------------- 35 | 36 | #include 37 | // Library for using network features of the official Arudino 38 | // Wifi Boards (MKR WiFi 1010, Nano 33 IOT etc) 39 | 40 | // Search for "nina" in the Arduino Library Manager 41 | // https://github.com/arduino-libraries/WiFiNINA 42 | 43 | #include 44 | // Library for connecting to the Slack API 45 | 46 | // Install from Github 47 | // https://github.com/witnessmenow/arduino-slack-api 48 | 49 | #include 50 | // Library used for parsing Json from the API responses 51 | 52 | // Search for "Arduino Json" in the Arduino Library manager 53 | // https://github.com/bblanchon/ArduinoJson 54 | 55 | //------- Replace the following! ------ 56 | 57 | char ssid[] = "SSID"; // your network SSID (name) 58 | char password[] = "password"; // your network password 59 | 60 | #define SLACK_ACCESS_TOKEN "AAAAAAAAAABBBBBBBBBBBCCCCCCCCCCCDDDDDDDDDDD" 61 | 62 | //------- ---------------------- ------ 63 | 64 | int status = WL_IDLE_STATUS; 65 | 66 | WiFiSSLClient client; 67 | ArduinoSlack slack(client, SLACK_ACCESS_TOKEN); 68 | 69 | unsigned long delayBetweenRequests = 30000; // Time between requests (1 minute) 70 | unsigned long requestDueTime; //time when request due 71 | 72 | bool isPresenceAway = false; 73 | 74 | void setup() 75 | { 76 | //Initialize serial and wait for port to open: 77 | Serial.begin(9600); 78 | while (!Serial) 79 | { 80 | ; // wait for serial port to connect. Needed for native USB port only 81 | } 82 | 83 | // check for the WiFi module: 84 | if (WiFi.status() == WL_NO_MODULE) 85 | { 86 | Serial.println("Communication with WiFi module failed!"); 87 | // don't continue 88 | while (true) 89 | ; 90 | } 91 | 92 | String fv = WiFi.firmwareVersion(); 93 | if (fv < "1.0.0") 94 | { 95 | Serial.println("Please upgrade the firmware"); 96 | } 97 | 98 | // attempt to connect to WiFi network: 99 | while (status != WL_CONNECTED) 100 | { 101 | Serial.print("Attempting to connect to SSID: "); 102 | Serial.println(ssid); 103 | // Connect to WPA/WPA2 network. Change this line if using open or WEP network: 104 | status = WiFi.begin(ssid, password); 105 | 106 | // wait 10 seconds for connection: 107 | delay(10000); 108 | } 109 | Serial.println("Connected to wifi"); 110 | printWiFiStatus(); 111 | 112 | // If you want to enable some extra debugging 113 | // uncomment the "#define SLACK_ENABLE_DEBUG" in ArduinoSlack.h 114 | } 115 | 116 | void loop() 117 | { 118 | if (millis() > requestDueTime) 119 | { 120 | if (isPresenceAway) 121 | { 122 | if (slack.setPresence(SLACK_PRESENCE_AUTO)) 123 | { 124 | Serial.println("Set presence to Auto"); 125 | } 126 | else 127 | { 128 | Serial.println("Failed to set presence to Auto"); 129 | } 130 | } 131 | else 132 | { 133 | if (slack.setPresence(SLACK_PRESENCE_AWAY)) 134 | { 135 | Serial.println("Set presence to Away"); 136 | } 137 | else 138 | { 139 | Serial.println("Failed to set presence to Away"); 140 | } 141 | } 142 | isPresenceAway = !isPresenceAway; 143 | requestDueTime = millis() + delayBetweenRequests; 144 | } 145 | } 146 | 147 | void printWiFiStatus() 148 | { 149 | // print the SSID of the network you're attached to: 150 | Serial.print("SSID: "); 151 | Serial.println(WiFi.SSID()); 152 | 153 | // print your board's IP address: 154 | IPAddress ip = WiFi.localIP(); 155 | Serial.print("IP Address: "); 156 | Serial.println(ip); 157 | 158 | // print the received signal strength: 159 | long rssi = WiFi.RSSI(); 160 | Serial.print("signal strength (RSSI):"); 161 | Serial.print(rssi); 162 | Serial.println(" dBm"); 163 | } 164 | -------------------------------------------------------------------------------- /examples/esp32/setCustomStatus/setCustomStatus.ino: -------------------------------------------------------------------------------- 1 | /******************************************************************* 2 | Sets a custom status on your slack account. It will toggle between 3 | two every 30 seconds 4 | 5 | You will need a bearer token, see readme for more details 6 | 7 | Parts: 8 | ESP32 D1 Mini style Dev board* - http://s.click.aliexpress.com/e/C6ds4my 9 | 10 | * * = Affiliate 11 | 12 | If you find what I do useful and would like to support me, 13 | please consider becoming a sponsor on Github 14 | https://github.com/sponsors/witnessmenow/ 15 | 16 | 17 | Written by Brian Lough 18 | YouTube: https://www.youtube.com/brianlough 19 | Tindie: https://www.tindie.com/stores/brianlough/ 20 | Twitter: https://twitter.com/witnessmenow 21 | *******************************************************************/ 22 | 23 | // ---------------------------- 24 | // Standard Libraries 25 | // ---------------------------- 26 | 27 | #include 28 | #include 29 | 30 | // ---------------------------- 31 | // Additional Libraries - each one of these will need to be installed. 32 | // ---------------------------- 33 | 34 | #include 35 | // Library for connecting to the Slack API 36 | 37 | // Install from Github 38 | // https://github.com/witnessmenow/arduino-slack-api 39 | 40 | #include 41 | // Library used for parsing Json from the API responses 42 | 43 | // Search for "Arduino Json" in the Arduino Library manager 44 | // https://github.com/bblanchon/ArduinoJson 45 | 46 | //------- Replace the following! ------ 47 | 48 | char ssid[] = "SSID"; // your network SSID (name) 49 | char password[] = "password"; // your network password 50 | 51 | #define SLACK_ACCESS_TOKEN "AAAAAAAAAABBBBBBBBBBBCCCCCCCCCCCDDDDDDDDDDD" 52 | 53 | //------- ---------------------- ------ 54 | 55 | // including a "slack_server_cert" variable 56 | // header is included as part of the ArduinoSlack libary 57 | #include 58 | 59 | WiFiClientSecure client; 60 | ArduinoSlack slack(client, SLACK_ACCESS_TOKEN); 61 | 62 | unsigned long delayBetweenRequests = 30000; // Time between requests (1 minute) 63 | unsigned long requestDueTime; //time when request due 64 | 65 | bool firstStatus = true; 66 | 67 | void setup() 68 | { 69 | 70 | Serial.begin(115200); 71 | 72 | WiFi.mode(WIFI_STA); 73 | WiFi.begin(ssid, password); 74 | Serial.println(""); 75 | 76 | // Wait for connection 77 | while (WiFi.status() != WL_CONNECTED) 78 | { 79 | delay(500); 80 | Serial.print("."); 81 | } 82 | Serial.println(""); 83 | Serial.print("Connected to "); 84 | Serial.println(ssid); 85 | Serial.print("IP address: "); 86 | Serial.println(WiFi.localIP()); 87 | 88 | client.setCACert(slack_server_cert); 89 | 90 | // If you want to enable some extra debugging 91 | // uncomment the "#define SLACK_ENABLE_DEBUG" in ArduinoSlack.h 92 | } 93 | 94 | void displayProfile(SlackProfile profile) 95 | { 96 | if (!profile.error) 97 | { 98 | Serial.println("--------- Profile ---------"); 99 | 100 | Serial.print("Display Name: "); 101 | Serial.println(profile.displayName); 102 | 103 | Serial.print("Status Text: "); 104 | Serial.println(profile.statusText); 105 | 106 | Serial.print("Status Emoji: "); 107 | Serial.println(profile.statusEmoji); 108 | 109 | Serial.print("Status Expiration: "); 110 | Serial.println(profile.statusExpiration); 111 | 112 | Serial.println("------------------------"); 113 | } 114 | else 115 | { 116 | Serial.println("error getting profile"); 117 | } 118 | } 119 | 120 | void loop() 121 | { 122 | if (millis() > requestDueTime) 123 | { 124 | SlackProfile profile; 125 | if (firstStatus) 126 | { 127 | profile = slack.setCustomStatus("I am the first status", ":sparkling_heart:"); 128 | } 129 | else 130 | { 131 | profile = slack.setCustomStatus("I am the second status", ":v:"); 132 | // There is an optional third parameter which takes a Unix timestamp for 133 | // when this custom status expires: 134 | // slack.setCustomStatus("I am the second status", ":v:", 1532627506); 135 | } 136 | firstStatus = !firstStatus; 137 | displayProfile(profile); 138 | requestDueTime = millis() + delayBetweenRequests; 139 | } 140 | } 141 | -------------------------------------------------------------------------------- /examples/esp32/setPresence/setPresence.ino: -------------------------------------------------------------------------------- 1 | /******************************************************************* 2 | Toggles between a presence of "away" and "auto" on your slack account. 3 | It will toggle between the two every 30 seconds 4 | 5 | (FYI: You can't set to "online"- https://api.slack.com/methods/users.setPresence) 6 | 7 | You will need a bearer token, see readme for more details 8 | 9 | Parts: 10 | ESP32 D1 Mini style Dev board* - http://s.click.aliexpress.com/e/C6ds4my 11 | 12 | * * = Affilate 13 | 14 | If you find what I do useful and would like to support me, 15 | please consider becoming a sponsor on Github 16 | https://github.com/sponsors/witnessmenow/ 17 | 18 | 19 | Written by Brian Lough 20 | YouTube: https://www.youtube.com/brianlough 21 | Tindie: https://www.tindie.com/stores/brianlough/ 22 | Twitter: https://twitter.com/witnessmenow 23 | *******************************************************************/ 24 | 25 | // ---------------------------- 26 | // Standard Libraries 27 | // ---------------------------- 28 | 29 | #include 30 | #include 31 | 32 | // ---------------------------- 33 | // Additional Libraries - each one of these will need to be installed. 34 | // ---------------------------- 35 | 36 | #include 37 | // Library for connecting to the Slack API 38 | 39 | // Install from Github 40 | // https://github.com/witnessmenow/arduino-slack-api 41 | 42 | #include 43 | // Library used for parsing Json from the API responses 44 | 45 | // Search for "Arduino Json" in the Arduino Library manager 46 | // https://github.com/bblanchon/ArduinoJson 47 | 48 | //------- Replace the following! ------ 49 | 50 | char ssid[] = "SSID"; // your network SSID (name) 51 | char password[] = "password"; // your network password 52 | 53 | #define SLACK_ACCESS_TOKEN "AAAAAAAAAABBBBBBBBBBBCCCCCCCCCCCDDDDDDDDDDD" 54 | 55 | //------- ---------------------- ------ 56 | 57 | // including a "slack_server_cert" variable 58 | // header is included as part of the ArduinoSlack libary 59 | #include 60 | 61 | WiFiClientSecure client; 62 | ArduinoSlack slack(client, SLACK_ACCESS_TOKEN); 63 | 64 | unsigned long delayBetweenRequests = 30000; // Time between requests (1 minute) 65 | unsigned long requestDueTime; //time when request due 66 | 67 | bool isPresenceAway = false; 68 | 69 | void setup() 70 | { 71 | 72 | Serial.begin(115200); 73 | 74 | WiFi.mode(WIFI_STA); 75 | WiFi.begin(ssid, password); 76 | Serial.println(""); 77 | 78 | // Wait for connection 79 | while (WiFi.status() != WL_CONNECTED) 80 | { 81 | delay(500); 82 | Serial.print("."); 83 | } 84 | Serial.println(""); 85 | Serial.print("Connected to "); 86 | Serial.println(ssid); 87 | Serial.print("IP address: "); 88 | Serial.println(WiFi.localIP()); 89 | 90 | client.setCACert(slack_server_cert); 91 | 92 | // If you want to enable some extra debugging 93 | // uncomment the "#define SLACK_ENABLE_DEBUG" in ArduinoSlack.h 94 | } 95 | 96 | void loop() 97 | { 98 | if (millis() > requestDueTime) 99 | { 100 | if (isPresenceAway) 101 | { 102 | if (slack.setPresence(SLACK_PRESENCE_AUTO)) 103 | { 104 | Serial.println("Set presence to Auto"); 105 | } 106 | else 107 | { 108 | Serial.println("Failed to set presence to Auto"); 109 | } 110 | } 111 | else 112 | { 113 | if (slack.setPresence(SLACK_PRESENCE_AWAY)) 114 | { 115 | Serial.println("Set presence to Away"); 116 | } 117 | else 118 | { 119 | Serial.println("Failed to set presence to Away"); 120 | } 121 | } 122 | isPresenceAway = !isPresenceAway; 123 | requestDueTime = millis() + delayBetweenRequests; 124 | } 125 | } 126 | -------------------------------------------------------------------------------- /examples/esp8266/setCustomStatus/setCustomStatus.ino: -------------------------------------------------------------------------------- 1 | /******************************************************************* 2 | Sets a custom status on your slack account. It will toggle between 3 | two every 30 seconds 4 | 5 | You will need a bearer token, see readme for more details 6 | 7 | You will also need to be on version 2.5 or higher of the ESP8266 core 8 | 9 | Parts: 10 | D1 Mini ESP8266 * - http://s.click.aliexpress.com/e/uzFUnIe 11 | 12 | * * = Affiliate 13 | 14 | If you find what I do usefuland would like to support me, 15 | please consider becoming a sponsor on Github 16 | https://github.com/sponsors/witnessmenow/ 17 | 18 | 19 | Written by Brian Lough 20 | YouTube: https://www.youtube.com/brianlough 21 | Tindie: https://www.tindie.com/stores/brianlough/ 22 | Twitter: https://twitter.com/witnessmenow 23 | *******************************************************************/ 24 | 25 | // ---------------------------- 26 | // Standard Libraries 27 | // ---------------------------- 28 | 29 | #include 30 | #include 31 | 32 | // ---------------------------- 33 | // Additional Libraries - each one of these will need to be installed. 34 | // ---------------------------- 35 | 36 | #include 37 | // Library for connecting to the Slack API 38 | 39 | // Install from Github 40 | // https://github.com/witnessmenow/arduino-slack-api 41 | 42 | #include 43 | // Library used for parsing Json from the API responses 44 | 45 | // Search for "Arduino Json" in the Arduino Library manager 46 | // https://github.com/bblanchon/ArduinoJson 47 | 48 | //------- Replace the following! ------ 49 | 50 | char ssid[] = "SSID"; // your network SSID (name) 51 | char password[] = "password"; // your network password 52 | 53 | #define SLACK_ACCESS_TOKEN "AAAAAAAAAABBBBBBBBBBBCCCCCCCCCCCDDDDDDDDDDD" 54 | 55 | //------- ---------------------- ------ 56 | 57 | WiFiClientSecure client; 58 | ArduinoSlack slack(client, SLACK_ACCESS_TOKEN); 59 | 60 | unsigned long delayBetweenRequests = 30000; // Time between requests (1 minute) 61 | unsigned long requestDueTime; //time when request due 62 | 63 | bool firstStatus = true; 64 | 65 | void setup() 66 | { 67 | 68 | Serial.begin(115200); 69 | 70 | // Set WiFi to station mode and disconnect from an AP if it was Previously 71 | // connected 72 | WiFi.mode(WIFI_STA); 73 | WiFi.disconnect(); 74 | delay(100); 75 | 76 | // Attempt to connect to Wifi network: 77 | Serial.print("Connecting Wifi: "); 78 | Serial.println(ssid); 79 | WiFi.begin(ssid, password); 80 | while (WiFi.status() != WL_CONNECTED) 81 | { 82 | Serial.print("."); 83 | delay(500); 84 | } 85 | Serial.println(""); 86 | Serial.println("WiFi connected"); 87 | Serial.println("IP address: "); 88 | IPAddress ip = WiFi.localIP(); 89 | Serial.println(ip); 90 | 91 | client.setFingerprint(SLACK_FINGERPRINT); 92 | 93 | // If you want to enable some extra debugging 94 | // uncomment the "#define SLACK_ENABLE_DEBUG" in ArduinoSlack.h 95 | } 96 | 97 | void displayProfile(SlackProfile profile) 98 | { 99 | if (!profile.error) 100 | { 101 | Serial.println("--------- Profile ---------"); 102 | 103 | Serial.print("Display Name: "); 104 | Serial.println(profile.displayName); 105 | 106 | Serial.print("Status Text: "); 107 | Serial.println(profile.statusText); 108 | 109 | Serial.print("Status Emoji: "); 110 | Serial.println(profile.statusEmoji); 111 | 112 | Serial.print("Status Expiration: "); 113 | Serial.println(profile.statusExpiration); 114 | 115 | Serial.println("------------------------"); 116 | } 117 | else 118 | { 119 | Serial.println("error getting profile"); 120 | } 121 | } 122 | 123 | void loop() 124 | { 125 | if (millis() > requestDueTime) 126 | { 127 | SlackProfile profile; 128 | if (firstStatus) 129 | { 130 | profile = slack.setCustomStatus("I am the first status", ":sparkling_heart:"); 131 | } 132 | else 133 | { 134 | profile = slack.setCustomStatus("I am the second status", ":v:"); 135 | // There is an optional third parameter which takes a Unix timestamp for 136 | // when this custom status expires: 137 | // slack.setCustomStatus("I am the second status", ":v:", 1532627506); 138 | } 139 | firstStatus = !firstStatus; 140 | displayProfile(profile); 141 | requestDueTime = millis() + delayBetweenRequests; 142 | } 143 | } 144 | -------------------------------------------------------------------------------- /examples/esp8266/setPresence/setPresence.ino: -------------------------------------------------------------------------------- 1 | /******************************************************************* 2 | Toggles between a presence of "away" and "auto" on your slack account. 3 | It will toggle between the two every 30 seconds 4 | 5 | (FYI: You can't set to "online"- https://api.slack.com/methods/users.setPresence) 6 | 7 | You will need a bearer token, see readme for more details 8 | 9 | You will also need to be on version 2.5 or higher of the ESP8266 core 10 | 11 | Parts: 12 | D1 Mini ESP8266 * - http://s.click.aliexpress.com/e/uzFUnIe 13 | 14 | * * = Affilate 15 | 16 | If you find what I do usefuland would like to support me, 17 | please consider becoming a sponsor on Github 18 | https://github.com/sponsors/witnessmenow/ 19 | 20 | 21 | Written by Brian Lough 22 | YouTube: https://www.youtube.com/brianlough 23 | Tindie: https://www.tindie.com/stores/brianlough/ 24 | Twitter: https://twitter.com/witnessmenow 25 | *******************************************************************/ 26 | 27 | // ---------------------------- 28 | // Standard Libraries 29 | // ---------------------------- 30 | 31 | #include 32 | #include 33 | 34 | // ---------------------------- 35 | // Additional Libraries - each one of these will need to be installed. 36 | // ---------------------------- 37 | 38 | #include 39 | // Library for connecting to the Slack API 40 | 41 | // Install from Github 42 | // https://github.com/witnessmenow/arduino-slack-api 43 | 44 | #include 45 | // Library used for parsing Json from the API responses 46 | 47 | // Search for "Arduino Json" in the Arduino Library manager 48 | // https://github.com/bblanchon/ArduinoJson 49 | 50 | //------- Replace the following! ------ 51 | 52 | char ssid[] = "SSID"; // your network SSID (name) 53 | char password[] = "password"; // your network password 54 | 55 | #define SLACK_ACCESS_TOKEN "AAAAAAAAAABBBBBBBBBBBCCCCCCCCCCCDDDDDDDDDDD" 56 | 57 | //------- ---------------------- ------ 58 | 59 | WiFiClientSecure client; 60 | ArduinoSlack slack(client, SLACK_ACCESS_TOKEN); 61 | 62 | unsigned long delayBetweenRequests = 30000; // Time between requests (1 minute) 63 | unsigned long requestDueTime; //time when request due 64 | 65 | bool isPresenceAway = false; 66 | 67 | void setup() 68 | { 69 | 70 | Serial.begin(115200); 71 | 72 | // Set WiFi to station mode and disconnect from an AP if it was Previously 73 | // connected 74 | WiFi.mode(WIFI_STA); 75 | WiFi.disconnect(); 76 | delay(100); 77 | 78 | // Attempt to connect to Wifi network: 79 | Serial.print("Connecting Wifi: "); 80 | Serial.println(ssid); 81 | WiFi.begin(ssid, password); 82 | while (WiFi.status() != WL_CONNECTED) 83 | { 84 | Serial.print("."); 85 | delay(500); 86 | } 87 | Serial.println(""); 88 | Serial.println("WiFi connected"); 89 | Serial.println("IP address: "); 90 | IPAddress ip = WiFi.localIP(); 91 | Serial.println(ip); 92 | 93 | client.setFingerprint(SLACK_FINGERPRINT); 94 | 95 | // If you want to enable some extra debugging 96 | // uncomment the "#define SLACK_ENABLE_DEBUG" in ArduinoSlack.h 97 | } 98 | 99 | void loop() 100 | { 101 | if (millis() > requestDueTime) 102 | { 103 | if (isPresenceAway) 104 | { 105 | if (slack.setPresence(SLACK_PRESENCE_AUTO)) 106 | { 107 | Serial.println("Set presence to Auto"); 108 | } 109 | else 110 | { 111 | Serial.println("Failed to set presence to Auto"); 112 | } 113 | } 114 | else 115 | { 116 | if (slack.setPresence(SLACK_PRESENCE_AWAY)) 117 | { 118 | Serial.println("Set presence to Away"); 119 | } 120 | else 121 | { 122 | Serial.println("Failed to set presence to Away"); 123 | } 124 | } 125 | isPresenceAway = !isPresenceAway; 126 | requestDueTime = millis() + delayBetweenRequests; 127 | } 128 | } 129 | -------------------------------------------------------------------------------- /library.properties: -------------------------------------------------------------------------------- 1 | name=SlackAPI 2 | version=1.0.1 3 | author=Brian Lough 4 | maintainer=Brian Lough 5 | sentence=A library to wrap the Slack API (supports ESP8266/ESP32 & others) 6 | paragraph=A library to wrap the Slack API (supports ESP8266/ESP32 & others) 7 | category=Communication 8 | url=https://github.com/witnessmenow/arduino-slack-api 9 | architectures=* 10 | -------------------------------------------------------------------------------- /src/ArduinoSlack.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2020 Brian Lough. All right reserved. 3 | 4 | ArduinoSlack - An Arduino library to wrap the Slack API 5 | 6 | MIT License 7 | */ 8 | 9 | #include "ArduinoSlack.h" 10 | 11 | ArduinoSlack::ArduinoSlack(Client &client, const char *bearerToken) 12 | { 13 | this->client = &client; 14 | this->_bearerToken = bearerToken; 15 | } 16 | 17 | int ArduinoSlack::makePostRequest(const char *command, const char *body, const char *contentType) 18 | { 19 | client->flush(); 20 | client->setTimeout(SLACK_TIMEOUT); 21 | if (!client->connect(SLACK_HOST, portNumber)) 22 | { 23 | SLACK_SERIAL_LN(F("Connection failed")); 24 | return false; 25 | } 26 | 27 | // give the esp a breather 28 | yield(); 29 | 30 | // Send HTTP request 31 | client->print(F("POST ")); 32 | client->print(command); 33 | client->println(F(" HTTP/1.1")); 34 | 35 | //Headers 36 | client->print(F("Host: ")); 37 | client->println(SLACK_HOST); 38 | 39 | client->println(F("Accept: application/json")); 40 | client->print(F("Content-Type: ")); 41 | client->println(contentType); 42 | 43 | client->print(F("Authorization: Bearer ")); 44 | client->println(_bearerToken); 45 | 46 | client->println(F("Cache-Control: no-cache")); 47 | 48 | client->print(F("Content-Length: ")); 49 | client->println(strlen(body)); 50 | 51 | client->println(); 52 | 53 | //send Data here? 54 | client->print(body); 55 | 56 | if (client->println() == 0) 57 | { 58 | SLACK_SERIAL_LN(F("Failed to send request")); 59 | return false; 60 | } 61 | 62 | int statusCode = getHttpStatusCode(); 63 | skipHeaders(); 64 | return statusCode; 65 | } 66 | 67 | bool ArduinoSlack::setPresence(const char *presence) 68 | { 69 | char command[100]; 70 | sprintf(command, SLACK_USERS_SET_PRESENCE_ENDPOINT, presence); 71 | SLACK_DEBUG_SERIAL_LN(command); 72 | 73 | // Get from https://arduinojson.org/v6/assistant/ 74 | const size_t bufferSize = 1000; 75 | bool okStatus = false; 76 | if (makePostRequest(command, "", "text/plain") == 200) 77 | { 78 | // Allocate DynamicJsonDocument 79 | DynamicJsonDocument doc(bufferSize); 80 | 81 | // Parse JSON object 82 | DeserializationError error = deserializeJson(doc, *client); 83 | if (!error) 84 | { 85 | SLACK_DEBUG_SERIAL_LN(F("parsed Json Object: ")); 86 | #ifdef SLACK_ENABLE_DEBUG 87 | serializeJson(doc, Serial); 88 | #endif 89 | okStatus = doc["ok"]; 90 | if (!okStatus) 91 | { 92 | if (doc.containsKey("error")) 93 | { 94 | const char *errorMsg = doc["error"]; 95 | SLACK_DEBUG_SERIAL(F("Got the following error: ")); 96 | SLACK_DEBUG_SERIAL_LN(errorMsg); 97 | } 98 | else 99 | { 100 | SLACK_DEBUG_SERIAL_LN(F("Unkown Error")); 101 | } 102 | } 103 | } 104 | else 105 | { 106 | SLACK_DEBUG_SERIAL(F("deserializeJson() failed with code ")); 107 | SLACK_DEBUG_SERIAL_LN(error.c_str()); 108 | } 109 | } 110 | closeClient(); 111 | return okStatus; 112 | } 113 | 114 | SlackProfile ArduinoSlack::setCustomStatus(const char *text, const char *emoji, int expiration) 115 | { 116 | char body[300]; 117 | sprintf(body, setEndpointBody, text, emoji, expiration); 118 | SLACK_DEBUG_SERIAL_LN(body); 119 | 120 | // Get from https://arduinojson.org/v6/assistant/ 121 | const size_t bufferSize = profileBufferSize; 122 | 123 | SlackProfile profile; 124 | // This flag will get cleared if all goes well 125 | profile.error = true; 126 | if (makePostRequest(SLACK_USERS_PROFILE_SET_ENDPOINT, body) == 200) 127 | { 128 | // Allocate DynamicJsonDocument 129 | DynamicJsonDocument doc(bufferSize); 130 | 131 | // Parse JSON object 132 | DeserializationError error = deserializeJson(doc, *client); 133 | if (!error) 134 | { 135 | SLACK_DEBUG_SERIAL_LN(F("parsed Json Object: ")); 136 | #ifdef SLACK_ENABLE_DEBUG 137 | serializeJson(doc, Serial); 138 | #endif 139 | JsonObject profileObj = doc["profile"]; 140 | 141 | profile.displayName = (char *)profileObj["display_name"].as(); 142 | profile.statusText = (char *)profileObj["status_text"].as(); 143 | profile.statusEmoji = (char *)profileObj["status_emoji"].as(); 144 | 145 | profile.statusExpiration = profileObj["status_expiration"].as(); 146 | 147 | profile.error = false; 148 | } 149 | else 150 | { 151 | SLACK_DEBUG_SERIAL(F("deserializeJson() failed with code ")); 152 | SLACK_DEBUG_SERIAL_LN(error.c_str()); 153 | } 154 | } 155 | closeClient(); 156 | return profile; 157 | } 158 | 159 | void ArduinoSlack::skipHeaders(bool tossUnexpectedForJSON) 160 | { 161 | // Skip HTTP headers 162 | if (!client->find("\r\n\r\n")) 163 | { 164 | SLACK_SERIAL_LN(F("Invalid response")); 165 | return; 166 | } 167 | 168 | if (tossUnexpectedForJSON) 169 | { 170 | // Was getting stray characters between the headers and the body 171 | // This should toss them away 172 | while (client->available() && client->peek() != '{') 173 | { 174 | char c = 0; 175 | client->readBytes(&c, 1); 176 | SLACK_DEBUG_SERIAL(F("Tossing an unexpected character: ")); 177 | SLACK_DEBUG_SERIAL_LN(c); 178 | } 179 | } 180 | } 181 | 182 | int ArduinoSlack::getHttpStatusCode() 183 | { 184 | // Check HTTP status 185 | if (client->find("HTTP/1.1")) 186 | { 187 | int statusCode = client->parseInt(); 188 | SLACK_DEBUG_SERIAL(F("Status Code: ")); 189 | SLACK_DEBUG_SERIAL_LN(statusCode); 190 | return statusCode; 191 | } 192 | 193 | return -1; 194 | } 195 | 196 | void ArduinoSlack::closeClient() 197 | { 198 | if (client->connected()) 199 | { 200 | 201 | SLACK_DEBUG_SERIAL_LN(F("Closing client")); 202 | client->stop(); 203 | } 204 | } -------------------------------------------------------------------------------- /src/ArduinoSlack.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2020 Brian Lough. All right reserved. 3 | 4 | ArduinoSlack - An Arduino library to wrap the Slack API 5 | 6 | MIT License 7 | */ 8 | 9 | #ifndef ArduinoSlack_h 10 | #define ArduinoSlack_h 11 | 12 | #include 13 | #include 14 | #include 15 | 16 | #define SLACK_ENABLE_SERIAL 17 | 18 | //un-mark following line to enable debug mode 19 | //#define SLACK_ENABLE_DEBUG 20 | 21 | #ifdef SLACK_ENABLE_SERIAL 22 | #define SLACK_SERIAL(STR) Serial.print(STR) 23 | #define SLACK_SERIAL_LN(STR) Serial.println(STR) 24 | #else 25 | #define SLACK_SERIAL(STR) 26 | #define SLACK_SERIAL_LN(STR) 27 | #endif 28 | 29 | #ifdef SLACK_ENABLE_DEBUG 30 | #define SLACK_DEBUG_SERIAL(STR) Serial.print(STR) 31 | #define SLACK_DEBUG_SERIAL_LN(STR) Serial.println(STR) 32 | #else 33 | #define SLACK_DEBUG_SERIAL(STR) 34 | #define SLACK_DEBUG_SERIAL_LN(STR) 35 | #endif 36 | 37 | #define SLACK_HOST "slack.com" 38 | // Fingerprint valid from Tue, 13 Apr 2021 00:00:00 GMT 39 | #define SLACK_FINGERPRINT "C3 CC ED 77 87 19 6D E7 76 5E AA A7 3D 67 7E CA 95 D2 46 E2" 40 | #define SLACK_TIMEOUT 2000 41 | 42 | #define SLACK_PRESENCE_AWAY "away" 43 | #define SLACK_PRESENCE_AUTO "auto" 44 | 45 | #define SLACK_USERS_PROFILE_SET_ENDPOINT "/api/users.profile.set" 46 | #define SLACK_USERS_SET_PRESENCE_ENDPOINT "/api/users.setPresence?presence=%s" 47 | 48 | struct SlackProfile 49 | { 50 | char *displayName; 51 | char *statusText; 52 | char *statusEmoji; 53 | int statusExpiration; 54 | bool error; 55 | }; 56 | 57 | class ArduinoSlack 58 | { 59 | public: 60 | ArduinoSlack(Client &client, const char *bearerToken); 61 | 62 | int makePostRequest(const char *command, const char *body, const char *contentType = "application/json"); 63 | SlackProfile setCustomStatus(const char *text, const char *emoji, int expiration = 0); 64 | bool setPresence(const char *presence); 65 | int portNumber = 443; 66 | int profileBufferSize = 10000; 67 | Client *client; 68 | 69 | private: 70 | const char *_bearerToken; 71 | int getHttpStatusCode(); 72 | void skipHeaders(bool tossUnexpectedForJSON = true); 73 | void closeClient(); 74 | 75 | const char *setEndpointBody = 76 | R"({"profile": { "status_text": "%s","status_emoji": "%s","status_expiration": %d}})"; 77 | }; 78 | 79 | #endif 80 | -------------------------------------------------------------------------------- /src/ArduinoSlackCert.h: -------------------------------------------------------------------------------- 1 | // Digi Cert Global Root Cert - as of 26/08/2020 2 | // Useful for ESP32 3 | // Usage: client.setCACert(slack_server_cert); 4 | const char *slack_server_cert = "-----BEGIN CERTIFICATE-----\n" 5 | "MIIDrzCCApegAwIBAgIQCDvgVpBCRrGhdWrJWZHHSjANBgkqhkiG9w0BAQUFADBh\n" 6 | "MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3\n" 7 | "d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBD\n" 8 | "QTAeFw0wNjExMTAwMDAwMDBaFw0zMTExMTAwMDAwMDBaMGExCzAJBgNVBAYTAlVT\n" 9 | "MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j\n" 10 | "b20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IENBMIIBIjANBgkqhkiG\n" 11 | "9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4jvhEXLeqKTTo1eqUKKPC3eQyaKl7hLOllsB\n" 12 | "CSDMAZOnTjC3U/dDxGkAV53ijSLdhwZAAIEJzs4bg7/fzTtxRuLWZscFs3YnFo97\n" 13 | "nh6Vfe63SKMI2tavegw5BmV/Sl0fvBf4q77uKNd0f3p4mVmFaG5cIzJLv07A6Fpt\n" 14 | "43C/dxC//AH2hdmoRBBYMql1GNXRor5H4idq9Joz+EkIYIvUX7Q6hL+hqkpMfT7P\n" 15 | "T19sdl6gSzeRntwi5m3OFBqOasv+zbMUZBfHWymeMr/y7vrTC0LUq7dBMtoM1O/4\n" 16 | "gdW7jVg/tRvoSSiicNoxBN33shbyTApOB6jtSj1etX+jkMOvJwIDAQABo2MwYTAO\n" 17 | "BgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUA95QNVbR\n" 18 | "TLtm8KPiGxvDl7I90VUwHwYDVR0jBBgwFoAUA95QNVbRTLtm8KPiGxvDl7I90VUw\n" 19 | "DQYJKoZIhvcNAQEFBQADggEBAMucN6pIExIK+t1EnE9SsPTfrgT1eXkIoyQY/Esr\n" 20 | "hMAtudXH/vTBH1jLuG2cenTnmCmrEbXjcKChzUyImZOMkXDiqw8cvpOp/2PV5Adg\n" 21 | "06O/nVsJ8dWO41P0jmP6P6fbtGbfYmbW0W5BjfIttep3Sp+dWOIrWcBAI+0tKIJF\n" 22 | "PnlUkiaY4IBIqDfv8NZ5YBberOgOzW6sRBc4L0na4UU+Krk2U886UAb3LujEV0ls\n" 23 | "YSEY1QSteDwsOoBrp+uvFRTp2InBuThs4pFsiv9kuXclVzDAGySj4dzp30d8tbQk\n" 24 | "CAUw7C29C79Fv1C5qfPrmAESrciIxpg0X40KPMbp1ZWVbd4=\n" 25 | "-----END CERTIFICATE-----\n"; --------------------------------------------------------------------------------