電報のためのLanボットでのウェイク

Telegram ボットAPIの発見後彼らの人口は急速に増加し始めました。 私は、コンピュータをリモートでオンにする機能を維持し、自分で取得することにしました。 開発では、C#が選択され、ホスティングとしてAzureが選択されました。



挑戦する

「マジックパケット」を送信して、指定されたアドレスとポートにコンピューターの電源を入れることができるボットを作成します。



注:この記事では、ボットのトークンの取得とサイトのAzureへのデプロイについては説明しません。 これらの質問は、HabrまたはGoogleで簡単に回答できます。



少しの理論とネットワーク設定



コンピューターの電源を入れるには、 Wake on Lanテクノロジーが使用されます。 ボットはクラウド内にあるため、パケットを外部アドレスに送信する必要があります。 この点で、パケットが最終的にローカルネットワークに到達し、目的のネットワークカードに到達することを確認する必要があります。 これを行うには、ルーターのポートを転送します。







ポート7とそのようなアドレスはなぜですか?
通常、Wake on Lanを使用してローカルネットワークでコンピューターの電源を入れるには、「マジックパケット」をローカルネットワークのブロードキャストアドレス、ポート7 / UDPに送信する必要があります(場合によっては、他のポートを使用できます)。 ネットワークカードは「その」パケットを受信すると、コンピューターの電源を入れるための信号を送信します。



パケットは、次の順序の一連のバイトで構成されます。最初の6バイトはゼロです。次に、ネットワークカードのポップアップアドレスからのバイトシーケンスがあり、16回繰り返されます。 実際、ネットワークカードは、コンピューターの電源を入れる必要があることをMACアドレスに認識しています。



このようなパケットを作成し、それを外部アドレス(ホームルーターのアドレスなど)に送信します。その後、パケットをローカルネットワークのブロードキャストアドレスにルーティングする必要があります。



私の場合、ポート7はネットワークのブロードキャストアドレス(10.10.10.255)に転送されます(インターネットからアクセス可能)。





コードを書く



ボットAPIを使用するために、 Telegram.Botライブラリが選択されました。 更新を受け取るためにwebhookオプションを使用します 。 この場合、ボットが受信する各メッセージまたはイベントは、指定されたURLに送信されます。



ホスティングとして、すべてのパラメーターに適合するAzureを使用することが決定されました。



最初に、ボットを操作するためのオブジェクトを返すクラスを作成します。



public static class Bot { private static Api _bot; /// <summary> ///  ,     ///   -  ///   /// </summary> public static Api Get() { if (_bot != null) return _bot; _bot = new Api(Config.BotApiKey); _bot.SetWebhook(Config.WebHookUrl); return _bot; } }
      
      





Configクラスから設定を取得します

Config.cs
 public static class Config { /// <summary> ///        /// </summary> private static readonly NameValueCollection Appsettings = ConfigurationManager.AppSettings; /// <summary> ///     /// </summary> public static string BotApiKey { get { return Appsettings["BotApiKey"]; } } /// <summary> /// URL,         /// </summary> public static string WebHookUrl { get { return Appsettings["WebHookUrl"]; } } }
      
      







次に、パッケージを作成して送信する必要があります。 WakeOnLanクラスがこれを担当します。



 /// <summary> ///   ""      /// </summary> public static class WakeOnLan { public static void Up(string ip, string mac, int? port = null) { var client = new UdpClient(); var data = new byte[102]; for (var i = 0; i <= 5; i++) //    -  data[i] = 0xff; var macDigits = GetMacDigits(mac); if (macDigits.Length != 6) throw new ArgumentException("Incorrect MAC address supplied!"); const int start = 6; for (var i = 0; i < 16; i++) //       for (var x = 0; x < 6; x++) data[start + i * 6 + x] = (byte)Convert.ToInt32(macDigits[x], 16); client.Send(data, data.Length, ip, port ?? 7); //   } private static string[] GetMacDigits(string mac) //  MAC { return mac.Split(mac.Contains("-") ? '-' : ':'); } public static bool ValidateMac(string mac) //     MAC  { return GetMacDigits(mac).Length == 6; } }
      
      







パッケージを作成して送信することができます。 / wolなどのコマンドに応答するようにボットに教えることは残っています。

簡単にするために、パラメーター付きのコマンドが実装されています。 ユーザーは次のようなものを入力する必要があります

/wol 1.2.3.4 01:02:03:04:05:06 7







パケットをアドレス1.2.3.4、ポート7に送信し、MACアドレス01:02:03:04:05:06でコンピューターを起動するため



 public async void Handle(Message message) { var text = message.Text.Split(' '); if (text.First() != "/wol") return; switch (text.Count()) { case 1: case 2: await _bot.SendTextMessage(message.Chat.Id, " : /wol 1.2.3.4 01:02:03:04:05:06 7"); break; default: if (!WakeOnLan.ValidateMac(text[2])) await _bot.SendTextMessage(message.Chat.Id, " MAC "); else { try { WakeOnLan.Up(text[1], text[2], GetPort(text)); await _bot.SendTextMessage(message.Chat.Id, " !"); } catch (Exception) { await _bot.SendTextMessage(message.Chat.Id, "  :("); } } break; } } /// <summary> ///     /// </summary> private static int? GetPort(IReadOnlyList<string> text) { int port; if (text.Count == 4 && int.TryParse(text[3], out port)) return port; return null; }
      
      





あとは、ボットから更新を受け取るコントローラーを作成するだけです。

 public class MessageController : ApiController { [Route(@"api/message/wol")] public OkResult Post([FromBody]Update value) { Task.Run(() => new Handler().Handle(value.Message)); return Ok(); } }
      
      





Azureでアプリケーションに「入力」した後、 ボットを確認します。





参照:

TelegramのWoLボット

GitHubプロジェクト

Telegram Bot API

Telegram.Bot Library(GitHub)



All Articles