Almost read to publish
This commit is contained in:
		
							parent
							
								
									4fcb3891a2
								
							
						
					
					
						commit
						0f495b881a
					
				
					 25 changed files with 229 additions and 70 deletions
				
			
		|  | @ -21,7 +21,7 @@ If desired, ntfy can temporarily keep notifications in an in-memory or an on-dis | ||||||
| of time is important to allow [phones](subscribe/phone.md) and other devices with brittle Internet connections to be able to retrieve | of time is important to allow [phones](subscribe/phone.md) and other devices with brittle Internet connections to be able to retrieve | ||||||
| notifications that they may have missed.  | notifications that they may have missed.  | ||||||
| 
 | 
 | ||||||
| By default, ntfy keeps messages in memory for 12 hours, which means that **cached messages do not survive an application | By default, ntfy keeps messages **in-memory for 12 hours**, which means that **cached messages do not survive an application | ||||||
| restart**. You can override this behavior using the following config settings: | restart**. You can override this behavior using the following config settings: | ||||||
| 
 | 
 | ||||||
| * `cache-file`: if set, ntfy will store messages in a SQLite based cache (default is empty, which means in-memory cache). | * `cache-file`: if set, ntfy will store messages in a SQLite based cache (default is empty, which means in-memory cache). | ||||||
|  | @ -29,7 +29,7 @@ restart**. You can override this behavior using the following config settings: | ||||||
| * `cache-duration`: defines the duration for which messages are stored in the cache (default is `12h`) | * `cache-duration`: defines the duration for which messages are stored in the cache (default is `12h`) | ||||||
| 
 | 
 | ||||||
