11
1

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 5 years have passed since last update.

kintoneAdvent Calendar 2018

Day 2

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

Last updated at Posted at 2018-12-02

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

Telegramとは

インスタントメッセンジャーでセキュリティの高さが売りのようです。
個人的にはプラットフォームの多さ、APIの豊富さから連携にチャレンジしました。
公式サイトはこちらです。
APIの一覧はこちらです。音声や動画ファイルの取り扱いもできます。

kintoneとは

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

やったこと

  • 会社名で顧客管理アプリに情報が登録されているか確認
  • 登録されている場合は選択肢を表示
  • 選択肢クリックで各種情報を表示
  • 写真送信で写真を登録

こんな感じです。

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

準備1. Botの作成

こちらの手順に従ってBotを作成します。
こんな感じでBotFatherに話しかけることでBotが作成できます。すごい。
IMG_2027.PNG
Bot名(↑の場合はcy_take_bot)と入力するとAPIトークンが表示されるのでそれをメモします。
APIトークンは「xxxx:xxxxxxxxx」のような形式でコロンの前部分もトークンに含まれるので注意が必要です。

準備2. kintoneのアプリ作成

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

追加できたら顧客管理アプリを開き、添付ファイルフィールドを追加します。
フィールドコードは添付ファイルのままで大丈夫です。
次に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楽しいですね!

11
1
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
11
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?