HOME
  Security
   Software
    Hardware
  
FPGA
  CPU
   Android
    Raspberry Pi
  
nLite
  Xcode
   etc.
    ALL
  
LINK
BACK
 

2023/01/30

ESP32で Slackに「勤怠管理」メッセージをワンボタン操作で投稿する方法 ESP32で Slackに「勤怠管理」メッセージをワンボタン操作で投稿する方法

(Slackの勤怠チャンネルに毎日毎日毎日毎日 手動で投稿するのが馬鹿らしいので ESP32で作った)

Tags: [電子工作]




● ESP32で Slackに「勤怠管理」メッセージをワンボタン操作で投稿する方法

 Slackの勤怠チャンネルに毎日毎日毎日毎日 手動で投稿するのが馬鹿らしいので ESP32で作った。

 ホント、機械化できる所は機械化して可能な限り省力化した方が便利になります。

 DX Digital Transformationの時代に相応しいのです。

 中にはそれに逆行している馬鹿な○○○で△△△の所も有りますが・・・

 「ハンコを押すだけの地味な仕事」と発言してニュースになり、批判からの辞任になった大臣がいますが、「脱ハンコ(ハンコレス)」の「デジタル革命」の時代でも「ハンコを押す」と言う状況を皮肉ったのが本心だと思っています。

 「おじぎハンコ」と言うこれまたキチガイな慣習も一部業界にあるそうですね(笑

ESP8266で Slackにメッセージをワンボタンで投稿する方法



● Slackにアプリを新規作成する

Slack

 Slackにログインした状態で Slack APIページにアクセスする。

Slack API

 ・Create an app
 ・From scratch
 ・Name app & choose workspace:App Name

・Slackにアプリを新規作成する
Slackにアプリを新規作成する


Slackにアプリを新規作成する


Slackにアプリを新規作成する


Slackにアプリを新規作成する




● Slackのアプリに OAuthのアクセストークンを発行する

 ・OAuth & Permissions
  ・Scopes
   ・Bot Token Scopes
    chat:write
     Send messages as App Name
   ・User Token Scopes
    chat:write
     Send messages on a user’s behalf
 ・OAuth Tokens for Your Workspace
   ・User OAuth Token
    xoxp-xxxxxxxxxxxxx-xxxxxxxxxxxxx-xxxxxxxxxxxxx-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
   ・Bot User OAuth Token
    xoxb-zzzzzzzzzzzzz-zzzzzzzzzzzzz-zzzzzzzzzzzzzzzzzzzzzzzz

・Slackのアプリに OAuthのアクセストークンを発行する
Slackのアプリに OAuthのアクセストークンを発行する


Slackのアプリに OAuthのアクセストークンを発行する


Slackのアプリに OAuthのアクセストークンを発行する


Slackのアプリに OAuthのアクセストークンを発行する


Slackのアプリに OAuthのアクセストークンを発行する


Slackのアプリに OAuthのアクセストークンを発行する


Slackのアプリに OAuthのアクセストークンを発行する


Slackのアプリに OAuthのアクセストークンを発行する


Slackのアプリに OAuthのアクセストークンを発行する


Slackのアプリに OAuthのアクセストークンを発行する




● Slackのチャンネルに自作のアプリを紐付ける

 「Slackのチャンネルに自作のアプリを紐付ける」のは Bot Token Scopesでアプリのアカウントが投稿する場合に必要。

 User Token Scopesを使用する場合は不要。(自分のアカウントがチャンネルに属していれば良い)

・Slackのチャンネルに自作のアプリを紐付ける
Slackのチャンネルに自作のアプリを紐付ける


Slackのチャンネルに自作のアプリを紐付ける


Slackのチャンネルに自作のアプリを紐付ける


Slackのチャンネルに自作のアプリを紐付ける


Slackのチャンネルに自作のアプリを紐付ける


Slackのチャンネルに自作のアプリを紐付ける


Slackのチャンネルに自作のアプリを紐付ける




● Slack APIの chat.postMessageでメッセージを投稿する

 Slack APIの chat.postMessageでメッセージを投稿できます。
 スレッドに返信も chat.postMessageを使用します。

 スレッドの返信で reply_broadcastを Ture(チャンネルにも返事を投稿)にすると何故か「アプリのアカウント」で投稿されます。Slackのバグ?使い方が間違っている?

chat.postMessage
 tokenは User OAuth Tokenか Bot User OAuth Tokenを指定する。
 User OAuth Tokenの場合は自分自身のアカウントとして投稿する。
 Bot User OAuth Tokenの場合はアプリとして投稿する。

 Botの場合は #generalチャンネルや #randomチャンネルにアプリを紐付けておく事。

● curlを使って #generalチャンネルにメッセージを投稿する。
curl -X POST "https://slack.com/api/chat.postMessage" ^
-d "token=xoxb-xxxxxxxxxxxxxxxxxxxxxxx" ^
-d "channel=#general" ^
-d "text=こんにちは!"

● curlを使って #randomチャンネルにメッセージを投稿する。
curl -X POST "https://slack.com/api/chat.postMessage" \
-d "token=xoxb-xxxxxxxxxxxxxxxxxxxxxxx" \
-d "channel=#random" \
-d "text=こんにちは!"

・Slack APIの chat.postMessageでメッセージを投稿する
Slack APIの chat.postMessageでメッセージを投稿する


Slack APIの chat.postMessageでメッセージを投稿する


Slack APIの chat.postMessageでメッセージを投稿する
 1) 「始まり」の投稿時のレスポンスの tsを「終わり」の投稿時の thread_tsに指定してスレッドに返信
 2) (1)に reply_broadcastを Trueでチャンネルにも返事を投稿。(何故か「アプリのアカウント」で投稿されます。Slackのバグ?使い方が間違っている?)
 3) thread_tsを指定しないでチャンネルに投稿

