زحمت می کشید
البته یه راه حل هم تولید کد در برنامه و ارسال اون فارغ از این امکان می باشه. و البته به جهت یادگیری روش ارزش کار روی اون هست
Printable View
زحمت می کشید
البته یه راه حل هم تولید کد در برنامه و ارسال اون فارغ از این امکان می باشه. و البته به جهت یادگیری روش ارزش کار روی اون هست
سلام وقت به خیر
ضمن تشکر از ابراز محبت شما در کمک به تکمیل کدهای بخش پیامک برنامه دو مورد وجود دارد که هنوز حل نشده باقی مانده است:
1- درخواست راهنمایی جهت تکمیل دستورات مربوط به گرفتن مانده اعتبار سامانه پیامکی. البته با روش شما این بخش را نوشته ام اما دستور دریافت اعتبار را نتوانستم
2- مورد دوم مربوط به خواندن پیامهای صندوق دریافتی و ارسالی در سامانه می باشد. آدرس وب سرویس http://sms.parsgreen.ir/Api/MsgService.asmx می باشد.
Public Const GetCreditXml = "<?xml version=1.0' encoding='utf-8'?>" & _
"<soap12:Envelope xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xmlns:xsd='http://www.w3.org/2001/XMLSchema' xmlns:soap12='http://www.w3.org/2003/05/soap-envelope'>" & _
"<soap12:Body>" & _
"<GetCredit xmlns='http://ParsGreen.com/'>" & _
"<signature>@SGN</signature>" & _
"</GetCredit>" & _
"</soap12:Body>" & _
"</soap12:Envelope>"
Public Type GetCreditResponse
GetCreditResult As Double
http_status As Integer
http_status_text As String
End Type
البته در برنامه نوشته شده با VB.NET دیتاست بازگردانده شده در دیتاگرید ریخته می شود. اما در اکسس سردر نیاوردم چه باید کرد.
3- در مورد رمز یکبار مصرف البته از یک روش ابتکاری ارسال سریال تولیدی به تعداد ارقام مشخص استفاده کردم. اما روش برنامه پیشنهادی خود سایت برام لاینحل باقی مونده. البته فعلا نیازی به اون ندارم
سلام و روز خوش
عجالتا یک signature و سه-چهار تا شماره موبایل ایمیل کنین.
سلام خداقوت
ارسال کردم
1- مانده اعتبار: این بمراتب خیلی ساده تر از موارد قبلی است!
فقط یک signature ارسال میکنید و response هم فقط یک مقدار برمیگردونه که با توجه به کدهای قبلی خیلی راحت پیاده میشه.
فکر کنم مشکل شما در کدنویسی نیست، بلکه در کار با داکیومنت های xml است.
اگر بخواهید بر همین مبنا پیش برین (یعنی استفاده از اکسس به جای برنامه دسکتاپ برای ارسال و دریافت) بدون تسلط به xml و ... کارتون خیلی سخت میشه.
شما میتونین دیتابیس رو همین اکسس نگه دارین، ولی اگر یک برنامه با vb.net بنویسین پیاده سازی هر متد فقط چند دقیقه زمان میبره بدون این که درگیر ساختار request و response بشین.
گذشته از این، نگهداری و توسعه کدها هم بسیار ساده تر و سریعتر هست.
با این وجود، تا زمانی که امکانش باشه، از راهنمایی و نمونه کد دریغ نمیکنم.
مثل قبل برای ساخت request و تفسیر response از خود مستندات متد getcredit وب سرویس کمک میگیریم:
https://login.parsgreen.com/api/Prof...x?op=GetCredit
REQUESTPOST /api/ProfileService.asmx HTTP/1.1
Host: login.parsgreen.com
Content-Type: application/soap+xml; charset=utf-8
Content-Length: length
<?xml version="1.0" encoding="utf-8"?>
<soap12:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap12="http://www.w3.org/2003/05/soap-envelope">
<soap12:Body>
<GetCredit xmlns="http://ParsGreen.com/">
<signature>string</signature>
</GetCredit>
</soap12:Body>
</soap12:Envelope>
RESPONSE
HTTP/1.1 200 OK
Content-Type: application/soap+xml; charset=utf-8
Content-Length: length
<?xml version="1.0" encoding="utf-8"?>
<soap12:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap12="http://www.w3.org/2003/05/soap-envelope">
<soap12:Body>
<GetCreditResponse xmlns="http://ParsGreen.com/">
<GetCreditResult>double</GetCreditResult>
</GetCreditResponse>
</soap12:Body>
</soap12:Envelope>
Option Compare Database
Option Explicit
Private Const WSURL = "https://login.parsgreen.com/Api/ProfileService.asmx"
Private Const Signature = "..."
Private Const XM = "<?xml version='1.0' encoding='utf-8'?>" & _
"<soap12:Envelope xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' " & _
"xmlns:xsd='http://www.w3.org/2001/XMLSchema' " & _
"xmlns:soap12='http://www.w3.org/2003/05/soap-envelope'>" & _
"<soap12:Body>" & _
"<GetCredit xmlns='http://ParsGreen.com/'>" & _
"<signature>@SGN</signature>" & _
"</GetCredit>" & _
"</soap12:Body>" & _
"</soap12:Envelope>"
Public Type GetCreditResponse
GetCreditResult As Double
http_status As Integer
http_status_text As String
End Type
Public Function GetCredit() As GetCreditResponse
Dim X As String
X = Replace(XM, "@SGN", Signature)
With New XMLHTTP60
.Open "POST", WSURL, False
.setRequestHeader "HOST", "login.parsgreen.com"
.setRequestHeader "CONTENT-TYPE", "application/soap+xml; charset=utf-8"
.Send X
GetCredit.http_status = .Status
GetCredit.http_status_text = .statusText
If .Status = 200 Then
Dim Doc As New DOMDocument60
Doc.SetProperty "SelectionNamespaces", "xmlns:pg='http://ParsGreen.com/'"
Doc.loadXML .responseText
GetCredit.GetCreditResult = Doc.selectSingleNode("//pg:GetCreditResult").Text
End If
End With
End Function
روش استفاده:
ضمیمه 153281
2- خواندن پیامهای صندوق دریافتی و ارسالی:
ساختار response در این متد شامل schema برای تعریف فیلدهای یک دیتاست هست، بنابراین لازم هست با این مبحث هم آشنا باشین.
سر فرصت میخونم مستندات رو و راهنمایی میکنم.
سلام استاد
بسیار عالی پاسخ میدید. خیلی ممنون.
دارم سعی می کنم یه مقدار XML مطالعه کنم. در خصوص داشتن برنامه تحت VB,NET راستش یه برنامه کوچولو در همین رابطه درست کردم اما اکسس یه مقدار ما رو تنبل کرده با چیزای حاضر و آماده ای که داره. راستش اشکم برای طراحی یک فرم تو اون برنامه دراومد. البته که قدرتمندتر و سریعتره. حقیقت امر اینه که من دیگه سنم بالا رفته و باید با همین برنامه خودمون ورزش مغز کنم هر چند با اون هم کمی سروکله می زنم ولی به هر جهت خواستم بخش پیامک برنامه هم در داخل خود برنامه اکسس باشه. در صورتیکه پیام های وارده رو بخونیم خوب برنامه رو میتونیم هوشمند و پاسخگو کنیم
تا چه پیش آید
پیش از هر کار باید یک جدول (مثلا به اسم Messages) برای نگهداری نتایج بسازیم.
گرچه الزامی نیست، ولی برای راحتی کدنویسی اسامی فیلدهای این جدول رو دقیقا از روی ساختار پاسخ برمیداریم:
ضمیمه 153290
از آدرس زیر ساختار request و response رو پیدا میکنیم:
https://login.parsgreen.com/api/msgs...?op=GetMessage
REQUESTPOST /api/msgservice.asmx HTTP/1.1
Host: login.parsgreen.com
Content-Type: application/soap+xml; charset=utf-8
Content-Length: length
<?xml version="1.0" encoding="utf-8"?>
<soap12:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap12="http://www.w3.org/2003/05/soap-envelope">
<soap12:Body>
<GetMessage xmlns="http://ParsGreen.com/">
<signature>string</signature>
<location>int</location>
<isRead>boolean</isRead>
</GetMessage>
</soap12:Body>
</soap12:Envelope>
RESPONSEHTTP/1.1 200 OK
Content-Type: application/soap+xml; charset=utf-8
Content-Length: length
<?xml version="1.0" encoding="utf-8"?>
<soap12:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap12="http://www.w3.org/2003/05/soap-envelope">
<soap12:Body>
<GetMessageResponse xmlns="http://ParsGreen.com/">
<GetMessageResult>
<xsd:schema>schema</xsd:schema>xml</GetMessageResult>
</GetMessageResponse>
</soap12:Body>
</soap12:Envelope>
فکر کنم آخرین پست دیروز رو فراموش کردم ارسال کنم!
دوباره مینویسم و ادامه میدیم.
برای تفسیر response و استخراج نتایج، یک نمونه از اون رو بررسی میکنیم.
پاسخ واقعی شامل 100 رکورد بوده که در اینجا فقط 2 رکورد اون رو پیوست میکنم و همین کافی هست.
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Body>
<GetMessageResponse xmlns="http://ParsGreen.com/">
<GetMessageResult>
<xs:schema id="Msg"
xmlns=""
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xs:element name="Msg"
msdata:IsDataSet="true"
msdata:UseCurrentLocale="true">
<xs:complexType>
<xs:choice minOccurs="0"
maxOccurs="unbounded">
<xs:element name="TBLMessages">
<xs:complexType>
<xs:sequence>
<xs:element name="MsgIdEncrypt"
type="xs:string"
minOccurs="0"/>
<xs:element name="Body"
type="xs:string"
minOccurs="0"/>
<xs:element name="Udh"
type="xs:string"
minOccurs="0"/>
<xs:element name="SendDate"
type="xs:dateTime"
minOccurs="0"/>
<xs:element name="Sender"
type="xs:string"
minOccurs="0"/>
<xs:element name="Receiver"
type="xs:string"
minOccurs="0"/>
<xs:element name="Parts"
type="xs:int"
minOccurs="0"/>
<xs:element name="IsFlash"
type="xs:boolean"
minOccurs="0"/>
<xs:element name="IsRead"
type="xs:boolean"
minOccurs="0"/>
<xs:element name="IsUnicode"
type="xs:boolean"
minOccurs="0"/>
<xs:element name="Credit"
type="xs:double"
minOccurs="0"/>
<xs:element name="RecCount"
type="xs:int"
minOccurs="0"/>
<xs:element name="RecFailed"
type="xs:int"
minOccurs="0"/>
<xs:element name="RecSuccess"
type="xs:int"
minOccurs="0"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:choice>
</xs:complexType>
</xs:element>
</xs:schema>
<diffgr:diffgram xmlns:msdata="urn:schemas-microsoft-com:xml-msdata"
xmlns:diffgr="urn:schemas-microsoft-com:xml-diffgram-v1">
<Msg xmlns="">
<TBLMessages diffgr:id="TBLMessages1"
msdata:rowOrder="0"
diffgr:hasChanges="inserted">
<MsgIdEncrypt>zixb67zjp3yhf3pe43u4ethrgr</MsgIdEncrypt>
<Body>10</Body>
<Udh/>
<SendDate>2021-05-01T11:33:32.92+04:30</SendDate>
<Sender>09363796940</Sender>
<Receiver>10002156713700</Receiver>
<Parts>1</Parts>
<IsFlash>false</IsFlash>
<IsRead>false</IsRead>
<IsUnicode>false</IsUnicode>
<Credit>0</Credit>
<RecCount>1</RecCount>
<RecFailed>0</RecFailed>
<RecSuccess>1</RecSuccess>
</TBLMessages>
<TBLMessages diffgr:id="TBLMessages2"
msdata:rowOrder="1"
diffgr:hasChanges="inserted">
<MsgIdEncrypt>5sp1ejkbh4x393pe43u4ethrgr</MsgIdEncrypt>
<Body>10</Body>
<Udh/>
<SendDate>2021-05-01T11:13:55.44+04:30</SendDate>
<Sender>09393092295</Sender>
<Receiver>10002156713700</Receiver>
<Parts>1</Parts>
<IsFlash>false</IsFlash>
<IsRead>false</IsRead>
<IsUnicode>false</IsUnicode>
<Credit>0</Credit>
<RecCount>1</RecCount>
<RecFailed>0</RecFailed>
<RecSuccess>1</RecSuccess>
</TBLMessages>
</Msg>
</diffgr:diffgram>
</GetMessageResult>
</GetMessageResponse>
</soap:Body>
</soap:Envelope>
با کمی بررسی میبینیم که هر رکورد در یک node به اسم TBLMessages ذخیره شده،
و مجموعه اونها هم درون node به اسم Msg قرار داره.
به بخش schema مربوط به تعریف فیلدها و دیتا کاری نداریم چون از قبل یک جدول آماده کردیم.
روش کار به این صورت هست که:
1- گره Msg رو پیدا میکنیم
2- یک رکوردست از جدول Messages باز میکنیم
3- در یک حلقه، تک تک TBLMessages ها رو میخونیم
4- یک رکورد جدید در رکوردست میسازیم
5- یک حلقه دیگه میسازیم که تمام node های درون TBLMessages v رو میخونه و در فیلدهای متناظر در رکوردست میریزه و در پایان حلقه رکورد رو ذخیره میکنه
Dim x As String
x = Replace(XM, "@SGN", Signature)
x = Replace(x, "@LOC", Location)
With New XMLHTTP60
.Open "POST", "https://login.parsgreen.com/Api/MsgService.asmx", False
.setRequestHeader "HOST", "login.parsgreen.com"
.setRequestHeader "CONTENT-TYPE", "application/soap+xml; charset=utf-8"
.setRequestHeader "SOAPAction", "http://ParsGreen.com/GetMessage"
.Send x
GetMessages.http_status = .Status
GetMessages.http_status_text = .statusText
If .Status = 200 Then
Dim doc As New DOMDocument60
doc.SetProperty "SelectionNamespaces", "xmlns:pg='http://ParsGreen.com/'"
doc.loadXML .responseText
Dim TBLMessages As MSXML2.IXMLDOMNode
Dim Node As MSXML2.IXMLDOMNode
Dim rs As Recordset
Set rs = CurrentDb.OpenRecordset("Messages")
For Each TBLMessages In doc.selectSingleNode("//pg:GetMessageResponse/pg:GetMessageResult//Msg").childNodes
rs.AddNew
For Each Node In TBLMessages.childNodes
rs(Node.baseName) = Node.Text
Next
rs.Update
Next
rs.Close
Set rs = Nothing
End If
End With
در واقع تمام موارد رو پیشتر هم داشتیم و عملا نکته جدیدی در این کد نیست!
تنها چیزی که باید بهش دقت کرد نوشتن کوئری جستجوی node ها هست.
کد زیر گره Msg رو پیدا میکنه:
doc.selectSingleNode("//pg:GetMessageResponse/pg:GetMessageResult//Msg")
و کد زیر مجموعه TBLMessages ها :
doc.selectSingleNode("//pg:GetMessageResponse/pg:GetMessageResult//Msg").childNodes
برای اینکه بدونیم چرا اکسس بعنوان یک ابزار همیشه راه حل خوبی برای هر مسئله ای نیست، یک نمونه desktop application با visual studio برای مقایسه ساختم و نتیجه گیری رو به خواننده واگذار میکنم.
بعد از ایجاد پروژه، پکیج پارس گرین رو به اون اضافه میکنیم:
ضمیمه 153292
یک باتن، یک datagridview و یک MsgService به فرم اضافه میکنیم:
ضمیمه 153293
ضمیمه 153294
کد زیر رو به فرم اضافه میکنیم
Private Const Signature = "..."
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Me.DataGridView1.DataSource = Me.MsgService1.GetMessage(Signature, 1, Nothing).Tables(0)
End Sub
و برنامه رو اجرا میکنیم:
ضمیمه 153295
تمام این کار در کمتر از 10 دقیقه و بدون هیچ نیازی به دونستن جزئیات وب سرویس و درگیری با کدهای xml و ... انجام شد.
سلام با سپاس فراوان از زحماتی که می کشید و مطئمنم زمان زیادی رو وقت گذاشتید تا این کدها را آماده کنید ولی خدا را شکر ضمن کمک به اینجانب بی شک بر غنای این سایت افزوده اید. مطالبی که بی شک حتی در stack overflow هم به این قشنگی توضیح داده نشده باشه
در این روز عزیز از خداوند سلامتی جنابعالی و خانواده محترم را آرزومندم
البته یک برنامک تحت vb.net ساختم و دقیقا با کد موجود براحتی پیامهای دریافتی در دیتاگریدویو نمایش داده میشه ولی همانطور که عرض کردم خواستم این کار در برنامه اصلی انجام بشه
سلام استاد
دوباره وقتتون رو میگرم
من کدها را به شکل زیر در ماژول قرار دادم
البته جواب نگرفتم. می خواستم اگر تا اینجای کار جایی از کدها اگر اشکالی داره که حتما داره رفعش کنیم
' location isread
'----------------------------------------------
' 1 : daryaft null : all message
' 2 : ersal true : is read
' 3 : hazf false : is not read
Public Const InboxXML = "<?xml version='1.0' encoding='utf-8'?>" & _
"<soap12:Envelope xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xmlns:xsd='http://www.w3.org/2001/XMLSchema' xmlns:soap12='http://www.w3.org/2003/05/soap-envelope'>" & _
"<soap12:Body>" & _
"<GetMessage xmlns='http://ParsGreen.com/'>" & _
"<signature>@SGN</signature>" & _
"<location>@loc</location>" & _
"<isRead>@RD</isRead>" & _
"</GetMessage>" & _
"</soap12:Body>" & _
"</soap12:Envelope>"
Public Type GetMessages
GetMessageResult As String
http_status As Integer
http_status_text As String
End Type
Public Function GetMessage(intLocation As Integer, blnRead As Boolean) As GetMessages
'Call ConnectToServer
'Call GetSettingFunc
Dim x As String
x = Replace(InboxXML, "@SGN", signature)
x = Replace(x, "@LOC", Location)
x = Replace(x, "@RD", isRead)
MsgBox x
With New XMLHTTP60
.Open "POST", "https://login.parsgreen.com/Api/MsgService.asmx", False
.setRequestHeader "HOST", "login.parsgreen.com"
.setRequestHeader "CONTENT-TYPE", "application/soap+xml; charset=utf-8"
.setRequestHeader "SOAPAction", "http://ParsGreen.com/GetMessage"
.send x
GetMessage.http_status = .status
GetMessage.http_status_text = .statusText
If .status = 200 Then
MsgBox "200"
Dim doc As New DOMDocument60
doc.SetProperty "SelectionNamespaces", "xmlns:pg='http://ParsGreen.com/'"
doc.loadXML .responseText
Dim TBLMessages As MSXML2.IXMLDOMNode
Dim Node As MSXML2.IXMLDOMNode
Dim rs As Recordset
Set rs = CurrentDb.OpenRecordset("Messages")
For Each TBLMessages In doc.selectSingleNode("//pg:GetMessageResponse/pg:GetMessageResult//Msg").childNodes
rs.AddNew
For Each Node In TBLMessages.childNodes
rs(Node.baseName) = Node.Text
Next
rs.Update
Next
rs.Close
Set rs = Nothing
Else
MsgBox "not 200"
End If
End With
End Function
سلام و روز خوش
کد پست 66 خام هست و باید چند مورد در اون گنجانده بشه،
بعنوان مثال تگ isread یا باید مقدارش True/false باشه یا اصلا نباید در Request باشه.
یک برنامه نمونه براتون میسازم که این موارد رو دربر بگیره.
Option Compare Database
Option Explicit
Private Const WSURL = "https://login.parsgreen.com/Api/MsgService.asmx"
Private Const Signature = "..."
Private Const XM = "<?xml version='1.0' encoding='utf-8'?>" & _
"<soap12:Envelope xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' " & _
"xmlns:xsd='http://www.w3.org/2001/XMLSchema' " & _
"xmlns:soap12='http://www.w3.org/2003/05/soap-envelope'>" & _
"<soap12:Body>" & _
"<GetMessage xmlns='http://ParsGreen.com/'>" & _
"<signature>@SGN</signature>" & _
"<location>@LOC</location>" & _
"@RD" & _
"</GetMessage>" & _
"</soap12:Body>" & _
"</soap12:Envelope>"
Public Enum Box
Inbox = 1
Outbox = 2
Deleted = 4
End Enum
Public Enum MessageStatus
All = 0
Read = 1
NotRead = 2
End Enum
Public Type GetMessageResponse
MessagesCount As Long
http_status As Integer
http_status_text As String
End Type
Public Function GetMessages(Location As Box, IsRead As MessageStatus) As GetMessageResponse
Dim x As String
x = Replace(XM, "@SGN", Signature)
x = Replace(x, "@LOC", Location)
Select Case IsRead
Case MessageStatus.All
x = Replace(x, "@RD", "")
Case MessageStatus.Read
x = Replace(x, "@RD", "<isRead>true</isRead>")
Case MessageStatus.NotRead
x = Replace(x, "@RD", "<isRead>false</isRead>")
End Select
With New XMLHTTP60
.Open "POST", "https://login.parsgreen.com/Api/MsgService.asmx", False
.setRequestHeader "HOST", "login.parsgreen.com"
.setRequestHeader "CONTENT-TYPE", "application/soap+xml; charset=utf-8"
.setRequestHeader "SOAPAction", "http://ParsGreen.com/GetMessage"
.Send x
GetMessages.http_status = .Status
GetMessages.http_status_text = .statusText
If .Status = 200 Then
Dim doc As New DOMDocument60
doc.SetProperty "SelectionNamespaces", "xmlns:pg='http://ParsGreen.com/'"
doc.loadXML .responseText
Dim Msg As MSXML2.IXMLDOMNode
Set Msg = doc.selectSingleNode("//pg:GetMessageResponse/pg:GetMessageResult//Msg")
If Msg Is Nothing Then
GetMessages.MessagesCount = 0
Else
GetMessages.MessagesCount = Msg.childNodes.length
Dim rs As Recordset
Set rs = CurrentDb.OpenRecordset("Messages")
Dim TBLMessages As MSXML2.IXMLDOMNode
Dim Node As MSXML2.IXMLDOMNode
For Each TBLMessages In Msg.childNodes
rs.AddNew
For Each Node In TBLMessages.childNodes
rs(Node.baseName) = Node.Text
Next
rs.Update
Next
rs.Close
Set rs = Nothing
End If
End If
End With
End Function
ضمیمه 153300
ضمیمه 153301
برنامه نمونه:
سلام. استاد مثل همیشه عالی بود
خیلی ممنون کمک بسیار بزرگی فرمودید