| Subscribers can retrieve cached messaging using the [`poll=1` parameter](subscribe/api.md#polling), as well as the | Subscribers can retrieve cached messaging using the [`poll=1` parameter](subscribe/api.md#polling), as well as the | ||||||
| [`since=` parameter](subscribe/api.md#since). | [`since=` parameter](subscribe/api.md#fetching-cached-messages). | ||||||
| 
 | 
 | ||||||
| ## Behind a proxy (TLS, etc.) | ## Behind a proxy (TLS, etc.) | ||||||
| 
 | 
 | ||||||
|  | @ -42,27 +42,27 @@ flag. This will instruct the [rate limiting](#rate-limiting) logic to use the `X | ||||||
| identifier for a visitor, as opposed to the remote IP address. If the `behind-proxy` flag is not set, all visitors will | identifier for a visitor, as opposed to the remote IP address. If the `behind-proxy` flag is not set, all visitors will | ||||||
| be counted as one, because from the perspective of the ntfy server, they all share the proxy's IP address. | be counted as one, because from the perspective of the ntfy server, they all share the proxy's IP address. | ||||||
| 
 | 
 | ||||||
| **TLS/SSL:** ntfy supports HTTPS/TLS by setting the `listen-https` config option. However, if you are behind a proxy, it is | **TLS/SSL:** ntfy supports HTTPS/TLS by setting the `listen-https` [config option](#config-options). However, if you  | ||||||
| recommended that TLS/SSL termination is done by the proxy itself. | are behind a proxy, it is recommended that TLS/SSL termination is done by the proxy itself. | ||||||
| 
 | 
 | ||||||
| ## Firebase (FCM) | ## Firebase (FCM) | ||||||
| !!! info | !!! info | ||||||
|     Using Firebase is **optional** and only works if you modify and build your own Android .apk. |     Using Firebase is **optional** and only works if you modify and [build your own Android .apk](develop.md#android-app). | ||||||
|     For a self-hosted instance, it's easier to just not bother with FCM. |     For a self-hosted instance, it's easier to just not bother with FCM. | ||||||
| 
 | 
 | ||||||
| [Firebase Cloud Messaging (FCM)](https://firebase.google.com/docs/cloud-messaging) is the Google approved way to send | [Firebase Cloud Messaging (FCM)](https://firebase.google.com/docs/cloud-messaging) is the Google approved way to send | ||||||
| push messages to Android devices. FCM is the only method that an Android app can receive messages without having to run a | push messages to Android devices. FCM is the only method that an Android app can receive messages without having to run a | ||||||
| [foreground service](https://developer.android.com/guide/components/foreground-services). | [foreground service](https://developer.android.com/guide/components/foreground-services). | ||||||
| 
 | 
 | ||||||
| For the main host [ntfy.sh](https://ntfy.sh), the [ntfy Android App](subscribe/phone.md) uses Firebase to send messages | For the main host [ntfy.sh](https://ntfy.sh), the [ntfy Android app](subscribe/phone.md) uses Firebase to send messages | ||||||
| to the device. For other hosts, instant delivery is used and FCM is not involved. | to the device. For other hosts, instant delivery is used and FCM is not involved. | ||||||
| 
 | 
 | ||||||
| To configure FCM for your self-hosted instance of the ntfy server, follow these steps: | To configure FCM for your self-hosted instance of the ntfy server, follow these steps: | ||||||
| 
 | 
 | ||||||
| 1. Sign up for a [Firebase account](https://console.firebase.google.com/) | 1. Sign up for a [Firebase account](https://console.firebase.google.com/) | ||||||
| 2. Create an app and download the key file (e.g. `myapp-firebase-adminsdk-ahnce-....json`) | 2. Create a Firebase app and download the key file (e.g. `myapp-firebase-adminsdk-...json`) | ||||||
| 3. Place the key file in `/etc/ntfy`, set the `firebase-key-file` in `config.yml` accordingly and restart the ntfy server | 3. Place the key file in `/etc/ntfy`, set the `firebase-key-file` in `config.yml` accordingly and restart the ntfy server | ||||||
| 4. Build your own Android .apk following [these instructions]() | 4. Build your own Android .apk following [these instructions](develop.md#android-app) | ||||||
| 
 | 
 | ||||||
| Example: | Example: | ||||||
| ``` | ``` | ||||||
|  | @ -100,7 +100,7 @@ During normal usage, you shouldn't encounter this limit at all, and even if you | ||||||
| reconnect after a connection drop), it shouldn't have any effect. | reconnect after a connection drop), it shouldn't have any effect. | ||||||
| 
 | 
 | ||||||
| ## Config options | ## Config options | ||||||
| Each config options can be set in the config file `/etc/ntfy/config.yml` (e.g. `listen-http: :80`) or as a | Each config option can be set in the config file `/etc/ntfy/config.yml` (e.g. `listen-http: :80`) or as a | ||||||
| CLI option (e.g. `--listen-http :80`. Here's a list of all available options. Alternatively, you can set an environment | CLI option (e.g. `--listen-http :80`. Here's a list of all available options. Alternatively, you can set an environment | ||||||
| variable before running the `ntfy` command (e.g. `export NTFY_LISTEN_HTTP=:80`). | variable before running the `ntfy` command (e.g. `export NTFY_LISTEN_HTTP=:80`). | ||||||
| 
 | 
 | ||||||
|  | @ -110,8 +110,8 @@ variable before running the `ntfy` command (e.g. `export NTFY_LISTEN_HTTP=:80`). | ||||||
| | `listen-https` | `NTFY_LISTEN_HTTPS` | `[host]:port` | - | Listen address for the HTTPS web server. If set, you also need to set `key-file` and `cert-file`. | | | `listen-https` | `NTFY_LISTEN_HTTPS` | `[host]:port` | - | Listen address for the HTTPS web server. If set, you also need to set `key-file` and `cert-file`. | | ||||||
| | `key-file` | `NTFY_KEY_FILE` | *filename* | - | HTTPS/TLS private key file, only used if `listen-https` is set. | | | `key-file` | `NTFY_KEY_FILE` | *filename* | - | HTTPS/TLS private key file, only used if `listen-https` is set. | | ||||||
| | `cert-file` | `NTFY_CERT_FILE` | *filename* | - | HTTPS/TLS certificate file, only used if `listen-https` is set. | | | `cert-file` | `NTFY_CERT_FILE` | *filename* | - | HTTPS/TLS certificate file, only used if `listen-https` is set. | | ||||||
| | `firebase-key-file` | `NTFY_FIREBASE_KEY_FILE` | *filename* | - | If set, also publish messages to a Firebase Cloud Messaging (FCM) topic for your app. This is optional and only required to save battery when using the Android app. | | | `firebase-key-file` | `NTFY_FIREBASE_KEY_FILE` | *filename* | - | If set, also publish messages to a Firebase Cloud Messaging (FCM) topic for your app. This is optional and only required to save battery when using the Android app. See [Firebase (FCM](#firebase-fcm). | | ||||||
| | `cache-file` | `NTFY_CACHE_FILE` | *filename* | - | If set, messages are cached in a local SQLite database instead of only in-memory. This allows for service restarts without losing messages in support of the since= parameter. | | | `cache-file` | `NTFY_CACHE_FILE` | *filename* | - | If set, messages are cached in a local SQLite database instead of only in-memory. This allows for service restarts without losing messages in support of the since= parameter. See [message cache](#message-cache). | | ||||||
| | `cache-duration` | `NTFY_CACHE_DURATION` | *duration* | 12h | Duration for which messages will be buffered before they are deleted. This is required to support the `since=...` and `poll=1` parameter. | | | `cache-duration` | `NTFY_CACHE_DURATION` | *duration* | 12h | Duration for which messages will be buffered before they are deleted. This is required to support the `since=...` and `poll=1` parameter. | | ||||||
| | `keepalive-interval` | `NTFY_KEEPALIVE_INTERVAL` | *duration* | 30s | Interval in which keepalive messages are sent to the client. This is to prevent intermediaries closing the connection for inactivity. Note that the Android app has a hardcoded timeout at 77s, so it should be less than that. | | | `keepalive-interval` | `NTFY_KEEPALIVE_INTERVAL` | *duration* | 30s | Interval in which keepalive messages are sent to the client. This is to prevent intermediaries closing the connection for inactivity. Note that the Android app has a hardcoded timeout at 77s, so it should be less than that. | | ||||||
| | `manager-interval` | `$NTFY_MANAGER_INTERVAL` | *duration* | 1m | Interval in which the manager prunes old messages, deletes topics and prints the stats. | | | `manager-interval` | `$NTFY_MANAGER_INTERVAL` | *duration* | 1m | Interval in which the manager prunes old messages, deletes topics and prints the stats. | | ||||||
|  |  | ||||||
|  | @ -18,7 +18,7 @@ rsync -a root@laptop /backups/laptop \ | ||||||
| 
 | 
 | ||||||
| ## Server-sent messages in your web app | ## Server-sent messages in your web app | ||||||
| Just as you can [subscribe to topics in the Web UI](subscribe/web.md), you can use ntfy in your own | Just as you can [subscribe to topics in the Web UI](subscribe/web.md), you can use ntfy in your own | ||||||
| web application. Check out the <a href="example.html">live example</a> or just look the source of this page. | web application. Check out the <a href="/example.html">live example</a> or just look the source of this page. | ||||||
| 
 | 
 | ||||||
| ## Notify on SSH login | ## Notify on SSH login | ||||||
| Years ago my home server was broken into. That shook me hard, so every time someone logs into any machine that I | Years ago my home server was broken into. That shook me hard, so every time someone logs into any machine that I | ||||||
|  |  | ||||||
							
								
								
									
										19
									
								
								docs/faq.md
									
										
									
									
									
								
							
							
						
						
									
										19
									
								
								docs/faq.md
									
										
									
									
									
								
							|  | @ -22,23 +22,24 @@ client network disruptions. | ||||||
| 
 | 
 | ||||||
| ## Can I self-host it? | ## Can I self-host it? | ||||||
| Yes. The server (including this Web UI) can be self-hosted, and the Android app supports adding topics from | Yes. The server (including this Web UI) can be self-hosted, and the Android app supports adding topics from | ||||||
| your own server as well. There are <a href="https://github.com/binwiederhier/ntfy#installation">install instructions</a> | your own server as well. Check out the [install instructions](install.md). | ||||||
| on GitHub. |  | ||||||
| 
 | 
 | ||||||
| ## Why is Firebase used? | ## Why is Firebase used? | ||||||
| In addition to caching messages locally and delivering them to long-polling subscribers, all messages are also | In addition to caching messages locally and delivering them to long-polling subscribers, all messages are also | ||||||
| published to Firebase Cloud Messaging (FCM) (if `FirebaseKeyFile` is set, which it is on ntfy.sh). This | published to Firebase Cloud Messaging (FCM) (if `FirebaseKeyFile` is set, which it is on ntfy.sh). This | ||||||
| is to facilitate instant notifications on Android. | is to facilitate notifications on Android.  | ||||||
|     </p> | 
 | ||||||
|  | If you do not care for Firebase, I suggest you install the [F-Droid version](https://f-droid.org/en/packages/io.heckel.ntfy/) | ||||||
|  | of the app and [self-host your own ntfy server](install.md). | ||||||
| 
 | 
 | ||||||
| ## How much battery does the Android app use? | ## How much battery does the Android app use? | ||||||
| If you use the ntfy.sh server and you don't use the <i>instant delivery</i> feature, the Android app uses no | If you use the ntfy.sh server and you don't use the [instant delivery](subscribe/phone.md#instant-delivery) feature,  | ||||||
| additional battery, since Firebase Cloud Messaging (FCM) is used. If you use your own server, or you use | the Android app uses no additional battery, since Firebase Cloud Messaging (FCM) is used. If you use your own server,  | ||||||
| <i>instant delivery</i>, the app has to maintain a constant connection to the server, which consumes about 4% of | or you use *instant delivery*, the app has to maintain a constant connection to the server, which consumes about 4% of | ||||||
| battery in 17h of use (on my phone). I use it and it makes no difference to me. | battery in 17h of use (on my phone). I use it, and it makes no difference to me. | ||||||
| 
 | 
 | ||||||
| ## What is instant delivery? | ## What is instant delivery? | ||||||
| Instant delivery is a feature in the Android app. If turned on, the app maintains a constant connection to the | [Instant delivery](subscribe/phone.md#instant-delivery) is a feature in the Android app. If turned on, the app maintains a constant connection to the | ||||||
| server and listens for incoming notifications. This consumes <a href="#battery-usage">additional battery</a>, | server and listens for incoming notifications. This consumes <a href="#battery-usage">additional battery</a>, | ||||||
| but delivers notifications instantly. | but delivers notifications instantly. | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -1,8 +1,79 @@ | ||||||
| # Getting started | # Getting started | ||||||
|  | ntfy lets you **send push notifications to your phone or desktop via scripts from any computer**, using simple HTTP PUT | ||||||
|  | or POST requests. I use it to notify myself when scripts fail, or long-running commands complete. | ||||||
| 
 | 
 | ||||||
| **ntfy** (pronounce: *notify*) is a simple HTTP-based [pub-sub](https://en.wikipedia.org/wiki/Publish%E2%80%93subscribe_pattern) | ## Step 1: Get the app | ||||||
| notification service. It allows you to **send push notifications to your phone or desktop via scripts from any computer**, | <a href="https://play.google.com/store/apps/details?id=io.heckel.ntfy"><img src="../../static/img/badge-googleplay.png"></a> | ||||||
| entirely **without signup, cost or setup**. It's [open source](https://github.com/binwiederhier/ntfy) if you want to run your own. | <a href="https://f-droid.org/en/packages/io.heckel.ntfy/"><img src="../../static/img/badge-fdroid.png"></a> | ||||||
|  | <a href="https://github.com/binwiederhier/ntfy/issues/4"><img src="../../static/img/badge-appstore.png"></a> | ||||||
|  | 
 | ||||||
|  | To [receive notifications on your phone](subscribe/phone.md), install the app, either via Google Play or F-Droid. | ||||||
|  | Once installed, open it and subscribe to a topic of your choosing. Topics don't have to explicitly be created, so just | ||||||
|  | pick a name and use it later when you [publish a message](publish.md). Note that **topic names are public, so it's wise  | ||||||
|  | to choose something that cannot be guessed easily.**  | ||||||
|  | 
 | ||||||
|  | For this guide, we'll just use `mytopic` as our topic name: | ||||||
|  | 
 | ||||||
|  | <figure markdown> | ||||||
|  |   { width=500 } | ||||||
|  |   <figcaption>Creating/adding your first topic</figcaption> | ||||||
|  | </figure> | ||||||
|  | 
 | ||||||
|  | That's it. After you tap "Subscribe", the app is listening for new messages on that topic. | ||||||
|  | 
 | ||||||
|  | ## Step 2: Send a message | ||||||
|  | Now let's [send a message](publish.md) to our topic. It's easy in every language, since we're just using HTTP PUT or POST. The message | ||||||
|  | is in the request body. Here's an example showing how to publish a simple message using a POST request: | ||||||
|  | 
 | ||||||
|  | === "Command line (curl)" | ||||||
|  |     ``` | ||||||
|  |     curl -d "Backup successful 😀" ntfy.sh/mytopic | ||||||
|  |     ``` | ||||||
|  | 
 | ||||||
|  | === "HTTP" | ||||||
|  |     ``` http | ||||||
|  |     POST /mytopic HTTP/1.1 | ||||||
|  |     Host: ntfy.sh | ||||||
|  |      | ||||||
|  |     Backup successful 😀 | ||||||
|  |     ``` | ||||||
|  | 
 | ||||||
|  | === "JavaScript" | ||||||
|  |     ``` javascript | ||||||
|  |     fetch('https://ntfy.sh/mytopic', { | ||||||
|  |         method: 'POST', // PUT works too | ||||||
|  |         body: 'Backup successful 😀' | ||||||
|  |     }) | ||||||
|  |     ``` | ||||||
|  | 
 | ||||||
|  | === "Go" | ||||||
|  |     ``` go | ||||||
|  |     http.Post("https://ntfy.sh/mytopic", "text/plain", | ||||||
|  |        strings.NewReader("Backup successful 😀")) | ||||||
|  |     ``` | ||||||
|  | 
 | ||||||
|  | === "PHP" | ||||||
|  |     ``` php-inline | ||||||
|  |     file_get_contents('https://ntfy.sh/mytopic', false, stream_context_create([ | ||||||
|  |         'http' => [ | ||||||
|  |             'method' => 'POST', // PUT also works | ||||||
|  |             'header' => 'Content-Type: text/plain', | ||||||
|  |             'content' => 'Backup successful 😀' | ||||||
|  |         ] | ||||||
|  |     ])); | ||||||
|  |     ``` | ||||||
|  | 
 | ||||||
|  | This will create a notification that looks like this: | ||||||
|  | 
 | ||||||
|  | <figure markdown> | ||||||
|  |   { width=500 } | ||||||
|  |   <figcaption>Android notification</figcaption> | ||||||
|  | </figure> | ||||||
|  | 
 | ||||||
|  | That's it. You're all set. Go play and read the rest of the docs. I highly recommend reading at least the page on | ||||||
|  | [publishing messages](publish.md), as well as the detailed page on the [Android app](subscribe/phone.md). | ||||||
|  | 
 | ||||||
|  | Here's another video showing the entire process: | ||||||
| 
 | 
 | ||||||
| <figure> | <figure> | ||||||
|   <video controls muted autoplay loop width="650" src="static/img/overview.mp4"></video> |   <video controls muted autoplay loop width="650" src="static/img/overview.mp4"></video> | ||||||
|  |  | ||||||
|  | @ -1,7 +1,10 @@ | ||||||
| # Install your own ntfy server | # Install your own ntfy server | ||||||
| The following steps are only required if you want to **self-host your own ntfy server**. If you just want to  | **Self-hosting your own ntfy server** is pretty straight forward. Just install the binary, package or Docker image, then  | ||||||
| [send messages using ntfy.sh](publish.md), you don't need to install anything. Just use `curl` | configure it and run it. Just like any other software. No fuzz.  | ||||||
| or your favorite HTTP client. | 
 | ||||||
|  | !!! info | ||||||
|  |     The following steps are only required if you want to **self-host your own ntfy server**. If you just want to  | ||||||
|  |     [send messages using ntfy.sh](publish.md), you don't need to install anything. | ||||||
| 
 | 
 | ||||||
| ## General steps | ## General steps | ||||||
| The ntfy server comes as a statically linked binary and is shipped as tarball, deb/rpm packages and as a Docker image. | The ntfy server comes as a statically linked binary and is shipped as tarball, deb/rpm packages and as a Docker image. | ||||||
|  | @ -129,7 +132,7 @@ The [ntfy image](https://hub.docker.com/r/binwiederhier/ntfy) is available for a | ||||||
| straight forward to use. | straight forward to use. | ||||||
| 
 | 
 | ||||||
| The server exposes its web UI and the API on port 80, so you need to expose that in Docker. To use the persistent  | The server exposes its web UI and the API on port 80, so you need to expose that in Docker. To use the persistent  | ||||||
| message cache, you also need to map a volume to `/var/cache/ntfy`. To change other settings, you should map `/etc/ntfy`, | [message cache](config.md#message-cache), you also need to map a volume to `/var/cache/ntfy`. To change other settings, you should map `/etc/ntfy`, | ||||||
| so you can edit `/etc/ntfy/config.yml`. | so you can edit `/etc/ntfy/config.yml`. | ||||||
| 
 | 
 | ||||||
| Basic usage (no cache or additional config): | Basic usage (no cache or additional config): | ||||||
|  |  | ||||||
|  | @ -1,7 +1,7 @@ | ||||||
| # Privacy policy | # Privacy policy | ||||||
| 
 | 
 | ||||||
| I love free software, and I'm doing this because it's fun. I have no bad intentions, and I will | I love free software, and I'm doing this because it's fun. I have no bad intentions, and **I will | ||||||
| never monetize or sell your information. This service will always stay free and open. | never monetize or sell your information, and this service and software will always stay free and open.** | ||||||
| 
 | 
 | ||||||
| Neither the server nor the app record any personal information, or share any of the messages and topics with | Neither the server nor the app record any personal information, or share any of the messages and topics with | ||||||
| any outside service. All data is exclusively used to make the service function properly. The only external service | any outside service. All data is exclusively used to make the service function properly. The only external service | ||||||
|  |  | ||||||
							
								
								
									
										9
									
								
								docs/static/css/extra.css
									
										
									
									
										vendored
									
									
								
							
							
						
						
									
										9
									
								
								docs/static/css/extra.css
									
										
									
									
										vendored
									
									
								
							|  | @ -6,9 +6,14 @@ article { | ||||||
|     padding-bottom: 50px; |     padding-bottom: 50px; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| figure img { | figure iframe, figure img, figure video { | ||||||
|  |     filter: drop-shadow(3px 3px 3px #ccc); | ||||||
|     border-radius: 7px; |     border-radius: 7px; | ||||||
|     filter: drop-shadow(3px 3px 5px #ccc); | } | ||||||
|  | 
 | ||||||
|  | figure video { | ||||||
|  |     width: 100%; | ||||||
|  |     max-height: 450px; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| .remove-md-box { | .remove-md-box { | ||||||
|  |  | ||||||
							
								
								
									
										
											BIN
										
									
								
								docs/static/img/getting-started-add.png
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								docs/static/img/getting-started-add.png
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 90 KiB | 
							
								
								
									
										
											BIN
										
									
								
								docs/static/img/web-pin.png
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								docs/static/img/web-pin.png
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 18 KiB | 
|  | @ -168,12 +168,12 @@ format of the message. It's very straight forward: | ||||||
| | Field | Required | Type | Example | Description | | | Field | Required | Type | Example | Description | | ||||||
| |---|---|---|---|---| | |---|---|---|---|---| | ||||||
| | `id` | ✔️ | *string* | `hwQ2YpKdmg` | Randomly chosen message identifier | | | `id` | ✔️ | *string* | `hwQ2YpKdmg` | Randomly chosen message identifier | | ||||||
| | `time` | ✔️ | *int* | 1635528741 | Message date time, as Unix time stamp |   | | `time` | ✔️ | *int* | `1635528741` | Message date time, as Unix time stamp |   | ||||||
| | `event` | ✔️ | `open`, `keepalive` or `message` | `message` | Message type, typically you'd be only interested in `message` | | | `event` | ✔️ | `open`, `keepalive` or `message` | `message` | Message type, typically you'd be only interested in `message` | | ||||||
| | `topic` | ✔️ | *string* | `topic1,topic2` | Comma-separated list of topics the message is associated with; only one for all `message` events, but may be a list in `open` events | | | `topic` | ✔️ | *string* | `topic1,topic2` | Comma-separated list of topics the message is associated with; only one for all `message` events, but may be a list in `open` events | | ||||||
| | `message` | - | *string* | `Some message` | Message body; always present in `message` events | | | `message` | - | *string* | `Some message` | Message body; always present in `message` events | | ||||||
| | `title` | - | *string* | `Some title` | Message [title](../publish.md#message-title); if not set defaults to `ntfy.sh/<topic>` | | | `title` | - | *string* | `Some title` | Message [title](../publish.md#message-title); if not set defaults to `ntfy.sh/<topic>` | | ||||||
| | `tags` | - | *string array* | `["tag1","tag2"]` | List of [tags](../publish.md#tags--emojis--) that may or not map to emojis | | | `tags` | - | *string array* | `["tag1","tag2"]` | List of [tags](../publish.md#tags-emojis) that may or not map to emojis | | ||||||
| | `priority` | - | *1, 2, 3, 4, or 5* | `4` | Message [priority](../publish.md#message-priority) with 1=min, 3=default and 5=max | | | `priority` | - | *1, 2, 3, 4, or 5* | `4` | Message [priority](../publish.md#message-priority) with 1=min, 3=default and 5=max | | ||||||
| 
 | 
 | ||||||
| Here's an example for each message type: | Here's an example for each message type: | ||||||
|  |  | ||||||
|  | @ -51,7 +51,7 @@ the settings (and custom sounds or vibration) for each of the priorities: | ||||||
| </figure> | </figure> | ||||||
| 
 | 
 | ||||||
| ### Instant delivery | ### Instant delivery | ||||||
| Instant delivery is allows you to receive messages on your phone instantly, **even when your phone is in doze mode**, i.e.  | Instant delivery allows you to receive messages on your phone instantly, **even when your phone is in doze mode**, i.e.  | ||||||
| when the screen turns off, and you leave it on the desk for a while. This is achieved with a foreground service, which  | when the screen turns off, and you leave it on the desk for a while. This is achieved with a foreground service, which  | ||||||
| you'll see as a permanent notification that looks like this: | you'll see as a permanent notification that looks like this: | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -11,4 +11,10 @@ To learn how to send messages, check out the [publishing page](../publish.md). | ||||||
|     <a href="../../static/img/web-detail.png"><img src="../../static/img/web-detail.png"/></a>  |     <a href="../../static/img/web-detail.png"><img src="../../static/img/web-detail.png"/></a>  | ||||||
| </div> | </div> | ||||||
| 
 | 
 | ||||||
|  | To keep receiving desktop notifications from ntfy, you need to keep the website open. What I do, and what I highly recommend, | ||||||
|  | is to pin the tab so that it's always open, but sort of out of the way: | ||||||
| 
 | 
 | ||||||
|  | <figure markdown> | ||||||
|  |   { width=500 } | ||||||
|  |   <figcaption>Pin web app to move it out of the way</figcaption> | ||||||
|  | </figure> | ||||||
|  |  | ||||||
|  | @ -4,7 +4,7 @@ | ||||||
| <head> | <head> | ||||||
|     <meta charset="UTF-8"> |     <meta charset="UTF-8"> | ||||||
| 
 | 
 | ||||||
|     <title>ntfy.sh | PUT/POST push notifications to your phone</title> |     <title>ntfy.sh | Send push notifications to your phone via PUT/POST</title> | ||||||
|     <link rel="stylesheet" href="static/css/app.css" type="text/css"> |     <link rel="stylesheet" href="static/css/app.css" type="text/css"> | ||||||
| 
 | 
 | ||||||
|     <!-- Mobile view --> |     <!-- Mobile view --> | ||||||
|  | @ -24,7 +24,7 @@ | ||||||
|     <meta property="og:type" content="website" /> |     <meta property="og:type" content="website" /> | ||||||
|     <meta property="og:locale" content="en_US" /> |     <meta property="og:locale" content="en_US" /> | ||||||
|     <meta property="og:site_name" content="ntfy.sh" /> |     <meta property="og:site_name" content="ntfy.sh" /> | ||||||
|     <meta property="og:title" content="ntfy.sh | send push notifications to your phone or desktop via PUT/POST" /> |     <meta property="og:title" content="ntfy.sh | Send push notifications to your phone or desktop via PUT/POST" /> | ||||||
|     <meta property="og:description" content="ntfy is a simple HTTP-based pub-sub notification service. It allows you to send desktop notifications via scripts from any computer, entirely without signup or cost. Made with ❤ by Philipp C. Heckel, Apache License 2.0, source at https://heckel.io/ntfy." /> |     <meta property="og:description" content="ntfy is a simple HTTP-based pub-sub notification service. It allows you to send desktop notifications via scripts from any computer, entirely without signup or cost. Made with ❤ by Philipp C. Heckel, Apache License 2.0, source at https://heckel.io/ntfy." /> | ||||||
|     <meta property="og:image" content="/static/img/ntfy.png" /> |     <meta property="og:image" content="/static/img/ntfy.png" /> | ||||||
|     <meta property="og:url" content="https://ntfy.sh" /> |     <meta property="og:url" content="https://ntfy.sh" /> | ||||||
|  | @ -38,12 +38,13 @@ | ||||||
| <nav id="header"> | <nav id="header"> | ||||||
|     <div id="headerBox"> |     <div id="headerBox"> | ||||||
|         <img id="logo" src="static/img/ntfy.png" alt="logo"/> |         <img id="logo" src="static/img/ntfy.png" alt="logo"/> | ||||||
|         <div id="name">ntfy.sh</div> |         <div id="name">ntfy</div> | ||||||
|         <ol> |         <ol> | ||||||
|             <li><a href="docs/">Getting started</a></li> |             <li><a href="docs/">Getting started</a></li> | ||||||
|             <li><a href="docs/subscribe/phone/">Android/iOS</a></li> |             <li><a href="docs/subscribe/phone/">Android/iOS</a></li> | ||||||
|             <li><a href="docs/publish/">API</a></li> |             <li><a href="docs/publish/">API</a></li> | ||||||
|             <li><a href="docs/install/">Self-hosting</a></li> |             <li><a href="docs/install/">Self-hosting</a></li> | ||||||
|  |             <li><a href="https://github.com/binwiederhier/ntfy">GitHub</a></li> | ||||||
|         </ol> |         </ol> | ||||||
|     </div> |     </div> | ||||||
| </nav> | </nav> | ||||||
|  | @ -63,14 +64,10 @@ | ||||||
|             <a href="static/img/screenshot-phone-notification.jpg"><img src="static/img/screenshot-phone-notification.jpg"/></a> |             <a href="static/img/screenshot-phone-notification.jpg"><img src="static/img/screenshot-phone-notification.jpg"/></a> | ||||||
|         </span> |         </span> | ||||||
|     </div> |     </div> | ||||||
|     <p> |  | ||||||
|         There are many ways to use it: Notify yourself when a build finishes, when an rsync is done or a backup fails, |  | ||||||
|         or know when somebody logs into your server. There are <a href="#examples">many more examples</a>, endless possibilities 😀. |  | ||||||
|     </p> |  | ||||||
| 
 | 
 | ||||||
|     <h2 id="publish" class="anchor">Publishing messages</h2> |     <h2 id="publish" class="anchor">Publishing messages</h2> | ||||||
|     <p> |     <p> | ||||||
|         Publishing messages can be done via PUT or POST. Topics are created on the fly by subscribing or publishing to them. |         <a href="docs/publish/">Publishing messages</a> can be done via PUT or POST. Topics are created on the fly by subscribing or publishing to them. | ||||||
|         Because there is no sign-up, <b>the topic is essentially a password</b>, so pick something that's not easily guessable. |         Because there is no sign-up, <b>the topic is essentially a password</b>, so pick something that's not easily guessable. | ||||||
|     </p> |     </p> | ||||||
|     <p class="smallMarginBottom"> |     <p class="smallMarginBottom"> | ||||||
|  | @ -81,8 +78,8 @@ | ||||||
|     </code> |     </code> | ||||||
|     <p class="smallMarginBottom"> |     <p class="smallMarginBottom"> | ||||||
|         There are <a href="docs/publish/">more features</a> related to publishing messages: You can set a |         There are <a href="docs/publish/">more features</a> related to publishing messages: You can set a | ||||||
|         <a href="#docs/publish/#message-priority">notification priority</a>, a <a href="docs/publish/#message-title">title</a>, |         <a href="docs/publish/#message-priority">notification priority</a>, a <a href="docs/publish/#message-title">title</a>, | ||||||
|         and <a href="docs/publish/#tags--emojis--">tag messages</a>. |         and <a href="docs/publish/#tags-emojis">tag messages</a>. | ||||||
|         Here's an example using all of them: |         Here's an example using all of them: | ||||||
|     </p> |     </p> | ||||||
|     <code> |     <code> | ||||||
|  | @ -93,6 +90,13 @@ | ||||||
|           -d "Remote access to $(hostname) detected. Act right away." \<br/> |           -d "Remote access to $(hostname) detected. Act right away." \<br/> | ||||||
|           <span class="ntfyUrl">ntfy.sh</span>/mytopic |           <span class="ntfyUrl">ntfy.sh</span>/mytopic | ||||||
|     </code> |     </code> | ||||||
|  |     <p> | ||||||
|  |         Here's what that looks like in the <a href="docs/subscribe/phone/">Android app</a>: | ||||||
|  |     </p> | ||||||
|  |     <figure> | ||||||
|  |         <img src="static/img/priority-notification.png" style="max-height: 200px"/> | ||||||
|  |         <figcaption>Urgent notification with pop-over</figcaption> | ||||||
|  |     </figure> | ||||||
| 
 | 
 | ||||||
|     <h2 id="subscribe" class="anchor">Subscribe to a topic</h2> |     <h2 id="subscribe" class="anchor">Subscribe to a topic</h2> | ||||||
|     <p> |     <p> | ||||||
|  | @ -110,9 +114,11 @@ | ||||||
|         <a href="https://f-droid.org/en/packages/io.heckel.ntfy/"><img src="static/img/badge-fdroid.png"></a> |         <a href="https://f-droid.org/en/packages/io.heckel.ntfy/"><img src="static/img/badge-fdroid.png"></a> | ||||||
|         <a href="https://github.com/binwiederhier/ntfy/issues/4"><img src="static/img/badge-appstore.png"></a> |         <a href="https://github.com/binwiederhier/ntfy/issues/4"><img src="static/img/badge-appstore.png"></a> | ||||||
|     </p> |     </p> | ||||||
| 
 |     <p> | ||||||
|  |         Here's a video showing the app in action: | ||||||
|  |     </p> | ||||||
|     <figure> |     <figure> | ||||||
|         <video controls muted autoplay loop width="650" src="static/img/android-video-overview.mp4"></video> |         <video controls muted autoplay loop src="static/img/android-video-overview.mp4" style="max-width: 650px"></video> | ||||||
|         <figcaption>Sending push notifications to your Android phone</figcaption> |         <figcaption>Sending push notifications to your Android phone</figcaption> | ||||||
|     </figure> |     </figure> | ||||||
| 
 | 
 | ||||||
|  | @ -143,7 +149,7 @@ | ||||||
|         as well as a <a href="docs/subscribe/api/#subscribe-as-raw-stream">plain text stream</a>. |         as well as a <a href="docs/subscribe/api/#subscribe-as-raw-stream">plain text stream</a>. | ||||||
|     </p> |     </p> | ||||||
|     <p class="smallMarginBottom"> |     <p class="smallMarginBottom"> | ||||||
|         Here's an example for JSON. Note that <b>the connection stays open</b>, so you can retrieve messages as they come in: |         Here's an example for JSON. The <b>connection stays open</b>, so you can retrieve messages as they come in: | ||||||
|     </p> |     </p> | ||||||
|     <code> |     <code> | ||||||
|         $ curl -s <span class="ntfyUrl">ntfy.sh</span>/mytopic/json<br/> |         $ curl -s <span class="ntfyUrl">ntfy.sh</span>/mytopic/json<br/> | ||||||
|  | @ -152,24 +158,30 @@ | ||||||
|         {"id":"DGUDShMCsc","time":1635528787,"event":"keepalive","topic":"mytopic"}<br/> |         {"id":"DGUDShMCsc","time":1635528787,"event":"keepalive","topic":"mytopic"}<br/> | ||||||
|         ... |         ... | ||||||
|     </code> |     </code> | ||||||
| 
 |  | ||||||
|     <p> |     <p> | ||||||
|         <script id="asciicast-453771" src="https://asciinema.org/a/453771.js" async></script> |         Here's a short video demonstrating it in action: | ||||||
|     </p> |     </p> | ||||||
|  |     <figure> | ||||||
|  |         <video controls muted autoplay loop src="static/img/android-video-subscribe-api.mp4" style="max-width: 650px"></video> | ||||||
|  |         <figcaption>Subscribing to the JSON stream with <tt>curl</tt></figcaption> | ||||||
|  |     </figure> | ||||||
| 
 | 
 | ||||||
|     <h3 id="more" class="anchor">More, more, more!</h3> |     <h3 id="docs" class="anchor">Check out the docs!</h3> | ||||||
|     <p> |     <p> | ||||||
|         ntfy has so <a href="docs/">many more features</a> and you can learn about all of them <a href="docs/">in the documentation</a> |         ntfy has so many more features and you can learn about all of them <a href="docs/">in the documentation</a> | ||||||
|         (I tried my very best to make it the best docs ever 😉, not sure if I succeeded, hehe). |         (I tried my very best to make it the best docs ever 😉, not sure if I succeeded, hehe). | ||||||
|     </p> |     </p> | ||||||
|  |     <figure> | ||||||
|  |         <a href="docs/"><img width="100%" src="static/img/screenshot-docs.png"/></a> | ||||||
|  |         <figcaption>Check out the documentation</figcaption> | ||||||
|  |     </figure> | ||||||
| 
 | 
 | ||||||
|     <a href="docs/"><img width="100%" src="static/img/screenshot-docs.png"/></a> |     <h3 id="free-software" class="anchor">100% open source & forever free</h3> | ||||||
| 
 |  | ||||||
|     <h3 id="free-software" class="anchor">Forever free, forever 100% free software</h3> |  | ||||||
|     <p> |     <p> | ||||||
|         I love free software, and I'm doing this because it's fun. I have no bad intentions, and I will |         I love free software, and I'm doing this because it's fun. I have no bad intentions, and I will | ||||||
|         never monetize or sell your information. This service will always stay free and open. You can |         never monetize or sell your information. This service will always stay | ||||||
|         read more in the <a href="docs/faq/">FAQs</a> and in the <a href="docs/privacy/">privacy policy</a>. |         <a href="https://github.com/binwiederhier/ntfy">free and open</a>. | ||||||
|  |         You can read more in the <a href="docs/faq/">FAQs</a> and in the <a href="docs/privacy/">privacy policy</a>. | ||||||
|     </p> |     </p> | ||||||
| 
 | 
 | ||||||
|     <center id="ironicCenterTagDontFreakOut"><i>Made with ❤️ by <a href="https://heckel.io">Philipp C. Heckel</a></i></center> |     <center id="ironicCenterTagDontFreakOut"><i>Made with ❤️ by <a href="https://heckel.io">Philipp C. Heckel</a></i></center> | ||||||
|  |  | ||||||
|  | @ -1,9 +1,10 @@ | ||||||
| /* general styling */ | /* general styling */ | ||||||
| 
 | 
 | ||||||
| html, body { | html, body { | ||||||
|     font-family: 'Lato', sans-serif; |     font-family: 'Roboto', sans-serif; | ||||||
|     color: #333; |     font-weight: 400; | ||||||
|     font-size: 1.1em; |     font-size: 1.1em; | ||||||
|  |     color: #444; | ||||||
|     margin: 0; |     margin: 0; | ||||||
|     padding: 0; |     padding: 0; | ||||||
| } | } | ||||||
|  | @ -29,31 +30,41 @@ h1 { | ||||||
|     font-size: 2.5em; |     font-size: 2.5em; | ||||||
|     word-wrap: break-word; /* For very long topics */ |     word-wrap: break-word; /* For very long topics */ | ||||||
|     padding-right: 40px; /* For the X on the detail page */ |     padding-right: 40px; /* For the X on the detail page */ | ||||||
|  |     font-weight: 300; | ||||||
|  |     color: #666; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| h2 { | h2 { | ||||||
|     margin-top: 30px; |     margin-top: 30px; | ||||||
|     margin-bottom: 5px; |     margin-bottom: 5px; | ||||||
|     font-size: 1.8em; |     font-size: 1.8em; | ||||||
|  |     font-weight: 300; | ||||||
|  |     color: #333; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| h3 { | h3 { | ||||||
|     margin-top: 25px; |     margin-top: 25px; | ||||||
|     margin-bottom: 5px; |     margin-bottom: 5px; | ||||||
|     font-size: 1.3em; |     font-size: 1.3em; | ||||||
|  |     font-weight: 300; | ||||||
|  |     color: #333; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| p { | p { | ||||||
|     margin-top: 10px; |     margin-top: 10px; | ||||||
|     margin-bottom: 20px; |     margin-bottom: 20px; | ||||||
|     font-size: 1.1em; |     line-height: 160%; | ||||||
|     line-height: 140%; |     font-weight: 400; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| p.smallMarginBottom { | p.smallMarginBottom { | ||||||
|     margin-bottom: 10px; |     margin-bottom: 10px; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | b { | ||||||
|  |     font-weight: 500; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| tt { | tt { | ||||||
|     background: #eee; |     background: #eee; | ||||||
|     padding: 2px 7px; |     padding: 2px 7px; | ||||||
|  | @ -72,16 +83,36 @@ code { | ||||||
|     white-space: nowrap; |     white-space: nowrap; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /* Lato font (OFL), https://fonts.google.com/specimen/Lato#about, | /* Roboto font, embedded with the help of https://google-webfonts-helper.herokuapp.com/fonts/roboto?subsets=latin */ | ||||||
|    embedded with the help of https://google-webfonts-helper.herokuapp.com/fonts/lato?subsets=latin */ |  | ||||||
| 
 | 
 | ||||||
|  | /* roboto-300 - latin */ | ||||||
| @font-face { | @font-face { | ||||||
|     font-family: 'Lato'; |     font-family: 'Roboto'; | ||||||
|  |     font-style: normal; | ||||||
|  |     font-weight: 300; | ||||||
|  |     src: local(''), | ||||||
|  |     url('../font/roboto-v29-latin-300.woff2') format('woff2'), /* Chrome 26+, Opera 23+, Firefox 39+ */ | ||||||
|  |     url('../font/roboto-v29-latin-300.woff') format('woff'); /* Chrome 6+, Firefox 3.6+, IE 9+, Safari 5.1+ */ | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /* roboto-regular - latin */ | ||||||
|  | @font-face { | ||||||
|  |     font-family: 'Roboto'; | ||||||
|     font-style: normal; |     font-style: normal; | ||||||
|     font-weight: 400; |     font-weight: 400; | ||||||
|     src: local(''), |     src: local(''), | ||||||
|     url('../font/lato-v17-latin-ext_latin-regular.woff2') format('woff2'), /* Chrome 26+, Opera 23+, Firefox 39+ */ |     url('../font/roboto-v29-latin-regular.woff2') format('woff2'), /* Chrome 26+, Opera 23+, Firefox 39+ */ | ||||||
|     url('../font/lato-v17-latin-ext_latin-regular.woff') format('woff'); /* Chrome 6+, Firefox 3.6+, IE 9+, Safari 5.1+ */ |     url('../font/roboto-v29-latin-regular.woff') format('woff'); /* Chrome 6+, Firefox 3.6+, IE 9+, Safari 5.1+ */ | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /* roboto-500 - latin */ | ||||||
|  | @font-face { | ||||||
|  |     font-family: 'Roboto'; | ||||||
|  |     font-style: normal; | ||||||
|  |     font-weight: 500; | ||||||
|  |     src: local(''), | ||||||
|  |     url('../font/roboto-v29-latin-500.woff2') format('woff2'), /* Chrome 26+, Opera 23+, Firefox 39+ */ | ||||||
|  |     url('../font/roboto-v29-latin-500.woff') format('woff'); /* Chrome 6+, Firefox 3.6+, IE 9+, Safari 5.1+ */ | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /* Main page */ | /* Main page */ | ||||||
|  | @ -119,6 +150,29 @@ code { | ||||||
|     visibility: visible; |     visibility: visible; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | /* Figures */ | ||||||
|  | 
 | ||||||
|  | figure { | ||||||
|  |     text-align: center; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | figure img, figure video { | ||||||
|  |     filter: drop-shadow(3px 3px 3px #ccc); | ||||||
|  |     border-radius: 7px; | ||||||
|  |     max-width: 100%; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | figure video { | ||||||
|  |     width: 100%; | ||||||
|  |     max-height: 450px; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | figcaption { | ||||||
|  |     text-align: center; | ||||||
|  |     font-style: italic; | ||||||
|  |     padding-top: 10px; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| /* Screenshots */ | /* Screenshots */ | ||||||
| 
 | 
 | ||||||
| #screenshots { | #screenshots { | ||||||
|  | @ -218,21 +272,20 @@ code { | ||||||
|     float: left; |     float: left; | ||||||
|     color: white; |     color: white; | ||||||
|     font-size: 2.6em; |     font-size: 2.6em; | ||||||
|     font-weight: bold; |     font-weight: 300; | ||||||
|     margin: 35px 0 0 20px; |     margin: 35px 0 0 20px; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| #header ol { | #header ol { | ||||||
|     list-style-type: none; |     list-style-type: none; | ||||||
|     float:right; |     float: right; | ||||||
|     margin-top: 80px; |     margin-top: 80px; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| #header ol li { | #header ol li { | ||||||
|     display: inline-block; |     display: inline-block; | ||||||
|     margin: 0 10px; |     margin: 0 10px; | ||||||
|     font-weight: bold; |     font-weight: 400; | ||||||
| 
 |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| #header ol li a, nav ol li a:visited { | #header ol li a, nav ol li a:visited { | ||||||
|  | @ -273,6 +326,14 @@ li { | ||||||
|     font-size: 0.9em; |     font-size: 0.9em; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | 
 | ||||||
|  | /* Hide top menu SMALL SCREEN */ | ||||||
|  | @media only screen and (max-width: 780px) { | ||||||
|  |     #header ol { | ||||||
|  |         display: none; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
| /* Subscribe box SMALL SCREEN */ | /* Subscribe box SMALL SCREEN */ | ||||||
| @media only screen and (max-width: 1599px) { | @media only screen and (max-width: 1599px) { | ||||||
|     #subscribeBox #subscribeForm { |     #subscribeBox #subscribeForm { | ||||||
|  |  | ||||||
										
											Binary file not shown.
										
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								server/static/font/roboto-v29-latin-300.woff
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								server/static/font/roboto-v29-latin-300.woff
									
										
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								server/static/font/roboto-v29-latin-300.woff2
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								server/static/font/roboto-v29-latin-300.woff2
									
										
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								server/static/font/roboto-v29-latin-500.woff
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								server/static/font/roboto-v29-latin-500.woff
									
										
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								server/static/font/roboto-v29-latin-500.woff2
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								server/static/font/roboto-v29-latin-500.woff2
									
										
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								server/static/font/roboto-v29-latin-regular.woff
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								server/static/font/roboto-v29-latin-regular.woff
									
										
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								server/static/font/roboto-v29-latin-regular.woff2
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								server/static/font/roboto-v29-latin-regular.woff2
									
										
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								server/static/img/android-video-subscribe-api.mp4
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								server/static/img/android-video-subscribe-api.mp4
									
										
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								server/static/img/basic-notification.png
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								server/static/img/basic-notification.png
									
										
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 24 KiB | 
							
								
								
									
										
											BIN
										
									
								
								server/static/img/priority-notification.png
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								server/static/img/priority-notification.png
									
										
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 270 KiB | 
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue