2017年2月23日 星期四

微信伺服器認證問題


微信機械人的編程工作完成了,得由測試服轉為正式服。在微信後台輸入正式服的網址,打好了認證簽字,點下「提交」掣,出現「認證失敗」。改回測試服再試一次,卻「認證成功」。非常奇怪。

正式服使用 Udomain。試過不止一次,它的伺服器會懶醒地把數據偷偷地改了。於是我把傳入的數據記錄下來,用 Postman 模擬一下,不論是測試服還是正式服,都有相同的長度、相同的結果。只是檔頭有少許不一樣,但不會影響認證。既然 99% 一致,那麼焦點落在連線上。其中一個可能性是微信國內的伺服器連不上 Udomain。Access Log 及 Error Log 找不到認證的影子,然而程式中的活動記錄卻有寫進檔案;意味著假設不成立。於是又想,會不會是 The Great Firewall 做的好事?沒欄測試服,只欄正式服。向 Udomain 求證,他們說沒有問題。

在毫無頭緒的情況下,想到目前 HTTP 的請求會自動轉到 HTTPS 渠道,會不會這個設定有所影響呢?認證網址一直都用 HTTPS,心想 99% 不關事吧。在沒有出路的情況下唯有一試。關閉了跳轉程式,再次認證,再次「認證失敗」。隨手也試試 HTTP,今次卻成功了。雖然不清楚問題的原因,但估計是 SSL 證書,或是 VirtualHost 設定出事吧。有待研究。

2017年2月22日 星期三

用 Javascript 關閉微信內建瀏覽器

最近開發了一個簡單的 WeChat Bot。沒有甚麼功能,只在「關注」時生成一條網址;點擊網址會去到一個由 HTML 寫成的表格。填妥後會跳轉到「多謝」頁面。可是微信的檔頭出現的「返回」掣卻是返回上一頁,但我想的是「關閉」。原來微信內建的瀏覽器會自動載入自帶的 JS 功能,只要調用:
WeixinJSBridge.call('closeWindow');
就能關閉瀏覽器。另外還有其他的 WeixinJSBridge 功能,例如:
WeixinJSBridge.call('hideOptionMenu');
減少微信選單內的分享項目。

2017年2月21日 星期二

初試 LUIS


上星期出席了 Microsoft Tech Submit,發現 LUIS 好像很好用,而且訓練數據不多就能順利分類,很想試試。今晚登入 LUIS 後,雖然有少許教學指引,但還是不清楚該做哪試事。

後來發現 https://www.luis.ai/Help 中有兩段 YouTube 教學,花了廿分鐘左右時間看完,才能懂得使用 LUIS 的介面。想嘗試 LUIS 的朋友一定要看。

2017年2月18日 星期六

一口好茶:工藝茶花束


內子從店裡帶回新的產品,是一枝枝獨立的工藝茶花束。跟之前情人節的花束不同,也過了情人節,正在思考要如何拍這張照片。

之前設計了 23 張海報,都是有大量的後期製作,如:退地、調節光暗、變色、加背景、加效果...等處理。今次想回歸基本,用照片表達情感。我覺得花束由少女把持的感覺最為溫馨,於是找來長女扮演模特兒。以往習慣連拍數張,避免手震或不對稱問題;今次卻隨意拍了一張。在家中拍的相片,出來的效果十分好。在構圖上,我認為花要突出,模特兒要不露臉,以免搶去主體的焦點。所以用了長鏡把背景打矇。女兒找來的外套顏色剛好能襯托出藍色的花束。多個巧合匯聚成這張作品,我自己也很喜歡。

2017年2月11日 星期六

微信 JS-SDK 需要 ICP 牌照


微信 WeChat 是對話機械人的先驅,比起 Facebook 及其他的 ChatBot 早了幾年上市。其實除了能在 WeChat 中開發 ChatBot 外,還能在網頁上用上 JS-SDK 來偵測在 WeChat 內的使用活動。在慕課網找到「PHP 微信公眾平台開發高級篇—微信 JS-SDK」這個免費課程講解了相關的技術。可是,要用 WeChat 的 JS-SDK,需要得到 ICP 牌照,否則 Javascript 程序無法順利執行。又沒有得嘗試...。

2017年2月10日 星期五

初試 Microsoft Azure Machine Learning Studio


三個星期前,拿到了 Microsoft Azure Machine Learning Studio 帳號,可以試試 Microsoft 的人工智能有多強。我第一時間想到利用它來預測股票走勢,而當中一個部份可以給用戶載入自編的 Python 程序。於是我問 Microsoft 負責人關於這個平台能否讀進第三方的 Python Package 呢?他說:「沒問題」。於是我便嘗試相關的方法。


看過文件,知道把 Python package 當成 dataset 檔案上傳到 Azure Storage 後,便能在 Machine Learning Studio 內的程序中調用。我依著指示進行,可是卻出現導入問題。想想可能是因為 yahoo_finance 這個 package 中有兩個 .py 檔,而文件範例只有一個;於是手動把它變成一個獨立檔案,然後上傳,然後再次失敗。後來向負責人查證,發現 Machine Learning Studio 是不支援的,只好放棄這個部份,繼續嘗試其他的功能...。

2017年2月9日 星期四

加入微信測試帳號


要測試寫好的 WeChat Bot,可以把 WeChat 帳號加入成為測試帳號。

登入「微信公眾平台」後選「開發者工具」,在右面頁面選「公眾平台測試帳號」後方的「進入」。再用想加入測試帳號的 WeChat 掃瞄畫面上的二維碼,點「關注」。該 WeChat 帳號便能成為測試帳號,從而測試 WeChat Bot 的功能。

