C++ Builder CE ネットワークプログラミング

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君の場合とは少し違いますね。

コメント

  1. […] C++ Builder CE ネットワークプログラミングhttpsでのputを扱う Discordのwebhookで… […]