diff --git a/ArasKargoAPI.sln b/ArasKargoAPI.sln new file mode 100644 index 0000000..95c7ca6 --- /dev/null +++ b/ArasKargoAPI.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.5.33424.131 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ArasKargoAPI", "src/ArasKargoAPI.csproj", "{CCB965D9-276E-429C-ACDD-17EC69F3FE4B}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {CCB965D9-276E-429C-ACDD-17EC69F3FE4B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {CCB965D9-276E-429C-ACDD-17EC69F3FE4B}.Debug|Any CPU.Build.0 = Debug|Any CPU + {CCB965D9-276E-429C-ACDD-17EC69F3FE4B}.Release|Any CPU.ActiveCfg = Release|Any CPU + {CCB965D9-276E-429C-ACDD-17EC69F3FE4B}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {45CB2A26-4E18-4896-B4D3-96FF70B4FFBA} + EndGlobalSection +EndGlobal diff --git a/readme.md b/readme.md new file mode 100644 index 0000000..e9c8422 --- /dev/null +++ b/readme.md @@ -0,0 +1,39 @@ +## ArasKargoAPI +Aras Kargo gönderi ve teslimat bilgilerini çekmek için ihtiyacın olan tek library. + +### Özellikler +- Hızlı, class bazlı bir yapı. +- Gönderi ve teslimat bilgilerini çekme. + +### Kullanım +```csharp + +var aras = new ArasKargoClient("TAKIPNO"); +var sonuc = aras.Al(); + +// Kargo İşlemleri (teslim alındı, dağıtıma çıktı vb.) +sonuc.Islemler.ForEach(x => +{ + Console.WriteLine($"{x.Aciklama} - {x.Tarih}"); +}); + +// Çıkış: +ÇIKIŞ ŞUBESİNDE; Kargonuz çıkış şubesinden transfer merkezine gönderilmek üzere aracımıza yüklenmiştir. - 21.07.2023 12:23:21 +YOLDA; Kargonuz çıkış transfer merkezinden varış transfer merkezine gönderiliyor. - 21.07.2023 21:01:58 +YOLDA; Kargonuz çıkış transfer merkezinden varış transfer merkezine gönderiliyor. - 21.07.2023 21:05:00 +YOLDA; Kargonuz çıkış transfer merkezinden varış transfer merkezine gönderiliyor. - 21.07.2023 21:54:00 +TESLİMAT ŞUBESİNDE; Kargonuz transfer merkezimizden teslimat şubemize ulaşmıştır. - 24.07.2023 20:41:53 + +// sonuc.Gonderi ile gönderi bilgilerini (alici şube, alici isim, şube bilgileri, desi vb.) çekebilirsiniz + + +``` + +### Notlar + +- Newtonsoft-Json paketini indirmeniz gerekebilir. +- Kodlar içindeki captcha code her 2 haftada bir expire yiyor. Eğer **gönderi alınamadı** hatası alıyorsanız captcha kodunu güncellemeniz gerekebilir. +- Dil seçeneği ingilizce ve türkçe olarak değiştirebilir. + +### Lisans +MIT \ No newline at end of file diff --git a/src/ArasKargoAPI.csproj b/src/ArasKargoAPI.csproj new file mode 100644 index 0000000..b21d398 --- /dev/null +++ b/src/ArasKargoAPI.csproj @@ -0,0 +1,60 @@ + + + + + Debug + AnyCPU + {CCB965D9-276E-429C-ACDD-17EC69F3FE4B} + Library + Properties + ArasKargoAPI + ArasKargoAPI + v4.8 + 512 + true + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + + + + packages\Newtonsoft.Json.13.0.3\lib\net45\Newtonsoft.Json.dll + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/ArasKargoClient.cs b/src/ArasKargoClient.cs new file mode 100644 index 0000000..bd4f028 --- /dev/null +++ b/src/ArasKargoClient.cs @@ -0,0 +1,135 @@ +using System; +using System.ComponentModel; +using System.Linq; +using System.Net.Http; +using System.Text; +using Newtonsoft.Json; + +namespace ArasKargoAPI +{ + public class ArasKargoClient + { + + public enum Dil + { + [Description("Türkçe")] + tr, + [Description("English")] + en + } + + private static string _takip_kodu; + private static Dil _dil; + + /// + /// Client'i hazırlar. + /// + /// Kargo takip kodu. + public ArasKargoClient(string TakipKodu, Dil dil = Dil.tr) + { + _takip_kodu = TakipKodu; + _dil = dil; + } + + /// + /// Kargo bilgilerini alır. + /// + /// Kargo bilgileri. + public KargoBilgileri Al() + { + + if (_takip_kodu == null) + { + throw new Exception("Önce client'i hazırlamalısın!"); + } + + #region HTTP + + var hClient = new HttpClient(); + var data = "{\r\n \"TrackingNumber\": \"" + _takip_kodu + "\",\r\n \"LanguageCode\": \"" + _dil + "\"\r\n}"; + var contentPost = new StringContent(data, Encoding.UTF8, "application/json"); + var response = hClient.PostAsync("https://kurumsalwebservice.araskargo.com.tr/api/getCargoTransactionByTrackingNumber", contentPost).Result; + var content = response.Content.ReadAsStringAsync().Result; + + #endregion + + #region Json Parsing + + ArasResponse aras; + try + { + aras = JsonConvert.DeserializeObject(content, new JsonSerializerSettings() + { + NullValueHandling = NullValueHandling.Ignore, + DefaultValueHandling = DefaultValueHandling.Ignore, + MissingMemberHandling = MissingMemberHandling.Ignore, + }); + } + catch (Exception e) + { + throw e; + } + + // 200 değil? Hata var demektir. + if (aras.Code != 200) + { + throw new Exception(aras.Message); + } + + #endregion + + #region Haritalama + + var cikis = new KargoBilgileri + { + Islemler = aras.Responses + }; + + #endregion + + #region Gönderici / Alıcı / Kaynak bilgilerini alma + + // Bu iki değişken captcha görevi görüyor olmadan alamıyoruz. + // Ne zeman expire yiyor? bende bilmiyorum aslında. + // Expire yiyene kadar bunları kullanmaya devam. + // Unique ID ile matchlenmiş bi kod olabilir. + // Edit: 2 haftada bir expire yiyor. + const string captcha_code = "n159sc"; + const string uniq_id = "6258ed31-a70e-493a-a41e-54e98d457f14"; + + var postData2 = "{\"TrackingNumber\":\"" + _takip_kodu + "\",\"IsWeb\":true,\"UniqueCode\":\"" + uniq_id + "\",\"SecretKey\":\"" + captcha_code + "\",\"LanguageCode\":\"" + _dil + "\"}"; + var contentPost2 = new StringContent(postData2, Encoding.UTF8, "application/json"); + var response2 = hClient.PostAsync("https://kurumsalwebservice.araskargo.com.tr/api/getShipmentByTrackingNumber", contentPost2).Result; + var content2 = response2.Content.ReadAsStringAsync().Result; + + var c2Dynamic = JsonConvert.DeserializeObject(content2); + dynamic kBilgileriNodeFirst = null; + + try + { + kBilgileriNodeFirst = Convert.ToString(c2Dynamic.Responses.First); + var gonderiBilgileri = JsonConvert.DeserializeObject(kBilgileriNodeFirst, new JsonSerializerSettings() + { + NullValueHandling = NullValueHandling.Ignore, + Error = delegate (object aq, Newtonsoft.Json.Serialization.ErrorEventArgs args) + { + args.ErrorContext.Handled = true; + } + }); + cikis.Gonderi = gonderiBilgileri; + } + catch (Exception e) + { + throw new Exception("Gönderi bilgileri alınamadı. +" + e.Message); + } + + + #endregion + + return cikis; + + } + + + } +} \ No newline at end of file diff --git a/src/ArasResponse.cs b/src/ArasResponse.cs new file mode 100644 index 0000000..575c89d --- /dev/null +++ b/src/ArasResponse.cs @@ -0,0 +1,123 @@ +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ArasKargoAPI +{ + + internal class ArasResponse + { + [JsonProperty("Code")] + public int Code { get; set; } + + [JsonProperty("Message")] + public string Message { get; set; } + + [JsonProperty("Responses")] + public List Responses { get; set; } + + [JsonProperty("ContactInfo")] + public string ContactInfo { get; set; } + } + + + public class KargoIslem + { + [JsonConverter(typeof(DateTimeConverter))] + [JsonProperty("TransactionDate")] + public DateTime? Tarih { get; set; } + + [JsonProperty("UnitName")] + public string Bolge { get; set; } + + [JsonProperty("ShipmentLineTransType")] + public string Tur { get; set; } + + [JsonProperty("Description")] + public string Aciklama { get; set; } + } + + public class GonderiBilgileri + { + [JsonProperty("TrackingNumber")] + public string TakipNo { get; set; } + + [JsonProperty("DocumentSerial")] + public string DokumenSeriNo { get; set; } + + [JsonProperty("DocumentNumber")] + public string DokumanNumarasi { get; set; } + + [JsonConverter(typeof(DateTimeConverter))] + [JsonProperty("WaybillDate")] + public DateTime GonderiTarihi { get; set; } + + [JsonProperty("SenderAccountAddressName")] + public string GondericiIsim { get; set; } + + [JsonProperty("ReceiverAccountAddressName")] + public string AliciIsim { get; set; } + + [JsonProperty("TotalVolume")] + public string Desi { get; set; } + + [JsonProperty("PieceCount")] + public string Adet { get; set; } + + [JsonProperty("LovShipmentStatusId")] + public string LovShipmentStatusId { get; set; } + + [JsonProperty("LovShipmentStatusName")] + public string SonDurum { get; set; } + + [JsonProperty("SourceUnitName")] + public string CikisSubesi { get; set; } + + [JsonProperty("DeliveryUnitName")] + public string VarisSubesi { get; set; } + + [JsonConverter(typeof(DateTimeConverter))] + [JsonProperty("PlannedDeliveryDate")] + public DateTime TahminiTeslimTarihi { get; set; } + + [JsonProperty("LovPayorTypeName")] + public string OdemeTuru { get; set; } + + [JsonProperty("LovPackTypeName")] + public string PaketTuru { get; set; } + + [JsonProperty("SourceCity")] + public string CikisIl { get; set; } + + [JsonProperty("DeliveryCity")] + public string VarisIl { get; set; } + + [JsonProperty("SourceTown")] + public string CikisIlce { get; set; } + + [JsonProperty("DeliveryTown")] + public string VarisIlce { get; set; } + + [JsonProperty("LovShipmentTypeName")] + public string GonderimTuru { get; set; } + } + + public class KargoBilgileri + { + + /// + /// Kargo işlemleri (işlem tarihleri, gönderi durumları vb.) + /// + public List Islemler { get; set; } + + /// + /// Kargo bilgileri (gönderici, alıcı, kargo türü vb.) + /// + public GonderiBilgileri Gonderi { get; set; } + + } + +} diff --git a/src/DateTimeConverter.cs b/src/DateTimeConverter.cs new file mode 100644 index 0000000..43919b5 --- /dev/null +++ b/src/DateTimeConverter.cs @@ -0,0 +1,35 @@ +using System; +using System.Globalization; +using System.Linq; +using Newtonsoft.Json; + +namespace ArasKargoAPI +{ + public class DateTimeConverter : JsonConverter + { + private readonly string format = "dd.MM.yyyy HH:mm:ss"; + + public override DateTime? ReadJson(JsonReader reader, Type objectType, DateTime? existingValue, bool hasExistingValue, JsonSerializer serializer) + { + if (reader.TokenType == JsonToken.Null) + return null; + + if (reader.TokenType == JsonToken.String && reader.Value is string dateStr) + { + if (DateTime.TryParseExact(dateStr, format, CultureInfo.InvariantCulture, DateTimeStyles.None, out DateTime parsedDate)) + return parsedDate; + } + + // handle + return null; + } + + public override void WriteJson(JsonWriter writer, DateTime? value, JsonSerializer serializer) + { + if (value.HasValue) + writer.WriteValue(value.Value.ToString(format)); + else + writer.WriteNull(); + } + } +} \ No newline at end of file diff --git a/src/Properties/AssemblyInfo.cs b/src/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..ce5fdba --- /dev/null +++ b/src/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("ArasKargoAPI")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("ArasKargoAPI")] +[assembly: AssemblyCopyright("Copyright © 2023")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("ccb965d9-276e-429c-acdd-17ec69f3fe4b")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/src/packages.config b/src/packages.config new file mode 100644 index 0000000..0b14af3 --- /dev/null +++ b/src/packages.config @@ -0,0 +1,4 @@ + + + + \ No newline at end of file