2017年2月8日 星期三

認證微信機械人伺服器


要開發 WeChat Bot,需要有微信公眾帳號。就像建立 Facebook Messenger Bot 一樣,在平台內建立應用程式,得到 App ID 及 App Secret;拿著這兩串數值換來兩小時期限的 Access Token;往後的 API 都是用 Access Token 來執行。

每個應用程式都需要一個伺服器用來接收由客戶發出的訊息;就像 Webhook 的方法差不多。所以,第一步得對伺服器做認證工作。根據上圖的要求去做認證。如果運算結果符合時,傳回 echostr 代表。以下是我的認證程式:
<?php
//----------------------------------------------------------------------------------------
//  WeChat Open Platform Test
//  API Token Checking Program
//----------------------------------------------------------------------------------------
//  Platform: Linux + Apache + PHP
//  Written by Pacess HO
//  Copyright 2017 Pacess Studio.  All rights reserved.
//----------------------------------------------------------------------------------------

header("Access-Control-Allow-Origin: https://home.pacess.com");
header("Access-Control-Allow-Methods: POST");

header("Content-type: text/plain");
header("Cache-Control: no-cache, must-revalidate");
header("Expires: Tue, 10 Mar 1987 00:00:00 GMT");

date_default_timezone_set("Asia/Hong_Kong");
mb_internal_encoding("UTF-8");
ini_set("memory_limit", "-1");
set_time_limit(0);

//----------------------------------------------------------------------------------------
//  Defines
define("TOKEN", "sita-chan");

//----------------------------------------------------------------------------------------
//  * Order is important
require("./libraries/wechatAPI.php");

//========================================================================================
//  Main Program
$_interfaceType = php_sapi_name();

//  apache2handler = Browser
//  cli = Terminal
if ($_interfaceType == "cli")  {
   echo("Please run this program with browser...");
   exit(0);
}

//----------------------------------------------------------------------------------------
$wechatAPI = new wechatAPI();
$wechatAPI->valid();
echo("Sorry, validation failed...");

?>
index.php

<?php
//----------------------------------------------------------------------------------------
//  WeChat Open Platform Test
//  WeChat API Test Object
//----------------------------------------------------------------------------------------
//  Platform: Linux + Apache + PHP
//  Written by Pacess HO
//  Copyright 2017 Pacess Studio.  All rights reserved.
//----------------------------------------------------------------------------------------

//========================================================================================
//  Main Program
class wechatAPI  {
      
   //----------------------------------------------------------------------------------------
   private function checkSignature()  {
      if (!defined("TOKEN"))  {throw new Exception('TOKEN is not defined!');}
      
      $signature = $_GET["signature"];
      $timestamp = $_GET["timestamp"];
      $nonce = $_GET["nonce"];
      $token = TOKEN;

      $parameterArray = array($token, $timestamp, $nonce);

      //  Use SORT_STRING rule
      sort($parameterArray, SORT_STRING);
      $string = implode($parameterArray);
      $sha1 = sha1($string);
      
      return ($sha1 == $signature);
   }

   //----------------------------------------------------------------------------------------
   public function valid()  {
      $echoStr = $_GET["echostr"];
      if ($this->checkSignature())  {echo($echoStr);  exit;}
   }
}
?>
wechatAPI.php

認證成功後,便可以正式編寫 WeChat 機械人的程式。

2017年2月7日 星期二

微信 JS 接口簽名校驗工具


千辛萬苦,終於拿到了 WeChat 的公眾帳號。一直想試 WeChat Bot 的開發,無奈沒有國內註冊公司及電話號碼而無法申請。

簡體中文的文件實在難看,於是在網上找來了教學影片跟著學習。發現到有一個叫「微信 JS 接口簽名校驗工具」網頁工具可以讓我針對不同的 API 接口進行測試,十分方便。

2017年2月6日 星期一

把 URL 中的路徑當成參數

今日在開發一個項目上需要盡量把網址縮短。最好的做法是扮成 RESTful 方式。即是把本來網址後面的參數變成路徑的一部份。我用 .htaccess 的 RewriteRule 來處理。
RewriteEngine on

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^/]+)$ index.php?value=$1 [L]

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^/]+)/([^/]+)$ index.php?type=$1&code=$2 [L]
簡單寫了一個 PHP 程式去顯示讀進來的數值:
<?php
//----------------------------------------------------------------------------------------
//  Rewrite Rules DEMO
//----------------------------------------------------------------------------------------
//  Platform: Linux + Apache + PHP
//  Written by Pacess HO
//  Copyright 2017 Pacess Studio.  All rights reserved.
//----------------------------------------------------------------------------------------

header("Access-Control-Allow-Origin: https://home.pacess.com");
header("Access-Control-Allow-Methods: POST");
 
header("Content-type: text/plain");
header("Cache-Control: no-cache, must-revalidate");
header("Expires: Tue, 10 Mar 1987 00:00:00 GMT");
 
date_default_timezone_set("Asia/Hong_Kong");
mb_internal_encoding("UTF-8");
ini_set("memory_limit", "-1");
set_time_limit(0);

//========================================================================================
//  Main Program
$_interfaceType = php_sapi_name();

//  apache2handler = Browser
//  cli = Terminal
if ($_interfaceType == "cli")  {
   echo("Please run this program with browser...");
   exit(0);
}

$requestDump = print_r($_REQUEST, TRUE);
echo($requestDump);

?>