Coder Social home page Coder Social logo

pushd's Introduction

Universal Mobile Push Daemon

Pushd is a pluggable unified push server for server-side notification to mobile native apps, web apps etc. With pushd you can send push notifications to any supported mobile platform, web app or HTTP server from a single entry point. Pushd takes care of which device is subscribed to which event and is designed to support an unlimited amount of subscribable events.

Architecture Overview

Features

  • Multi protocols APNs (iOS), C2DM/GCM (Android), MPNS (Windows Phone), HTTP POST, EventSource, WNS (Windows Notification Service)
  • Pluggable protocols
  • Register unlimited number of subscribers (device)
  • Subscribe to unlimited number of events
  • Automatic badge increment for iOS
  • Silent subscription mode (no alert message, only data or badge increment)
  • Server side message translation
  • Message template
  • Broadcast
  • Direct messages
  • GCM multicast messaging
  • Events statistics
  • Automatic failing subscriber unregistration
  • Built-in Apple Feedback API handling
  • Redis backend
  • Fracking fast!

Installation

  • Install redis, node.js, npm and coffeescript.
  • Clone the repository: git clone git://github.com/rs/pushd.git && cd pushd
  • Install dependancies: npm install
  • Configure the server: cp settings-sample.coffee settings.coffee && vi settings.coffee
  • Start redis: redis-server
  • Start the server: sudo coffee pushd.coffee

