記事"MQL5言語でのTelegram用ボットの作成"についてのディスカッション - ページ 6

 

エラーは非常に明確で、まさにその通りだ。

コンパイラーは、インクルード・ファイルが見つからないことを警告する。

インクルード・ファイルには不足している関数が 含まれているため、追加のエラーが発生するのです。

telegram.mqhというファイルがfilesフォルダに存在することを確認してください。

他のコードの問題にも関連すると思われるエラーがもっとあるので、そこから始めてください。
 

エキスパート・アドバイザーではなく、カスタム・インジケータから 作ることは可能ですか?

 
Franky Frentiono Nangoy:

エキスパートアドバイザーではなく、カスタムインジケータから 作成することは可能ですか?

インジケータから関数WebRequestを 呼び出そうとすると、GetLastError() はエラー4014 - "Function is not allowed for call"を返します。

これを行うには、 インジケータからWininet.dllで動作するようにプロジェクトを作り直す必要があります

Documentation on MQL5: Common Functions / WebRequest
Documentation on MQL5: Common Functions / WebRequest
  • www.mql5.com
Common Functions / WebRequest - Reference on algorithmic/automated trading language for MetaTrader 5
 
Andrey Voytenko:

インジケータから関数WebRequestを 呼び出そうとすると、GetLastError() はエラー4014 - "Function is not allowed for call"を返します。

これを行うには、 インジケータからWininet.dllで動作するようにプロジェクトを作り直す必要があります


ありがとうございます。

 

を見る

<Telegram.mqh>
{ 
   "ok":true,
   "result":[ 
      { 
         "update_id":349778698,
         "message":{ 
            "message_id":2,
            "from":{ 
               "id":198289825,
               "first_name":"Andriy",
               "last_name":"Voitenko",
               "username":"avaticks"
            },
            "chat":{ 
               "id":198289825,
               "first_name":"Andriy",
               "last_name":"Voitenko",
               "username":"avaticks",
               "type":"private"
            },
            "date":1459775817,
            "text":"\/start"
         }
      }
   ]
}
 

Aimak:

エラーを見つける手助けをしていただければ幸いです。よろしくお願いします。

チャンネルをパブリックモードに切り替えてください。または、プライベートチャンネルとの通信に(チャンネル名ではなく)chatIDを使用してください。

 
Aimak:

チャンネルは公開されており、チャンネル名やIDを使用しても同じ結果が得られます。スクリーンショットを見る

Telegram.mqhとJason.mqhの最新リリースを使用していますか?

 

親愛なるアンドレイ、

お疲れ様でした。私はあなたのファイルをインストールし、次のことを行うエキスパートを設定しました:

1) エキスパートはボットにx分ごとにメッセージを送ります(テスト用です)、

2) テレグラムでメッセージを読み、テレグラムクライアントのキーボードで「open trade」をクリックします、

3) メタトレーダーが(可能であれば)取引を開始する。

すべてうまくいくのですが、しばらくするとボットにアクセスできなくなります。ボットを再び動かすには、キーボードメニューのコマンド(たとえばチャートとか/startとか口座情報とか......)を押してボットを起こさなければなりません。メタトレーダーは "bad request:chat not found "と言いますが、ボットを再度起動させると1時間以上は完璧に動作しますが、その後停止してしまいます。

ご指摘の通りボットを作成しました(botFather を使用)。どうすればこの問題を解決できますか?

ありがとうございました。

ファイル:
error.gif  26 kb
 

興味深い記事をありがとう。コードにエラーがあります(スクリーンショットで確認できます):

写真送信時のエラー、タイトル