Slack APIの chat.postMessageでメッセージを投稿する
 1) 「始まり」の投稿時のレスポンスの tsを「終わり」の投稿時の thread_tsに指定してスレッドに返信

Slack APIの chat.postMessageでメッセージを投稿する
 2) (1)に reply_broadcastを Trueでチャンネルにも返事を投稿。(何故か「アプリのアカウント」で投稿されます)

 Bot Token Scopesに chat:writeを指定していない場合、
 チャンネルにアプリを紐付けしていない場合、
 でも「アプリのアカウント」で投稿されます。(本来なら不正な動作)

Slack APIの chat.postMessageでメッセージを投稿する
 スレッドの返信で reply_broadcastを Ture(チャンネルにも返事を投稿)にすると何故か「アプリのアカウント」で投稿されます。Slackのバグ?使い方が間違っている?


● ESP32の Arduinoで Slackのチャンネルにメッセージを登録する。

ArduinoJson: Efficient JSON serialization for embedded C++

char* sendSlackMessage(const char* token, const char* channel, const char* message, const char* thread_ts)
{
      static char ts[20];
      char buf[256];

      // Slack Messaging API
      HTTPClient httpClient;
      httpClient.begin("https://slack.com/api/chat.postMessage");
      httpClient.addHeader("Content-Type", "application/x-www-form-urlencoded");

      sprintf(buf, ""
        "token=%s"
        "&channel=%s"
        "&text=%s"
        "&thread_ts=%s"
        "&reply_broadcast=%s",
        token,
        channel,
        message,
        thread_ts,
        strlen(thread_ts) > 0 ? "True" : "False"
      );

      strcpy(ts, "");

      int status_code = httpClient.POST((uint8_t *)buf, strlen(buf));
      if (status_code == 200)
      {
        Serial.print("OK");

        String json = httpClient.getString();
        Serial.println(json);

        deserializeJson(doc, json);
        if (doc.containsKey("ts"))
        {
          strcpy(ts, doc["ts"]);
          Serial.println(ts);
        }
      }
      else
      {
        Serial.printf("ERR %d", status_code);
      }
      httpClient.end();

      return ts;
}


● ESP32の Arduinoで NTPから現在時刻を取得する

Arduino NTPClient NTP

 NTPの更新間隔を 1分間隔とかの超短いキチガイな設定はやめましょうね。
 (相手の NTPサーバの負荷になるだけです)

 下記の例では NTPの更新間隔を 12時間毎にしています。

https://github.com/arduino-libraries/NTPClient/archive/refs/tags/3.2.1.zip

#include "NTPClient.h"

