[C#.NET][SMS] 使用 Every8D Web Service API 2.1 發送簡訊
官網:https://tw.every8d.com/every8d30/index.aspx
要使用人家的API第一步就是找到文件,個人覺得這網站的操作不是那麼的便利,功能找好久。
點選API介接:
找到API系統介接
按下下載文件
最後來到了下載頁面,https://tw.every8d.com/every8d30/introduction/download.aspx
或是在首頁直接連到文件下載處,直接來到文件下載處(帖子都寫好了才看=.=!!!)
把這些文件都抓下來看。
先針對 企業簡訊應用:API 2.1立即上手 來調查使用,當然開始前你必須要先有帳號跟密碼,去申請一個吧
開始前,加入Web Service http://api.every8d.com/API21/SOAP/SMS.asmx
簡單來講就是要你的帳號跟密碼,getConnection 方法會回傳以下XML內容,連線建立起來後才會得到Session Key,有了它才能進行發簡訊的動作。
既然是Xml,我們就依照文件,定義Entity Class,準備用反序列化處理它,不知怎麼使用反序列化的捧油請參考以下:
[XML][C#.NET] 處理 ezTRACK 的 EPCIS Xml文件
[XML][C#.NET] 忽略XML宣告及XML命名空間
[Serializable, XmlRoot("SMS")]
public class ConnectionResponse
{
[XmlElement("GET_CONNECTION")]
public ConnectionSession Session { get; set; }
public override string ToString()
{
return string.Format("{0},{1}", Session.Code, Session.Description);
}
}
[Serializable, XmlRoot("GET_CONNECTION")]
public class ConnectionSession
{
[XmlElement("CODE")]
public string Code { get; set; }
[XmlElement("SESSION_KEY")]
public string SessionKey { get; set; }
[XmlElement("DESCRIPTION")]
public string Description { get; set; }
public override string ToString()
{
return string.Format("{0}", SessionKey);
}
}
登入參數類別
/// 登入參數
/// <summary>
/// 登入參數
/// </summary>
public class ConnectionRequest
{
private string _CustID = "av8d20";
public string CustID
{
get { return _CustID; }
set { _CustID = value; }
}
public string UserID { get; set; }
public string Password { get; set; }
}
類別建構子
#region fields
SMS _sms = new SMS();
DeSerialization _deSerial = new DeSerialization();
#endregion fields
private string _SessionKey;
public string SessionKey
{
get { return _SessionKey; }
private set
{
_SessionKey = value;
}}
private ConnectionRequest _ConnectionRequest;
public ConnectionRequest ConnectionRequest
{
get { return _ConnectionRequest; }
set { _ConnectionRequest = value; }
}
public MessageFactory(ConnectionRequest ConnectionRequest)
{
if (ConnectionRequest == null)
{
throw new ArgumentNullException("ConnectionRequest");
}
this.ConnectionRequest = ConnectionRequest;
}
登入的方法我這樣寫:
/// 登入
/// <summary>
/// 登入
/// </summary>
/// <returns></returns>
public string Login()
{
string data = this._sms.getConnection(this.ConnectionRequest.UserID, this.ConnectionRequest.Password);
if (string.IsNullOrEmpty(data))
{
return string.Empty;
}
ConnectionResponse sms = this._deSerial.FromXmlString<ConnectionResponse>(data);
this.SessionKey = sms.Session.SessionKey;
return this.SessionKey;
}
在單元測試這樣寫:
設中斷觀察,確定能被正確的反序列化。
登入成功後,拿著Session Key就可以發簡訊了,
時間在這裡有特殊的格式,
所以我為它們定義了格式
internal class globalParameter
{
public readonly static string SendMessageTimeFormat = "yyyyMMddHHmmss";
public readonly static string GetReportTimeFormat = "yyyyMMdd";
}
似乎很多人都喜歡用逗點隔開當訊息,但這樣相當的醜,字串就算被分割得到了陣列,還要查文件才知道哪個索引擺了誰,寫程式已經很累了,還要到處翻文件。
不如就回傳類別吧,用來接收簡訊發送結果
[Serializable]
public class SentMessageResponse
{
public string Credit { get; set; }
public string Sended { get; set; }
public string Cost { get; set; }
public string Unsend { get; set; }
public string BatchID { get; set; }
}
傳簡訊的參數也把它給定義好
/// 簡訊傳送參數
/// <summary>
/// 簡訊傳送參數
/// </summary>
public class SendMessageRequest
{
public string Subject { get; set; }
public string Content { get; set; }
public DateTime? SendTime { get; set; }
private List<Mobile> _Mobiles = null;
public List<Mobile> Mobiles
{
get
{
if (_Mobiles == null)
{
_Mobiles = new List<Mobile>();
}
return _Mobiles;
}
set { _Mobiles = value; }
}
}
別忘了處理手機簡訊的格式!
/// 手機簡訊格式
/// <summary>
/// 手機簡訊格式
/// </summary>
public class Mobile
{
private CountryCodeTable _Country = CountryCodeTable.Taiwan;
public CountryCodeTable Country
{
get { return _Country; }
set
{
_Country = value;
}
}
private string _Number;
public string Number
{
get
{
if (string.IsNullOrEmpty(_Number))
{
throw new ArgumentNullException();
}
if (!_Number.IsAllNumber())
{
throw new NotSupportedException();
}
return _Number;
}
set
{
if (string.IsNullOrEmpty(value))
{
throw new ArgumentNullException();
}
if (!value.IsAllNumber())
{
throw new NotSupportedException();
}
_Number = value;
}
}
public string FullCellPhone
{
get { return string.Format("+{0}{1}", (int)this.Country, this.Number); }
}
}
/// <summary>
/// 國碼
/// </summary>
public enum CountryCodeTable
{
//亞洲
/// <summary>
/// 台灣
/// </summary>
Taiwan = 886,
/// <summary>
/// 中國
/// </summary>
China = 86,
/// <summary>
/// 香港
/// </summary>
HongKong = 852,
}
於是發送簡訊的程式碼如下:
/// 送簡訊
/// <summary>
/// 送簡訊
/// </summary>
/// <param name="Config"></param>
/// <returns></returns>
public SentMessageResponse Send(SendMessageRequest Config)
{
if (string.IsNullOrEmpty(this.SessionKey))
{
throw new ArgumentNullException("SessionKey");
}
SentMessageResponse response = null;
StringBuilder mobiles = null;
foreach (var item in Config.Mobiles)
{
if (mobiles == null)
{
mobiles = new StringBuilder();
mobiles.Append(string.Format("{0}", item.FullCellPhone));
}
else
{
mobiles.Append(string.Format(",{0}", item.FullCellPhone));
}
}
string status = null;
if (Config.SendTime == null)
{
status = this._sms.sendSMS(this.SessionKey, Config.Subject, Config.Content, mobiles.ToString(), "");
}
else if (Config.SendTime != null)
{
string time = ((DateTime)Config.SendTime).ToString(globalParameter.SendMessageTimeFormat);
status = this._sms.sendSMS(this.SessionKey, Config.Subject, Config.Content, mobiles.ToString(), time);
}
if (string.IsNullOrEmpty(status))
{
return response;
}
else
{
string[] split = status.Split(',');
response = new SentMessageResponse()
{
Credit = split[0],
Sended = split[1],
Cost = split[2],
Unsend = split[3],
BatchID = split[4],
};
return response;
}
}
單元測試撰寫如下:
PS.電話號碼就算不存在,也是會扣點數的唷
PS.Session Key錯誤則會產生以下訊息,這表示陣列數量變了,這很典型,開發者為了求快,而苦了後面的人。
Every8d還有一個不錯的功能,當你發送簡訊後,對方可以回覆簡訊,這簡訊會存在Every8d的Server裡,同樣透過Web Service取得
使用getDeliveryStatus所回傳的Xml資料
依照Xml文件,定義Entiry 類別,我用它來接收查詢結果
[Serializable, XmlRoot("SMS_LOG")]
public class DeliveryLogResponse
{
[XmlElement("CODE")]
public string Code { get; set; }
[XmlElement("DESCRIPTION")]
public string Description { get; set; }
[XmlElement("GET_DELIVERY_STATUS")]
public DeliveryStatus Status { get; set; }
public override string ToString()
{
return string.Format("Description:{0}", Description);
}
}
[Serializable, XmlRoot("GET_DELIVERY_STATUS")]
public class DeliveryStatus
{
[XmlAttribute("COUNT")]
public int Count { get; set; }
[XmlElement("SMS")]
public List<DeliverySendMessage> SentMessages { get; set; }
public override string ToString()
{
return string.Format("Count:{0}", Count);
}
}
[Serializable, XmlRoot("SMS")]
public class DeliverySendMessage
{
[XmlElement("NAME")]
public string Name { get; set; }
[XmlElement("MOBILE")]
public string Mobile { get; set; }
[XmlElement("SENT_TIME")]
public string SentTime { get; set; }
[XmlElement("COST")]
public string Cost { get; set; }
[XmlElement("STATUS")]
public string Status { get; set; }
[XmlElement("REPLY_SMS")]
public List<DeliveryReplyMessage> ReplyMessages { get; set; }
public override string ToString()
{
return string.Format("SentTime:{0},Mobile:{1}", SentTime, Mobile.Trim());
}
}
[Serializable, XmlRoot("REPLY_SMS")]
public class DeliveryReplyMessage
{
[XmlElement("REPLY_TIME")]
public string ReplyTime { get; set; }
[XmlElement("MESSAGE")]
public string ReplyMessage { get; set; }
public override string ToString()
{
return string.Format("ReplyTime:{0},ReplyMessage:{1}", ReplyTime, ReplyMessage);
}
}
定義查詢類別:
/// 簡訊回覆狀態查詢
/// <summary>
/// 簡訊回覆狀態查詢
/// </summary>
public class MessageDeliveryRequest
{
public string BatchID { get; set; }
public string PageNo { get; set; }
}
查詢發送需要BatchID,當你發送一則成功的簡訊後會得到,往上滾動查看sendSMS所回傳的內容吧
/// 查詢發送狀態
/// <summary>
/// 查詢發送狀態
/// </summary>
/// <param name="Config"></param>
/// <returns></returns>
public DeliveryLogResponse GetDeliveryStatus(MessageDeliveryRequest Request)
{
if (string.IsNullOrEmpty(this.SessionKey))
{
throw new ArgumentNullException("SessionKey");
}
string status = this._sms.getDeliveryStatus(this.SessionKey, Request.BatchID, Request.PageNo);
if (string.IsNullOrEmpty(status))
{
return null;
}
else
{
DeliveryLogResponse response = this._deSerial.FromXmlString<DeliveryLogResponse>(status);
return response;
}
}
測試程式這樣寫
中斷觀察反序列化結果,果然很順利的得到我要的結果:
若有謬誤,煩請告知,新手發帖請多包涵
Microsoft MVP Award 2010~2017 C# 第四季
Microsoft MVP Award 2018~2022 .NET