1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Selenium経由でSlackのDMを取得・送信・スクショする

Posted at

ブラウザの操作を自動化するライブラリ「Selenium」を使ってSlackへ自動でログインし、特定のメンバーのDM欄からテキストを自動で取得・送信したり、スクリーンショットを保存したりするプログラムの一例です。

先日の投稿の上位互換プログラムです。

auto-dm.py
# (Selenium 4.1.0 で動作確認済み)
# webdriver は使用しているChromeのバージョンに合わせて以下のページから取得する。
# https://chromedriver.chromium.org/downloads

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.chrome import service as fs
import time
import sys
import os

# パラメータ
slackurl    = 'sample.slack.com'        # Slack URL
mailaddress = 'sample@gmail.com'        # 登録済みメールアドレス
mypassword  = 'abrakadabra'             # ログインパスワード
waittime    = 10.0                      # (sec.) 待機時間 (通信速度 & PCスペックに応じて調整)
logintime   = 10.0                      # (sec.) ログインを維持する時間 (適宜調整)
driverpath  = 'C:/Users/[user名]/Downloads/chromedriver_win32/chromedriver.exe' # webdriver が置かれている path を指定
workpath    = 'C:/Users/[user名]/Downloads/'                                    # 取得した画像などの保存先を指定
url         = 'https://app.slack.com/client/XXXYYYZZZ/AAABBBCCC'                # 目的地となる Slack WorkSpace のURL
recipient   = '山田'    # 相手(DMの受信者)のアカウント名
mymessage   = 'Yes My Darkness!'    # DMの内容
order       = 1  # 何番目に最新のメッセージを取得するか
dm_mode     = 0  # 0 -> 何もしない  //  1 -> メッセージを送信する
ss_mode     = 1  # 0 -> 何もしない  //  1 -> 最新のメッセージのスクリーンショットを保存  //  2 -> DM欄全体のスクリーンショットを保存


# フォルダの存在確認
if os.path.exists(workpath) == False:
    print('% Error: The "workpath" is invalid...')
    sys.exit()

# webdriverの存在確認
if os.path.exists(driverpath) == False:
    print('% Error: The "driverpath" is invalid...')
    sys.exit()

try:
    # 自動ログイン
    try:
        # Webページにアクセス
        chrome_service = fs.Service(executable_path=driverpath)
        driver  = webdriver.Chrome(service=chrome_service)
        driver.maximize_window()  #全画面表示にする (オプション)
        driver.get(url)
        driver.implicitly_wait(waittime)  # 遷移待ち

        # Slack WorkSpaceの選択
        ch_element = driver.find_element(By.ID, 'domain')
        ch_element.send_keys(slackurl)
        ch_element.send_keys(Keys.ENTER)
        driver.implicitly_wait(waittime)  # 遷移待ち

        # email, password の自動入力
        mail_element = driver.find_element(By.ID, 'email')
        mail_element.send_keys(mailaddress)
        driver.implicitly_wait(waittime)  # 待機 (オプション)
        password_element = driver.find_element(By.ID, 'password')
        password_element.send_keys(mypassword)
        password_element.send_keys(Keys.ENTER)
        driver.implicitly_wait(waittime)  # 遷移待ち (少し長め)

        # 自動ログインに成功
        print('% Successfully logged in:')
        url     = driver.current_url    # URLを取得する (オプション)
        title   = driver.title          # タイトルを取得する (オプション)
        print("% URL       :", url, )
        print("% title     :", title)

    except:
        # ログインに失敗した場合はセッションを終了する
        driver.quit()
        print("% Error: Your login has been failed...")
        sys.exit()

    # 送信先(recipient)のDMを開く
    recipient_list = driver.find_elements(By.CSS_SELECTOR, '[data-qa="channel_sidebar_name_' + recipient + '"]')
    if len(recipient_list) > 0:    # DMリストに名前が表示されている場合
        print("% DM is showing in the current list.")
        driver.find_element(By.CSS_SELECTOR, '[data-qa="channel_sidebar_name_' + recipient + '"]').click()
        driver.implicitly_wait(waittime)  # 遷移待ち
    else:    # DMリストに名前が表示されていない場合
        print("% DM is NOT showing in the current list.")
        searchbox_element = driver.find_element(By.CSS_SELECTOR, '[class="c-button-unstyled p-top_nav__search p-top_nav__search--windows-linux"]')
        searchbox_element.send_keys("@" + recipient)
        driver.implicitly_wait(waittime)  # 待機 (オプション)
        driver.find_element(By.CSS_SELECTOR, '[class="c-truncate c-truncate--break_words"]').click()
        driver.implicitly_wait(waittime)  # 待機 (オプション)

    # DMの要素をリストとして取得
    message_element_list = driver.find_elements(By.CSS_SELECTOR, '[class="c-message_kit__gutter"]')  # メッセージの要素を特定
    messagenum = -1*order
    target_massage = message_element_list[messagenum]  # 最新のメッセージをテキストで取得
    print("% sender    :", target_massage.find_element(By.CSS_SELECTOR, '[class="c-message__sender c-message_kit__sender"]').text) # 最新のメッセージの送信者
    print("% timestamp :", target_massage.find_element(By.CSS_SELECTOR, '[class="c-timestamp__label"]').text) # 最新のメッセージの送信時刻
    if target_massage.find_elements(By.CSS_SELECTOR, '[class="p-rich_text_section"]'):
        print("% message   :", target_massage.find_element(By.CSS_SELECTOR, '[class="p-rich_text_section"]').text, sep="\n") # 最新のメッセージの本文
    else:
        print("% (There is no text in the message.)")  # テキストを含まないメッセージの場合
        ss_mode = 1  # スクリーンショットの保存を強制する (オプション)

    # メッセージを送る (オプション)
    if dm_mode == 1:
        post_element = driver.find_element(By.CSS_SELECTOR, '[class="ql-editor ql-blank"]')
        post_element.click()
        driver.implicitly_wait(waittime)  # 待機 (オプション)
        post_element.send_keys(mymessage)  # メッセージ入力
        post_element.send_keys(Keys.ENTER)
        driver.implicitly_wait(waittime)  # 待機 (オプション)
        driver.find_element(By.CSS_SELECTOR, '[class="c-icon c-icon--paperplane-filled"]').click()
        print("% Your message was successfully sent.")

    # DMの画像を取得する (オプション)
    if ss_mode == 1:
        time.sleep(waittime)  # 強制的な待機 (オプション)
        png = message_element_list[messagenum].screenshot_as_png  # 最新のメッセージのみをpngで取得
        with open(workpath + 'image_from_slack.png', 'wb') as f:
            f.write(png)  # 画像の書き出し
            print("% The image of the latest message has been saved successfully.")
    elif ss_mode == 2:
        time.sleep(waittime)  # 強制的な待機 (オプション)
        dmfield_element = driver.find_elements(By.CSS_SELECTOR, '[class="p-workspace__primary_view"]')  # DM欄の要素を特定
        png = dmfield_element[messagenum].screenshot_as_png  #DM欄をpngで取得
        with open(workpath + 'image_from_slack.png', 'wb') as f:
            f.write(png)  # 画像の書き出し
            print("% The image of the messages being displayed has been saved successfully.")


    time.sleep(logintime)    # 任意時間ログイン状態を維持

finally:
    driver.quit()    # セッションの終了
    print("% Done.")
    sys.exit()

セキュリティの問題が生じない範囲で適宜改変してご利用下さい。
Slack内のクラス名などは予告なく変更されることがありますので、継続的に使用する場合は適宜保守して下さい。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?