WiFiUDP udp;
// timeOffset Japan JST 9 hours, updateInterval 12 hours
NTPClient ntp(udp, "ntp.nict.jp", 9 * 60 * 60, 12 * 60 * 60 * 1000);

void setup()
{
}

void loop()
{
    ntp.update();

    unsigned long epochTime = ntp.getEpochTime();
    String formattedTime = ntp.getFormattedTime(); // hh:mm:ss

    Serial.print(epochTime);
    Serial.print(", ");
    Serial.println(formattedTime);
}


● ESP32で SLACKに勤怠管理のメッセージを投稿するのソースリスト

 これで毎日の単純作業から解放されます!

#include <HTTPClient.h>
#include <WiFi.h>
#include "boards.h"
#include "NTPClient.h"
#include <ArduinoJson.h>

// WiFi Internet Router
const char* ssid     = "WIFI_SSID";
const char* password = "WIFI_PASSWORD";

// Slack API
const char* slack_user_oauth_token = "xoxb-xxxxx";
const char* slack_channel = "#勤怠_猫さんチーム";

// JSON
StaticJsonDocument<512> doc;

// NTP
WiFiUDP udp;
// timeOffset Japan JST 9 hours, updateInterval 12 hours
NTPClient ntp(udp, "ntp.nict.jp", 9 * 60 * 60, 12 * 60 * 60 * 1000);

volatile bool hasButtonPushed = false;

void setup()
{
    // ESP32 CPU Freq. 80MHz(240, 160, 80, 40, 20, 10)
    // setCpuFrequencyMhz(40); // WiFi Failed
    setCpuFrequencyMhz(80);

    initBoard();
    // When the power is turned on, a delay is required.
    delay(1500);

    Serial.println("WiFi Begin");
    WiFi.begin(ssid, password);
    while (WiFi.status() != WL_CONNECTED) {
        Serial.print(".");
        delay(1000);
    }
    Serial.println("WiFi Connected");

#ifdef HAS_DISPLAY
    if (u8g2) {
        u8g2->sleepOff();
        u8g2->clearBuffer();
        u8g2->setContrast(1);
        u8g2->setFontMode(0); // Transparent
        u8g2->setDrawColor(1);
    }
#endif

    digitalWrite(BOARD_LED, LED_OFF);

    attachInterrupt(BOARD_SW, isr, FALLING);
}

void ARDUINO_ISR_ATTR isr() {
    hasButtonPushed = true;
}

void loop()
{
    ntp.update();

    unsigned long epochTime = ntp.getEpochTime();
    String formattedTime = ntp.getFormattedTime(); // hh:mm:ss(24時間制)

    if (epochTime % 2L != 0L) {
      digitalWrite(BOARD_LED, (digitalRead(BOARD_LED) == LED_OFF) ? LED_ON : LED_OFF);
      u8g2->sleepOn();
    } else {
      digitalWrite(BOARD_LED, LED_OFF);
      u8g2->sleepOff();
    }

    char message[256];
    boolean isSyussya;
    if (ntp.getHours() < 12) {
      isSyussya = true;
      Serial.println("[午前]");
      strcpy(message, "始めるにゃん🐈");
    } else {
      isSyussya = false;
      Serial.println("[午後]");
      strcpy(message, "終わりだにゃん🐈");
    }

#ifdef HAS_DISPLAY
    if (u8g2) {
        do {
          u8g2->setFont(u8g2_font_inb19_mr);
          u8g2->drawStr(0, 30, formattedTime.c_str());
          u8g2->drawStr(0, 60, isSyussya ? "AM" : "PM");
        } while ( u8g2->nextPage() );
    }
#endif


    if (!hasButtonPushed) {
      delay(200);
      return;
    }

    digitalWrite(BOARD_LED, LED_ON);
    u8g2->sleepOff();

    if (isSyussya) {
      char* ts = sendSlackMessage(slack_user_oauth_token, slack_channel, message, "");
      strcpy(saved_ts, ts);
    } else {
      sendSlackMessage(slack_user_oauth_token, slack_channel, message, saved_ts);
      strcpy(saved_ts, "");
    }

    delay(5000);

    hasButtonPushed = false;
    digitalWrite(BOARD_LED, LED_OFF);
}