Glossary

  • Application Data Provider: The service emitting Events (i.e: other users actions) to be notified to Subscribers (i.e.: mobiles app)
  • Subscribers: Entities wanting to be notified about certain type of Events. There's two kind of subscribers: offline subscribers and online subscribers. The current implementation of pushd does only support offline subscribers. Difference between online and offline subscribers is that online subscribers are required to stay connected to maintain subscriptions while offline subscribers are persisted in pushd database, and only have to instruct pushd when they change their status (subscriptions etc.).
  • Event: A string with associated metadata representing an action performed on the Application Data Provider. Events are emitted by the Application Data Provider (i.e.: a web site or your application's server-side backend), and Subscribers can subscribe to them in order to be notified by the Protocol of their choice.
  • Protocol: A communication standard to send notification back to the Subscriber. Protocols are pluggable in pushd so you can add your own custom protocol. By default, pushd is bundled with support for APNs (iOS), C2DM/GCM (Android) and MPNS (Windows Phone). More protocols will be added in the future.

Getting Started

Register

At first launch, your app must register with the push notification service to get a registration id. It then provides this registration id to pushd in exchange for a subscriber id (This subscriber id will be used with all further communications with pushd). Some informations can be sent with the request to pushd like: subscriber language, version or current badge value.

Subscriber registration is performed through a HTTP REST API (see later for more details). Here is an example of a subscriber registration simulated using the curl command. As an example, we will register the iOS device with the registration id FE66489F304DC75B8D6E8200DFF8A456E8DAEACEC428B427E9518741C92C6660. For iOS, we have to specify the apns protocol. We also set the subscriber language to fr for French and init the badge to 0. We suppose the command is run on the same machine as pushd:

$ curl -d proto=apns \
       -d token=FE66489F304DC75B8D6E8200DFF8A456E8DAEACEC428B427E9518741C92C6660 \
       -d lang=fr \
       -d badge=0 \
       -d category=show \
       -d contentAvailable=true \
       http://localhost/subscribers

In reply, we get the following JSON structure:

{
    "proto":"apns",
    "token":"fe66489f304dc75b8d6e8200dff8a456e8daeacec428b427e9518741c92c6660",
    "lang":"fr",
    "badge":0,
    "updated":1332953375,
    "created":1332953375,
    "id":"J8lHY4X1XkU"
}

Your app must save the id field value, it will be used for all further communication with pushd.

Note: If you perform a registration using an already registered token, the server will respond with the same subscriber id and will just update the transmitted informations. You may choose to always register the given token instead of calling the ping endpoint.

Ping

Once the app is registered, it has to ping the pushd server each time the app is launched to let pushd know the subscriber still exists. The subscriber may have been unregistered automatically in case of repeated errors for instance. To ping pushd, you perform a POST on the /subscriber/SUBSCRIBER_ID url as follow:

$ curl -d lang=fr -d badge=0 http://localhost/subscriber/J8lHY4X1XkU

On iOS, you must update the badge value to inform pushd the user read the pending notifications. You may call this URL several times, each time the badge is updated, so the next notification will still increment the badge with the correct value.

Subscriptions

Depending on your service, your app may auto-subscribe the subscriber to some events or ask the user which events he wants to be subscribed to (an event is identified as an arbitrary string meaningful for your service). For each event your app wants to be subscribed to, a call to the pushd API must be performed.

For instance, if your app is news related, you may want to create one subscriptable event for each news category. So if your user wants to subscribe to sport events, the following call to pushd has to be performed:

$ curl -X POST http://localhost/subscriber/J8lHY4X1XkU/subscriptions/sport

You may later unsubscribe by switching from the POST to the DELETE method.

You may also prefer to set all subscriptions at once by using the bulk subscription endpoint:

$ curl -H 'Content-Type: application/json' -d '{"sport":{}, "music":{}}' http://localhost/subscriber/J8lHY4X1XkU/subscriptions

We recommend to auto-subscribe your users to some global event like for instance a country event if your app is international. This will let you send targeted messages to all of a given country’s users.

Typical App Launch Tasks

  1. Obtain device token from the OS
  2. Post the token on /subscriber/:token with parameters like lang, badge and version
  3. Extract the id from the response (you don't need to store it, treat it like a session id)
  4. Resubscribe the device to all its previously subscribed events by posting on /subscriber/:id/subscriptions

This workflow ensures device stay registered and subscriptions are always up-to-date.

Event Ingestion

Once subscribers are registered, your service may start to send events. Events are composed of a message, optionally translated in several languages and some additional data to be passed to your application. To send an event, you may either use the HTTP REST API or send UDP datagrams.

You don't need to create events before sending them. If nobody is subscribed to a given event, it will be simply ignored. It's thus recommended to send all the possible types of events and let your application choose which to subscribe to.

Here we will send a message to all subscribers subscribed to the sport event:

$ curl -d msg=Test%20message http://localhost/event/sport

Event Source

Pushd supports the Event Source protocol, also known as Server Sent Events. This allows your web application to benefits from the same pushed event than your native apps.

This protocol is very different from other pushd supported protocol because it doesn't involve subscriber registration nor stored subscriptions. The web service connects to the pushd server and declars which event it is interested in, and then pushd will push subscribed events in this same connections until the client stays connected.

You may want to use Yaffle EventSource polyfill on the client side in order to support CORS requests with older browsers (see code example bellow).

When Event Source is enabled, a new /subscribe API endpoint is available. Use the events query-string parameter with a list of events separated by spaces:

> GET /subscribe?events=event1+event2+event3 HTTP/1.1
> Accept: text/event-stream
>
---
< HTTP/1.1 200 OK
< Content-Type: text/event-stream
< Cache-Control: no-cache
< Access-Control-Allow-Origin: *
< Connection: close
<
... some time passes ...
< data: {"event": "event1", "title": {"default": "Title", "fr": "Titre"}, "message": {...}, "data": {"var1": "val1", "var2": "val2"}}
... some time passes ...
< data: {"event": "event2", "title": {"default": "Title", "fr": "Titre"}, "message": {...}, "data": {"var1": "val1", "var2": "val2"}}

Or in Javascript:

<script src="https://raw.github.com/Yaffle/EventSource/master/eventsource.js"></script>
<script>
var es = new EventSource('http://localhost/subscribe?events=event1+event2+event3');
es.addEventListener('message', function (e)
{
    var event = JSON.parse(e.data);
    document.body.appendChild(document.createTextNode(event.message.default));
    document.body.appendChild(document.createElement('br'));
});
</script>

See codepen example: http://codepen.io/rs/pen/xAjpy

API

Subscriber Registration

Register a subscriber ID

Register a subscriber by POSTing on /subscribers with some subscriber information like registration id, protocol, language, OS version (useful for Windows Phone OS) or initial badge number (only relevant for iOS, see bellow).

> POST /subscribers HTTP/1.1
> Content-Type: application/x-www-form-urlencoded
>
> proto=apns&
> token=FE66489F304DC75B8D6E8200DFF8A456E8DAEACEC428B427E9518741C92C6660&
> lang=fr&
> badge=0
>
---
< HTTP/1.1 201 Created
< Location: /subscriber/JYJ1ehuEHbU
< Content-Type: application/json
<
< {
<   "created":1332638892,
<   "updated":1332638892,
<   "proto":"apns",
<   "token":"FE66489F304DC75B8D6E8200DFF8A456E8DAEACEC428B427E9518741C92C6660",
<   "lang":"fr",
<   "badge":10
< }

Carriage returns are added for readability

Mandatory parameters:
  • proto: The protocol to be used for the subscriber. Use one of the following values:
    • apns: iOS (Apple Push Notification service)
    • gcm or c2dm: Android (Cloud to subscriber Messaging)
    • mpns Window Phone (Microsoft Push Notification Service)
  • token: The device registration id delivered by the platform's push notification service
Allowed parameters:
  • lang: The language code for the of the subscriber. This parameter is used to determine which message translation to use when pushing text notifications. You may use the 2 chars ISO code or a complete locale code (i.e.: en_CA) or any value you want as long as you provide the same values in your events. See below for info about events formatting.
  • badge: The current app badge value. This parameter is only applicable to iOS for which badge counters must be maintained server side. On iOS, when a user read or loads more unread items, you must inform the server of the badge's new value. This badge value will be incremented automatically by pushd each time a new notification is sent to the subscriber.
  • category: The category for the push notification action. This parameter is only applicable to iOS8.
  • contentAvailable: The 'content-available' flag value. This parameter is only applicable to iOS7 and applications which support Silent Remote Notifications or Newsstand capability. With iOS7 it is possible to have the application wake up before the user opens the app.
  • version: This is the OS subscriber version. This parameter is only needed by Windows Phone OS. By setting this value to 7.5 or greater an mpns subscriber ids will enable new MPNS push features.
Return Codes
  • 200 subscriber previously registered
  • 201 subscriber successfully registered
  • 400 Invalid specified registration id or protocol

Update subscriber Registration Info

On each app launch, it is highly recommended to update your subscriber information in order to inform pushd your subscriber is still alive and registered for notifications. Do not forget to check if the app notifications hasn't been disabled since the last launch, and call DELETE if so. If this request returns a 404 error, it means your subscriber registration has been cancelled by pushd. You must then delete the previously obtained subscriber id and restart the registration process for this subscriber. Registration can be cancelled after pushd error count for the subscriber reached a predefined threshold or if the target platform push service informed pushd about an inactive subscriber (i.e. Apple Feedback Service).

> POST /subscriber/SUBSCRIBER_ID HTTP/1.1
> Content-Type: application/x-www-form-urlencoded
>
> lang=fr&badge=0
>
---
< HTTP/1.1 204 No Content
Allowed parameters:
  • lang: The language code for the of the subscriber. This parameter is used to determine which message translation to use when pushing text notifications. You may use the 2 chars ISO code or a complete locale code (i.e.: en_CA) or any value you want as long as you provide the same values in your events. See below for info about events formatting.
  • badge: The current app badge value. This parameter is only applicable to iOS for which badge counters must be maintained server side. On iOS, when a user read or loads more unread items, you must inform the server of the badge's new value. This badge value will be incremented automatically by pushd each time a new notification is sent to the subscriber.
  • version: This is the OS subscriber version. This parameter is only needed by Windows Phone OS. By setting this value to 7.5 or greater an mpns subscriber ids will enable new MPNS push features.

NOTE: this method should be called each time the app is opened to inform pushd the subscriber is still alive. If you don’t, the subscriber may be automatically unregistered in case of repeated push error.

Return Codes
  • 204 subscriber info edited successfully
  • 400 Format of the subscriber id or a field value is invalid
  • 404 The specified subscriber does not exist

Unregister a subscriber ID

When the user chooses to disable notifications from within your app, you can delete the subscriber from pushd so pushd won't send further push notifications.

> DELETE /subscriber/SUBSCRIBER_ID HTTP/1.1
>
---
< HTTP/1.1 204 No Content
Return Codes
  • 204 subscriber unregistered successfully
  • 400 Invalid subscriber id format
  • 404 The specified subscriber does not exist

Get information about a subscriber ID

You may want to read informations stored about a subscriber id.

> GET /subscriber/SUBSCRIBER_ID HTTP/1.1
>
---
< HTTP/1.1 200 Ok
< Content-Type: application/json
<
< {
<   "created":1332638892,
<   "updated":1332638892,
<   "proto":"apns",
<   "token":"FE66489F304DC75B8D6E8200DFF8A456E8DAEACEC428B427E9518741C92C6660",
<   "lang":"fr",
<   "badge":10
< }

Carriage returns are added for readability

Return Codes
  • 200 subscriber exists, information returned
  • 400 Invalid subscriber id format
  • 404 The specified subscriber does not exist

Self Subscriber Test

You may want to test from your app if the push notification system is working. You can test this by POSTing an empty body on /subscriber/SUBSCRIBER_ID/test. Pushd will send back a test notification with "Test" as message and {"test": "ok"} as data.

> POST /subscriber/SUBSCRIBER_ID/test HTTP/1.1
>
--
< HTTP/1.1 201 Created
Return Codes
  • 200 subscriber exists, information returned
  • 400 Invalid subscriber id format
  • 404 The specified subscriber does not exist

Subscribe to an Event

For pushd, an event is represented as a simple string. By default a subscriber won't receive push notifications other than broadcasts or direct messages if it’s not subscribed to events. Events are text and/or data sent by your service on pushd. Pushd's role is to convert this event into a push notification for any subscribed subscriber.

You subscribe a previously registered subscriber by POSTing on /subscriber/SUBSCRIBER_ID/subscriptions/EVENT_NAME where EVENT_NAME is a unique string code for the event. You may post an option parameter to configure the subscription.

> POST /subscriber/SUBSCRIBER_ID/subscriptions/EVENT_NAME HTTP/1.1
> Content-Type: application/x-www-form-urlencoded
>
> ignore_message=1
>
---
< HTTP/1.1 204 No Content
Allowed Parameter
  • ignore_message: Defaults to 0, if set to 1, the message part of the subscribed event won't be sent with the notification. On iOS, the badge will still be incremented and updated. You can use this to update the badge counter on iOS without disturbing the user if he didn't want to be explicitly notified for this event but still wants to know how many new items are available. On Android you may use this kind of subscription to notify your application about new items available so it can perform background pre-fetching without user notification.
Return Codes
  • 201 Subscription successfully created
  • 204 Subscription successfully updated
  • 400 Invalid subscriber id event name format
  • 404 The specified subscriber does not exist

Unsubscribe from an Event

To unsubscribe from an event, perform a DELETE on the subscription URL.

> DELETE /subscriber/SUBSCRIBER_ID/subscriptions/EVENT_NAME HTTP/1.1
>
---
< HTTP/1.1 204 No Content
Return Codes
  • 204 Subscription deleted
  • 400 Invalid subscriber id or event name format
  • 404 The specified subscriber does not exist

List subscribers’ Subscriptions

To get the list of events a subscriber is subscribed to, perform a GET on /subscriber/SUBSCRIBER_ID/subscriptions.

> GET /subscriber/SUBSCRIBER_ID/subscriptions HTTP/1.1
>
---
< HTTP/1.1 200 Ok
< Content-Type: application/json
<
< {
<   "EVENT_NAME": {"ignore_message": false},
<   "EVENT_NAME2": ...
< }

To test for the presence of a single subscription, perform a GET on the subscription URL

> GET /subscriber/SUBSCRIBER_ID/subscriptions/EVENT_NAME HTTP/1.1
>
---
< HTTP/1.1 200 Ok
< Content-Type: application/json
<
< {"ignore_message":false}

Bulk edit subscribers's Subscriptions

To set all subscriptions in one request, perform a POST with a JSON object on /subscriber/SUBSCRIBER_ID/subscriptions with event names as key and a dictionary of options as value or null.

> POST /subscriber/SUBSCRIBER_ID/subscriptions HTTP/1.1
> Content-Type: application/json
>
> {
>   "EVENT_NAME": {"ignore_message": false},
>   "EVENT_NAME2": ...
> }
---
< HTTP/1.1 200 Ok

Event Ingestion

To generate notifications, your service must send events to pushd. The service doesn't have to know if a subscriber is subscribed to an event in order to send it, it just sends all subscriptable events as they happen and pushd handles the rest.

It is also possible to ignore subscriptions and generate notifications directly using specialized event names.

An event is some key/value pairs in a specific format sent to pushd either using HTTP POST or UDP datagrams.

Event names

The event name is commonly used to send notifications for registered subscriptions. There are two exceptions, in which case notifications can be sent without a subscription:

  • broadcast sends the notification to all subscribers
  • unicast:SUBSCRIBER_ID sends the notification to the subscriber with the specified id

Event Message Format

An event message is a dictionary of optional key/values:

  • title, msg: The event title/message. If no title nor message are provided, the event will only send data to the app and won't notify the user. The title is only relevant for Android and Windows Phone, iOS doesn't support this value: the application name is always used as notification title. The value can contain placeholders to other keys, see Message Template bellow.
  • title.<lang>, msg.<lang>: The translated version of the event title/message. The <lang> part must match the lang property of a target subscriber. If subscribers use full locale (i.e. fr_CA), and no matching locale value is provided, pushd will fallback to a language only version of the value if any (i.e. fr). If no translation matches, the title or msg key is used. The value can contain placeholders to other keys, see Message Template bellow.
  • data.<key>: Key/values to be attached to the notification
  • var.<key>: Stores strings to be reused in msg and <lang>.msg contents
  • sound: The name of a sound file to be played. It must match a sound file name contained in you bundle app. (iOS only)

Event Message Template

The msg and <lang>.msg keys may contain references to others keys in the event object. You may refer either to data.<key> or var.<key>. Use the ${<key name>} syntax to refer to those keys (ex: ${var.title}).

Here is an example of an event message using translations and templating (spaces and carriage returns have been added for readability):

msg=${var.name} sent a new video: ${var.title}
msg.fr=${var.name} a envoyé une nouvelle video: ${var.title}
sound=newVideo.mp3
data.user_id=fkwhpd
data.video_id=1k3dxk
var.name=John Doe
var.title=Super awesome video

Event API

HTTP

To send an event to pushd over HTTP, POST some urlencoded key/value pairs to the /event/EVENT_NAME endpoint of the pushd server:

> POST /event/user.newVideo:fkwhpd HTTP/1.1
> Content-Type: application/x-www-form-urlencoded
>
> msg=${var.name} sent a new video: ${var.title}&
> msg.fr=${var.name} a envoyé une nouvelle video: ${var.title}&
> sound=newVideo.mp3&
> data.user_id=fkwhpd&
> data.video_id=1k3dxk&
> var.name=Jone Doe&
> var.title=Super awesome video
---
< HTTP/1.1 204 Ok

Carriage returns are added for readability

The server will answer OK immediately. This doesn't mean the event has already been delivered.

UDP

The UDP event posting API consists of a UDP datagram targeted at the UDP port 80 containing the URI of the event followed by the message content as query-string compressed using gzip:

GZIP(POST /event/user.newVideo:fkwhpd?msg=%24%7Bvar.name%7D+sent+a+new+video%3A+%24%7Bvar.title%7D&msg.fr=%24%7Bvar…)

Here is a simple PHP example to post an UDP event:

$pushdHost = '1.2.3.4';
$pushdPort = 80;
$eventName = 'user.newVideo:fkwhpd';
$payload = array
(
    'msg' => '${var.name} sent a new video: ${var.title}',
    'msg.fr' => '${var.name} a envoyé une nouvelle video: ${var.title}',
    'sound' => 'newVideo.mp3',
    'data.user_id' => 'fkwhpd',
    'data.video_id' => '1k3dxk',
    'var.name' => 'Jone Doe',
    'var.title' => Super awesome video'
);
$msg = gzcompress('POST /event/' . urldecode($eventName) . '?' . http_build_query($payload));
$socket = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP);
socket_sendto($socket, $msg, strlen($msg), 0, $pushdHost, $pushdPort);
socket_close($socket);

Event Statistics

When an event get at least one subscriber, pushd start to account some statistics on the event. Those stats persists until the event keep at least one subscriber. Those statistics can be used for monitoring or to present stats about the event to the user like approx number of notification per day for this event.

To get statistics from an event, perform a GET on /event/EVENT_NAME:

> GET /event/EVENT_NAME HTTP/1.1
>
---
< HTTP/1.1 200 Ok
< Content-Type: application/json
<
< {
<   "created": 1334097188,
<   "total": 154
< }
Return Codes
  • 200 Statistics returned
  • 404 The specified event does not exist

Event Purge

When the application data provider know about a particular event will no longer be available, it can force pushd to forget about it and unsubscribe all current subscribers from it. To purge an event, perform a DELETE on /event/EVENT_NAME

> DELETE /event/EVENT_NAME HTTP/1.1
>
---
< HTTP/1.1 204 Ok
<

The DELETE method is also available thrus UDP.

Return Codes
  • 204 Event deleted
  • 404 The specified event does not exist

Monitoring

Check service status

Ensures that the service is running and connected to Redis.

> GET /status HTTP/1.1
>
---
< HTTP/1.1 204 No Content 
Return Codes
  • 204 Server running and connected to Redis
  • 503 Server running but not connected to Redis

Logging

The verbosity of logging can be configured with the loglevel property in settings.coffee.

exports['loglevel'] = 'verbose'

Possible levels:

  • error: log errors only
  • warn: log also warnings
  • info: log status messages
  • verbose: log event and subscriber creation and deletion
  • silly: log submitted message content

Testing

Unit tests

npm test

Performance testing

See tests/performance/README.md.

License

(The MIT License)

Copyright (c) 2011 Olivier Poitrey [email protected]

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the 'Software'), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

