Programming language: Go
License: MIT License
Tags: Messaging    

Chanify alternatives and similar packages

Based on the "Messaging" category.
Alternatively, view chanify alternatives based on common mentions on social networks and blogs.

Do you think we are missing an alternative of Chanify or a related project?

Add another 'Messaging' Package



Docker Release iTunes App Store WebStore Workflow CodeQL Codecov Total alerts Go Report Card Go Reference [GitHub](LICENSE) Docker pull Downloads Users

English | [简体中文](README-zh_CN.md)

Chanify is a safe and simple notification tools. For developers, system administrators, and everyone can push notifications with API.

Table of Contents Features Getting Started Installation Precompiled binary Docker From source Usage As Sender Client As Serverless node As Serverful node Add New Node Send message Command Line Python 3 Ruby NodeJS PHP HTTP API Send Text Send Link Send Image Send Audio Send File Send Actions Configuration Security Setting Registrable Token Lifetime Chrome Extension Contributing License


Chanify is include these features:

  • Customize channel for notifications.
  • Deploy your own node server.
  • Distributed architecture design.
  • Design for privacy protection.
  • Support text/image/audio/file message format.

Getting Started

  1. Install iOS App(1.0.0 version and above).
  2. Get send token, more detail.
  3. Send message.


Precompiled binary

Download precompiled binary from this.


$ docker pull wizjin/chanify:latest

From source

$ git clone https://github.com/chanify/chanify.git
$ cd chanify
$ make install


As Sender Client

Use chanify to send message.

# Text message
$ chanify send --endpoint=http://<address>:<port> --token=<token> --text=<message>

# URL message
$ chanify send --endpoint=http://<address>:<port> --token=<token> --link=<web url>

# Image message
$ chanify send --endpoint=http://<address>:<port> --token=<token> --image=<image file path>

# Audio message
$ chanify send --endpoint=http://<address>:<port> --token=<token> --audio=<audio file path>

# File message
$ chanify send --endpoint=http://<address>:<port> --token=<token> --file=<file path> --text=<file description>

# Action  message
$ chanify send --endpoint=http://<address>:<port> --token=<token> --text=<message> --title=<title> --action="<action name>|<action url>"

# Timeline message
$ chanify send --endpoint=http://<address>:<port> --token=<token> --timeline.code=<code> <item1>=<value1> <item2>=<value2> ...

endpoint default value is https://api.chanify.net, and notification will send by default server. If you have own node server, please set endpoint to your node server url.

As Serverless node

Chanify run in stateless mode, no device token will be stored in node.

All device token will be stored in api.chanify.net.

Message will send to apple apns server by api.chanify.net.

Send message workflow:

Start => node server => api.chanify.net => Apple server => iOS client
# Start chanify
$ chanify serve --host=<ip address> --port=<port> --secret=<secret key> --name=<node name> --endpoint=http://<address>:<port>

# Docker
$ docker run -it wizjin/chanify:latest serve --secret=<secret key> --name=<node name> --endpoint=http://<address>:<port>

As Serverful node

Chanify run in stateful mode, device token will be stored in node.

Message will send to apple apns server direct.

Send message workflow:

Start => node server => Apple server => iOS client

Start server

# Start chanify
$ chanify serve --host=<ip address> --port=<port> --name=<node name> --datapath=~/.chanify --endpoint=http://<address>:<port>

# Docker
$ docker run -it -v /my/data:/root/.chanify wizjin/chanify:latest serve --name=<node name> --endpoint=http://<address>:<port>

Use MySQL as a backend

--dburl=mysql://<user>:<password>@tcp(<ip address>:<port>)/<database name>?charset=utf8mb4&parseTime=true&loc=Local

Chanify will not create database.

