I’m tyring to send a message to my mobile. Via browser I call the method that does this operation, I’ve logged the registrationId, authToken, etc.. and this is correct, because I tested in a local server and the message has been send to my phone using these keys.
However on App Engine, I have a 401 error on the result of the urlfetch.fetch for ‘https://android.clients.google.com/c2dm/send‘.
Or if this is a problem with authentication. I doubt it is the problem above, because the method is called, and the error happens right in the end of the method in my App Engine server.
Here is how I make the request to the C2DM servers:
params = {
'registration_id':registrationId,
'collapse_key':0,
'data.payload':encoded_msg
}
paramsByte = urllib.urlencode(params)
logging.info(registrationId)
url = 'https://android.clients.google.com/c2dm/send'
logging.info(token)
result = urlfetch.fetch(url=url,
payload=paramsByte,
method=urlfetch.POST,
headers={'Content-Type':'application/x-www-form-urlencoded',
'Authorization':'GoogleLogin auth='+token}
)
Any help would be appreciated. Thanks.
UPDATE
Now the client is running in a hosting server as suggested, and the
401 error happens when contacting
‘https://android.clients.google.com/c2dm/send’.
However when using the following command on terminal with the same token and regId, it works.
curl –header “Authorization: GoogleLogin auth=your_authenticationid”
“https://android.apis.google.com/c2dm/send” -d
registration_id=your_registration -d “data.payload=payload” -d
collapse_key=0
Client code calling the method in server:
$.getJSON('http://myapp.appspot.com/method?userId='+userId+'&message='+theMessage+'&callback=?',
function(data)
{
console.log(data);
});
Full method code for server:
class PushHandler(webapp.RequestHandler):
'''This method sends the message to C2DM server to send the message to the phone'''
def get(self):
logging.info('aqui dentro')
userId = self.request.get('userId')
message = self.request.get('message')
callback = self.request.get('callback')
token = getToken(self) #this is a method I've implemented to get the token from C2DM servers by passing the SenderId and Password
registrationId = ''
contactNumber = ''
# Get the registrationId to send to the C2DM server to know which
# device it may send the message
regQuery = C2DMUser.all()
regQuery.filter('userId =', int(userId))
for k in regQuery:
registrationId = k.registrationId
# Builds the json to be sent to the phone
record_to_json = {
'userId':userId,
'message':message
}
data = []
data.append(record_to_json)
jsondata = simplejson.dumps(data) # Creates the json
# Encode the JSON String
u = unicode(jsondata, "utf-8")
encoded_msg = u.encode("utf-8")
params = {
'registration_id':registrationId,
'collapse_key':0,
'data.payload':encoded_msg
}
paramsByte = urllib.urlencode(params)
url = 'https://android.clients.google.com/c2dm/send'
logging.info(token)
result = urlfetch.fetch(url=url,
payload=paramsByte,
method=urlfetch.POST,
headers={'Content-Type':'application/x-www-form-urlencoded',
'Authorization':'GoogleLogin auth='+token}
)
data = []
params_key = { 'status_code':result.status_code }
data.append(params_key)
self.response.headers['Content-Type'] = 'application/json'
jsondata = simplejson.dumps(data)
if result.status_code == 200:
logging.info(result.status_code)
self.response.out.write('' + callback + '(' + jsondata + ')') # handle the JSONP
else:
logging.info(result.status_code)
self.response.out.write(result.status_code)
The package name of your code must match the one you gave when you signed up for the c2dm account. For Java, if you gave com.myapp when you signed up, your c2dm calls must occur within that package. Not sure how this translates to Python, though.