Reputation: 1695
I'm trying to send push notifications using the APNS from Python (I know there are lots of libraries that do just that, but this has pedagogic intentions).
I started using this script (source):
def send_push(token, payload):
# Your certificate file
cert = 'ck.pem'
# APNS development server
apns_address = ('gateway.sandbox.push.apple.com', 2195)
# Use a socket to connect to APNS over SSL
s = socket.socket()
sock = ssl.wrap_socket(s, ssl_version=ssl.PROTOCOL_SSLv3, certfile=cert)
sock.connect(apns_address)
# Generate a notification packet
token = binascii.unhexlify(token)
fmt = '!cH32sH{0:d}s'.format(len(payload))
cmd = '\x00'
message = struct.pack(fmt, cmd, len(token), token, len(payload), payload)
sock.write(message)
sock.close()
Which works, but Python 2.x only supports TSL until version 1. So I tried to run it using Python 3, and I get this error:
Traceback (most recent call last):
File "push_notificator.py", line 52, in <module>
send_notification(TOKEN, json.dumps(TEST_PAYLOAD))
File "push_notificator.py", line 46, in send_push
payload
struct.error: char format requires a bytes object of length 1
So it seems I must convert the payload to binary, but I'm really lost. This is the first time that I work with binary data on Python.
Upvotes: 4
Views: 9844
Reputation: 1281
@cdonts's answer ultimately helped me out, but i thought it might be cleaner in a separate answer, instead of a comment...
@cdonts's answer: https://stackoverflow.com/a/31551978/2298002
I had to encode both cmd
as well as payload
, before packing.
here is my code that solved it...
cmd = bytes(cmd, "utf-8")
payload = bytes(payload, "utf-8")
here is a longer code snippet to demonstrate in context...
token = "<string apns token from iOS client side>"
try:
token = binascii.unhexlify(token)
payload = json.dumps(payload)
fmt = "!cH32sH{0:d}s".format(len(payload))
cmd = '\x00'
#python3 requirement
cmd = bytes(cmd, "utf-8")
payload = bytes(payload, "utf-8")
msg = struct.pack(fmt, cmd, len(token), token, len(payload), payload)
except Exception as e: # ref:
print(e)
@cdonts THANK YOU!! (https://stackoverflow.com/a/31551978/2298002)
Upvotes: 3
Reputation: 9631
In Python 3.x use:
bytes(payload, "utf-8")
Replace utf-8
with the necessary encoding.
Hope it helps.
Upvotes: 2