char* sendSlackMessage(const char* token, const char* channel, const char* message, const char* thread_ts)
{
    // Slack Messaging API
    HTTPClient httpClient;
    httpClient.begin("https://slack.com/api/chat.postMessage");
    httpClient.addHeader("Content-Type", "application/x-www-form-urlencoded");

    static char ts[20];
    char buf[256];
    sprintf(buf, ""
      "token=%s"
      "&channel=%s"
      "&text=%s"
      "&thread_ts=%s",
      // "&reply_broadcast=%s",
      token,
      channel,
      message,
      thread_ts,
      // strlen(thread_ts) > 0 ? "True" : "False"
    );

    strcpy(ts, "");

    int status_code = httpClient.POST((uint8_t *)buf, strlen(buf));
    if (status_code == 200)
    {
      Serial.print("OK");

      String json = httpClient.getString();
      Serial.println(json);

      deserializeJson(doc, json);
      if (doc.containsKey("ts"))
      {
        strcpy(ts, doc["ts"]);
        Serial.println(ts);
      }
    }
    else
    {
      Serial.printf("ERR %d", status_code);
    }
    httpClient.end();

    return ts;
}



Tags: [電子工作]

●関連するコンテンツ(この記事を読んだ人は、次の記事も読んでいます)

ESP32で東方の Bad Apple!!の動画を 128 x 64 dotの OLED SSD1306で再生する!
ESP32で東方の Bad Apple!!の動画を 128 x 64 dotの OLED SSD1306で再生する!

  ESP32で東方の Bad Apple!!の動画を再生する!実際にはパラパラ漫画です

LilyGO ESP32 LoRa SX1276を買ってみた、LPWAの急先鋒、LoRaWANも無料
LilyGO ESP32 LoRa SX1276を買ってみた、LPWAの急先鋒、LoRaWANも無料

  LilyGO ESP32 LoRa SX1276を買ってみた

LoRa通信を使用してポストに郵便物が投函されるとスマホの LINE宛に通知する IoTの作り方
LoRa通信を使用してポストに郵便物が投函されるとスマホの LINE宛に通知する IoTの作り方

  LoRaを使用した IoT郵便受け LoRa IoT Mailbox Sensor with LINE Messaging API

ESP32のプログラムを ESP8266に移植する方法、Arduinoでも微妙に互換性が無い所が有ります
ESP32のプログラムを ESP8266に移植する方法、Arduinoでも微妙に互換性が無い所が有ります

  ESP32の https SSLや GPIO割込み等を ESP8266に移植する方法

Espressif ESP32 Arduino互換でスケッチが使える WROOM32開発基板
Espressif ESP32 Arduino互換でスケッチが使える WROOM32開発基板

  Espressif ESP32 32ビット Arduino互換マイコンボードをお手軽に開発する方法

Espressif ESP8266 Arduino互換でスケッチが使える ESP-12Eモジュール基板
Espressif ESP8266 Arduino互換でスケッチが使える ESP-12Eモジュール基板

  Espressif ESP8266 ESP-12-E NodeMCU V1 ESP12 CP2102

ESP8266で Python言語 MicroPythonを動かす方法
ESP8266で Python言語 MicroPythonを動かす方法

  Windows 10の WSL環境で ESP8266で Python言語 MicroPythonを動かします

ESP32で Python言語 MicroPythonを動かす方法
ESP32で Python言語 MicroPythonを動かす方法

  Windows 10の WSL環境で ESP32で Python言語 MicroPythonを動かします

LilyGO TTGO T-display ESP32/ RP2040/ GD32 GD32VF103CBT6を買ってみた
LilyGO TTGO T-display ESP32/ RP2040/ GD32 GD32VF103CBT6を買ってみた

  LilyGO TTGO T-display ESP32/ RP2040/ GD32 GD32VF103CBT6を買ってみた

新型 Arduino UNO R4 Minimaのクローンを買った!!
新型 Arduino UNO R4 Minimaのクローンを買った!!

  Renesas RA4M1 Arduino UNO R4 Minima clone 无名科技Nologo Tech




[HOME] | [BACK]
リンクフリー(連絡不要、ただしトップページ以外は Web構成の変更で移動する場合があります)
Copyright (c) 2023 FREE WING,Y.Sakamoto
Powered by 猫屋敷工房 & HTML Generator

http://www.neko.ne.jp/~freewing/hardware/espressif_esp32_slack_post_memmage/