阿里大于是阿里通信旗下产品,融合了三大运营商的通信能力,提供包括短信、语音、流量直充、私密专线、店铺手机号等个性化服务。每条四分五,价钱还算公道,经老农测试,响应速度非常快,基本上是秒到。官方文档提供了JAVA、.NET、PHP、Python、C/C++、NodeJS 等语言的 Demo,唯独没有 Dephi,但这也不能怪马云,毕竟 Delphi 实在太小众了。
最近用 Delphi 写个 App,注册用户需要用到手机短信验证,于是找到的阿里大于,使用 Delphi 10.1 berlin 写了个简单的 Demo 并测试通过,现在交出代码:
/// <author>全能地图(QQ:64445322)</author> /// <summary> /// 利用阿里大于接口发短信 /// 阿里大于网址:http://www.alidayu.com /// 阿里大于短信接口文档:https://api.alidayu.com/doc2/apiDetail.htm?apiId=25450 /// </summary> /// <param name="AppKey">TOP分配给应用的AppKey</param> /// <param name="AppSecret">AppSecret</param> /// <param name="ReceiveNumber">接收手机号码</param> /// <param name="FreeSignName">短信签名,传入的短信签名必须是在阿里大于“管理中心-短信签名管理”中的可用签名</param> /// <param name="TemplateCode">短信模板ID</param> /// <param name="TemplateContent">短信模板变量,例如:{"code":"1234","product":"alidayu"}</param> /// <param name="ResultMsg">下发结果消息</param> /// <returns>是否成功,True = 成功 ,false = 失败</returns> function SendSMS(const AppKey, AppSecret, ReceiveNumber, FreeSignName, TemplateCode, TemplateContent: string; var ResultMsg: string): Boolean; // 签名算法:http://open.taobao.com/doc2/detail.htm?articleId=101617&docType=1&treeId=1 function MakeSign(const AParams: TStringList; const AppSecret: string): string; var I: Integer; Data: string; begin // 参数排序 AParams.Sort; // 参数拼接 Data := \'\'; for I := 0 to AParams.Count - 1 do Data := Data + AParams[I].Replace(\'=\', \'\'); // HMAC 算法 Result := THashMD5.GetHMAC(Data, AppSecret).ToUpper; end; var HTTP: TNetHTTPClient; JO: TJSONObject; Params: TStringList; Response: string; begin Result := False; HTTP := TNetHTTPClient.Create(nil); Params := TStringList.Create(); try Params.Values[\'app_key\'] := AppKey; Params.Values[\'format\'] := \'json\'; Params.Values[\'method\'] := \'alibaba.aliqin.fc.sms.num.send\'; Params.Values[\'sign_method\'] := \'hmac\'; Params.Values[\'timestamp\'] := FormatDateTime(\'yyyy-MM-dd HH:mm:ss\', Now); Params.Values[\'v\'] := \'2.0\'; Params.Values[\'sms_type\'] := \'normal\'; Params.Values[\'sms_free_sign_name\'] := FreeSignName; Params.Values[\'rec_num\'] := ReceiveNumber; Params.Values[\'sms_template_code\'] := TemplateCode; Params.Values[\'sms_param\'] := TemplateContent; Params.Values[\'sign\'] := MakeSign(Params, AppSecret); HTTP.ContentType := \'application/x-www-form-urlencoded\'; try Response := HTTP.Post(\'https://eco.taobao.com/router/rest\', Params).ContentAsString(); except on E: Exception do begin ResultMsg := E.Message; Exit; end; end; JO := TJSONObject.ParseJSONValue(Response) as TJSONObject; try if JO <> nil then begin if JO.TryGetValue<string>(\'alibaba_aliqin_fc_sms_num_send_response.result.success\', ResultMsg) then Result := ResultMsg.ToUpper = \'TRUE\' else if JO.TryGetValue<string>(\'error_response.msg\', ResultMsg) then Result := False; end; finally JO.Free; end; finally HTTP.Free; Params.Free; end; end;
D7的版本
function SendSMS(const AppKey, AppSecret, ReceiveNumber, FreeSignName, TemplateCode, TemplateContent: string; var ResultMsg: string): Boolean; function GetStringMD5(const AInPut: string): string; var MD5: TIdHashMessageDigest5; Digest: T4x4LongWordRecord; begin MD5 := TIdHashMessageDigest5.Create; try Digest := MD5.HashValue(AInPut); Result := MD5.AsHex(Digest); finally MD5.Free; end; end; // 签名算法:http://open.taobao.com/doc2/detail.htm?articleId=101617&docType=1&treeId=1 function MakeSign(const AParams: TStringList; const AppSecret: string): string; var I: Integer; Data: string; begin // 参数排序 AParams.Sort; // 参数拼接 Data := \'\'; for I := 0 to AParams.Count - 1 do Data := Data + StringReplace(AParams[I], \'=\', \'\', [rfReplaceAll]); // MD5 算法 Result := GetStringMD5(AppSecret + Data + AppSecret); end; var HTTP: TIdHTTP; Params: TStringList; Response: string; JsonObject: ISuperObject; begin Result := False; HTTP := TIdHTTP.Create(nil); Params := TStringList.Create(); try Params.Values[\'app_key\'] := AppKey; Params.Values[\'format\'] := \'json\'; Params.Values[\'method\'] := \'alibaba.aliqin.fc.sms.num.send\'; Params.Values[\'sign_method\'] := \'md5\'; Params.Values[\'timestamp\'] := FormatDateTime(\'yyyy-MM-dd HH:mm:ss\', Now); Params.Values[\'v\'] := \'2.0\'; Params.Values[\'sms_type\'] := \'normal\'; Params.Values[\'sms_free_sign_name\'] := UTF8Encode(FreeSignName); Params.Values[\'rec_num\'] := ReceiveNumber; Params.Values[\'sms_template_code\'] := TemplateCode; Params.Values[\'sms_param\'] := UTF8Encode(TemplateContent); Params.Values[\'sign\'] := MakeSign(Params, AppSecret); HTTP.HandleRedirects := True; HTTP.Request.AcceptCharSet := \'utf-8\'; HTTP.Request.ContentType := \'application/x-www-form-urlencoded\'; try Response := HTTP.Post(\'http://gw.api.taobao.com/router/rest\', Params); except on E: Exception do begin ResultMsg := E.Message; Exit; end; end; JsonObject := SO(Response); if JsonObject <> nil then begin ResultMsg := JsonObject.S[\'alibaba_aliqin_fc_sms_num_send_response.result.success\']; if ResultMsg <> \'\' then Result := UpperCase(ResultMsg) = \'TRUE\' else begin ResultMsg := JsonObject.S[\'error_response.msg\']; Result := False; end; end; finally HTTP.Free; Params.Free; end; end;