Telegramを介してTableauでの作業を簡素化する

画像



みなさんこんにちは。 準備されたレポートへのアクセスを提供することは、しばしば別の問題です。 管理のためのデータ処理結果への利便性と運用アクセスの問題が、それらのさらなる使用の運命を大きく左右します。 Tableauシステム(または単にスコアボード)は、このようなタスクではあまり人気がなく、多くのソースからのデータをすばやく分析したり、オンラインレポートをサーバーに公開したり、レポートのPDFバージョンの自動配信を構成したりすることができます。



ただし、すべてがセットアップされ、公開され、配布されたとしても、同僚は問題に直面します。





このような問題の解決策の1つは、ボタンをクリックするだけでスコアボードサーバーからPDFレポートをエクスポートしてユーザーに送信できるテレグラムボットです。 この記事では、このようなボットの最も単純なバージョンのコードと例を見ていきます。



次の簡略化から進みます。





この記事では、Amazon Web Services仮想マシンにインストールされているTableau Server 10.1.3のバージョンを使用しました:Windows Server 2016 64ビット、RAM 16GB(はい、ScoreboardサーバーはWindows Serverでのみ動作します)。 エクスポートされたレポートの例は、スコアボードサーバーと共にデ​​フォルトでインストールされるTableauサンプルプロジェクトから取得されました。 たとえば、これ:



画像



Telegramでボットを作成する方法の優れた例はたくさんありますが、 ドキュメントを使用するだけです。 Telegram APIを使用するには、既製のPythonライブラリを使用しますPython 2.7 Anacondaを使用します。



B-セキュリティ



Telegramを使用すると、企業サーバーから外部のどこかにレポートを送信できます。 したがって、誰もが自分に割り当てられたレポートのみを受信できるように、アクセスレジストリを維持する必要があります。 また、スクリプトを再起動せずにユーザー/権限を追加する必要があります。 ボットで作業を開始するときにユーザーのchat_idを見つけ、すぐに必要なアクセス権を与えます。



ユーザーがボットの操作を開始したら、chat_idを確認する必要があります。 これを行うには、/ startコマンドハンドラー(コードのstart関数)で、chat_idをボットの管理者に送信します。ボットの管理者は、このユーザーのレポート(つまり、chat_id)でキーボードを作成できます。



STARTボタンが押されると、ユーザーIvan Ivanovは次のメッセージを受け取ります。

こんにちは、現在、レポートにはアクセスできません。 申し込みが承認されました。近い将来アクセスが許可されます。



ボット管理者は次のメッセージを受け取ります:



アクセスの申請iivanov Ivan Ivanov 123456789



このような手順のために、YAMLファイルを作成します。このファイルでは、各ユーザーのユーザーセクションで、必要なレポートを含む「キーボード」を作成します。 この形式は、スクリプトで読み取り、キーボードの形でTelegramに送信するのが非常に簡単です。



ユーザーアクセス構成ファイル
users: 123456789: keyboard: - #  ,      - buttonText: 'Global Temperatures' #  ,     reportName: 'Global Temperatures' #      report: '/views/Regional/GlobalTemperatures' #  ,      - buttonText: 'College Admissions' #  ,     reportName: 'College Admissions' #      report: '/views/Regional/College' - #  ,      - buttonText: 'Regional FlightDelays' #  ,     reportName: 'Regional FlightDelays' #      report: '/views/Regional/FlightDelays'
      
      







この実施形態では、キーボードは2つの行を含む:



画像



このようなキーボードエントリをテレグラム形式に変換することは、特別な機能になります。



Telegramのキーボード形成
 def makeCustomKeyboard( userKeyboard ): """     .     keyboard    privacy.yaml. """ custom_keyboard = map( lambda z: [ telegram.KeyboardButton(x['buttonText']) for x in z ], userKeyboard ) return telegram.ReplyKeyboardMarkup(custom_keyboard, resize_keyboard='True')
      
      







スクリプトコード内の構成ファイルのアドレスは、変数CONFIG_FILEによって設定されます。 ボットの操作中にこれらのパラメーターを更新するには、updateSettings()関数を使用します。



/ startコマンドとメッセージの処理機能は、毎回アクセスレジストリを更新します。



 def updateSettings(): """     """ return load( file( CONFIG_FILE ) )
      
      





Scoreboardサーバーを操作するためのアクセスファイルに加えて、次のパラメーターが必要です。



