見出し画像

#111 LINE WORKSの投稿をTeamsへ自動転送!ー学校ではTeams、学校外ではLINE WORKS。職員連絡を二重投稿せずに共有する方法ー


0 はじめに

 学校現場では、職員間の連絡手段として、TeamsやLINE WORKSなどを使う場面が増えてきました。

 一方で、悩ましいのが、私物スマホでの校務連絡の扱いです。

 私物スマホにTeamsをインストールし、教育委員会から付与されているアカウントでログインすれば、学校の連絡をすぐに確認できます。たしかに便利です。

 しかし、私物端末で校務情報を扱うことには慎重さが必要です。文部科学省の「教育情報セキュリティポリシーに関するガイドライン」では、支給以外のパソコンやモバイル端末等について、業務上やむを得ない場合を除き原則として業務に利用してはならないこと、利用する場合は教育情報セキュリティ管理者の許可と必要な安全管理措置が必要であることが示されています。(教育情報セキュリティポリシーに関するガイドライン(令和7年3月)

 校務情報や児童生徒に関わる情報を、どの端末で、どこまで扱うのか。
 これは、便利さだけで決めてよい話ではありません。

 さらに、学校によっては、不祥事根絶の観点から、学級担任が教室へ私物スマホを持ち込まない運用にしている場合もあります。

 その場合、LINE WORKSに連絡が来ても、授業中や教室では確認できません。

 すると、こんな困り感が出てきます。

・LINE WORKSに連絡が来ている
・でも、教室ではスマホを見られない
・あとで見ようと思って忘れる
・Teamsにも同じ内容を投稿するのは二度手間
・連絡の場所が分かれてしまう

 LINE WORKSは便利です。
 でも、校務用端末で確認するTeamsにも情報が残っていてほしい。

 そこで今回は、次のような仕組みを作りました。

①LINE WORKSに投稿する
 ↓
②同じ内容がTeamsの指定チャネルにも自動で投稿される

 連絡の入口はLINE WORKS
 確認と記録の場所はTeams

 私物スマホにTeamsを入れなくても、LINE WORKSに投稿した職員連絡をTeams側にも残せるようにしました。


1 なぜこの仕組みを作ったのか

 学校では、職員間の連絡手段が一つにまとまらないことがあります。

 例えば、次のような形です。

・急ぎの連絡はLINE WORKS
・資料や正式な連絡はTeams
・ちょっとした確認は口頭
・あとから見返したい情報はチャネル投稿

 それぞれのツールにはよさがあります。

 LINE WORKSは、スマホで確認しやすく、短い連絡や急ぎの共有には向いています。

 一方、Teamsは校務用端末で開く機会が多く、チャネルに投稿されていれば後から確認しやすくなります。

 ただし、学級担任が教室に私物スマホを持ち込まない運用をしている場合、LINE WORKSだけに連絡があると、確認が遅れることがあります。

 そこで考えたのが、次の仕組みです。

 「LINE WORKSに一度投稿すれば、Teamsにも自動で残る。」

 二重投稿をなくしつつ、連絡の見落としを減らすことをねらいました。


2 今回作った仕組み

 今回作った仕組みは、次の流れです。

①LINE WORKSの転送用トークルーム
 ↓
②LINE WORKS Bot
 ↓
③Google Apps Script
 ↓
④Teamsチャネルのメールアドレス
 ↓
⑤Teamsチャネルに投稿

 ポイントは、Teamsチャネルにメールアドレスを発行できることです。

 Teamsでは、チャネルの「その他のオプション」から「メール アドレスの取得」を選び、取得したメールアドレスにメールを送ると、チャネル内のユーザーが転送されたメールを受け取れると説明されています。(チームの会話を最適化する - Microsoft サポート

 今回はこの機能を使い、LINE WORKSの投稿をGoogle Apps Scriptで受け取り、Teamsチャネルのメールアドレスへ送るようにしました。

 なお、この方法は、Teamsの投稿を読み取る仕組みではありません。
 LINE WORKSに投稿された内容を、Teamsへ送るだけです。

 そのため、Microsoft Graph APIなどの難しい権限設定を使わずに試せるのがよいところです。


3 完成イメージ

 LINE WORKSに、例えば次のように投稿します。

 すると、Teamsには次のように投稿されます。

 LINE WORKSに投稿するだけで、Teamsにも同じ内容が残ります。


4 よかったこと

 この仕組みを使うと、次のようなメリットがあります。

・LINE WORKSとTeamsへの二重投稿がなくなる
・担任が校務用端末からTeamsで確認できる
・連絡がTeamsチャネルにも残る
・あとから見返しやすい
・私物スマホにTeamsを入れなくてもよい

 特に大きいのは、私物スマホにTeamsを入れなくても、Teams側に連絡が残ることです。

 私物スマホで校務情報を扱うことには慎重さが必要です。通知画面に校務情報が出ることや、端末紛失時の対応なども考えなければなりません。

 だからこそ、私物スマホにTeamsを入れて連絡を見るのではなく、LINE WORKSの投稿をTeamsにも残すという形にしました。


5 事前に必要なもの

 今回の仕組みを作るには、次のものが必要です。

・LINE WORKSの管理者画面に入れること
・LINE WORKSのDeveloper ConsoleでBotを作成できること
・Teamsチャネルのメールアドレスを取得できること
・Google Apps Scriptを使えるGoogleアカウント
・LINE WORKSからTeamsへ送るための転送用トークルーム

 特に大事なのは、次の2つです。

・LINE WORKSでBotを作成・追加できるか
・Teamsチャネルの「メールアドレスを取得」が使えるか

 どちらかが使えない場合は、この方法では進められません。


6 手順1 Teamsチャネルのメールアドレスを取得する

 まず、Teamsで転送先にしたいチャネルを開きます。

①Teamsを開く
 ↓
②転送先のチームを開く
 ↓
③転送先のチャネルを開く
 ↓
④チャネル名の「…」を押す
 ↓
⑤「メールアドレスを取得」を押す
 ↓
⑥表示されたメールアドレスをコピー

 ここで取得したメールアドレスに送信すると、Teamsチャネルに投稿されます。

 ただし、組織の設定によっては「メールアドレスを取得」が表示されない場合があります。その場合は、Teams側の管理者設定で制限されている可能性があります。

 この後の作業に進む前に、普通のメールからTeamsチャネルのメールアドレスへテスト送信しておくと安心です。

件名:テスト
本文:Teamsチャネルにメールで投稿できるか確認しています。

 このメールがTeamsチャネルに表示されれば、Teams側の準備は完了です。


7 手順2 Google Apps Scriptを作る

 Googleドライブを開きます。

①Googleドライブ
 ↓
②新規
 ↓
③その他
 ↓
④Google Apps Script

 プロジェクト名は、次のような名前にしておくと分かりやすいです。

LINE WORKSからTeams転送


8 手順3 GASにコードを貼り付ける

 Google Apps Scriptに、次のコードを貼り付けます。

// ===============================
// 設定
// ===============================

// Teamsチャネルのメールアドレス
const TEAMS_CHANNEL_EMAIL = 'ここにTeamsチャネルのメールアドレスを貼り付ける';

// 簡易認証用の合言葉
// Callback URLの末尾にも同じ文字列を付ける
const SECRET_TOKEN = '自分で決めた長い文字列にする';

// テキスト以外の投稿をTeamsに知らせるか
// false:画像・ファイル・スタンプなどは転送しない
// true :「テキスト以外が投稿されました」とTeamsに知らせる
const NOTIFY_NON_TEXT = false;

// 投稿者IDと氏名の対応表
// 最初は空でもよい
const USER_NAME_MAP = {
  // 'LINE WORKSのuserId': '氏名'
};


// ===============================
// 接続確認用
// ===============================
function doGet(e) {
  return ContentService
    .createTextOutput('LINE WORKS to Teams transfer app is running.')
    .setMimeType(ContentService.MimeType.TEXT);
}


// ===============================
// LINE WORKSからの投稿を受け取る
// ===============================
function doPost(e) {
  try {
    // 簡易認証
    if (!e || !e.parameter || e.parameter.token !== SECRET_TOKEN) {
      return textResponse('invalid token');
    }

    if (!e.postData || !e.postData.contents) {
      return textResponse('no post data');
    }

    const data = JSON.parse(e.postData.contents);

    // メッセージイベント以外は無視
    if (data.type !== 'message') {
      return textResponse('ignored event: ' + data.type);
    }

    const source = data.source || {};
    const content = data.content || {};

    const userId = source.userId || '不明';
    const issuedTime = data.issuedTime || new Date().toISOString();
    const postedAt = formatDateJST(issuedTime);

    let messageText = '';

    // テキスト投稿の場合
    if (content.type === 'text') {
      messageText = content.text || '';
    } else {
      // 画像・ファイル・スタンプなど
      if (!NOTIFY_NON_TEXT) {
        return textResponse('non-text ignored');
      }

      messageText =
        'テキスト以外のメッセージがLINE WORKSに投稿されました。\n' +
        'LINE WORKS側で確認してください。\n' +
        '種類:' + content.type;
    }

    if (!messageText.trim()) {
      return textResponse('empty message');
    }

    const userName = USER_NAME_MAP[userId] || userId;

    const subject = '【LINE WORKSから転送】';

    const body =
      '投稿時刻:' + postedAt + '\n' +
      '投稿者名:' + userName + '\n' +
      '------------------------------\n' +
      messageText + '\n' +
      '------------------------------\n';

    MailApp.sendEmail({
      to: TEAMS_CHANNEL_EMAIL,
      subject: subject,
      body: body
    });

    return textResponse('ok');

  } catch (error) {
    console.error(error);
    return textResponse('error: ' + error.message);
  }
}


// ===============================
// 共通処理
// ===============================
function textResponse(text) {
  return ContentService
    .createTextOutput(text)
    .setMimeType(ContentService.MimeType.TEXT);
}

function formatDateJST(dateString) {
  const date = new Date(dateString);
  return Utilities.formatDate(date, 'Asia/Tokyo', 'yyyy/MM/dd HH:mm:ss');
}

 Google Apps Scriptでは、Webアプリに対してHTTP POSTリクエストが送られたときに doPost(e) が実行されます。(Google for Developers)


9 手順4 コードの設定を変更する

 まず、Teamsチャネルのメールアドレスを入れます。

const TEAMS_CHANNEL_EMAIL = 'ここにTeamsチャネルのメールアドレスを貼り付ける';

 先ほどTeamsで取得したメールアドレスを貼り付けます。

 次に、合言葉を設定します。

const SECRET_TOKEN = '自分で決めた長い文字列にする';

 この合言葉は、あとでLINE WORKSのCallback URLにも付けます。

 例えば、次のようにします。

const SECRET_TOKEN = 'LW_to_Teams_20260706_xxxxx';

 この文字列は、外部から勝手に送信されないようにするための簡易的な確認用です。
 他の人に見られにくい、長めの文字列にしておくとよいです。


10 手順5 GASをWebアプリとしてデプロイする

 GAS画面右上の「デプロイ」から進みます。

①デプロイ
 ↓
②新しいデプロイ
 ↓
③種類の選択
 ↓
④ウェブアプリ

 設定は次のようにします。

実行するユーザー:自分
アクセスできるユーザー:全員

 デプロイすると、WebアプリURLが発行されます。

 このURLの末尾に、先ほど設定した合言葉を付けます。

https://script.google.com/macros/s/xxxxxxxx/exec?token=LW_to_Teams_20260706_xxxxx

 このURLを、LINE WORKS BotのCallback URLに設定します。

 なお、コードを修正した後は、毎回「新しいデプロイ」を作るのではなく、「デプロイを管理」から既存のデプロイを編集し、「新バージョン」として更新します。

①デプロイ
 ↓
②デプロイを管理
 ↓
③対象のデプロイを選ぶ
 ↓
④編集
 ↓
⑤バージョンを「新バージョン」にする
 ↓
⑥デプロイ

 新しいデプロイを作るとURLが変わってしまい、LINE WORKS側のCallback URLも修正する必要が出てしまいます。


11 手順6 LINE WORKS Developer ConsoleでBotを作成する

 LINE WORKSのDeveloper Consoleを開きます。

①Developer Console
 ↓
②Bot
 ↓
③登録

 Botの設定例です。

Bot名:
Teams転送Bot

説明:
LINE WORKSの投稿をTeamsチャネルへ転送するBot

Callback URL:
ON

URL:
GASのWebアプリURL
例:
https://script.google.com/macros/s/xxxxxxxx/exec?token=LW_to_Teams_20260706_xxxxx

受信するイベント:
Message Event

トークルームへの招待:
複数人のトークルームで利用可能

 ここで大切なのは、トークルームへの招待を有効にすることです。

 これが有効になっていないと、Botを複数人のトークルームに追加できません。

 LINE WORKSのBot Callbackは、Botが受信したメッセージやイベント情報を、Developer Consoleで指定したCallback URLへHTTPS POSTで送る仕組みです。(Works Mobile Developers)


12 手順7 LINE WORKS管理者画面でBotを追加する

 Developer ConsoleでBotを作っただけでは、LINE WORKS上で使えない場合があります。

 次に、管理者画面でBotを追加します。

①LINE WORKS 管理者画面
 ↓
②サービス
 ↓
③Bot
 ↓
④Bot追加
 ↓
⑤作成したBotを選択
 ↓
⑥追加

 最初のテストでは、Botの使用権限を「すべて」にしておくと確認しやすいです。


13 手順8 LINE WORKSに転送用トークルームを作る

 LINE WORKSに、Teams転送用のトークルームを作ります。

 名前は、次のようなものにすると分かりやすいです。

・Teams転送用
・Teamsへ送る連絡
・校務Teams連携

 最初から全職員のトークルームで試すのではなく、少人数のテスト用トークルームで試すのがおすすめです。


14 手順9 Botをトークルームに追加する

 転送用トークルームを開きます。

①転送用トークルームを開く
 ↓
②メンバー追加
 ↓
③Teams転送Botを追加

 もしBotを追加できない場合は、次を確認します。

・Developer Consoleで「トークルームへの招待」が有効になっているか
・管理者画面でBotが追加済みか
・Botの使用権限が自分にあるか
・外部ユーザーが含まれるトークルームではないか

 Botに直接メッセージを送ることはできても、トークルームに追加できない場合は、「トークルームへの招待」の設定が原因であることがあります。


15 手順10 テストする

 LINE WORKSの転送用トークルームに投稿します。

テストです。
この内容がTeamsに転送されるか確認しています。

 Teamsチャネルに次のような投稿が届けば成功です。

投稿時刻:2026/07/06 11:15:14
投稿者名:LINE WORKSのuserId
------------------------------
テストです。
この内容がTeamsに転送されるか確認しています。
------------------------------

 最初は、投稿者名のところに氏名ではなく、長いIDが表示される場合があります。
 これはエラーではありません。
 次の手順で、IDと氏名を対応させます。


16 投稿者名を氏名で表示するには

 LINE WORKSからGASへ送られてくる情報には、投稿者の氏名ではなく、userId が含まれます。

 そのため、最初の状態では、Teamsに次のように表示されることがあります。

投稿時刻:2026/07/06 11:15:14
投稿者名:b785c90e-248a-4875-17c4-0482743e0718
------------------------------
テストです。
------------------------------

 この長い文字列が、LINE WORKS上の投稿者IDです。

 GASのコードでは、次の部分で「投稿者IDを氏名に置き換える」設定をしています。

const USER_NAME_MAP = {
  // 'LINE WORKSのuserId': '氏名'
};

 例えば、Teamsに次のように表示された場合、

投稿者名:b785c90e-248a-4875-17c4-0482743e0718

 GASの対応表を次のように修正します。

const USER_NAME_MAP = {
  'b785c90e-248a-4875-17c4-0482743e0718': '氏名'
};

 複数人登録する場合は、次のように追加していきます。
 注意点は、氏名の後ろに「,(カンマ)」をつけていくことです。最後の人には「,」はつけないようにします。

const USER_NAME_MAP = {
  'b785c90e-248a-4875-17c4-0482743e0718': '氏名1',
  '別のuserId': '氏名2',
  'さらに別のuserId': '氏名3'
};

 修正したら、GASを再デプロイします。

①デプロイ
 ↓
②デプロイを管理
 ↓
③対象のデプロイを選ぶ
 ↓
④編集
 ↓
⑤バージョンを「新バージョン」にする
 ↓
⑥デプロイ

 再デプロイ後、その人の投稿はTeams上で氏名として表示されるようになります。

投稿時刻:2026/07/06 11:15:14
投稿者名:氏名
------------------------------
テストです。
------------------------------

 つまり、流れとしては次の通りです。

①1回目の投稿
 ↓
②TeamsにuserIdが表示される
 ↓
③そのuserIdをGASのUSER_NAME_MAPに登録する
 ↓
④再デプロイする
 ↓
⑤次回以降は氏名で表示される


17 うまく転送されないときの確認

 LINE WORKSに投稿してもTeamsに届かない場合は、次の順番で確認します。

17-1 GASの実行履歴を見る

 GASの画面で、左側の「実行数」を開きます。

①GASを開く
 ↓
②実行数
 ↓
③doPost が動いているか確認

 doPost が表示されていれば、LINE WORKSからGASまでは届いています。

 doPost がない場合は、LINE WORKSのCallback URLが間違っているか、BotのCallback設定が動いていない可能性があります。

17-2 token が合っているか確認する

 実行結果に invalid token と出ている場合は、GAS側の SECRET_TOKEN と、Callback URLの末尾に付けた token が一致していません。

 GAS側が次のようになっている場合、

const SECRET_TOKEN = 'LW_to_Teams_20260706_xxxxx';

 Callback URLは次のようにします。

https://script.google.com/macros/s/xxxxxxxx/exec?token=LW_to_Teams_20260706_xxxxx

 1文字でも違うと転送されません。

17-3 Teamsチャネルにメールが届くか確認する

 GASやLINE WORKSの設定に問題がなくても、Teamsチャネルがメールを受け付けていなければ投稿されません。

 普通のメールからTeamsチャネルのメールアドレスへ送って、Teamsに表示されるか確認します。

 これが届かない場合は、Teams側の設定やメールアドレスの問題です。

17-4 GASを再デプロイしたか確認する

 コードを修正しただけでは、Webアプリに反映されないことがあります。

 コードを直した後は、必ず「デプロイを管理」から新バージョンとして更新します。


18 運用上の注意点

 この仕組みは便利ですが、何でも転送してよいわけではありません。

 LINE WORKSに投稿した内容が、そのままTeamsにも流れます。

 そのため、次のような情報は投稿しないようにルールを決めておく必要があります。

・児童生徒の詳細な個人情報
・健康情報
・家庭状況
・成績に関する情報
・生徒指導上の詳細
・配慮事項

 今回の仕組みは、あくまで職員連絡や共有事項を見落とさないためのものです。

 例えば、次のような内容に絞って使うのがよいと思います。

・今日の予定
・提出期限
・職員への周知
・会議時刻
・Teamsを確認してほしいという連絡

 また、今回のGASでは、URL末尾の token による簡易的な確認を使っています。
 より厳密に運用する場合は、LINE WORKSの署名検証なども検討した方がよいです。


19 転送数が多い場合の注意

 今回の仕組みでは、Google Apps ScriptからTeamsチャネルのメールアドレスへメールを送ります。

 Google Apps Scriptには日ごとの利用上限があります。Googleの公式ドキュメントでは、MailAppなどによるメール送信先数について、個人向けアカウントは1日100件、Google Workspaceは1日1,500件などの上限が示されています。なお、これらの上限は変更される場合があります。(Google for Developers)

 学校の職員連絡で、1日100件も転送しない運用であれば、大きな問題にはなりにくいと思います。

 ただし、全職員が頻繁に投稿するようなトークルームをそのまま転送すると、通知が多くなりすぎることがあります。

 最初は、転送用トークルームを分けて、Teamsにも残したい連絡だけを投稿する運用にするのがよいと思います。


20 まとめ

 学校の連絡は、ただ便利にすればよいわけではありません。

 私物スマホをどう扱うか。
 不祥事根絶の観点をどう守るか。
 情報セキュリティをどう確保するか。
 職員が連絡を見落とさないようにするにはどうするか。

 こうしたことを同時に考える必要があります。

 LINE WORKSは、職員連絡の入口として使いやすいです。

 Teamsは、校務用端末で確認しやすく、情報を残す場所として使いやすいです。

 だから、今回はこう考えました。

連絡の入口はLINE WORKS
確認と記録の場所はTeams

 この仕組みによって、LINE WORKSに投稿するだけでTeamsにも情報が残るようになりました。

 私物スマホにTeamsを入れるのではなく、学校の運用に合わせて、必要な情報が必要な場所に届くようにする。

 小さな仕組みですが、学校現場の困り感を減らす一つの方法になると思います。

 今後も授業改善や働き方改革に向けて、効果的な活用方法を模索していきたいと思います。

 子供たちの深い学びの実現、教員の働き方改革の推進に向けて、ともに頑張りましょう。