httpsでのputを扱う Discordのwebhookで書き込む
http[s]でのgetは色々な場面で扱いますが、ここではDiscordでbot経由で書き込むのと同様にして、webhook経由で書き込んでみます。curl使うのだとurlが違うだけなので、久しぶりのC++ Builder CEのネットワークプログラミングです。
まずは前記事
の続きから。まずwebhookを作成します。それにはDiscordにログインして、

チャンネルの編集へ、

連携サービスをクリックして、ウエブフックを作成します。

ここで”ウエブフックURLをコピー”します。上のようにアイコンを割り当てても良いです。urlは、
https://discord.com/api/webhooks/あなたのサーバーIDの数字列/qLUuT以下ランダムなトークン
こんな感じでbot君を使うときのurlと若干異なります。一応試すのであれば、curl君に
curl -X POST -d 'content=Hello world.' 上記のwebhookのurl
とかでメッセージが書けます。画像を添付するならば、file=の手順でおけです。慎重な方は、ここで少なくてもテキストが書けるかは試すのが吉です。
さてVCLプログラムを新規作成し、以下のようなフォームを作ります。

フォームにTEdit、TButton,TLabelを置きます。上図のようにEdit1->Textの初期値やTButtonの“Name”とかは変更しても良いと思います。後者の変更はむしろ推奨します。さて今回はIndy関係のコンポーネントTIdHTTP等に加えてDebugのためのコンポーネントやSSL関連のコンポーネントを加えますが、動的に割り当てます。ので、Unit1.hは、
#ifndef Unit1H
#define Unit1H
//---------------------------------------------------------------------------
#include <System.Classes.hpp>
#include <Vcl.Controls.hpp>
#include <Vcl.StdCtrls.hpp>
#include <Vcl.Forms.hpp>
#include <Vcl.ExtCtrls.hpp>
#include <IdBaseComponent.hpp>
#include <IdComponent.hpp>
#include <IdHTTP.hpp>
#include <IdIntercept.hpp>
#include <IdIOHandler.hpp>
#include <IdIOHandlerSocket.hpp>
#include <IdIOHandlerStack.hpp>
#include <IdLogBase.hpp>
#include <IdLogDebug.hpp>
#include <IdSSL.hpp>
#include <IdSSLOpenSSL.hpp>
#include <IdTCPClient.hpp>
#include <IdTCPConnection.hpp>
//---------------------------------------------------------------------------
class TForm1 : public TForm
{
__published: // IDE で管理されるコンポーネント
TEdit *Edit1;
TButton *Push;
TLabel *Label1;
void __fastcall PushClick(TObject *Sender);
private: // ユーザー宣言
public: // ユーザー宣言
__fastcall TForm1(TComponent* Owner);
};
//---------------------------------------------------------------------------
extern PACKAGE TForm1 *Form1;
//---------------------------------------------------------------------------
#endif
と長いです。Unit1.cppは、
#include <vcl.h>
#pragma hdrstop
#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
TIdHTTP* http;
TIdLogDebug* logdebug;
TIdSSLIOHandlerSocketOpenSSL* ssl;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
http = new TIdHTTP();
logdebug = new TIdLogDebug();
ssl = new TIdSSLIOHandlerSocketOpenSSL();
http->Intercept = logdebug;
http->IOHandler = ssl;
logdebug->Active = true;
http->HTTPOptions = http->HTTPOptions>>hoForceEncodeParams;
ssl->SSLOptions->Method = sslvTLSv1_2;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::PushClick(TObject *Sender)
{
TStringStream* resp = new TStringStream();
TIdMultiPartFormDataStream* parms = new TIdMultiPartFormDataStream();
parms->AddFormField("content",Edit1->Text);
parms->AddFile("file","test.jpg","image/jpeg");
String url = "https://discord.com/api/webhooks/ランダムなトークン";
//http->Request->ContentType = "application/json";
http->Request->UserAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.139 Safari/537.36";
try {
http->Post(url,parms,resp);
}
catch (const Exception &E){
ShowMessage(E.Message);
}
Label1->Caption = http->ResponseText;
}
添付したい画像ファイルの名前を“test.jpg”として実行ファイルと同じ階層に置く必要があります。実行すると、

となり、サーバーのレスポンスがLabel1に表示されます。デバッグメッセージは、

のようにIDE画面下部に表示されます。POSTで何を送って、どういうレスポンスが返ってきたかがわかります。HTTP/1.1 200 OKはうまくいったということで、Label1の表示と同じです。Discord側には、

このように表示されます。bot君の場合とは少し違いますね。
コメント
[…] C++ Builder CE ネットワークプログラミングhttpsでのputを扱う Discordのwebhookで… […]