ボットトークンとサーバー設定
 config: #   botToken: '111222333:AAO4L0Ttt1tt01-1TtT1t_t22tT' #   tabcmd.exe   tabcmdLocation: 'C:\Program Files\Tableau\Tableau Server\10.1\bin\' #     reportsLocation: 'C:\Users\Administrator\Documents\bot\reports\' #    logsLocation: 'C:\Users\Administrator\Documents\bot\logs\' admin: #   chat id      id: 198765432
      
      







すべての準備が整ったら、/ startコマンドの処理機能を定義できます。 また、ログ機能は便利です。ボットを使用したアクションのユーザーのchat_idをテキストファイルに書き込むだけです。 エラーが発生した場合のこのような単純なオプションにより、エラーが発生した行がわかります。



コマンド処理/開始
 def start(bot, update): """   /start  .        ( privacy.yaml,  users).  ,       .         """ # chat_id  chat_id = update.message.chat_id #      config = updateSettings() #        if chat_id in config['users']: logs(update, 'Received /start command from user in privacy.yaml') #           reply_markup = makeCustomKeyboard(config['users'][int(chat_id)]['keyboard']) bot.sendMessage(chat_id=chat_id, text=',    ', reply_markup=reply_markup) logs(update, 'List of available reports sent') #       else: logs(update, 'Received /start command from user NOT IN privacy.yaml') #    bot.sendMessage(chat_id=chat_id, text=',         . ' + \ '  ,      ') #         u = ast.literal_eval(str(update)) bot.sendMessage(chat_id=config['admin']['id'], text='   ' + str(u['message']['from']['username'].encode('utf-8')) + ' ' + str(u['message']['from']['first_name'].encode('utf-8')) + ' ' + str(u['message']['from']['last_name'].encode('utf-8')) + ' ' + str(chat_id)) logs(update, 'Request for access sent')
      
      







わかりました、レポートを利用できるキーボードをユーザーに送信しました。 このバージョンでは、着信メッセージを、このchat_idのprivacy.yamlアクセスファイル内のレポート名と比較する必要があります。 受信したメッセージがレポートの1つと一致する場合、このレポートをエクスポートするコマンドをScoreboardサーバーに送信します。 そして、生成されたレポートをユーザーに送信します。



サーバーからレポートをPDF形式でエクスポートするコマンドは、コマンドラインから「get」または「export」を使用して送信できます(ドキュメントへのリンク )。



これを行うには、最初にスコアボードサーバーとのセッションを開きます(localhost、adminおよびadminPasswordの代わりに、スコアボードサーバードメイン、ユーザー名、およびパスワードを指定します)。



「重い」レポートをエクスポートする前に、ユーザーに警告しておくと便利です。



 bot.sendMessage(chat_id=chat_id, text=' ,  ...', reply_markup=reply_markup) executeFile = os.path.join( tabcmdLocation, 'tabcmd.exe' ) subprocess.call([ executeFile, 'login', '-s', 'localhost', '-u', 'admin', '-p', 'adminPassword '])
      
      





レポートをディスク上のフォルダーにエクスポートします



 subprocess.call([ executeFile, 'get', reportAddress, '-f', reportsLocation + reportName + '.pdf'])
      
      





サーバー上のセッションを閉じます



 subprocess.call([ executeFile, 'logout'])
      
      





生成されたレポートをユーザーに送信するだけです



 bot.send_document(chat_id=chat_id, document=open(reportsLocation + reportName.encode('utf-8') + '.pdf', 'rb'))
      
      





仕組みを確認しましょう。



画像



サーバーからエクスポートされたPDFレポート:



画像



それだけです。このアプローチがレポートへのアクセスを簡素化し、作業効率を向上させることを願っています。 コードのフルバージョン:



構成ファイル
 users: 123456789: keyboard: - #  ,      - buttonText: 'Global Temperatures' #  ,     reportName: 'Global Temperatures' #      report: '/views/Regional/GlobalTemperatures' #  ,      - buttonText: 'College Admissions' #  ,     reportName: 'College Admissions' #      report: '/views/Regional/College' - #  ,      - buttonText: 'Regional FlightDelays' #  ,     reportName: 'Regional FlightDelays' #      report: '/views/Regional/FlightDelays' config: #   botToken: '111222333:AAO4L0Ttt1tt01-1TtT1t_t22tT' #   tabcmd.exe   tabcmdLocation: 'C:\Program Files\Tableau\Tableau Server\10.1\bin\' #     reportsLocation: 'C:\Users\Administrator\Documents\bot\reports\' #    logsLocation: 'C:\Users\Administrator\Documents\bot\logs\' admin: #   chat id      id: 198765432
      
      







