SORACOM LTE-M Buttonのボタンを押したら、Slackに通知する
SORACOM LTE-M Buttonのボタンを押したら、Slackに通知する:
SORACOMさんから発売された「SORACOM LTE-M Button powered by AWS」を入手して、ちょっとやってみたメモです。
エリア検索で調べたら、自宅、エリア外疑惑。。。
KDDI IoT通信サービス LPWA: エリア検索
・・・結果。
つながりました。ふー。
さて、気を取り直して、色々やって見ます。
SORACOMのAPIリファレンスを見ていたら、ボタンの情報がAPIで取れるようになっていたので、
LambdaでAPI叩いて、ボタンの情報取得して、その情報含めてSlackに投稿するようにしました。
(API Reference#Gadget)
突貫感すみません。
流れは以下。
Lambda関数(最近node.js使いなので、node.jsで書いてます。)
slack投げる部分は、LambdaのBluePrintとか参考にしてます。
他にも色々できそうですので、それは引き続き...
/gadgets の公開、待ってました!
あと、APIでもっとボタンの情報取れるといいですね。 これは #ソラコムサンタ かな。
SORACOMさんから発売された「SORACOM LTE-M Button powered by AWS」を入手して、ちょっとやってみたメモです。
まず繋がるの?
エリア検索で調べたら、自宅、エリア外疑惑。。。KDDI IoT通信サービス LPWA: エリア検索
・・・結果。
つながりました。ふー。
さて、気を取り直して、色々やって見ます。
作って見た
SORACOMのAPIリファレンスを見ていたら、ボタンの情報がAPIで取れるようになっていたので、LambdaでAPI叩いて、ボタンの情報取得して、その情報含めてSlackに投稿するようにしました。
(API Reference#Gadget)
突貫感すみません。
流れは以下。
- ボタンクリック
- AWS IoT 1-Clickで受ける
- Lambda起動
- SORACOM APIでボタンの情報取得
- SlackのIncoming WebHooksのURL叩いて、メッセージ投稿
シングルクリック
ダブルクリック
長押し
Lambda関数(最近node.js使いなので、node.jsで書いてます。)
slack投げる部分は、LambdaのBluePrintとか参考にしてます。
index.js
'use strict' const request = require('request'); const moment = require('moment-timezone'); const AWS = require('aws-sdk'); AWS.config.update({ region: 'ap-northeast-1' }); const kms = new AWS.KMS(); const encryptedSlackWebHookUrl = process.env['SLACK_WEBHOOK_URL']; // slackのURL let decryptedSlackWebHookUrl; const encryptedSoracomKey = process.env['SORACOM_KEY']; // SORACOM API認証キー let decryptedSoracomKey; const encryptedSoracomKeyId = process.env['SORACOM_KEY_ID'];SORACOM API認証キー ID let decryptedSoracomKeyId; /** * 初期化 * @param {[type]} event [description] * @param {[type]} context [description] * @return {[type]} [description] */ const initialize = (event, context) => { return new Promise((resolve) => { // クリックのタイプで文字変えてます。 let clickTypeName = 'クリック'; if (event.deviceEvent.buttonClicked.clickType == "DOUBLE") { clickTypeName = 'ダブルクリック'; } else if (event.deviceEvent.buttonClicked.clickType == "LONG") { clickTypeName = '長押し'; } const stash = { apiKey:'', token:'', serialNumber: event.deviceInfo.deviceId, remainingLife: event.deviceInfo.remainingLife, clickType: event.deviceEvent.buttonClicked.clickType, clickTypeName, reportedTime: event.deviceEvent.buttonClicked.reportedTime, gadgetsInfo:{}, }; console.log(stash); resolve(stash); }); }; /** * キー情報復号化処理 * @param {[type]} stash [description] * @return {[type]} [description] */ const decryptedUrl = (stash) => { return new Promise((resolve, reject) => { if (!decryptedSlackWebHookUrl) { kms.decrypt({ CiphertextBlob: new Buffer(encryptedSlackWebHookUrl, 'base64') }, (err, data) => { if (err) { console.log('Decrypt error:', err); reject(err); } decryptedSlackWebHookUrl = data.Plaintext.toString('ascii'); resolve(stash); }); } else { resolve(stash); } }); }; /** * キー情報復号化処理 * @param {[type]} stash [description] * @return {[type]} [description] */ const decryptedKey = (stash) => { return new Promise((resolve, reject) => { if (!decryptedSoracomKey && !decryptedSoracomKeyId) { kms.decrypt({ CiphertextBlob: new Buffer(encryptedSoracomKey, 'base64') }, (err, data) => { if (err) { console.log('Decrypt error:', err); reject(err); } decryptedSoracomKey = data.Plaintext.toString('ascii'); kms.decrypt({ CiphertextBlob: new Buffer(encryptedSoracomKeyId, 'base64') }, (err, data) => { if (err) { console.log('Decrypt error:', err); reject(err); } decryptedSoracomKeyId = data.Plaintext.toString('ascii'); resolve(stash); }); }); } else { resolve(stash); } }); }; /** * SORACOM API 認証 * @param {[type]} stash [description] * @return {[type]} [description] */ const getSoracomApiAuth = (stash) => { return new Promise((resolve, reject) => { const optionsAuth = { url: 'https://api.soracom.io/v1/auth', method: 'POST', headers: { 'Content-Type': 'application/json', 'Accept': 'application/json' }, json: { 'authKeyId':decryptedSoracomKeyId, 'authKey':decryptedSoracomKey, 'tokenTimeoutSeconds':86400 } }; // SORACOM Auth APIコール request(optionsAuth, function (error, response, body) { if (error) { console.log('Auth API Error: ' + error); reject(error); } else if (response.statusCode != 200) { console.log('Auth API Error response.statusCode: ' + response.statusCode); const err = { 'statusCode': response.statusCode } reject(err); } else { console.log('APIコール成功'); stash.apiKey = body.apiKey; stash.token = body.token; resolve(stash); } }); }); }; /** * SORACOM API ボタン情報取得 * @param {[type]} stash [description] * @return {[type]} [description] */ const getGadgetInfo = (stash) => { return new Promise((resolve, reject) => { const apiKey = stash.apiKey; const token = stash.token; const optionsGetGadgetsData = { url: `https://api.soracom.io/v1/gadgets/button/${stash.serialNumber}`, method: 'GET', headers: { 'Content-Type': 'application/json', 'Accept': 'application/json', 'X-Soracom-API-Key': apiKey, 'X-Soracom-Token': token } }; // APIコール request(optionsGetGadgetsData, function (error, response, body) { if (error) { console.log('Gadgets API Error: ' + error); reject(error); } else if (response.statusCode != 200) { console.log('Gadgets API Error Response.statusCode: ' + response.statusCode); const err = { 'statusCode': response.statusCode } reject(err); } else { console.log('APIコール成功 body:' + JSON.parse(body).operatorId); const gadget = JSON.parse(body); stash.gadgetInfo = gadget; resolve(stash); } }); }); }; /** * Slack POST * @param {[type]} stash [description] * @return {[type]} [description] */ const postSlackMessage = (stash) => { return new Promise((resolve, reject) => { console.log('slack Call'); const gadget = stash.gadgetInfo; let messageArray = []; messageArray.push(`ボタン${gadget.tags.name}が${stash.clickTypeName}されました。`); const useCount = 1500 - gadget.attributes.remainingCount; messageArray.push(`現在のクリック数は${useCount}で残り${gadget.attributes.remainingCount}です。`); messageArray.push(`有効期限は${moment(gadget.attributes.contractEndingTime).tz("Asia/Tokyo").format('YYYY-MM-DD hh:mm:ss')}です。`); const message = messageArray.join('\n'); // リクエスト設定 const options = { url: decryptedSlackWebHookUrl, headers: { 'Content-type': 'application/json' }, body: { "text": message }, json: true }; // メッセージ送信 request.post(options, function(error, response, body) { if (!error && response.statusCode == 200) { resolve(stash); } else { if (error) { console.log('Slack API Error: ' + error); reject(error); } else { console.log('Slack API Error: ' + response.statusCode); const err = { 'statusCode': response.statusCode } reject(err); } } }); }); }; /** * Main処理 * @param {[type]} event [description] * @param {[type]} context [description] * @param {Function} callback [description] * @return {[type]} [description] */ exports.handler = (event, context, callback) => { initialize(event, context) .then(decryptedKey) .then(getSoracomApiAuth) .then(getGadgetInfo) .then(decryptedUrl) .then(postSlackMessage) .then(callback.bind(null, null)) .catch(callback); };
最後に
/gadgets の公開、待ってました!あと、APIでもっとボタンの情報取れるといいですね。 これは #ソラコムサンタ かな。
コメント
コメントを投稿