pushd's People

Contributors

afterthought avatar argon avatar behrad avatar catwashere avatar danielheckrath avatar fvant avatar guglie avatar jvah avatar kennethlj avatar krzysiekbielicki avatar marcelfalliere avatar mennopruijssers avatar mscheffer avatar peleccom avatar przemeq avatar pwyrobek avatar rapropos avatar reu avatar rs avatar yanncoupin avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

pushd's Issues

What is the best practice while subscribing to events

I have written a chat application in PHP which uses Pushd to send new message notification. When the user registers for the first time, I have created an event which is unique to that user and everytime when I have to send the push notification to that user I send the message to that event.

This scenario is fine in case of one to one chat. But when it comes to Group chat, Should I create a separate event for that group Or intelligently find out the events corresponding to recipients and push the message?

In short, what is the best practice- Use minimum number of events or Use minimum number of subscriptions per user?

Connection refused

Pushd is sending notifications out, but sometimes users don't receive some push notifications. We discovered that pushd sometimes seems to refuse the connection.
Any thoughts how to solve this?

This is what we see:
{ Error: connect ECONNREFUSED
code: 'ECONNREFUSED',
errno: 'ECONNREFUSED',
syscall: 'connect' }

GCM Automatic unregistration for subscriber

I have my Android app successfully registering with my pushd server:

