WebRequest関数の書式だけを見て、「結局どう書けばLINEやDiscordに通知を送れるのか分からない」と感じたことはないでしょうか。

WebRequest関数は、MT4のEA・スクリプトなどから外部サーバーへHTTPリクエストを送信するための関数で、LINEやDiscordに通知を送る際によく使われます。

この記事では、WebRequest関数の書式だけでなく、実際にコンパイルして動かせるサンプルコードと、実行前に必要な設定まで解説します。

WebRequest関数

WebRequest関数とは、指定されたサーバーにHTTPリクエストを送信します。

WebRequest関数はLINEやDiscordなどに通知を送る際に使用するケースが多いですね。

WebRequest関数の書式

WebRequest関数の書式は以下のとおりです。

int WebRequest(
const string method, // HTTP メソッド GET,POST
const string url, // URL
const string cookie, // クッキー
const string referer, // リファラ
int timeout, // 時間切れ 
const char &data[], // HTTPメッセージ本文の配列 , POST送信などもできます。 GETの時は、空で良いです。
int data_size, // data[] 配列のバイトサイズ
char &result[], // サーバ応答データを含む配列 webサーバからの応答をこの配列に受け取ります。
string &result_headers // サーバ応答ヘッダ      
);

data_size(6番目の引数)には、data配列の要素数をそのまま渡すのが基本です。`ArraySize(data)`で取得できます。手入力でバイト数を計算する必要はありません。

実際にWebRequestを使ってみる

書式だけでは実際にどう書けばよいかイメージしづらいので、指定したURLにGETリクエストを送り、レスポンスをログに表示するだけの最小限のサンプルを見てみましょう。

//+------------------------------------------------------------------+
//|                                             WebRequestSample.mq4 |
//+------------------------------------------------------------------+
#property strict

int OnInit()
  {
   string method  = "GET";
   string url     = "https://example.com/";//実際に許可登録したURLに置き換える
   string cookie  = NULL;
   string referer = NULL;
   int    timeout = 5000;//ミリ秒
   char   data[];
   char   result[];
   string result_headers;

   ArrayResize(data, 0);//GETの場合は空でよい

   ResetLastError();
   int res = WebRequest(method, url, cookie, referer, timeout,
                         data, ArraySize(data), result, result_headers);

   if(res == -1)
     {
      int err = GetLastError();
      Print("WebRequestが失敗しました。エラーコード=", err);
      if(err == 4060)
         Print("URLが許可リストに登録されていません。次の「WebRequestを使う前の準備」を確認してください。");
     }
   else
     {
      string response = CharArrayToString(result);
      Print("HTTPステータス: ", res, " 受信データ: ", response);
     }

   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
Copy

data配列とresult配列は役割が逆です。data配列は「これから送るデータ」を自分で用意して渡す配列(GETなら空でよい)、result配列は「サーバーから返ってきたデータ」をWebRequest関数が書き込んでくれる配列です。受け取ったresult配列はバイト配列のままではログに読める形で出力できないため、`CharArrayToString()`で文字列に変換してから表示しています。LINE Notifyなど、POSTでJSONやフォームデータを送りたい場合は、送信したい文字列を`StringToCharArray()`でdata配列に変換してから渡します。

WebRequestを使う前の準備

WebRequest関数は、初期状態では外部サイトへのアクセスがすべてブロックされています。実行する前に、MT4の「ツール」→「オプション」→「エキスパートアドバイザ」タブを開き、「WebRequestを許可するURLリスト」にアクセスしたいURLのドメイン(https://から始まる形)を追加してください。

この登録を忘れると、コンパイルは通ってもWebRequest()が常にエラーコード4060(関数が許可されていません)を返します。上のサンプルコードのエラーハンドリングは、このケースを想定したものです。

WebRequest関数でできないこと

WebRequest関数でできないことをご紹介します。

WebRequest関数をインジケーターから呼び出す場合の注意点

WebRequest関数は、実はインジケーターから呼び出すこと自体は可能です。

ただし、インジケーターの計算処理はチャートの再描画のたびに何度も呼ばれる設計になっており、そのたびに外部サーバーへ通信すると、MT4の動作が重くなったり、意図しない頻度でリクエストが飛んだりする問題が起きやすいため、実務上はEAかスクリプトから呼び出すことが推奨されています。

指定したサイトしかアクセスできない

MT4のオプションから指定したサイトにしかアクセス出来ないという問題があるので、

古いバージョンのMT4やこの制限を回避したい場合に、dllを読み込んで処理を作成する場面もありますが、上級者向けの手法です。まずは上記の許可URL登録によるWebRequest関数の利用を検討することをおすすめします。

まとめ

関連記事