
TeamsにSelenium経由で自動投稿したいんだよ!
っと思ったのでPython+Seleniumのブラウザ経由でTeamsに投稿する手順を記載します。
※無料のMSアカウントを利用しているので会社アカウントでは勝手が違うかも
目次
ソース
import os
import time
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
id = "xxxxx" #ログイン用のメアド
pw = "xxxxx" #ログイン用のパス
url = "https://teams.live.com/_#/xxxxx" #投稿チャネルをブラウザで開いた時のTeamsのURL
# ChromeWebdriverファイルのパス指定
driver = webdriver.Chrome(executable_path=os.getcwd() + "\\webdriver\\chromedriver.exe")
# ブラウザを起動し指定のURLを開く
driver.get(url)
#メアド入力
time.sleep(3)
driver.find_element_by_name("loginfmt").send_keys(id)
driver.find_element_by_id("idSIButton9").click()
#パスワード入力
time.sleep(3)
driver.find_element_by_name("passwd").send_keys(pw)
driver.find_element_by_id("idSIButton9").click()
#サインインの状態を維持しますか? → いいえ
time.sleep(3)
driver.find_element_by_id("idBtn_Back").click()
# Teamsチャット画面
time.sleep(15)
driver.find_element_by_xpath('/html/body/div[1]/div/div/div[2]/div/button[2]/div').click()
time.sleep(2)
#id、nameは可変するたxpathを使用
driver.switch_to_frame(driver.find_element_by_tag_name("iframe"))
#テスト入力
driver.find_element_by_class_name("cke_textarea_inline").send_keys("一行目")
driver.find_element_by_class_name("cke_textarea_inline").send_keys(Keys.SHIFT,"\n")
driver.find_element_by_class_name("cke_textarea_inline").send_keys("二行目")
driver.find_element(By.XPATH, "//button[@data-tid='newMessageCommands-send']").click()
driver.switch_to_default_content()
MSアカウントと投稿しておきたいTeamsへのアクセス権限は持っているものとします。
投稿対象にするTeamsのチャットルーム、チャネルについては事前にブラウザでURLを確認し、Seleniumで開くためのURLとして変数に代入しておきます。
随所でsleepをしておかないとSeleniumのスピードにブラウザの描画処理が追い付かないため(追いつかないとタグが検索できなかったりする)、描画処理を待つために適当な時間を設定しておきます。待つだけなのでほかの手段でもいいと思います。
投稿するまでのフロー
サインイン(メールアドレス)

driver.find_element_by_name("loginfmt").send_keys(id)
driver.find_element_by_id("idSIButton9").click()
idはログインで使用するメールアドレスを指定します。
サインイン(パスワードの入力)

driver.find_element_by_name("passwd").send_keys(pw)
driver.find_element_by_id("idSIButton9").click()
pwはログインで使用するパスワードを指定します。
サインインの状態を維持しますか? ⇒ しない

driver.find_element_by_id("idBtn_Back").click()
"いいえ"をクリックします。※起動するたびに聞かれるのでどちらでもいいです
通知をオンにしてください。 ⇒ 閉じる

driver.find_element_by_xpath('/html/body/div[1]/div/div/div[2]/div/button[2]/div').click()
ポップアップが残っているとエラーする場合があるので閉じておきます。
投稿テキストの入力と投稿ボタンのクリック

#id、nameは可変するたxpathを使用
driver.switch_to_frame(driver.find_element_by_tag_name("iframe"))
driver.find_element_by_class_name("cke_textarea_inline").send_keys("一行目")
driver.find_element_by_class_name("cke_textarea_inline").send_keys(Keys.SHIFT,"\n")
driver.find_element_by_class_name("cke_textarea_inline").send_keys("二行目")
driver.find_element(By.XPATH, "//button[@data-tid='newMessageCommands-send']").click()
投稿周りの表示にはiframeが使われているため、参照するframeを変更します。
改行はShiftキー押しながらEnter(\n)で実現します。
投稿完了

投稿できました。
投稿ボタンを押すときElementClickInterceptedExceptionが出る場合

投稿ボタンを押そうとしたとき、「ElementClickInterceptedException」というエラーが発生するかもしれません。
これは「ボタンが直接押せない状況になっているとき」に発生します。
「デスクトップ通知をオンにしてください。」ウインドウが重なっていないか確認し、もし重なっていれば閉じれば解消されます。
「別アクションを発生させていないと通常のブラウザ操作で実現できない命令をしている」かを検証するため、実際に手動で手順を確認しながら進めれば気づけると思います。
※ブラウザの最大化などで投稿ボタンがウインドウと重なっていなければエラーしません