coffee log file messages:

verbose: Registering subscriber: {"proto":"gcm","token":"5C031846816AE7D69FC6FD222D272EB121FD8FFC"}
verbose: creating subscriber proto = gcm, token = 5C031846816AE7D69FC6FD222D272EB121FD8FFC
POST /subscribers 201
verbose: Registered subscriber 2JhNnIHO-5w to event newband
POST /subscriber/2JhNnIHO-5w/subscriptions/newband 201

I can check the subscriptions for this subscriber using curl, and I see it:

verbose: Status of 2JhNnIHO-5w: {"newband":{"ignore_message":false}}
GET /subscriber/2JhNnIHO-5w/subscriptions 200

But when I try and use curl to send a message to the event newband, I get the following in the coffee log:

POST /event/newband 204
verbose: Pushing message for event newband
silly: Title: Test
silly: More Stuff
verbose: Pushed to 2 subscribers
verbose: 1 gcm subscribers
verbose: 1 apns subscribers
warn: GCM Automatic unregistration for subscriber 2JhNnIHO-5w

And this subscriber is no longer subscribed to the event newband.

What am I doing wrong?

JSON reply

Hi,

We are trying to play with pushd (with event-source proto) but when we want to register our app with the push notification service nothing happen (no JSON reply). Have you ever face this problem?

EDIT: I solve my issue by create unixsocket.

Thanks,
Bilal

How run both Dev and Prod for IOS

How do you setup the coffee.setting so that you can do either Prod or Dev on the same server for IOS and decide via parameter if you are going to register on prod or dev.

apns-cert.pem issue

me@ubuntu:~/pushd$ sudo coffee pushd.coffee
info: Registering push service: event-source
info: Registering push service: apns
info: Registering push service: gcm
info: Registering push service: http
info: Registering push service: mpns-toast
info: Registering push service: mpns-tile
info: Registering push service: mpns-raw
info: Listening on tcp port 80
info: Listening on udp port 80
error: APNS Error Error: ENOENT, no such file or directory 'apns-cert.pem' for subscriber undefined

The error at the end is something i am unable to understand and resolve, please help.

Error deploying to heroku

Continuously getting this error : npm ERR! Error: Cannot find module 'readable-stream'

When attempting to deploy to Heroku for testing.

What is causing this problem?

Installing dependencies with npm
npm ERR! Error: Cannot find module 'readable-stream'
npm ERR! at Function.Module._resolveFilename (module.js:338:15)
npm ERR! at Function.Module._load (module.js:280:25)
npm ERR! at Module.require (module.js:362:17)
npm ERR! at require (module.js:378:17)
npm ERR! at Object. (/tmp/node-npm-eqJY/node_modules/sha/index.js:3:48)
npm ERR! at Module._compile (module.js:449:26)
npm ERR! at Object.Module._extensions..js (module.js:467:10)
npm ERR! at Module.load (module.js:356:32)
npm ERR! at Function.Module._load (module.js:312:12)
npm ERR! at Module.require (module.js:362:17)
npm ERR! If you need help, you may report this log at:
npm ERR! http://github.com/isaacs/npm/issues
npm ERR! or email it to:
npm ERR! [email protected]

   npm ERR! System Linux 3.8.11-ec2
   npm ERR! command "/tmp/node-node-vzFI/bin/node" "/tmp/node-npm-eqJY/cli.js" "install" "--production"
   npm ERR! cwd /tmp/build_2sqhgpk0vquy5
   npm ERR! node -v v0.8.25
   npm ERR! npm -v 1.3.5
   npm ERR! code MODULE_NOT_FOUND
   npm ERR! 
   npm ERR! Additional logging details can be found in:
   npm ERR!     /tmp/build_2sqhgpk0vquy5/npm-debug.log
   npm ERR! not ok code 0