スクリプトコード
 # -*- coding: utf-8 -*- CONFIG_FILE = r'C:\Users\Administrator\Documents\bot\privacy.yaml' #     API  import telegram from telegram.ext import Updater from telegram.ext import MessageHandler, Filters from telegram.ext import CommandHandler import sys import subprocess from yaml import load import ast import os.path def updateSettings(): """     """ return load( file( CONFIG_FILE ) ) #     config = updateSettings() #   token = config['config']['botToken'] #   tabcmd.exe   tabcmdLocation = config['config']['tabcmdLocation'] #     reportsLocation = config['config']['reportsLocation'] #    logsLocation = config['config']['logsLocation'] def makeCustomKeyboard( userKeyboard ): """     .     keyboard    privacy.yaml. """ custom_keyboard = map( lambda z: [ telegram.KeyboardButton(x['buttonText']) for x in z ], userKeyboard ) return telegram.ReplyKeyboardMarkup(custom_keyboard, resize_keyboard='True') def logs(update, comment): """   .  comment    logs  ,   chat id . """ u = ast.literal_eval(str(update)) with open( os.path.join(logsLocation, str(update.message.chat_id) + '.txt'), 'a') as f: f.write( str(u['message']['from']['username'].encode('utf-8')) + '\t' + str(u['message']['from']['first_name'].encode('utf-8')) + '\t' + str(u['message']['from']['last_name'].encode('utf-8')) + '\t' + str(u['message']['text'].encode('utf-8')) + '\t' + str(comment) + '\n') def start(bot, update): """   /start  .        ( privacy.yaml,  users).  ,       .         """ # chat_id  chat_id = update.message.chat_id #      config = updateSettings() #        if chat_id in config['users']: logs(update, 'Received /start command from user in privacy.yaml') #           reply_markup = makeCustomKeyboard(config['users'][int(chat_id)]['keyboard']) bot.sendMessage(chat_id=chat_id, text=',    ', reply_markup=reply_markup) logs(update, 'List of available reports sent') #       else: logs(update, 'Received /start command from user NOT IN privacy.yaml') #    bot.sendMessage(chat_id=chat_id, text=',         . ' + \ '  ,      ') #         u = ast.literal_eval(str(update)) bot.sendMessage(chat_id=config['admin']['id'], text='   ' + str(u['message']['from']['username'].encode('utf-8')) + ' ' + str(u['message']['from']['first_name'].encode('utf-8')) + ' ' + str(u['message']['from']['last_name'].encode('utf-8')) + ' ' + str(chat_id)) logs(update, 'Request for access sent') def echo(bot, update): """    ,  .            ,     """ # chat_id   chat_id=update.message.chat_id #    response = update.message.text #      config = updateSettings() #     (    greenLight = True) greenLight = False #         for line in config['users'][chat_id]['keyboard']: #        for button in line: if button['buttonText'] == response: logs(update, 'Menu found, generating current keyboard and reports') #        reply_markup = makeCustomKeyboard( config['users'][chat_id]['keyboard'] ) logs(update, 'Current keyboard generated') #    greenLight = True #    reportName = button['reportName'] reportAddress = button['report'] + '?:refresh=yes' if greenLight: logs(update, 'Starting to generate report') #       (   ) bot.sendMessage(chat_id=chat_id, text=' ,  ...', reply_markup=reply_markup) logs(update, 'Message about report generation sent') #       executeFile = os.path.join( tabcmdLocation, 'tabcmd.exe' ) #     subprocess.call([ executeFile, 'login', '-s', 'localhost', '-u', 'admin', '-p', 'adminPassword']) #     PDF subprocess.call([ executeFile, 'get', reportAddress, '-f', reportsLocation + reportName + '.pdf']) #   subprocess.call([ executeFile, 'logout']) logs(update, 'Report generated, sending document') #    bot.send_document(chat_id=chat_id, document=open(reportsLocation + reportName.encode('utf-8') + '.pdf', 'rb')) logs(update, 'Report sent') elif response == token: updater.stop() #  ,     else: logs(update, 'Bad message, no access to this report') #          reply_markup = makeCustomKeyboard(config['users'][chat_id]['keyboard']) bot.sendMessage(chat_id=chat_id, text='       . ' + \ ',  admin@tableau.mycompany.ru   ', reply_markup=reply_markup) logs(update, 'Main menu keyboard sent after bad message') #     updater = Updater(token=token) dispatcher = updater.dispatcher updater.start_polling() #   /start start_handler = CommandHandler('start', start) dispatcher.add_handler(start_handler) #    echo_handler = MessageHandler([Filters.text], echo) dispatcher.add_handler(echo_handler)
      
      








All Articles