CCustomBotクラスのSendPhotoメソッドの修正が必要です。このオプションをお勧めします:

   int SendPhoto(const string _channel_name,
                 const string _local_path,
                 string &_photo_id,
                 const string _caption=NULL,
                 const bool _common_flag=false,
                 const int _timeout=10000)
     {
      //---
      // const long _chat_id
      //---
      
      if(m_token==NULL)
         return(ERR_TOKEN_ISEMPTY);

      string name=StringTrim(_channel_name);
      if(StringGetCharacter(name,0)!='@')
         name="@"+name;
      
      
      ResetLastError();
      //--- メモリ・バッファにファイルをコピーする
      if(!FileIsExist(_local_path,_common_flag))
         return(ERR_FILE_NOT_EXIST);

      //---
      int flags=FILE_READ|FILE_BIN|FILE_SHARE_WRITE|FILE_SHARE_READ;
      if(_common_flag)
         flags|=FILE_COMMON;

      //---
      int file=FileOpen(_local_path,flags);
      if(file<0)
         return(_LastError);

      //---
      int file_size=(int)FileSize(file);
      uchar photo[];
      ArrayResize(photo,file_size);
      FileReadArray(file,photo,0,file_size);
      FileClose(file);

      //--- 境界の作成:(データ -> base64 -> 1024 バイト -> md5)
      uchar base64[];
      uchar key[];
      CryptEncode(CRYPT_BASE64,photo,key,base64);
      //---
      uchar temp[1024]={0};
      ArrayCopy(temp,base64,0,0,1024);
      //---
      uchar md5[];
      CryptEncode(CRYPT_HASH_MD5,temp,key,md5);
      //---
      string hash=NULL;
      int total=ArraySize(md5);
      for(int i=0;i<total;i++)
         hash+=StringFormat("%02X",md5[i]);
      hash=StringSubstr(hash,0,16);
      //---

      //--- WebRequest
      uchar result[];
      string result_headers;

      string url=StringFormat("%s/bot%s/sendPhoto",TELEGRAM_BASE_URL,m_token);

      string part1="Content-Type: multipart/form-data; boundary="+hash+"\r\n";
      part1+="\r\n";

      //--- chart_idを追加する
      part1+="--"+hash+"\r\n";
      part1+="Content-Disposition: form-data; name=\"chat_id\"\r\n";
      part1+="\r\n";
      part1+=name; //IntegerToString(_chat_id);
      part1+="\r\n";

      //--- キャプションの追加
      if(_caption!=NULL)
        {
         part1+="--"+hash+"\r\n";
         part1+="Content-Disposition: form-data; name=\"caption\"\r\n";
         //part1+="Content-Type: text/plain}";
         //part1+="Content-Transfer-Encoding: quoted-printable ;
         part1+="\r\n";
         //part1+=UrlEncode(_caption);
         part1+=_caption;
         part1+="\r\n";
        }

      //--- 画像を追加する
      part1+="--"+hash+"\r\n";
      part1+="Content-Disposition: form-data; name=\"photo\"; filename=\"lampash.gif\"\r\n";
      part1+="\r\n";

      //--- 1
      uchar array1[];
      int size1=StringLen(part1);
      StringToCharArray(part1,array1,0,size1);

      //--- 2
      //写真
      int size2=ArraySize(photo);

      //---
      string part3="\r\n--"+hash+"--\r\n";
      int size3=StringLen(part3);
      uchar array3[];
      StringToCharArray(part3,array3,0,size3);

      //---
      uchar data[];
      ArrayResize(data,size1+size2+size3);
      ArrayCopy(data,array1,0);
      ArrayCopy(data,photo,size1);
      ArrayCopy(data,array3,size1+size2);

      //---
      string headers="Content-Type: multipart/form-data; boundary="+hash+"\r\n";
      int res=WebRequest("POST",url,headers,_timeout,data,result,result_headers);
      if(res==200)//OK
        {
         //--- BOMを削除する
         int start_index=0;
         int size=ArraySize(result);
         for(int i=0; i<fmin(size,8); i++)
           {
            if(result[i]==0xef || result[i]==0xbb || result[i]==0xbf)
               start_index=i+1;
            else
               break;
           }

         //---
         string out=CharArrayToString(result,start_index,WHOLE_ARRAY,CP_UTF8);

         //--- 解析結果
         CJAVal js(NULL,jtUNDEF);
         bool done=js.Deserialize(out);
         if(!done)
            return(ERR_JSON_PARSING);

         //--- エラーの説明を取得する
         bool ok=js["ok"].ToBool();
         if(!ok)
            return(ERR_JSON_NOT_OK);

         total=ArraySize(js["result"]["photo"].m_e);
         for(int i=0; i<total; i++)
           {
            CJAVal image=js["result"]["photo"].m_e[i];

            long image_size=image["file_size"].ToInt();
            if(image_size<=file_size)
               _photo_id=image["file_id"].ToStr();
           }

         return(0);
        }
      else
        {
         if(res==-1)
           {
            string out=CharArrayToString(result,0,WHOLE_ARRAY,CP_UTF8);
            //印刷(out);
            return(_LastError);
           }
         else
           {
            if(res>=100 && res<=511)
              {
               string out=CharArrayToString(result,0,WHOLE_ARRAY,CP_UTF8);
               //印刷(out);
               return(ERR_HTTP_ERROR_FIRST+res);
              }
            return(res);
           }
        }
      //--- 
      return(0);
     }
 
Andrey Emelyanov:

興味深い記事をありがとう。コードにエラーがあります(スクリーンショットで確認できます):

CCustomBotクラスのSendPhotoメソッドの修正が必要です。このオプションをお勧めします:

メッセージありがとうございます。しかし、あなたの修正したバリエーションはラテン文字でのみ動作します。

論理的には、文字列を UTF-8エンコーディングの配列に 変換して、リクエストボディのキャプションとして代入する必要があります。

私の変形は添付ファイルにあります。

ファイル:
Telegram.mqh  64 kb