How do I create an event?

I am trying to use curl to create an event from the command line to test pushd. I can register and I can ping, but I don't see how to create an event.

Thanks!

error: MPNS Error: (200) Error: read ECONNRESET

Hello, i'm using pushd to send notification to wp device. I've succesfully send a notification to a device, but when devices subscribed are more than one i get this error

error: MPNS Error : (undefined) Error: getaddrinfo ENOTFOUND (firts error)
and then
error: MPNS Error: (200) Error: read ECONNRESET (foreach device subscribed)

i'm using the latest verision of node.js(v0.10.26) on Centos
is this a known iussue?

content-available

Hello,

I tried to send a notification with content-available param but it seems that pushd doesn't recognize it. Is there a way to do it ? Otherwise do you plan to add this feature?

Thank you

curl: (7) couldn't connect to host

Running both redis and pushd.coffee as background processes. I was trying some curl commands from the doc. The first command responds normal and the second gives 'curl: (7) couldn't connect to host'. I see that the process just has stopped working.

The trace gives:
select(6, [3 5], [], NULL, NULL) = ? ERESTARTNOHAND (To be restarted)
--- SIGCHLD (Child exited) @ 0 (0) ---
write(6, "\21", 1) = 1
rt_sigreturn(0x6) = -1 EINTR (Interrupted system call)
select(6, [3 5], [], NULL, NULL) = 1 (in [5])
read(5, "\21", 1) = 1
wait4(3250, [{WIFEXITED(s) && WEXITSTATUS(s) == 8}], WNOHANG|WSTOPPED, NULL) = 3250
rt_sigprocmask(SIG_BLOCK, NULL, [], 8) = 0
getuid() = 0
sendto(7, "<86>May 24 22:29:47 sudo: pam_un"..., 78, MSG_NOSIGNAL, NULL, 0) = 78
munmap(0x7f16620f9000, 2109656) = 0
munmap(0x7f1661edf000, 2200480) = 0
munmap(0x7f1661ca6000, 2327040) = 0
munmap(0x7f1661a87000, 2221680) = 0
munmap(0x7f1661885000, 2101280) = 0
munmap(0x7f1661683000, 2101296) = 0
munmap(0x7f1661480000, 2105560) = 0
exit_group(8) = ?

What is causing this problem?

Sending raw notifications on WP8

Hi,
I've just noticed that pushd supports toast and tile modes for the MPNS protocol. Am I missing something or the raw mode isn't implemented yet? What's the workaround for this?

Second Instance of pushd on 1 Server

Is it possible to use a second instance for a second app on the same server with a different redis database?

is it enough to just modify: pushd.coffee like so:

redis = require('redis').createClient(settings.server.redis_socket or          settings.server.redis_port, settings.server.redis_host).select(2) <<<--- add this select!?

how to configure pushd on production?

Hello, we tested pushd on development mode and everything works fine. When using it on distribution mode (InHouse), we didn't succeed to receive a push on any device, even if we've changed the certificates with the ones for distribution, and commented the lines of code for apns sandbox server. Is there anything else to configure? The devices do register to pushNotifications when first run of the application, so the distribution certificates should be ok

How to unscubscribe to all events at once?

I have a need for a dynamic list of events, rather than keeping track of to-be-removed events in my app, i'd like to unsubscribe all at once and then (re)subscribe in bulk.

Push messages are not sent to every devices

It seems there is a bug when sending push messages.
On my application, I have 25k users on iPhone and 10k on Android but almost none receive the messages on iPhone whereas less than 30% receive it on Android. I can't find any error in the logs.

Because I though the apn plugin could be the problem, I changed it to the last version available but it doesn't change anything.

Have you got any ideas what could be wrong?

Cannot register device in development push

Hi, I generated the .cer and .p12 pair. it's OK cause I had tested via:
"openssl s_client -connect gateway.sandbox.push.apple.com:2195 -cert apns-dev.pem -key apns-key.pem"

I started pushed server, it's ok too, listening port 80.

but When I register my device (token is extracted fron app delegate),

pushd server alway return
{
"error": "Unauthorized"
}

Can someone help me?

Feedback service handling

It's not possible to get a list of tokens which are deleted based on the feedback service. The code shows pushd automatically deletes those tokens, but we want to update this on other servers too. Node-apn does offer this, so it would be great if pushd does the exact same implementation on feedback service as node-apn.

Pushd asks for pass phrase in case of APNS everytime after a specific interval.

When running Pushd for apns, it asks the PEM Passphrase after a specific interval of time. The thing is that , this service is going to run in the background or as a daemon so entering pass phrase everytime is not viable.

Is there a workaround for this?

I tried to change the default pass phrase in connection.js and feedback.js in
folder : pushd/node_modules/apn/lib
It worked for a few notifications but failed later.

Use var.<mykey>

Hello,

I am trying to use and define var. but it seems that I cannot retrive it. In the msg I use '${var.}' and it's write '${var.} on the message.

Someone can help me with this ?

Regards,

Bilal

Testing connections to providers

I am trying to send push messages to APNS. I am able to register, subscribe and send events to pushd correctly, but apple doesn't appear to be sending any messages to the devices

How can I debug further?

Can event name be an emailadres ?

I'd like to push to users (devices, browsers) based on their accountname, typically an emailadress.

i have changed the regexp in the eventource code to include @ so i can push to it but the call to test for event existince keeps failing.

Self Subscriber Test make pushd crash with http pushservice

With HTTP POST pushservices, calling the self Subscriber Test crash pushd:

POST /subscriber/1yhW0rbTM84/test 201

/home/xxxxxxx/pushd/node_modules/redis/index.js:551
throw err;
^
TypeError: Cannot read property 'name' of undefined
at /home/xxxxxxx/pushd/lib/pushservices/http.coffee:34:31
at Subscriber.get (/home/xxxxxxx/pushd/lib/subscriber.coffee:153:16)
at PushServiceHTTP.push (/home/xxxxxxx/pushd/lib/pushservices/http.coffee:25:25)
at /home/xxxxxxx/pushd/lib/pushservices.coffee:24:18
at /home/xxxxxxx/pushd/lib/subscriber.coffee:165:20
at try_callback (/home/xxxxxxx/pushd/node_modules/redis/index.js:548:9)
at RedisClient.return_reply (/home/xxxxxxx/pushd/node_modules/redis/index.js:630:13)
at HiredisReplyParser. (/home/xxxxxxx/pushd/node_modules/redis/index.js:282:14)
at HiredisReplyParser.EventEmitter.emit (events.js:95:17)
at HiredisReplyParser.execute (/home/xxxxxxx/pushd/node_modules/redis/lib/parser/hiredis.js:43:18)
at RedisClient.on_data (/home/xxxxxxx/pushd/node_modules/redis/index.js:504:27)
at Socket. (/home/xxxxxxx/pushd/node_modules/redis/index.js:82:14)
at Socket.EventEmitter.emit (events.js:95:17)
at Socket. (stream_readable.js:746:14)
at Socket.EventEmitter.emit (events.js:92:17)
at emitReadable
(_stream_readable.js:408:10)
at emitReadable (_stream_readable.js:404:5)
at readableAddChunk (_stream_readable.js:165:9)
at Socket.Readable.push (_stream_readable.js:127:10)
at TCP.onread (net.js:526:21)

