發短訊API

  • 2019 年 10 月 11 日
  • 筆記

由於需要進行短訊發送,選擇了百度的API,現貢獻一下源碼。

     /// <summary>      /// 百度接口簽名幫助類      /// </summary>      public class BaiduApiHelper      {          #region 構造函數            /// <summary>          /// 構造函數          /// </summary>          /// <param name="accessKeyId">百度AccessKeyId(AK)</param>          /// <param name="secretAccessKey">百度SecretAccessKey(SK)</param>          public BaiduApiHelper(string accessKeyId, string secretAccessKey)          {              _accessKeyId = accessKeyId;              _secretAccessKey = secretAccessKey;          }            #endregion            #region 內部成員            private string _accessKeyId { get; }          private string _secretAccessKey { get; }          private string UriEncode(string input, bool encodeSlash = false)          {              StringBuilder builder = new StringBuilder();              foreach (byte b in Encoding.UTF8.GetBytes(input))              {                  if ((b >= 'a' && b <= 'z') || (b >= 'A' && b <= 'Z') || (b >= '0' && b <= '9') || b == '_' || b == '-' || b == '~' || b == '.')                  {                      builder.Append((char)b);                  }                  else if (b == '/')                  {                      if (encodeSlash)                      {                          builder.Append("%2F");                      }                      else                      {                          builder.Append((char)b);                      }                  }                  else                  {                      builder.Append('%').Append(b.ToString("X2"));                  }              }              return builder.ToString();          }          private string Hex(byte[] data)          {              var sb = new StringBuilder();              foreach (var b in data)              {                  sb.Append(b.ToString("x2"));              }              return sb.ToString();          }          private string CanonicalRequest(HttpWebRequest req)          {              Uri uri = req.RequestUri;              StringBuilder canonicalReq = new StringBuilder();              canonicalReq.Append(req.Method).Append("n").Append(UriEncode(Uri.UnescapeDataString(uri.AbsolutePath))).Append("n");                var parameters = HttpUtility.ParseQueryString(uri.Query);              List<string> parameterStrings = new List<string>();              foreach (KeyValuePair<string, string> entry in parameters)              {                  parameterStrings.Add(UriEncode(entry.Key) + '=' + UriEncode(entry.Value));              }              parameterStrings.Sort();              canonicalReq.Append(string.Join("&", parameterStrings.ToArray())).Append("n");                string host = uri.Host;              if (!(uri.Scheme == "https" && uri.Port == 443) && !(uri.Scheme == "http" && uri.Port == 80))              {                  host += ":" + uri.Port;              }              canonicalReq.Append("host:" + UriEncode(host));              return canonicalReq.ToString();          }            #endregion            #region 外部接口            /// <summary>          /// 發送POST請求          /// </summary>          /// <param name="method">請求方法,需要大寫,列如(POST)</param>          /// <param name="host">主機地址列如(http://sms.bj.baidubce.com)</param>          /// <param name="url">接口地址列如(/bce/v2/message)</param>          /// <param name="paramters">參數列表</param>          /// <returns></returns>          public string RequestData(string method, string host, string url, Dictionary<string, object> paramters = null)          {              string ak = _accessKeyId;              string sk = _secretAccessKey;              DateTime now = DateTime.Now;              int expirationInSeconds = 1200;                HttpWebRequest req = WebRequest.Create(host + url) as HttpWebRequest;              Uri uri = req.RequestUri;              req.Method = method;              req.ContentType = "application/json";                if (paramters != null)              {                  Stream requestStream = req.GetRequestStream();                  byte[] data = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(paramters));                  requestStream.Write(data, 0, data.Length);              }                string signDate = now.ToUniversalTime().ToString("yyyy'-'MM'-'dd'T'HH':'mm':'ssK");              string authString = "bce-auth-v1/" + ak + "/" + signDate + "/" + expirationInSeconds;              string signingKey = Hex(new HMACSHA256(Encoding.UTF8.GetBytes(sk)).ComputeHash(Encoding.UTF8.GetBytes(authString)));                string canonicalRequestString = CanonicalRequest(req);                string signature = Hex(new HMACSHA256(Encoding.UTF8.GetBytes(signingKey)).ComputeHash(Encoding.UTF8.GetBytes(canonicalRequestString)));              string authorization = authString + "/host/" + signature;                req.Headers.Add("x-bce-date", signDate);              req.Headers.Add(HttpRequestHeader.Authorization, authorization);                HttpWebResponse res;              string message = "";              try              {                  res = req.GetResponse() as HttpWebResponse;              }              catch (WebException e)              {                  res = e.Response as HttpWebResponse;              }              message = new StreamReader(res.GetResponseStream()).ReadToEnd();                return message;          }            /// <summary>          /// 發送短訊          /// </summary>          /// <param name="phoneNum">手機號碼</param>          /// <param name="code">驗證碼</param>          /// <returns></returns>          public static bool SendMsg(string phoneNum, string code)          {              try              {                  BaiduApiHelper baiduApiHelper = new BaiduApiHelper("8888", "8888");                    string host = "http://sms.bj.baidubce.com";                  string url = "/bce/v2/message";                  Dictionary<string, object> paramters = new Dictionary<string, object>();                  paramters.Add("invokeId", "Vhn0B-vCXn-8888");                  paramters.Add("phoneNumber", phoneNum);                  paramters.Add("templateCode", "smsTpl:e747612888e9018888");                  paramters.Add("contentVar", new { code = code });                    string resJsonStr = baiduApiHelper.RequestData("POST", host, url, paramters);                  var resJson = JsonConvert.DeserializeObject<JObject>(resJsonStr);                    return resJson["code"]?.ToString() == "1000";              }              catch              {                  return false;              }          }            #endregion      }