2021-12-17 01:33:01 +00:00
package cmd
import (
"errors"
2021-12-20 02:01:49 +00:00
"fmt"
2021-12-17 01:33:01 +00:00
"github.com/urfave/cli/v2"
"heckel.io/ntfy/client"
2022-06-20 14:56:45 +00:00
"heckel.io/ntfy/log"
2022-02-02 04:39:57 +00:00
"heckel.io/ntfy/util"
2022-01-13 02:24:48 +00:00
"io"
"os"
"path/filepath"
2021-12-17 01:33:01 +00:00
"strings"
2022-06-20 14:56:45 +00:00
"time"
2021-12-17 01:33:01 +00:00
)
2022-05-09 15:03:40 +00:00
func init ( ) {
commands = append ( commands , cmdPublish )
}
2022-05-30 02:14:14 +00:00
var flagsPublish = append (
flagsDefault ,
& cli . StringFlag { Name : "config" , Aliases : [ ] string { "c" } , EnvVars : [ ] string { "NTFY_CONFIG" } , Usage : "client config file" } ,
& cli . StringFlag { Name : "title" , Aliases : [ ] string { "t" } , EnvVars : [ ] string { "NTFY_TITLE" } , Usage : "message title" } ,
& cli . StringFlag { Name : "priority" , Aliases : [ ] string { "p" } , EnvVars : [ ] string { "NTFY_PRIORITY" } , Usage : "priority of the message (1=min, 2=low, 3=default, 4=high, 5=max)" } ,
& cli . StringFlag { Name : "tags" , Aliases : [ ] string { "tag" , "T" } , EnvVars : [ ] string { "NTFY_TAGS" } , Usage : "comma separated list of tags and emojis" } ,
& cli . StringFlag { Name : "delay" , Aliases : [ ] string { "at" , "in" , "D" } , EnvVars : [ ] string { "NTFY_DELAY" } , Usage : "delay/schedule message" } ,
& cli . StringFlag { Name : "click" , Aliases : [ ] string { "U" } , EnvVars : [ ] string { "NTFY_CLICK" } , Usage : "URL to open when notification is clicked" } ,
& cli . StringFlag { Name : "actions" , Aliases : [ ] string { "A" } , EnvVars : [ ] string { "NTFY_ACTIONS" } , Usage : "actions JSON array or simple definition" } ,
& cli . StringFlag { Name : "attach" , Aliases : [ ] string { "a" } , EnvVars : [ ] string { "NTFY_ATTACH" } , Usage : "URL to send as an external attachment" } ,
& cli . StringFlag { Name : "filename" , Aliases : [ ] string { "name" , "n" } , EnvVars : [ ] string { "NTFY_FILENAME" } , Usage : "filename for the attachment" } ,
& cli . StringFlag { Name : "file" , Aliases : [ ] string { "f" } , EnvVars : [ ] string { "NTFY_FILE" } , Usage : "file to upload as an attachment" } ,
& cli . StringFlag { Name : "email" , Aliases : [ ] string { "mail" , "e" } , EnvVars : [ ] string { "NTFY_EMAIL" } , Usage : "also send to e-mail address" } ,
& cli . StringFlag { Name : "user" , Aliases : [ ] string { "u" } , EnvVars : [ ] string { "NTFY_USER" } , Usage : "username[:password] used to auth against the server" } ,
2022-06-20 14:56:45 +00:00
& cli . IntFlag { Name : "pid" , Aliases : [ ] string { "done" , "w" } , EnvVars : [ ] string { "NTFY_PID" } , Usage : "monitor process with given PID and publish when it exists" } ,
2022-05-30 02:14:14 +00:00
& cli . BoolFlag { Name : "no-cache" , Aliases : [ ] string { "C" } , EnvVars : [ ] string { "NTFY_NO_CACHE" } , Usage : "do not cache message server-side" } ,
& cli . BoolFlag { Name : "no-firebase" , Aliases : [ ] string { "F" } , EnvVars : [ ] string { "NTFY_NO_FIREBASE" } , Usage : "do not forward message to Firebase" } ,
& cli . BoolFlag { Name : "env-topic" , Aliases : [ ] string { "P" } , EnvVars : [ ] string { "NTFY_ENV_TOPIC" } , Usage : "use topic from NTFY_TOPIC env variable" } ,
& cli . BoolFlag { Name : "quiet" , Aliases : [ ] string { "q" } , EnvVars : [ ] string { "NTFY_QUIET" } , Usage : "do not print message" } ,
)
2021-12-17 01:33:01 +00:00
var cmdPublish = & cli . Command {
Name : "publish" ,
2021-12-20 02:01:49 +00:00
Aliases : [ ] string { "pub" , "send" , "trigger" } ,
2021-12-17 01:33:01 +00:00
Usage : "Send message via a ntfy server" ,
2022-05-30 02:14:14 +00:00
UsageText : "ntfy publish [OPTIONS..] TOPIC [MESSAGE]\nNTFY_TOPIC=.. ntfy publish [OPTIONS..] -P [MESSAGE]" ,
2021-12-17 01:33:01 +00:00
Action : execPublish ,
2022-01-23 06:00:38 +00:00
Category : categoryClient ,
2022-05-30 02:14:14 +00:00
Flags : flagsPublish ,
2022-06-01 20:57:35 +00:00
Before : initLogFunc ,
2021-12-17 01:33:01 +00:00
Description : ` Publish a message to a ntfy server .
Examples :
ntfy publish mytopic This is my message # Send simple message
ntfy send myserver . com / mytopic "This is my message" # Send message to different default host
ntfy pub - p high backups "Backups failed" # Send high priority message
ntfy pub -- tags = warning , skull backups "Backups failed" # Add tags / emojis to message
ntfy pub -- delay = 10 s delayed_topic Laterzz # Delay message by 10 s
ntfy pub -- at = 8 : 30 am delayed_topic Laterzz # Send message at 8 : 30 am
2021-12-24 14:01:29 +00:00
ntfy pub - e phil @ example . com alerts ' App is down ! ' # Also send email to phil @ example . com
2022-01-04 23:11:36 +00:00
ntfy pub -- click = "https://reddit.com" redd ' New msg ' # Opens Reddit when notification is clicked
2022-01-13 02:24:48 +00:00
ntfy pub -- attach = "http://some.tld/file.zip" files # Send ZIP archive from URL as attachment
ntfy pub -- file = flower . jpg flowers ' Nice ! ' # Send image . jpg as attachment
2022-02-02 04:39:57 +00:00
ntfy pub - u phil : mypass secret Psst # Publish with username / password
NTFY_USER = phil : mypass ntfy pub secret Psst # Use env variables to set username / password
NTFY_TOPIC = mytopic ntfy pub - P "some message" " # Use NTFY_TOPIC variable as topic
2022-01-13 02:24:48 +00:00
cat flower . jpg | ntfy pub -- file = - flowers ' Nice ! ' # Same as above , send image . jpg as attachment
2021-12-18 03:38:29 +00:00
ntfy trigger mywebhook # Sending without message , useful for webhooks
2022-02-02 04:39:57 +00:00
2021-12-17 01:33:01 +00:00
Please also check out the docs on publishing messages . Especially for the -- tags and -- delay options ,
2021-12-20 02:01:49 +00:00
it has incredibly useful information : https : //ntfy.sh/docs/publish/.
2022-05-10 01:25:00 +00:00
` + clientCommandDescriptionSuffix ,
2021-12-17 01:33:01 +00:00
}
func execPublish ( c * cli . Context ) error {
2021-12-20 02:01:49 +00:00
conf , err := loadConfig ( c )
if err != nil {
return err
2021-12-17 01:33:01 +00:00
}
title := c . String ( "title" )
priority := c . String ( "priority" )
tags := c . String ( "tags" )
delay := c . String ( "delay" )
2022-01-04 23:11:36 +00:00
click := c . String ( "click" )
2022-04-20 20:31:25 +00:00
actions := c . String ( "actions" )
2022-01-13 02:24:48 +00:00
attach := c . String ( "attach" )
filename := c . String ( "filename" )
file := c . String ( "file" )
2021-12-24 14:01:29 +00:00
email := c . String ( "email" )
2022-02-02 04:39:57 +00:00
user := c . String ( "user" )
2022-06-20 14:56:45 +00:00
pid := c . Int ( "pid" )
2021-12-17 01:33:01 +00:00
noCache := c . Bool ( "no-cache" )
noFirebase := c . Bool ( "no-firebase" )
2022-02-02 04:39:57 +00:00
envTopic := c . Bool ( "env-topic" )
2021-12-20 02:01:49 +00:00
quiet := c . Bool ( "quiet" )
2022-02-02 04:39:57 +00:00
var topic , message string
if envTopic {
topic = os . Getenv ( "NTFY_TOPIC" )
if c . NArg ( ) > 0 {
message = strings . Join ( c . Args ( ) . Slice ( ) , " " )
}
} else {
if c . NArg ( ) < 1 {
return errors . New ( "must specify topic, type 'ntfy publish --help' for help" )
}
topic = c . Args ( ) . Get ( 0 )
if c . NArg ( ) > 1 {
message = strings . Join ( c . Args ( ) . Slice ( ) [ 1 : ] , " " )
}
2021-12-18 03:38:29 +00:00
}
2021-12-17 01:33:01 +00:00
var options [ ] client . PublishOption
if title != "" {
options = append ( options , client . WithTitle ( title ) )
}
if priority != "" {
options = append ( options , client . WithPriority ( priority ) )
}
if tags != "" {
2021-12-19 19:27:26 +00:00
options = append ( options , client . WithTagsList ( tags ) )
2021-12-17 01:33:01 +00:00
}
if delay != "" {
options = append ( options , client . WithDelay ( delay ) )
}
2022-01-04 23:11:36 +00:00
if click != "" {
2022-01-13 02:24:48 +00:00
options = append ( options , client . WithClick ( click ) )
}
2022-04-20 20:31:25 +00:00
if actions != "" {
options = append ( options , client . WithActions ( strings . ReplaceAll ( actions , "\n" , " " ) ) )
}
2022-01-13 02:24:48 +00:00
if attach != "" {
options = append ( options , client . WithAttach ( attach ) )
}
if filename != "" {
options = append ( options , client . WithFilename ( filename ) )
2022-01-04 23:11:36 +00:00
}
2021-12-24 14:01:29 +00:00
if email != "" {
options = append ( options , client . WithEmail ( email ) )
}
2021-12-17 01:33:01 +00:00
if noCache {
options = append ( options , client . WithNoCache ( ) )
}
if noFirebase {
options = append ( options , client . WithNoFirebase ( ) )
}
2022-02-02 04:39:57 +00:00
if user != "" {
var pass string
parts := strings . SplitN ( user , ":" , 2 )
if len ( parts ) == 2 {
user = parts [ 0 ]
pass = parts [ 1 ]
} else {
fmt . Fprint ( c . App . ErrWriter , "Enter Password: " )
p , err := util . ReadPassword ( c . App . Reader )
if err != nil {
return err
}
pass = string ( p )
fmt . Fprintf ( c . App . ErrWriter , "\r%s\r" , strings . Repeat ( " " , 20 ) )
}
options = append ( options , client . WithBasicAuth ( user , pass ) )
}
2022-01-13 02:24:48 +00:00
var body io . Reader
if file == "" {
body = strings . NewReader ( message )
} else {
if message != "" {
options = append ( options , client . WithMessage ( message ) )
}
if file == "-" {
if filename == "" {
options = append ( options , client . WithFilename ( "stdin" ) )
}
body = c . App . Reader
} else {
if filename == "" {
options = append ( options , client . WithFilename ( filepath . Base ( file ) ) )
}
body , err = os . Open ( file )
if err != nil {
return err
}
}
}
2022-06-20 14:56:45 +00:00
if pid > 0 {
if err := waitForProcess ( pid ) ; err != nil {
return err
}
}
2021-12-20 02:01:49 +00:00
cl := client . New ( conf )
2022-01-13 02:24:48 +00:00
m , err := cl . PublishReader ( topic , body , options ... )
2021-12-18 19:43:27 +00:00
if err != nil {
return err
}
2021-12-20 02:01:49 +00:00
if ! quiet {
fmt . Fprintln ( c . App . Writer , strings . TrimSpace ( m . Raw ) )
}
return nil
2021-12-17 01:33:01 +00:00
}
2022-06-20 14:56:45 +00:00
func waitForProcess ( pid int ) error {
if ! processExists ( pid ) {
return fmt . Errorf ( "process with PID %d not running" , pid )
}
log . Debug ( "Waiting for process with PID %d to exit" , pid )
for processExists ( pid ) {
time . Sleep ( 500 * time . Millisecond )
}
log . Debug ( "Process with PID %d exited" , pid )
return nil
}