Add New Node

  • Start node server
  • iOS client can scan QRCode(http://<address>:<port>/) to add node.

Send message

Command Line

# Text message
$ curl --form-string "text=hello" "http://<address>:<port>/v1/sender/<token>"

# Text file
$ cat message.txt | curl -H "Content-Type: text/plain" --data-binary @- "http://<address>:<port>/v1/sender/<token>"

Python 3

from urllib import request, parse

data = parse.urlencode({ 'text': 'hello' }).encode()
req = request.Request("http://<address>:<port>/v1/sender/<token>", data=data)


require 'net/http'

uri = URI('http://<address>:<port>/v1/sender/<token>')
res = Net::HTTP.post_form(uri, 'text' => 'hello')
puts res.body


const https = require('https')
const querystring = require('querystring');

const data = querystring.stringify({ text: 'hello' })
const options = {
    hostname: '<address>:<port>',
    port: 80,
    path: '/v1/sender/<token>',
    method: 'POST',
    headers: {
        'Content-Type': 'application/x-www-form-urlencoded',
        'Content-Length': data.length
    var req = https.request(options, (res) => {
    res.on('data', (d) => {


$curl = curl_init();

curl_setopt_array($curl, [
    CURLOPT_URL           => 'http://<address>:<port>/v1/sender/<token>',
    CURLOPT_POSTFIELDS    => [ 'text' => 'hello' ],

$response = curl_exec($curl);

echo $response;


Send Text

  • GET

  • POST



  • text/plain: Body is text message
  • multipart/form-data: The block of data("text") is text message
  • application/x-www-form-urlencoded: text=<url encoded text message>
  • application/json; charset=utf-8: The fields are optional json { "token": "<token>", "title": "<message title>", "text": "<text message content>", "copy": "<copy text for text message>", "autocopy": 1, "sound": 1, "priority": 10, "actions": [ "ActionName1|http://<action host>/<action1>", "ActionName2|http://<action host>/<action2>", ... ], "timeline": { "code": "<timeline code>", "timestamp": 1620000000000, "items": { "key1": "value1", "key2": "value2", ... } } }

Additional params

Key Default Description
title None The title for notification message.
copy None The copy text for text notification.
autocopy 0 Enable autocopy text for text notification.
sound 0 1 enable sound, otherwise disable sound.
priority 10 10 normal, 5 lower level.
actions None Actions list.
timeline None Timeline object.

timestamp in milliseconds (timezone - UTC)



Send Link

$ curl --form "[email protected]<web url>" "http://<address>:<port>/v1/sender/<token>"
    "link": "<web url>",
    "sound": 1,
    "priority": 10,

Send Image

Send image only support POST method used serverful node.

  • Content-Type: image/png OR image/jpeg
cat <jpeg image path> | curl -H "Content-Type: image/jpeg" --data-binary @- "http://<address>:<port>/v1/sender/<token>"
  • Content-Type: multipart/form-data
$ curl --form "[email protected]<jpeg image path>" "http://<address>:<port>/v1/sender/<token>"

Send Audio

Send mp3 audio only support POST method used serverful node.

  • Content-Type: audio/mpeg
cat <mp3 audio path> | curl -H "Content-Type: audio/mpeg" --data-binary @- "http://<address>:<port>/v1/sender/<token>"
  • Content-Type: multipart/form-data
$ curl --form "[email protected]<mp3 audio path>" "http://<address>:<port>/v1/sender/<token>"

Send File

Send file only support POST method used serverful node.

  • Content-Type: multipart/form-data
$ curl --form "[email protected]<file path>" "http://<address>:<port>/v1/sender/<token>"

Send Actions

Send Actions (Up to 4 actions).

  • Content-Type: multipart/form-data
$ curl --form "action=ActionName1|http://<action host>/<action1>" "http://<address>:<port>/v1/sender/<token>"


Chanify can be configured with a yml format file, and the default path is ~/.chanify.yml.

    host:   # Listen ip address
    port: 8080      # Listen port
    endpoint: http://my.server/path # Endpoint URL
    name: Node name # Name for node server
    secret: <secret code> # key for serverless node server
    datapath: <data path> # data storage path for serverful node server
    dburl: mysql://root:[email protected]( # database dsn for serverful node server
        enable: false # Disable user register
        whitelist: # whitelist for user register
            - <user id 1>
            - <user id 2>

client: # configuration for sender client
    sound: 1    # enable sound
    endpoint: <default node server endpoint>
    token: <default token>


Setting Registrable

Node server can be disabled user registration and become a private server.

chanify serve --registerable=false --whitelist=<user1 id>,<user2 id>
  • --registerable=false: used to disable user registration
  • whitelist: list users can be add into node server

Token Lifetime

  • Token lifetime is about 90 days (default).
  • Can configurable token lifetime (1 day ~ 5 years) in channel detail page.

If your token is leaked, add leaked token into the blocklist (iOS client settings).

Note: Please protect your token from leakage. The blockist need trusted node server (1.1.9 version and above).

Chrome Extension

Download the extension for Chrome web store.

Extension features:

  • Send select text/image/audio/url message to Chanify
  • Send page url to Chanify


Contributions are what make the open source community such an amazing place to be learn, inspire, and create. Any contributions you make are greatly appreciated.

  1. Fork the Project
  2. Change to dev Branch (git checkout dev)
  3. Create your Feature Branch (git checkout -b feature/AmazingFeature)
  4. Commit your Changes (git commit -m 'Add some AmazingFeature')
  5. Push to the Branch (git push origin feature/AmazingFeature)
  6. Open a Pull Request (merge to chanify:dev branch)


Distributed under the MIT License. See [LICENSE](LICENSE) for more information.

*Note that all licence references and agreements mentioned in the Chanify README section above are relevant to that project's source code only.