الاتصال ب APNS للحصول على iPhone باستخدام Python
-
19-09-2019 - |
سؤال
أحاول إرسال إشعارات الدفع إلى iPhone باستخدام Python. لقد تصدير بلدي شهادة ومفتاح خاص في ملف P12 من وصول المفاتيح ثم تحويله إلى ملف PEM باستخدام الأمر التالي:
openssl pkcs12 -in cred.p12 -out cert.pem -nodes -clcerts
أنا استخدم apnswrapper. في بيثون للاتصال.
قمت بتشغيل التعليمات البرمجية التالية:
devicetoken = 'qun xaa xd ... c0 x9c xf6 xca' # إنشاء التفاف المجمع = apnsnotificationWrapper ('/ مسار / to / cert / cert.pem'، صحيح) # إنشاء رسالة رسالة = رسالة apnsnotification () .token (devicetoken) message.badge (5) # أضف رسالة إلى tuple وأرسلها إلى Apns Server Wrapper.append (رسالة) Wrapper.notify ()
ثم أحصل على رسالة الخطأ:
SSL.SSLERROR: (1، '_ssl.c: 485: خطأ: 14094416: إجراءات SSL: SSL3_READ_BYTES: شهادة تنبيه SSLV3 غير معروفة)
يمكن لأي شخص أن يساعدني على ذلك؟
المحلول
لقد فعلت ذلك مؤخرا هذا باستخدام Django - http://leecutsco.de/2009/07/14/14/push-on-the-iphone/
ربما يكون مفيدا؟ إنها تستفيد من أي مكتبات إضافية غير تلك المضمنة مع Python بالفعل. لن يستغرق الكثير لاستخراج طريقة send_message ().
نصائح أخرى
هل اعتبرت ملتوية صفقة؟ يؤخذ الرمز أدناه من هنا:
from struct import pack
from OpenSSL import SSL
from twisted.internet import reactor
from twisted.internet.protocol import ClientFactory, Protocol
from twisted.internet.ssl import ClientContextFactory
APNS_SERVER_HOSTNAME = "<insert the push hostname from your iPhone developer portal>"
APNS_SERVER_PORT = 2195
APNS_SSL_CERTIFICATE_FILE = "<your ssl certificate.pem>"
APNS_SSL_PRIVATE_KEY_FILE = "<your ssl private key.pem>"
class APNSClientContextFactory(ClientContextFactory):
def __init__(self):
self.ctx = SSL.Context(SSL.SSLv3_METHOD)
self.ctx.use_certificate_file(APNS_SSL_CERTIFICATE_FILE)
self.ctx.use_privatekey_file(APNS_SSL_PRIVATE_KEY_FILE)
def getContext(self):
return self.ctx
class APNSProtocol(Protocol):
def sendMessage(self, deviceToken, payload):
# notification messages are binary messages in network order
# using the following format:
# <1 byte command> <2 bytes length><token> <2 bytes length><payload>
fmt = "!cH32cH%dc" % len(payload)
command = 0
msg = struct.pack(fmt, command, deviceToken,
len(payload), payload)
self.transport.write(msg)
class APNSClientFactory(ClientFactory):
def buildProtocol(self, addr):
print "Connected to APNS Server %s:%u" % (addr.host, addr.port)
return APNSProtocol()
def clientConnectionLost(self, connector, reason):
print "Lost connection. Reason: %s" % reason
def clientConnectionFailed(self, connector, reason):
print "Connection failed. Reason: %s" % reason
if __name__ == '__main__':
reactor.connectSSL(APNS_SERVER_HOSTNAME,
APNS_SERVER_PORT,
APNSClientFactory(),
APNSClientContextFactory())
reactor.run()
كان هناك عدد قليل من الأخطاء في التعليمات البرمجية المنشور أصلا، لذلك إليك نسخة تصحيح تعمل بالنسبة لي.
from struct import pack
from OpenSSL import SSL
from twisted.internet import reactor
from twisted.internet.protocol import ClientFactory, Protocol
from twisted.internet.ssl import ClientContextFactory
import binascii
import struct
APNS_SERVER_HOSTNAME = "gateway.sandbox.push.apple.com"
APNS_SERVER_PORT = 2195
APNS_SSL_CERTIFICATE_FILE = "<your ssl certificate.pem>"
APNS_SSL_PRIVATE_KEY_FILE = "<your ssl private key.pem>"
DEVICE_TOKEN = "<hexlified device token>"
MESSAGE = '{"aps":{"alert":"twisted test"}}'
class APNSClientContextFactory(ClientContextFactory):
def __init__(self):
self.ctx = SSL.Context(SSL.SSLv3_METHOD)
self.ctx.use_certificate_file(APNS_SSL_CERTIFICATE_FILE)
self.ctx.use_privatekey_file(APNS_SSL_PRIVATE_KEY_FILE)
def getContext(self):
return self.ctx
class APNSProtocol(Protocol):
def connectionMade(self):
print "connection made"
self.sendMessage(binascii.unhexlify(DEVICE_TOKEN), MESSAGE)
self.transport.loseConnection()
def sendMessage(self, deviceToken, payload):
# notification messages are binary messages in network order
# using the following format:
# <1 byte command> <2 bytes length><token> <2 bytes length><payload>
fmt = "!cH32sH%ds" % len(payload)
command = '\x00'
msg = struct.pack(fmt, command, 32, deviceToken,
len(payload), payload)
print "%s: %s" %(binascii.hexlify(deviceToken), binascii.hexlify(msg))
self.transport.write(msg)
class APNSClientFactory(ClientFactory):
def buildProtocol(self, addr):
print "Connected to APNS Server %s:%u" % (addr.host, addr.port)
return APNSProtocol()
def clientConnectionLost(self, connector, reason):
print "Lost connection. Reason: %s" % reason
def clientConnectionFailed(self, connector, reason):
print "Connection failed. Reason: %s" % reason
if __name__ == '__main__':
reactor.connectSSL(APNS_SERVER_HOSTNAME,
APNS_SERVER_PORT,
APNSClientFactory(),
APNSClientContextFactory())
reactor.run()
حاول التحديث بأحدث إصدار APNSWRAPPER (0.4). يوجد في دعم أداة سطر الأوامر Openssl (Openssl S_Client) الآن.
حاولت كليهما APNSWrapper
و Lee Peckham's Code ولم تتمكن من الحصول عليها للعمل تحت سنو نمر مع بيثون 2.6. بعد الكثير من التجربة والخطأ يعمل أخيرا مع pyOpenSSL
.
فعلت بالفعل وظيفة مع التفاصيل ومقشرات التعليمات البرمجية هنا لذلك سوف أحال لك فقط هناك.