Pushd not working on ubuntu

Invalid byte: ::ffff:127
at ip2long (/home/ubuntu/pushd/node_modules/netmask/lib/netmask.js:19:44)
at Netmask.contains (/home/ubuntu/pushd/node_modules/netmask/lib/netmask.js:84:17)
at /home/ubuntu/pushd/pushd.coffee:110:32
at callbacks (/home/ubuntu/pushd/node_modules/express/lib/router/index.js:161:37)
at param (/home/ubuntu/pushd/node_modules/express/lib/router/index.js:135:11)
at paramCallback (/home/ubuntu/pushd/node_modules/express/lib/router/index.js:147:30)
at /home/ubuntu/pushd/pushd.coffee:82:9
at paramCallback (/home/ubuntu/pushd/node_modules/express/lib/router/index.js:148:7)
at param (/home/ubuntu/pushd/node_modules/express/lib/router/index.js:130:11)
at pass (/home/ubuntu/pushd/node_modules/express/lib/router/index.js:142:5)
at Router._dispatch (/home/ubuntu/pushd/node_modules/express/lib/router/index.js:170:5)
at Object.router (/home/ubuntu/pushd/node_modules/express/lib/router/index.js:33:10)
at next (/home/ubuntu/pushd/node_modules/express/node_modules/connect/lib/proto.js:190:15)
at multipart (/home/ubuntu/pushd/node_modules/express/node_modules/connect/lib/middleware/multipart.js:60:27)
at /home/ubuntu/pushd/node_modules/express/node_modules/connect/lib/middleware/bodyParser.js:57:9
at IncomingMessage. (/home/ubuntu/pushd/node_modules/express/node_modules/connect/lib/middleware/urlencoded.js:70:11)
at IncomingMessage.emit (events.js:104:17)
at _stream_readable.js:898:16
at process._tickCallback (node.js:343:11)

Setup Question

I have successfully installed pushd, and have it running. I have the redis-server on port 6379, and coffee running off of port 881 since Apache is responding on port 80. When I try the first curl example in the README.md, my web server is responding, usually with a 404. What other steps do I need to follow to get this working properly?

Where is http://localhost/subscribers created?

Receving empty content for WP8 Push messages

We are currently developing a cross-platform software solution with PhoneGap, using the PushPlugin at client side and pushd for the server side. It is working perfectly for Android and iOS but we are having a problem in Windows Phone 8.

The WP8 app is correctly registering against the MPNS server and then against pushd (for raw notifications). If we launch a PUSH message against a registered device using Microsoft's sample project to send push notifications (http://code.msdn.microsoft.com/wpapps/Raw-Notification-Sample-71a49078), we receive them and can successfully extract the content.

But if we send a notification via pushd as we do for Android and iOS (for instance, curl -d msg=Sending%20PUSH%notification%20WP8 http://localhost:11180/event/nacho) where nacho is an event to which the WP8 app is subscribed, we receive the notification but its content is empty.

In PhoneGap, the callback method for WP8 PUSH messages reception implemented so far is as simple as follows, inspecting the content of the object received in PhoneGap

function xinspect(o,i){
if(typeof i=='undefined')i='';
if(i.length>50)return '[MAX ITERATIONS]';
var r=[];
for(var p in o){
var t=typeof o[p];
r.push(i+'"'+p+'" ('+t+') => '+(t=='object' ? 'object:'+xinspect(o[p],i+' ') : o[p]+''));
}
return r.join(i+'\n');
}

function onNotificationWP8(e) {
if (e.type == "raw" && e.jsonContent) {
alert(xinspect(e.jsonContent.Body));
}
}

The alert shows an empty JSON object ("{}"). If we inspect the object e and show its content via an alert and all we find is

emptyrawwp8pushmessage

I'd like to insist that, if we send a message via the sample project at MSDN we properly receive the message...

Maybe we are doing something wrong, but we cannot find where. Has anyone been through this problem before? How could it be solved?

I am willing to improve documentation (README.md) if some steps need to be better document in order to stop others from making the same mistake.

Thanks in advance!

Send notification to one user

The docs mention publishing an event to all subscribers... Is is also possible to publish it to only one user?
If not: Whats the best practice to emulate this behavior? Suffix the event-name with the user-id and subscribe each user also on it's "own" events?

Plans for Multiple App Keys?

Do you have plans to add support for multiple app keys? I would be happy to help if you could provide a little implementation advice/direction. Thanks!

Unauthorized

I have the coffee and redis servers running properly in the background, started by the Linux service command. I can see their messages in my log files. My subscriber has registered successfully. I can ping the server, and I have created a subscription. When I try to send an event, I get an error in my coffee log.

curl -d msg=Hello http://www.plugmyband.com/event/newband

Error:
POST /event/newband 204
verbose: Pushing message for event newband
verbose: Pushed to 2 subscribers
verbose: 2 gcm subscribers
Unauthorized
error: GCM Error: empty response

I am guessing that this is some permission issue somewhere, just not sure what it is...

how to format message body for iOS?

Hi guys,
when generating an event, how should be the body of the message formatted, so that iOS will know to interpret it, and won't display only the badge incremented number?
If I add the following in the body: title=My_title&msg=My_msg, the badge is incremented, but the notification does not show up at all.
Thanks

crash at second HTTP POST /subscribers

Bonjour,

so I'm posting to /subscribers like so 👍

 NSString* dToken = [[[deviceToken description]
                stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@"<>"]]
               stringByReplacingOccurrencesOfString:@" "
               withString:@""];

AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
NSDictionary *parameters = @{@"proto": @"apns", @"token":dToken};
[manager POST:@"http://<myserveurplease>/subscribers" parameters:parameters success:^(AFHTTPRequestOperation *operation, id responseObject) {

    NSString* id = [responseObject valueForKey:@"id"];


} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
    NSLog(@"Error: %@", error);
}];
  • The first time I got a deviceId.
  • without changing one line of code, I rerun the app
  • crash (the server)

