2018-07-12

【Delphi】Delphi7 透過 HTTPS 傳 LINE 訊息

參考資料 ----
download SSL
LINE Messaging API
Indy 10.6 HTTPS POST example with JSON body


這篇筆記有 2 個重點:
1. Delphi7 以 HTTPS 傳遞 post 資料
2. 透過 LINE Messaging API 傳送訊息


開發環境 ----
WinXP 32bit, Delphi7




申請 LINE 開發者帳號(關於 LINE 的相關流程,是老人家的同事處理的,老人家只是依據同事的說法概略的描述流程,更進一步詳細的做法請上 LINE 官網),這是免費的,不過只能傳給 50 個對象,這 50 個對象可以是 個人群組,因為只是做公司內部消息佈達用,所以我們的做法是建立一個群組(省著點用),再將相關的人拉進群組內,發訊息給這個群組就可以了。



在您的官網放置 line.php,目的是要接收取得所建立的 LINE 群組的 ID,並寫入 line.txt
 
<?php
echo "LINE";
$fp = fopen('line.txt' , "a+");
fwrite($fp , print_r( apache_request_headers() , true));

fwrite($fp , print_r(  file_get_contents('php://input'), true));
fclose($fp);
?>
 
 

隨意發個訊息給群組,然後打開 line.txt,取得 LINE groupID,這是要給 Delphi7 程式用的。


1. 建立專案目錄

2. download SSL 下載  indy_OpenSSL096m.zip (經嘗試錯誤,要這個檔案才能用),解壓後,將 ssleay32.dll, libeay32.dll 放入專案的目錄內

3. FormidHTTP(Indy Clients 頁籤 )idSSLIOHandlerSocket (Indy I/O Handlers 頁籤) 2 個元件,這 2 個是主角;再放 Label(name=lblMessage)、Edit(name=txtMessage)、Memo、Button(name=btnLine),如下圖:




4. idHTTP 元件的 name 屬性改為 idHttpidSSLIOHandlerSocketname 屬性改為 IdSSL

5. IdSSLMethod 屬性改為 sslvSSLv23

6. idHttpIOHandler 屬性指向 IdSSL


 
...
...

procedure TfrmMain.FormCreate(Sender: TObject);
begin
    // 這段的目的是讓程式一啟動先載入 ssleay32.dll, libeay32.dll
    // 但第一次執行會出現錯誤
    // 所以用 try 把錯誤訊息壓下來不顯示
    // 
    // 2019.12.02
    // 無意間得知, 會發生這個現象是因為版本因素
    // 請自行上網尋找適合 INDY 的版本
    try
        idHttp.Get('https://隨便打個網址');    // 重點是網址要支援 https
    except

    end;
end;

...
...

procedure TfrmMain.btnLineClick(Sender: TObject);
const
    url = 'https://api.line.me/v2/bot/message/push';
var
    RequestBody: TStream;
    ResponseBody: string;
begin
    idHttp.Request.ContentType := 'application/json';
    idHttp.Request.CustomHeaders.Text := 'Authorization:Bearer  jj/dAZOPVE/blablabla很長的字串=';
    try
        try
            RequestBody := TStringStream.Create('{"to":"群組 ID", "messages": [{"type": "text","text": "'+UTF8Encode(txtMessage.Text)+'"}]}');    // UTF8Encode 很重要, 尤其訊息內有中文
            try
                ResponseBody := idHttp.Post(url, RequestBody);
                memo1.lines.add(ResponseBody);
            finally
                RequestBody.Free;
            end;
        except on E: EIdHTTPProtocolException do
                begin
                    memo1.Lines.Add(e.Message);
                    memo1.Lines.Add(e.ErrorMessage);
                end;
                on E: Exception do
                begin
                    memo1.Lines.Add(e.Message);
                end;
        end;
    finally
        
    end;
end;

 


這個程式有個小問題,就是第一次執行 idHttp 時會跳出錯誤訊息,所以才在 FormCreate

try

except

end;

將錯誤訊息欄截不顯示。如果看倌有更好的解法,也請您分享。謝謝啦~



2019.12.02
無意間得知, 會發生這個現象是因為版本因素
請自行上網尋找適合 INDY 的 ssleay32.dll, libeay32.dll 版本
您可以以 "Could not load SSL library" 查詢
會得到許多相關討論