Edited at
kintoneDay 2

Telegram Botで顧客情報をちゃちゃっと確認

Telegram, Node.jsを使ってkintoneのデータをちゃちゃっと閲覧/登録することにチャレンジしました。


Telegramとは

インスタントメッセンジャーでセキュリティの高さが売りのようです。

個人的にはプラットフォームの多さ、APIの豊富さから連携にチャレンジしました。

公式サイトはこちらです。

APIの一覧はこちらです。音声や動画ファイルの取り扱いもできます。


kintoneとは

「kintoneとは、サイボウズ株式会社が開発しクラウドで提供するWebデータベース型業務アプリ構築サービス(作成したアプリケーションを連携したりシステム管理機能も活用できるよ)

2015年のkintone Advent Calendarから引用しました。

公式サイトはこちらです。


やったこと


  • 会社名で顧客管理アプリに情報が登録されているか確認

  • 登録されている場合は選択肢を表示

  • 選択肢クリックで各種情報を表示

  • 写真送信で写真を登録

こんな感じです。


実際に試してみたい方は以下の手順をご確認ください。


準備1. Botの作成

こちらの手順に従ってBotを作成します。

こんな感じでBotFatherに話しかけることでBotが作成できます。すごい。



Bot名(↑の場合はcy_take_bot)と入力するとAPIトークンが表示されるのでそれをメモします。

APIトークンは「xxxx:xxxxxxxxx」のような形式でコロンの前部分もトークンに含まれるので注意が必要です。


準備2. kintoneのアプリ作成

アプリストアから顧客サポートパックを追加します。

追加できたら顧客管理アプリを開き、添付ファイルフィールドを追加します。

フィールドコードは添付ファイルのままで大丈夫です。

次にURLから確認できるドメインとアプリIDをメモします。

https://xxxx.cybozu.com/k/100/の場合は「xxxx.cybozu.com」がドメインです。

「100」がアプリIDです。

顧客管理アプリにAPIトークンを追加します。アクセス権はレコード閲覧と編集をチェックします。


準備3. Node.jsにライブラリ追加

$ npm install --save node-telegram-bot-api kintone-nodejs-sdk axios


準備4. 実行ファイルの保存

以下のコードをbot.jsという名前で保存します。

冒頭のコメント箇所はメモした内容に変更してください。


bot.js

'use strict';

process.env.NTBA_FIX_319 = 1;

const Path = require('path');
const Axios = require('axios');
const TelegramBot = require('node-telegram-bot-api');
const kintone = require('kintone-nodejs-sdk');
const FormData = require('form-data');

// 個別の設定
const botToken = 'xxxxxxxxx:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'; // BotのAPIトークン
const kintoneDomain = 'xxxx.cybozu.com'; // kintoneのドメイン
const kintoneAppId = xxxx; // kintoneのアプリID
const kintoneToken = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'; // kintoneのAPIトークン

const bot = new TelegramBot(botToken, {polling: true});
const kintoneAuthWithAPIToken = (new kintone.Auth()).setApiToken(kintoneToken);
const kintoneConnection = new kintone.Connection(kintoneDomain, kintoneAuthWithAPIToken);
const kintoneRecord = new kintone.Record(kintoneConnection);

const fileUpload = async (fileStream, fileName) => {
const form = new FormData();
form.append('file', fileStream, fileName);
const options = {
method: 'POST',
url: `https://${kintoneDomain}/k/v1/file.json`,
headers: {
'X-Cybozu-API-Token': kintoneToken,
'Content-Type': form.getHeaders()['content-type']
},
data: form
};
const res = await Axios(options);
return res.data.fileKey;
}

const fileDownload = async (fileKey) => {
const options = {
method: 'GET',
url: `https://${kintoneDomain}/k/v1/file.json?fileKey=${fileKey}`,
headers: {
'X-Cybozu-API-Token': kintoneToken
},
responseType: 'arraybuffer'
};
const res = await Axios(options);
return res.data;
}

let record = {};

bot.onText(/[^(担当者名|連絡先|住所|添付ファイル)]/, (msg) => {
const chatId = msg.chat.id;
const customerName = msg.text;
const query = `会社名 like "${customerName}"`;

kintoneRecord.getRecords(kintoneAppId, query).then((res) => {
record = res.records[0];

let select_options = {};
if (record['添付ファイル'].value[0] !== undefined) {
select_options = {
reply_markup: {
keyboard: [['担当者名'], ['連絡先'], ['住所'], ['添付ファイル']],
one_time_keyboard: true
}
};
} else {
select_options = {
reply_markup: {
keyboard: [['担当者名'], ['連絡先'], ['住所']],
one_time_keyboard: true
}
};
}

bot.sendMessage(chatId, 'ヒットしました。何を確認しますか。', select_options);
});
});

bot.onText(/担当者名|連絡先|住所|添付ファイル/, (msg, match) => {
const chatId = msg.chat.id;
const rid = record.$id.value;
const file = record['添付ファイル'].value[0];

let text = '';
if (match[0] === '担当者名') {
text = `${record['部署名'].value} ${record['担当者名'].value}`;
bot.sendMessage(chatId, text);
} else if (match[0] === '連絡先') {
text = `${record['メールアドレス'].value} ${record['電話番号'].value}`;
bot.sendMessage(chatId, text);
} else if (match[0] === '住所') {
text = `${record['住所'].value}`
bot.sendMessage(chatId, text);
} else if (match[0] === '添付ファイル') {
fileDownload(file.fileKey).then((fileData) => {
const fileOptions = {
filename: file.name,
contentType: file.contentType
}
bot.sendPhoto(chatId, fileData, {}, fileOptions);
});
}
});

bot.on('photo', (file) => {
const rid = record.$id.value;
const botFileId = file.photo[0].file_id;
bot.getFileLink(botFileId).then((fileLink) => {
const fileName = Path.basename(fileLink);
fileUpload(bot.getFileStream(botFileId), fileName).then((fileKey) => {
const params = {
'添付ファイル': {
'value': [
{'fileKey': fileKey}
]
}
};
kintoneRecord.updateRecordById(kintoneAppId, rid, params);
});
});
});



実行!

以下のコマンドを入力して実行します。

$ node bot.js

実行できたらTelegramからメッセージを送信してみてください。


まとめ

Bot楽しいですね!