Here's the log output :

/pushd_server/node_modules/redis/index.js:563
throw callback_err;
^
TypeError: Cannot read property '0' of undefined
at /pushd_server/lib/subscriber.coffee:147:20
at Command.callback (/pushd_server/node_modules/redis/index.js:1105:17)
at RedisClient.return_error (/pushd_server/node_modules/redis/index.js:559:25)
at HiredisReplyParser. (/pushd_server/node_modules/redis/index.js:306:18)
at HiredisReplyParser.EventEmitter.emit (events.js:95:17)
at HiredisReplyParser.execute (/pushd_server/node_modules/redis/lib/parser/hiredis.js:41:18)
at RedisClient.on_data (/pushd_server/node_modules/redis/index.js:535:27)
at Socket. (/pushd_server/node_modules/redis/index.js:91:14)
at Socket.EventEmitter.emit (events.js:95:17)
at Socket. (stream_readable.js:746:14)
at Socket.EventEmitter.emit (events.js:92:17)
at emitReadable
(_stream_readable.js:408:10)
at emitReadable (_stream_readable.js:404:5)
at readableAddChunk (_stream_readable.js:165:9)
at Socket.Readable.push (_stream_readable.js:127:10)
at TCP.onread (net.js:526:21)

Delete event not unregistering subscriptions

I was doing some tests with the following schema:

  1. Subscribe several users to an event
  2. Send a notification to the event
  3. Delete the event

I realized that when I delete the event, Pushd only unregister one user from the event, and if I want to unregister every user (without using DELETE subscriber/SUBSCRIBER_ID) I must call several times to delete event. In each of this calls, I will receive "error: No Event <event_name>" and one user will be unregistered. Then I have to make this call as many times as user are registered in the event.

I can solve this by using the unregister one user method (DELETE subscriber/SUBSCRIBER_ID) but I want to know if this is a bug, or it is a problem of my execution environment.

You can see the text shown in my console in the following lines:

Registering subscribers to event rnjc8sunnfmyrpb9

verbose: Registered subscriber u02xrUFRWfc to event rnjc8sunnfmyrpb9
POST /subscriber/u02xrUFRWfc/subscriptions/rnjc8sunnfmyrpb9 201
verbose: Registered subscriber R5VetRlwltk to event rnjc8sunnfmyrpb9
POST /subscriber/R5VetRlwltk/subscriptions/rnjc8sunnfmyrpb9 201
verbose: Registered subscriber Erdgg32Ludk to event rnjc8sunnfmyrpb9
POST /subscriber/Erdgg32Ludk/subscriptions/rnjc8sunnfmyrpb9 201

Pushing a message to the event rnjc8sunnfmyrpb9

POST /event/rnjc8sunnfmyrpb9 204
verbose: Pushing message for event rnjc8sunnfmyrpb9
verbose: Pushed to 3 subscribers
verbose: 3 gcm subscribers

Deleting event rnjc8sunnfmyrpb9

verbose: Deleting event rnjc8sunnfmyrpb9
verbose: Subscriber Erdgg32Ludk unregistered from event rnjc8sunnfmyrpb9
verbose: Unsubscribed 1 subscribers from rnjc8sunnfmyrpb9
DELETE /event/rnjc8sunnfmyrpb9 204

Second delete of the event rnjc8sunnfmyrpb9

verbose: Deleting event rnjc8sunnfmyrpb9
verbose: Subscriber R5VetRlwltk unregistered from event rnjc8sunnfmyrpb9
verbose: Unsubscribed 1 subscribers from rnjc8sunnfmyrpb9
DELETE /event/rnjc8sunnfmyrpb9 404
error: No event rnjc8sunnfmyrpb9

Third delete of the event rnjc8sunnfmyrpb9

verbose: Deleting event rnjc8sunnfmyrpb9
verbose: Deleting event rnjc8sunnfmyrpb9
verbose: Subscriber u02xrUFRWfc unregistered from event rnjc8sunnfmyrpb9
verbose: Unsubscribed 1 subscribers from rnjc8sunnfmyrpb9
error: No event rnjc8sunnfmyrpb9
verbose: Unsubscribed 0 subscribers from rnjc8sunnfmyrpb9
DELETE /event/rnjc8sunnfmyrpb9 404

I made some tries of fixing it inside the code, and I was able to fix it replacing in event.coffee (line 97) the method async.series with async.parallel (this was just to see what happened with that replace....i guess that this could create a lot of problems in other cases). Now after this tries I guess that the problem is that the functions executed in async.series are returning some error, so it stops to execute functions after the first error, which appears to happen in the first unregistering.

More info: I looked in redis, and the first unregistering is done right, and with some logging I realize that the second unregistering doesn't even start, so it points to some returning error in the first unregistering.

Any idea about what could be happening?

Cannot POST /suscribers

Hello.

I've just installed pushd in a droplet and I'm trying first to suscribe through a curl call from my personal machine. According to README, I'm doing the following:

curl -d proto=http -d token=FE66489F304DC75B8D6E8200DFF8A456E8DAEACEC428B427E9518741C92C6660 -d lang=en http://DROPLET_IP/suscribers

The answer is always Cannot POST /suscribers, while in pushd's console I got POST /suscribers 404

I'm trying with proto=http because I'm having the error: APNS Error Error: ENOENT, open 'apns-cert.pem' as shown in #62, since I'm not producing any certificates right now.
It's the same outcome if I change the protocol to gcm.

Any ideas of what I could be doing wrong?

How to send custom field in push notification for IOS

I have bee trying to send custom fields in apns notification. It is possible in android(GCM) where I can send custom fields using data.key=value;

In IOS when the app receives the notification these fields are not visible.

How to go about it?

Unsubscribe from all Events except of 1!

Hi have one default event everyone gets automatically subscribed to.

Other events are optional is it somehow possible to unsubscribe from all events except one WITHOUT getting all current subscriptions and unsubscribe one by one on the client side !?

Plans for Multiple App Keys?

Do you have plans to add support for multiple app keys? I would be happy to help if you could provide a little implementation advice/direction. Thanks!

Installation on Debian Squeeze fail

Hi,

I tried to install Pushd on Debian Squeeze but it failed. The whole output of installation process was:

npm install

