GoogleAppsScriptで発言した内容に応答するTelegram BOTを作る

# はじめに
この記事ではTelegramのBotに話しかけると、自分の名前を読んで応答してくれるBotについて解説します。
# BOTアカウントの登録
[@BotFather](https://telegram.me/BotFather)に話しかけます。
[GoogleAppsScriptでTelegram BOTを作る ～第1回 はじめてのTelegram BOT \- Qiita](https://qiita.com/nowdon/items/00d55c34dc3f06ae2aea) を参考にしてください。

# GASでスクリプトを作成する
[@新しいSpreadsheetを作成](https://spreadsheet.new/)するURLに飛びます。
Spreadsheetを開いたら、ツール→スクリプトエディタを開きます。
「無題のスプレッドシート」になっているので、そこは適当にわかりやすい名前に変えておきましょう。今回は「GAS Bot Test」とします。
![Screenshot of GAS Bot test - プロジェクト編集者 - Apps Script.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/8633/47b9d932-3207-d1f9-089a-c400acabfb94.jpeg)

# Botに発言させてみよう
Botに発言させるためにはTelegramのsendmessageというAPIを使用します。
APIの仕様は[Telegram Bot API#sendmessage](https://core.telegram.org/bots/api#sendmessage)をみてください。これをみると、chat_id(発言するチャットルームのID)とtext(発言内容)が必須だとわかります。ここではチャットルームを新たに作成して、そこでBotに発言をさせてみましょう。
Telegramのクライアントを起動して、三　→　New Groupをして適当に部屋を作ります。
チャットルームのIDを調べる方法はいくつかありますが、こここでは[@RawDataBot](https://t.me/RawDataBot)を部屋に呼んでみましょう。そして、発言すると以下のような発言をすると思います。
この場合は``-33333333``がchat_idになります。

```JSON
{
    "update_id": 814822145,
    "message": {
        "message_id": 851345,
        "from": {
            "id": 220219021,
            "is_bot": false,
            "first_name": "k32ru",
            "username": "k32ru",
            "language_code": "ja"
        },
        "chat": {
            "id": -33333333,  ←この部分です。
            "title": "bot test room",
            "type": "group",
            "all_members_are_administrators": true
        },
        "date": 1632575759,
        "text": "test"
    }
}
````

チャットルームのIDがわかったら、Botに発言するために、GASに以下を書いて見ましょう。

```javascript
//以下2行は自分のに変更してください。
const botToken = "2007692564:xxxxxxxxxxx"
const chat_id = "-33333333"
const telegramUrl = "https://api.telegram.org/bot" + botToken;


function hello(){
  sendText(chatid,"こんにちは！")
}
function sendText(id,text) {
  let url = telegramUrl + "/sendMessage?chat_id=" + id + "&text=" + text;
  Logger.log(url);
  let response = UrlFetchApp.fetch(url);
  Logger.log(response.getContentText());
}
```

コードを書いたら、コードを保存して、helloを選択して実行してみましょう。
実行したら、下に実行ログが出てきます。
最初の一行は```Logger.log(url);```の部分で、URLを組み立てたものを表示しています。
2行目はそれをTelegramサーバに送った結果を表示しています。```"ok":true```となっているので成功です。
部屋にも発言はされましたか？

```
	https://api.telegram.org/bot2007692564:xxxxxxxxxxx/sendMessage?chat_id=-33333333&text=こんにちは！
	{"ok":true,"result":{"message_id":3,"from":{"id":2044451845,"is_bot":true,"first_name":"k32ruk32ru","username":"k32ruk32ru_bot"},"chat":{"id":-33333333,"title":"bot test room","type":"group","all_members_are_administrators":true},"date":1632576114,"text":"\u3053\u3093\u306b\u3061\u306f\uff01"}}
```
今回の処理概要を図に書くとこんな感じです。
![Screenshot of GASでTelegramBotを作成する方法(基礎編) - Google スライド.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/8633/73c784be-3fb4-bc0d-abee-9dde4fd4e269.jpeg)

# Botに応答してもらおう
いきなりですが、概略図を表示します。
今回の処理として必要なのは
①TelegramのBotを受け取って、それをGASに送る設定が必要です
②GASではそのデータを処理して、発言した人の名前を取り出します。
③発言した人の名前とチャットルームのIDを取り出して、TelegramのAPIを使って送信します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/8633/8963c4c2-40a6-76c2-8307-c6f5bf9bc533.png)

## ①TelegramのBotを受け取って、それをGASに送る設定
###  Botの設定変更
TelegramのBOTは初期設定では、コマンド(/chatid 等/から始まる発言)しか受け取れません。つまり、チャットルームで「こんにちは」と発言しても、Botはその発言を拾う事ができません。
[@BotFather](https://telegram.me/BotFather)に話して```/setprivacy```と発言します。```Choose a bot to change group messages settings(どのBOTの設定を変えるのか？）```と聞かれるので、変更したいBOTを選びます。

```
'Enable' - your bot will only receive messages that either start with the '/' symbol or mention the bot by username.　BOTは/とユーザからのメンテンションしか受け取れないよ
'Disable' - your bot will receive all messages that people send to groups.  BOTは発言した内容を受け取れるよ
Current status is: ENABLED
```

今回は、```Disable```と発言します。```Success! The new status is: DISABLED. /help```と出れば成功です。

### WebHook設定
BotがGASにデータを送るためには、送り先を決めなくてはいけません。そのために、GASをウエブアプリケーションとして動作させます。
上の青いボタンで「デプロイ」をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/8633/5872e781-6745-3ca0-5499-9f37857d2a57.png)
「新しいデプロイ」を選択し、⚙から「ウエブアプリ」を選びます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/8633/af46f286-7673-858e-f656-29de06a39f65.png)
![new deploy.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/8633/46d8d821-d82c-7f40-eba5-a1e90e390feb.png)
説明を入れる箇所がでますが、いれなくても大丈夫です。アクセスできるユーザを「全員」にしてから「デプロイ」を押します。
以下のような画面になるので、ウエブアプリのURLをコピーします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/8633/393292e6-407f-2676-d0fe-a1b090887edb.png)
以下のコードを入力して、```setWebhook```を実行します。```{"ok":true,"result":true,"description":"Webhook was set"}```と出れば成功です。

```javascript
var webAppUrl = "https://script.google.com/macros/s/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx/exec"
function setWebhook() {
  let url = telegramUrl + "/setWebhook?url=" + webAppUrl;
  let response = UrlFetchApp.fetch(url);
  Logger.log(response.getContentText());
}
````

ちなみに、WebHookを削除する場合には以下のように```url```のパラメータを空にします。

```javascript
function delWebhook() {
  let url = telegramUrl + "/setWebhook?url=" + "";
  let response = UrlFetchApp.fetch(url);
  Logger.log(response.getContentText());
}
````

また、現状何が設定されているのかわからなくなったら、以下を実行すると現状されているWebHookのURLがわかります。

```javascript
function getWebhookInfo() {
  let url = telegramUrl + "/getWebhookinfo";
  let response = UrlFetchApp.fetch(url);
  Logger.log(response.getContentText());
}
```

## ②GASで受けとデータを処理して発言した人の名前を取り出す
①でWebHookを設定したことにより、データはTelegramから届くようになりましたが、GASでデータを処理する必要があります。GASでは```doPost(e)```でデータを受け取ります。```e```に受信したデータが含まれています。届いたデータは以下のようになります。このようなデータの形はJSONと呼ばれており、データのやり取りによく使われる形式です。このデータを処理をして必要な情報を取り出します。


```JSON
    "queryString": "",
    "parameter": {},
    "postData": {
        "contents": "{\"update_id\":265255108,\n\"message\":{\"message_id\":4,\"from\":{\"id\":220219021,\"is_bot\":false,\"first_name\":\"k32ru@Hiroshima,JPN\\ud83c\\uddef\\ud83c\\uddf5\\ud83d\\udc89\\ud83d\\udc89\",\"username\":\"k32ru\",\"language_code\":\"ja\"},\"chat\":{\"id\":220219021,\"first_name\":\"k32ru@Hiroshima,JPN\\ud83c\\uddef\\ud83c\\uddf5\\ud83d\\udc89\\ud83d\\udc89\",\"username\":\"k32ru\",\"type\":\"private\"},\"date\":1632559782,\"text\":\"test\"}}",
        "length": 388,
        "name": "postData",
        "type": "application/json"
    },
    "parameters": {},
    "contentLength": 388,
    "contextPath": ""
}
````

Telegramの発言内容は```postData```の```contents```の中にあります。なので以下のようにして、一旦```data```という変数に発言内容を入れます。

```javascript
var data = JSON.parse(e.postData.contents);
````

今度は```data```の中身はどのようになっているのかというと例としては以下のようになっています。

```JSON
{
    "update_id": 814821658,
    "message": {
        "message_id": 851230,
        "from": {
            "id": 220219021,
            "is_bot": false,
            "first_name": "k32ru@Hiroshima,JPN",
            "username": "k32ru",
            "language_code": "ja"
        },
        "chat": {
            "id": -510239868,
            "title": "bot test room",
            "type": "group",
            "all_members_are_administrators": true
        },
        "date": 1632569162,
        "text": "\u3053\u3093\u306b\u3061\u306f"　//こんにちは
    }
}
````

なので、以下のように必要な情報は取り出せます。

```javascript
let data = JSON.parse(e.postData.contents);//発言を抽出  
let text = data.message.text;//発言内容 
let name = data.message.from.first_name;//発言者の表示名
let id   = data.message.chat.id//発言したチャットルーム
```

## 発言した人の名前とチャットルームのIDを取り出して、TelegramのAPIを使って送信する
Telegramにデータを送る部分については```sendText```を使ったのでそれを利用します。
ユーザが発言した内容に対して、発言した人の名前をつけて応答すると以下のようになります。

```javascript
function doPost(e) {
  //telegramからのデータ
  let data = JSON.parse(e.postData.contents);
  let text = data.message.text;
  let name = data.message.from.first_name;
  let id   = data.message.chat.id
  let answer = text  +  name + "さん！"
  sendText(id,answer);
  
}
````
ここまでできたら、動くかどうか試してみましょう。最初はデプロイ→新しいデプロイを選択しましたが、**2回目以降は「デプロイを管理」を選択します。**
なぜかというと、新しいデプロイにするとウエブアプリのURLが変わってしまうからです。コードでは```webAppUrl```で代入している部分が変わります。
そしたら、毎回WebHookを削除して、再度設定しないといけなくなるので、大変ですよね。
あとたまにあるのが、いつの間にか新しいウエブアプリのURLが出来ていて、WebHookでは古いURLを見ているためにソースを変えたはずなのに処理内容は古いままで頭を抱えるなんてこともあります。

「デプロイを管理」を選択肢、右上の✏をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/8633/6d6c0df1-b709-6f32-6a13-f815c1080f20.png)
一番上にある「新バージョン」にして「デプロイ」を選びます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/8633/cfc753ae-47b4-ffd4-0e30-da90147d05f6.png)

これでデプロイは終わったので、さっそく試してみましょう。(非常に煽り耐性の高いBOTができました)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/8633/b01749d8-2c32-36c2-63f2-6cbb87608105.png)


ここまでのソースを全部表示すると以下の様になります

```javascript
const botToken = "2222222222:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
const telegramUrl = "https://api.telegram.org/bot" + botToken;
const webAppUrl = "https://script.google.com/macros/s/yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy/exec"

const chat_id = "-33333333"
function getMe(){
  let url = telegramUrl + "/getMe"
  let response = UrlFetchApp.fetch(url);
  Logger.log(response.getContentText)
}

function hello(){
  sendText(chat_id,"こんにちは！")
}
function sendText(id,text) {
  let url = telegramUrl + "/sendMessage?chat_id=" + id + "&text=" + text;
  Logger.log(url);
  let response = UrlFetchApp.fetch(url);
  Logger.log(response.getContentText());
}
function setWebhook() {
  let url = telegramUrl + "/setWebhook?url=" + webAppUrl;
  let response = UrlFetchApp.fetch(url);
  Logger.log(response.getContentText());
}

function doPost(e) {
  //telegramからのデータ
  let data = JSON.parse(e.postData.contents);
  let text = data.message.text;
  let name = data.message.from.first_name;
  let id   = data.message.chat.id
  let answer = text  +  name + "さん！"
  sendText(id,answer);
  
}