chvanikoff / apns4ex Goto Github PK
View Code? Open in Web Editor NEWAPNS for Elixir
License: MIT License
APNS for Elixir
License: MIT License
When attempting to connect to APNS using apns4ex v0.0.6, the connection fails with an error
[error] [APNS] failed to connect gateway.sandbox.push.apple.com:2195, reason given: {:options, {:password, "foobar1"}}
[error] [APNS] failed to connect gateway.sandbox.push.apple.com:2195, reason given: {:options, {:password, "foobar1"}}
[error] [APNS] failed to connect gateway.sandbox.push.apple.com:2195, reason given: {:options, {:password, "foobar1"}}
[error] GenServer #PID<0.339.0> terminating
However, this is the correct password as a call to openssl s_client -connect gateway.sdbox.push.apple.com:2195 -cert ARootLevelCert.pem -key ARootLevelKey.pem -pass pass:foobar1
succeeds. No combination of certificate, key, and password generates a connection to APNS.
Below is the current configuration for the apns service:
config :apns,
certfile: "ARootLevelCert.pem",
keyfile: "ARootLevelKey.pem",
cert_password: "foobar1"
It seems like the feedback/error callbacks are not working properly.
When I first connect I get this info:
[debug] [APNS] connected to gateway.sandbox.push.apple.com:2195
[debug] [APNS] connected to feedback.sandbox.push.apple.com:2196
[debug] [APNS] Feedback socket was closed. Reconnect in 10000s.
If I try to send something to a wrong id, Apple just closes the gateway.sandbox.push.apple.com
connection and there's no error. Also next time callback connects - there's no feedback either.
What is the expected behavior?
Hi, by looking at the package Hex page it seems that only 0.0.x are published.
It would be really nice if you could publish the latest version.
Thanks a lot!
Add an option to choose whether to limit PNs to 256 bytes or 2kb. Also I think it would be good to allow dynamically change this property and to set limit for each message individually for the case when it is known in advance what device you are sending PN to (which means you know it's possible limit)
Hey guys!
I see only version 0.9.4 in hex, could you please publish the new version? 😄
Hello,
I noticed a problem in that push notifications strangely stop working after a few hours after server restart on Google Compute Engine. I was using Heroku before and didn't notice this problem but since migrating to google, it started popping up. (Not completely ruling out it didn't happen with Heroku as well)
I enabled full debug output to get an idea of what's going on but still can't figure out why the push notifications never make it to the device. After server restart it again works for a few hours.
This is probably a problem with Google. If you have any idea what could be causing this (since you implemented apns4ex), it would help us a lot.
My first thought was that a long-lasting connection got terminated so I adjusted expiry
, timeout
and feedback_interval
but no luck.
Here is some debug output when sending a notification:
01:41:14.820 request_id=fecds3h3s1so2825c44qfestvvvpv707 [debug] [APNS] #PID<0.20135.97> 23303051:1ad798 sending in poolboy transaction :myapp
01:41:14.821 request_id=fecds3h3s1so2825c44qfestvvvpv707 [debug] [APNS] #PID<0.20135.97> 23303051:1ad798 sending message
01:41:14.821 request_id=fecds3h3s1so2825c44qfestvvvpv707 [debug] [APNS] #PID<0.20135.97> 62064556:b12e98 sending in poolboy transaction :myapp
01:41:14.821 [debug] [APNS] #PID<0.349.0> 23303051:1ad798 handling cast :send
01:41:14.821 [debug] [APNS] #PID<0.349.0> 23303051:1ad798 message's payload looks good
01:41:14.821 request_id=fecds3h3s1so2825c44qfestvvvpv707 [debug] [APNS] #PID<0.20135.97> 62064556:b12e98 sending message
01:41:14.821 request_id=fecds3h3s1so2825c44qfestvvvpv707 [debug] [APNS] #PID<0.20135.97> 19048099:b3ed8e sending in poolboy transaction :myapp
01:41:14.822 [debug] [APNS] #PID<0.349.0> success sending ssl package
01:41:14.822 [debug] [APNS] #PID<0.349.0> 23303051:1ad798 success sending
01:41:14.822 [debug] [APNS] #PID<0.349.0> 23303051:1ad798 handle call :send received :ok
01:41:14.822 [debug] [APNS] #PID<0.348.0> 62064556:b12e98 handling cast :send
01:41:14.822 [debug] [APNS] #PID<0.348.0> 62064556:b12e98 message's payload looks good
01:41:14.823 request_id=fecds3h3s1so2825c44qfestvvvpv707 [debug] [APNS] #PID<0.20135.97> 19048099:b3ed8e sending message
01:41:14.823 request_id=fecds3h3s1so2825c44qfestvvvpv707 [info] Sent 200 in 22ms
01:41:14.823 [debug] [APNS] #PID<0.348.0> success sending ssl package
01:41:14.823 [debug] [APNS] #PID<0.348.0> 62064556:b12e98 success sending
01:41:14.823 [debug] [APNS] #PID<0.348.0> 62064556:b12e98 handle call :send received :ok
01:41:14.823 [debug] [APNS] #PID<0.347.0> 19048099:b3ed8e handling cast :send
01:41:14.824 [debug] [APNS] #PID<0.347.0> 19048099:b3ed8e message's payload looks good
01:41:14.824 [debug] [APNS] #PID<0.347.0> success sending ssl package
01:41:14.824 [debug] [APNS] #PID<0.347.0> 19048099:b3ed8e success sending
01:41:14.824 [debug] [APNS] #PID<0.347.0> 19048099:b3ed8e handle call :send received :ok
01:41:15.027 [debug] [APNS] #PID<0.348.0> ssl socket closed, returning :connect
01:41:15.029 [debug] [APNS] #PID<0.347.0> ssl socket closed, returning :connect
01:41:15.043 [debug] [APNS] #PID<0.349.0> ssl socket closed, returning :connect
01:41:15.207 [debug] [APNS] #PID<0.348.0> successfully connected to gateway.push.apple.com:2195
01:41:15.207 [debug] [APNS] #PID<0.348.0> successfully connected to socket
01:41:15.209 [debug] [APNS] #PID<0.347.0> successfully connected to gateway.push.apple.com:2195
01:41:15.209 [debug] [APNS] #PID<0.347.0> successfully connected to socket
01:41:15.214 [debug] [APNS] #PID<0.349.0> successfully connected to gateway.push.apple.com:2195
01:41:15.214 [debug] [APNS] #PID<0.349.0> successfully connected to socket
Hi!
I am new to push notification, and quite frankly to elixir too. I was happy to find this library! But I run into an error in the very first step of using it. I hope you can help me figuring it out!
I have a valid certificate ck.pem (combined with my private key) and simple password "hello" -- I am able to connect with "openssl s_client -connect gateway.sandbox.push.apple.com:2195 -cert ck.pem"
I am setting this up in my phoenix project:
config :apns,
callback_module: APNS.Callback,
timeout: 30,
feedback_interval: 1200,
reconnect_after: 1000,
support_old_ios: true,
pools: [
myapp_dev_pool: [
env: :dev,
pool_size: 10,
pool_max_overflow: 5,
certfile: "ck.pem",
cert_password: "hello"
]
]
Then I try to fire up phoenix.server, but I run into the above error:
[error] [APNS] failed to connect gateway.sandbox.push.apple.com:2195, reason given: {:options, {:password, "hello"}}
What's happening?
Thank you !!
Currently push messages are sent one by one even if there are many workers configured in the pool.
It might not be a good idea to just wrap APNS.push/2
in Task.async/1
but having this as a separate function would make it clearer that this is a choice the consumer can do.
An even fancier version of this would be to have a push_many
function that process tokens in chunks and runs x push-calls in parallel but so that there is a cap on how many processes is spawned.
pseudo example:
Enum.chunk(tokens, 100, fn (chunk) ->
jobs = for token <- chunk do
Task.async(fn->
APNS.push(pool, message)
end)
await_many(jobs)
end
end)
I would like to use HTTP2 endpoint of APNS, are you planning to update the lib and use the apns4erl v2 or should I start my own lib?
If I have my reconnect timeout sent to X seconds I see 1000x of the value in . For example for 120 seconds: [debug] [APNS] Feedback socket was closed. Reconnect in 1200000s.
I believe the offending lien is:
Line 82 in 9e20565
Can you quick fix next time you make a release or do you want a PR?
Currently it's hardly possible to test notifications being sent. With mock PN server testability would increase significantly.
when i get error , in callback module, it is calling error/2 so, can you change in doc or elaborate what is the situation which one is right ?
Since they never reach Apple, they won't be returned by the feedback service and thus needs to be removed from the error callback.
This is of course the consumer's responsibility but it should be clearly documented.
You seem to use Hexate.encode
and Hexate.decode
but both functions already exist in Elixir via Base.encode16
and Base.decode16
. Maybe you can drop this dependency?
[info] ['TLS', 32, 'client', 58, 32, 73, 110, 32, 115, 116, 97, 116, 101, 32, 'hello', 32, 'received SERVER ALERT: Fatal - Handshake Failure', 10]
[error] [APNS] #PID<0.292.0> failed to connect to push socket gateway.sandbox.push.apple.com:2195, reason given: {:tls_alert, 'handshake failure'}
[warn] [APNS] #PID<0.292.0> unable to connect to socket, backing off
I run simple push notification module with pure apns push function on Production and after a few of hours it's can not deliver any message to device and console log still look good (without any error log in console - debug level). And I restart the apns app with command Application.stop(:apns); Application.start(:apns), it's back. I don't know what problems.
I think there might be an issue with sending alert-message string for Localizable.strings.
Apple docs never clearly say it's an exclusive or between the 'body' key and the 'loc_key' + 'loc_args' keys. However, my tests show that in alerts including a 'body' key != nil, iOS seems to ignore the 'loc_key' + 'loc_args' keys.
Your private function 'format_loc' in the APNS.Worker module returns an alert with a body never nil (at minimum an empty string). I think this prevents any alert-message string for Localizable.strings from being activated on the user device.
Hi!
message = APNS.Message.new
msg_id = :erlang.system_time(:milli_seconds)
message = message
|> Map.put(:id, msg_id)
|> Map.put(:token, token)
|> Map.put(:alert, content)
def error(error = %APNS.Error{}, token) do
# handle error
Logger.error "Apns Callback error: #{inspect error}"
end
[error] Apns Callback error: %APNS.Error{error: "Invalid token", message_id: 4058550999, status: 8}
Callback's message_id does not match APNS.Message's id
This is a long-shot and might not be related to apns4ex at all so feel free to close it.
With that said we're experiencing problems with devices sometimes not receiving pushes we send. We can see that :ssl.send/2
returns :ok
(https://github.com/chvanikoff/apns4ex/blob/master/lib/apns/worker.ex#L277) for the token associated with the device that should have received the push. Other devices, on the same network, receives the same message (with a different APNS push token ofc) and the same device that didn't receive the push earlier has a good chance of receiving another push later.
We get no errors in the error callback or via the feedback service for the affected token. The problem isn't either connected to one specific APNS push token but seems to be random among all our stored tokens.
Do you know if there is any chance that :ssl.send/2
can return :ok
without the message actually being sent? Have you experienced anything similar?
The feedback module gets called with an uppercase representation of the hex APNS token (https://github.com/chvanikoff/apns4ex/blob/master/lib/apns/worker.ex#L122). It would be nice to allow the user to configure this.
config :apns,
callback_module: APNS.Callback,
token_case: :lower # defaults to :upper,
…
Would you consider a PR to address this?
In the case where there are hundreds, thousands, or even millions of messages being pushed, the APNS service may need to be alive for a long while. In order to shut the service down on-demand, a finished/1
or completed/1
callback would be very useful once the service has finished pushing all messages. The single argument to this function would be the pid of the APNS service. This functionality would help to facilitate integrity checks for the messages, and allow for spin-down of the APNS service when pushing is finished.
An example implementation that helps to illustrate the point is below:
defmodule MyFeedback do
def completed(apnsPID) do
APNS.stop(apnsPID)
end
end
Key | Value type | Comment |
---|---|---|
title | string | A short string describing the purpose of the notification. Apple Watch displays this string as part of the notification interface. This string is displayed only briefly and should be crafted so that it can be understood quickly. This key was added in iOS 8.2. |
body | string | The text of the alert message. |
title-loc-key | string or null | The key to a title string in the Localizable.strings file for the current localization. The key string can be formatted with %@ and %n$@ specifiers to take the variables specified in the title-loc-args array. See Localized Formatted Strings for more information. This key was added in iOS 8.2. |
title-loc-args | array of strings or null | Variable string values to appear in place of the format specifiers in title-loc-key. See Localized Formatted Strings for more information. This key was added in iOS 8.2. |
action-loc-key | string or null | If a string is specified, the system displays an alert that includes the Close and View buttons. The string is used as a key to get a localized string in the current localization to use for the right button’s title instead of “View”. See Localized Formatted Strings for more information. |
loc-key | string | A key to an alert-message string in a Localizable.strings file for the current localization (which is set by the user’s language preference). The key string can be formatted with %@ and %n$@ specifiers to take the variables specified in the loc-args array. See Localized Formatted Strings for more information. |
loc-args | array of strings | Variable string values to appear in place of the format specifiers in loc-key. See Localized Formatted Strings for more information. |
launch-image | string | The filename of an image file in the app bundle; it may include the extension or omit it. The image is used as the launch image when users tap the action button or move the action slider. If this property is not specified, the system either uses the previous snapshot,uses the image identified by the UILaunchImageFile key in the app’s Info.plist file, or falls back to Default.png. This property was added in iOS 4.0. |
https://github.com/chvanikoff/apns4ex/blob/master/lib/apns/message.ex#L5 from what I understand this should be a calculated offset from epoch. That is if the message is to expire in 1 minute it should be sent as epoch + 60
Messages should support sending a category field as specified by Apple:
See table 3-1
It seems that there is no support for this right now, right? Should we send a PR for this?
Hi!
I'm investigating why a lot of our push messages aren't delivered.
When reading here:
https://developer.apple.com/library/ios/technotes/tn2265/_index.html#//apple_ref/doc/uid/DTS40010376-CH1-TNTAG44
Is states that
"If you get six bytes back, that's an error response that you can check for the response code and the ID of the notification that caused the error. You'll need to send every notification following that one again."
So, I believe that our issue is that we send some notifications, hit a bad token and all subsequent notifications are discarded by Apple.
As far as I can see this isn't handled by apns4ex. Is that correct?
If it isn't handled by apns4ex, how are you supposed to tackle this issue?
Any input here is very welcome since I am a bit lost at the moment... :)
cc @ramhoj
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.