npm http GET https://registry.npmjs.org/redis
npm http GET https://registry.npmjs.org/netmask
npm http GET https://registry.npmjs.org/async
npm http GET https://registry.npmjs.org/mocha
npm http GET https://registry.npmjs.org/should
npm http GET https://registry.npmjs.org/hiredis
npm http GET https://registry.npmjs.org/apn/1.3.1
npm http GET https://registry.npmjs.org/c2dm/1.1.0
npm http GET https://registry.npmjs.org/express
npm ERR! git clone git://github.com/rs/node-gcm.git error: unknown option mirror' npm ERR! git clone git://github.com/rs/node-gcm.git usage: git-clone [options] [--] <repo> [<dir>] npm ERR! git clone git://github.com/rs/node-gcm.git npm ERR! git clone git://github.com/rs/node-gcm.git -q, --quiet be quiet npm ERR! git clone git://github.com/rs/node-gcm.git -n, --no-checkout don't create a checkout npm ERR! git clone git://github.com/rs/node-gcm.git --bare create a bare repository npm ERR! git clone git://github.com/rs/node-gcm.git --naked create a bare repository npm ERR! git clone git://github.com/rs/node-gcm.git -l, --local to clone from a local repository npm ERR! git clone git://github.com/rs/node-gcm.git --no-hardlinks don't use local hardlinks, always copy npm ERR! git clone git://github.com/rs/node-gcm.git -s, --shared setup as shared repository npm ERR! git clone git://github.com/rs/node-gcm.git --template <path> path the template repository npm ERR! git clone git://github.com/rs/node-gcm.git --reference <repo> reference repository npm ERR! git clone git://github.com/rs/node-gcm.git -o, --origin <branch> npm ERR! git clone git://github.com/rs/node-gcm.git use <branch> instead or 'origin' to track upstream npm ERR! git clone git://github.com/rs/node-gcm.git -u, --upload-pack <path> npm ERR! git clone git://github.com/rs/node-gcm.git path to git-upload-pack on the remote npm ERR! git clone git://github.com/rs/node-gcm.git --depth <depth> create a shallow clone of that depth npm http GET https://registry.npmjs.org/coffee-script npm ERR! git clone git://github.com/rs/mpns.git error: unknown optionmirror'
npm ERR! git clone git://github.com/rs/mpns.git usage: git-clone [options] [--] [

]
npm ERR! git clone git://github.com/rs/mpns.git
npm ERR! git clone git://github.com/rs/mpns.git -q, --quiet be quiet
npm ERR! git clone git://github.com/rs/mpns.git -n, --no-checkout don't create a checkout
npm ERR! git clone git://github.com/rs/mpns.git --bare create a bare repository
npm ERR! git clone git://github.com/rs/mpns.git --naked create a bare repository
npm ERR! git clone git://github.com/rs/mpns.git -l, --local to clone from a local repository
npm ERR! git clone git://github.com/rs/mpns.git --no-hardlinks don't use local hardlinks, always copy
npm ERR! git clone git://github.com/rs/mpns.git -s, --shared setup as shared repository
npm ERR! git clone git://github.com/rs/mpns.git --template path the template repository
npm ERR! git clone git://github.com/rs/mpns.git --reference reference repository
npm ERR! git clone git://github.com/rs/mpns.git -o, --origin
npm ERR! git clone git://github.com/rs/mpns.git use instead or 'origin' to track upstream
npm ERR! git clone git://github.com/rs/mpns.git -u, --upload-pack
npm ERR! git clone git://github.com/rs/mpns.git path to git-upload-pack on the remote
npm ERR! git clone git://github.com/rs/mpns.git --depth create a shallow clone of that depth
npm ERR! Error: git "clone" "--mirror" "git://github.com/rs/node-gcm.git" "/root/.npm/_git-remotes/git-github-com-rs-node-gcm-git-3012d575" failed with 129
npm ERR! at ChildProcess. (/usr/local/lib/node_modules/npm/lib/utils/exec.js:59:20)
npm ERR! at ChildProcess.EventEmitter.emit (events.js:98:17)
npm ERR! at maybeClose (child_process.js:730:16)
npm ERR! at Socket. (child_process.js:943:11)
npm ERR! at Socket.EventEmitter.emit (events.js:95:17)
npm ERR! at Pipe.close (net.js:451:12)
npm ERR! If you need help, you may report this log at:
npm ERR! http://github.com/isaacs/npm/issues
npm ERR! or email it to:
npm ERR! [email protected]

npm ERR! System Linux 2.6.26-2-686
npm ERR! command "/usr/local/bin/node" "/usr/local/bin/npm" "install"
npm ERR! cwd /usr/local/src/pushd
npm ERR! node -v v0.10.4
npm ERR! npm -v 1.2.18
npm http 200 https://registry.npmjs.org/netmask
npm http GET https://registry.npmjs.org/netmask/-/netmask-0.0.2.tgz
npm http 200 https://registry.npmjs.org/mocha
npm http GET https://registry.npmjs.org/mocha/-/mocha-1.9.0.tgz
npm http 200 https://registry.npmjs.org/should
npm http GET https://registry.npmjs.org/should/-/should-1.2.2.tgz
npm http 200 https://registry.npmjs.org/hiredis
npm http GET https://registry.npmjs.org/hiredis/-/hiredis-0.1.15.tgz
npm http 304 https://registry.npmjs.org/express
npm http 200 https://registry.npmjs.org/redis
npm http 200 https://registry.npmjs.org/apn/1.3.1
npm http GET https://registry.npmjs.org/express/-/express-3.1.2.tgz
npm http GET https://registry.npmjs.org/apn/-/apn-1.3.1.tgz
npm http GET https://registry.npmjs.org/redis/-/redis-0.8.3.tgz
npm http 200 https://registry.npmjs.org/c2dm/1.1.0
npm http GET https://registry.npmjs.org/c2dm/-/c2dm-1.1.0.tgz
npm http 304 https://registry.npmjs.org/coffee-script
npm http GET https://registry.npmjs.org/coffee-script/-/coffee-script-1.2.0.tgz
npm http 200 https://registry.npmjs.org/netmask/-/netmask-0.0.2.tgz
npm http 200 https://registry.npmjs.org/async
npm http GET https://registry.npmjs.org/async/-/async-0.2.7.tgz
npm http 200 https://registry.npmjs.org/mocha/-/mocha-1.9.0.tgz
npm http 200 https://registry.npmjs.org/should/-/should-1.2.2.tgz
npm http 200 https://registry.npmjs.org/apn/-/apn-1.3.1.tgz
npm http 200 https://registry.npmjs.org/hiredis/-/hiredis-0.1.15.tgz
npm http 200 https://registry.npmjs.org/express/-/express-3.1.2.tgz
npm http 200 https://registry.npmjs.org/redis/-/redis-0.8.3.tgz
npm http 200 https://registry.npmjs.org/c2dm/-/c2dm-1.1.0.tgz
npm http 200 https://registry.npmjs.org/coffee-script/-/coffee-script-1.2.0.tgz
npm http 200 https://registry.npmjs.org/async/-/async-0.2.7.tgz
npm ERR!
npm ERR! Additional logging details can be found in:
npm ERR! /usr/local/src/pushd/npm-debug.log
npm ERR! not ok code 0

Hope you - ore anybody - can help me out.

Best regards,

AceLine

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.