VSCode Macros拡張を使ってSwitchBot APIを操作するマクロを作成してみたので紹介します。
今回はXの界隈で流行りのCursor Composerを使ってマクロを組んでみましたが、一発で作れてしまった…。Cursorエディタ便利すぎますね。
事前準備
-
SwitchBotのAPIトークンとシークレットキーの取得
以下の公式サイトの方法でAPIトークンとシークレットキーを取得してください。
SwitchBotサポート
トークンの取得方法 -
ライブラリのインストール ※ハードコードする場合はスキップできます。
環境変数をdotenvを使ってマクロファイルフォルダ内の.envから取得しているため、
npm i dotenv
でマクロフォルダにインストールしてください。
-
APIトークンとシークレットキーを環境変数に登録
マクロディレクトリに.envファイルを作成し、以下の環境変数に先程取得したAPIトークンとシークレットキーを登録します。
環境変数名 値 API_TOKEN APIトークン API_SECRET シークレットキー
サンプルマクロ
SwitchBot.js
const vscode = require('vscode');
const process = require('process');
const crypto = require('crypto');
const https = require('https');
const { Buffer } = require('buffer');
const path = require('path');
// マクロディレクトリから.envファイルを読み込む
require('dotenv').config({ path: path.join(__dirname, '.env') });
const token = process.env.API_TOKEN;
const secret = process.env.API_SECRET;
const lightDeviceId1 = process.env.LIGHT_DEVICE_ID_1;
// 環境変数のチェック
if (!token || !secret || !lightDeviceId1) {
vscode.window.showErrorMessage('環境変数が設定されていません。.env ファイルを確認してください。');
process.exit(1);
}
module.exports.macroCommands = {
電気を消す: {
no: 1,
func: TurnOffLight,
},
電気をつける: {
no: 2,
func: TurnOnLight,
},
デバイス情報取得: {
no: 3,
func: getDevices,
},
};
// 電気を消すコマンド
async function TurnOffLight() {
try {
await sendCommand('turnOff', lightDeviceId1);
await vscode.window.showInformationMessage('電気を消しました');
} catch (error) {
await vscode.window.showErrorMessage('電気を消すコマンドの実行中にエラーが発生しました:', error);
}
}
// 電気をつけるコマンド
async function TurnOnLight() {
try {
await sendCommand('turnOn', lightDeviceId1);
await vscode.window.showInformationMessage('電気を点けました');
} catch (error) {
await vscode.window.showErrorMessage('電気を点けるコマンドの実行中にエラーが発生しました:', error);
}
}
// デバイスID取得関数
async function getDevices() {
try {
const deviceInfo = await getDeviceInfo();
const newEditor = await vscode.workspace.openTextDocument({ content: JSON.stringify(deviceInfo, null, 2), language: 'json' });
await vscode.window.showTextDocument(newEditor);
return deviceInfo;
} catch (error) {
await vscode.window.showErrorMessage(`デバイス情報の取得中にエラーが発生しました: ${error.message}`);
throw error;
}
}
// コマンド送信関数
async function sendCommand(command, deviceId) {
const t = Date.now();
const nonce = 'requestID';
const data = token + t + nonce;
const signTerm = crypto.createHmac('sha256', secret).update(Buffer.from(data, 'utf-8')).digest();
const sign = signTerm.toString('base64');
const body = JSON.stringify({
command: command,
parameter: 'default',
commandType: 'command',
});
const options = {
hostname: 'api.switch-bot.com',
port: 443,
path: `/v1.1/devices/${deviceId}/commands`,
method: 'POST',
headers: {
Authorization: token,
sign: sign,
nonce: nonce,
t: t,
'Content-Type': 'application/json',
'Content-Length': body.length,
},
};
return new Promise((resolve, reject) => {
const req = https.request(options, (res) => {
let data = '';
res.on('data', (chunk) => {
data += chunk;
});
res.on('end', () => {
vscode.window.showInformationMessage(`ステータスコード: ${res.statusCode}`);
vscode.window.showInformationMessage(data);
resolve(data);
});
});
req.on('error', (error) => {
vscode.window.showErrorMessage(`エラー: ${error.message}`);
reject(error);
});
req.write(body);
req.end();
});
}
// デバイス情報取得関数
async function getDeviceInfo() {
const path = '/v1.1/devices';
const nonce = crypto.randomUUID(); // Node.jsのcryptoモジュールを使用してUUIDを生成
const timestamp = Date.now().toString();
const data = token + timestamp + nonce;
const signTerm = crypto.createHmac('sha256', secret).update(Buffer.from(data, 'utf-8')).digest();
const sign = signTerm.toString('base64');
const options = {
hostname: 'api.switch-bot.com',
port: 443,
path: path,
method: 'GET',
headers: {
Authorization: token,
sign: sign,
t: timestamp,
nonce: nonce,
},
};
return new Promise((resolve, reject) => {
const req = https.request(options, (res) => {
let data = '';
res.on('data', (chunk) => {
data += chunk;
});
res.on('end', () => {
vscode.window.showInformationMessage(`ステータスコード: ${res.statusCode}`);
try {
const parsedData = JSON.parse(data);
vscode.window.showInformationMessage('デバイス情報を取得しました');
resolve(parsedData);
} catch (error) {
vscode.window.showErrorMessage(`レスポンスの解析中にエラーが発生しました: ${error.message}`);
reject(error);
}
});
});
req.on('error', (error) => {
vscode.window.showErrorMessage(`エラー: ${error.message}`);
reject(error);
});
req.end();
});
}
使い方
ここからはVSCode Macrosのコマンド(VSCMacros: Select a macro file
→SwitchBot.js
→VSCMacros: Run a macro
)で操作します。
-
デバイスIDの取得
VSCode Macrosのコマンドから
デバイス情報取得
コマンドを実行すると、新しいテキストエディタが開いて利用中のSwitchBotデバイス一覧がJson形式で表示されるので、制御したいデバイスのデバイスIDを見つけて.envに登録します(本例の場合はライトなのでLIGHT_DEVICE_ID_1)。 -
デバイスの制御
後は想像通りですが、VSCode Macrosのコマンドから
電気を点ける
を実行すればライトが点灯し、電気を消す
コマンドを実行すればライトが消灯します。
SwitchBot APIの詳しい使い方については、参考ウェブサイトのドキュメント参照してみてください。
参考ウェブサイトなど
- GitHub
OpenWonderLabs/SwitchBotAPI
以上です。