altsrc.NewStringFlag(&cli.StringFlag{Name:"base-url",Aliases:[]string{"base_url","B"},EnvVars:[]string{"NTFY_BASE_URL"},Usage:"externally visible base URL for this host (e.g. https://ntfy.sh)"}),
altsrc.NewStringFlag(&cli.StringFlag{Name:"listen-http",Aliases:[]string{"listen_http","l"},EnvVars:[]string{"NTFY_LISTEN_HTTP"},Value:server.DefaultListenHTTP,Usage:"ip:port used as HTTP listen address"}),
altsrc.NewStringFlag(&cli.StringFlag{Name:"listen-https",Aliases:[]string{"listen_https","L"},EnvVars:[]string{"NTFY_LISTEN_HTTPS"},Usage:"ip:port used as HTTPS listen address"}),
altsrc.NewStringFlag(&cli.StringFlag{Name:"listen-unix",Aliases:[]string{"listen_unix","U"},EnvVars:[]string{"NTFY_LISTEN_UNIX"},Usage:"listen on unix socket path"}),
altsrc.NewIntFlag(&cli.IntFlag{Name:"listen-unix-mode",Aliases:[]string{"listen_unix_mode"},EnvVars:[]string{"NTFY_LISTEN_UNIX_MODE"},DefaultText:"system default",Usage:"file permissions of unix socket, e.g. 0700"}),
altsrc.NewStringFlag(&cli.StringFlag{Name:"key-file",Aliases:[]string{"key_file","K"},EnvVars:[]string{"NTFY_KEY_FILE"},Usage:"private key file, if listen-https is set"}),
altsrc.NewStringFlag(&cli.StringFlag{Name:"cert-file",Aliases:[]string{"cert_file","E"},EnvVars:[]string{"NTFY_CERT_FILE"},Usage:"certificate file, if listen-https is set"}),
altsrc.NewStringFlag(&cli.StringFlag{Name:"firebase-key-file",Aliases:[]string{"firebase_key_file","F"},EnvVars:[]string{"NTFY_FIREBASE_KEY_FILE"},Usage:"Firebase credentials file; if set additionally publish to FCM topic"}),
altsrc.NewStringFlag(&cli.StringFlag{Name:"cache-file",Aliases:[]string{"cache_file","C"},EnvVars:[]string{"NTFY_CACHE_FILE"},Usage:"cache file used for message caching"}),
altsrc.NewStringFlag(&cli.StringFlag{Name:"cache-duration",Aliases:[]string{"cache_duration","b"},EnvVars:[]string{"NTFY_CACHE_DURATION"},Value:util.FormatDuration(server.DefaultCacheDuration),Usage:"buffer messages for this time to allow `since` requests"}),
altsrc.NewIntFlag(&cli.IntFlag{Name:"cache-batch-size",Aliases:[]string{"cache_batch_size"},EnvVars:[]string{"NTFY_BATCH_SIZE"},Usage:"max size of messages to batch together when writing to message cache (if zero, writes are synchronous)"}),
altsrc.NewStringFlag(&cli.StringFlag{Name:"cache-batch-timeout",Aliases:[]string{"cache_batch_timeout"},EnvVars:[]string{"NTFY_CACHE_BATCH_TIMEOUT"},Value:util.FormatDuration(server.DefaultCacheBatchTimeout),Usage:"timeout for batched async writes to the message cache (if zero, writes are synchronous)"}),
altsrc.NewStringFlag(&cli.StringFlag{Name:"cache-startup-queries",Aliases:[]string{"cache_startup_queries"},EnvVars:[]string{"NTFY_CACHE_STARTUP_QUERIES"},Usage:"queries run when the cache database is initialized"}),
altsrc.NewStringFlag(&cli.StringFlag{Name:"auth-file",Aliases:[]string{"auth_file","H"},EnvVars:[]string{"NTFY_AUTH_FILE"},Usage:"auth database file used for access control"}),
altsrc.NewStringFlag(&cli.StringFlag{Name:"auth-startup-queries",Aliases:[]string{"auth_startup_queries"},EnvVars:[]string{"NTFY_AUTH_STARTUP_QUERIES"},Usage:"queries run when the auth database is initialized"}),
altsrc.NewStringFlag(&cli.StringFlag{Name:"auth-default-access",Aliases:[]string{"auth_default_access","p"},EnvVars:[]string{"NTFY_AUTH_DEFAULT_ACCESS"},Value:"read-write",Usage:"default permissions if no matching entries in the auth database are found"}),
altsrc.NewStringFlag(&cli.StringFlag{Name:"attachment-cache-dir",Aliases:[]string{"attachment_cache_dir"},EnvVars:[]string{"NTFY_ATTACHMENT_CACHE_DIR"},Usage:"cache directory for attached files"}),
altsrc.NewStringFlag(&cli.StringFlag{Name:"attachment-total-size-limit",Aliases:[]string{"attachment_total_size_limit","A"},EnvVars:[]string{"NTFY_ATTACHMENT_TOTAL_SIZE_LIMIT"},Value:util.FormatSize(server.DefaultAttachmentTotalSizeLimit),Usage:"limit of the on-disk attachment cache"}),
altsrc.NewStringFlag(&cli.StringFlag{Name:"attachment-expiry-duration",Aliases:[]string{"attachment_expiry_duration","X"},EnvVars:[]string{"NTFY_ATTACHMENT_EXPIRY_DURATION"},Value:util.FormatDuration(server.DefaultAttachmentExpiryDuration),Usage:"duration after which uploaded attachments will be deleted (e.g. 3h, 20h)"}),
altsrc.NewStringFlag(&cli.StringFlag{Name:"keepalive-interval",Aliases:[]string{"keepalive_interval","k"},EnvVars:[]string{"NTFY_KEEPALIVE_INTERVAL"},Value:util.FormatDuration(server.DefaultKeepaliveInterval),Usage:"interval of keepalive messages"}),
altsrc.NewStringFlag(&cli.StringFlag{Name:"manager-interval",Aliases:[]string{"manager_interval","m"},EnvVars:[]string{"NTFY_MANAGER_INTERVAL"},Value:util.FormatDuration(server.DefaultManagerInterval),Usage:"interval of for message pruning and stats printing"}),
altsrc.NewStringSliceFlag(&cli.StringSliceFlag{Name:"disallowed-topics",Aliases:[]string{"disallowed_topics"},EnvVars:[]string{"NTFY_DISALLOWED_TOPICS"},Usage:"topics that are not allowed to be used"}),
altsrc.NewStringFlag(&cli.StringFlag{Name:"web-root",Aliases:[]string{"web_root"},EnvVars:[]string{"NTFY_WEB_ROOT"},Value:"/",Usage:"sets root of the web app (e.g. /, or /app), or disables it (disable)"}),
altsrc.NewBoolFlag(&cli.BoolFlag{Name:"enable-signup",Aliases:[]string{"enable_signup"},EnvVars:[]string{"NTFY_ENABLE_SIGNUP"},Value:false,Usage:"allows users to sign up via the web app, or API"}),
altsrc.NewBoolFlag(&cli.BoolFlag{Name:"enable-login",Aliases:[]string{"enable_login"},EnvVars:[]string{"NTFY_ENABLE_LOGIN"},Value:false,Usage:"allows users to log in via the web app, or API"}),
altsrc.NewBoolFlag(&cli.BoolFlag{Name:"enable-reservations",Aliases:[]string{"enable_reservations"},EnvVars:[]string{"NTFY_ENABLE_RESERVATIONS"},Value:false,Usage:"allows users to reserve topics (if their tier allows it)"}),
altsrc.NewStringFlag(&cli.StringFlag{Name:"upstream-base-url",Aliases:[]string{"upstream_base_url"},EnvVars:[]string{"NTFY_UPSTREAM_BASE_URL"},Value:"",Usage:"forward poll request to an upstream server, this is needed for iOS push notifications for self-hosted servers"}),
altsrc.NewStringFlag(&cli.StringFlag{Name:"upstream-access-token",Aliases:[]string{"upstream_access_token"},EnvVars:[]string{"NTFY_UPSTREAM_ACCESS_TOKEN"},Value:"",Usage:"access token to use for the upstream server; needed only if upstream rate limits are exceeded or upstream server requires auth"}),
altsrc.NewStringFlag(&cli.StringFlag{Name:"smtp-sender-addr",Aliases:[]string{"smtp_sender_addr"},EnvVars:[]string{"NTFY_SMTP_SENDER_ADDR"},Usage:"SMTP server address (host:port) for outgoing emails"}),
altsrc.NewStringFlag(&cli.StringFlag{Name:"smtp-sender-user",Aliases:[]string{"smtp_sender_user"},EnvVars:[]string{"NTFY_SMTP_SENDER_USER"},Usage:"SMTP user (if e-mail sending is enabled)"}),
altsrc.NewStringFlag(&cli.StringFlag{Name:"smtp-sender-pass",Aliases:[]string{"smtp_sender_pass"},EnvVars:[]string{"NTFY_SMTP_SENDER_PASS"},Usage:"SMTP password (if e-mail sending is enabled)"}),
altsrc.NewStringFlag(&cli.StringFlag{Name:"smtp-sender-from",Aliases:[]string{"smtp_sender_from"},EnvVars:[]string{"NTFY_SMTP_SENDER_FROM"},Usage:"SMTP sender address (if e-mail sending is enabled)"}),
altsrc.NewStringFlag(&cli.StringFlag{Name:"smtp-server-listen",Aliases:[]string{"smtp_server_listen"},EnvVars:[]string{"NTFY_SMTP_SERVER_LISTEN"},Usage:"SMTP server address (ip:port) for incoming emails, e.g. :25"}),
altsrc.NewStringFlag(&cli.StringFlag{Name:"smtp-server-domain",Aliases:[]string{"smtp_server_domain"},EnvVars:[]string{"NTFY_SMTP_SERVER_DOMAIN"},Usage:"SMTP domain for incoming e-mail, e.g. ntfy.sh"}),
altsrc.NewStringFlag(&cli.StringFlag{Name:"smtp-server-addr-prefix",Aliases:[]string{"smtp_server_addr_prefix"},EnvVars:[]string{"NTFY_SMTP_SERVER_ADDR_PREFIX"},Usage:"SMTP email address prefix for topics to prevent spam (e.g. 'ntfy-')"}),
altsrc.NewStringFlag(&cli.StringFlag{Name:"twilio-account",Aliases:[]string{"twilio_account"},EnvVars:[]string{"NTFY_TWILIO_ACCOUNT"},Usage:"Twilio account SID, used for phone calls, e.g. AC123..."}),
altsrc.NewStringFlag(&cli.StringFlag{Name:"twilio-phone-number",Aliases:[]string{"twilio_phone_number"},EnvVars:[]string{"NTFY_TWILIO_PHONE_NUMBER"},Usage:"Twilio number to use for outgoing calls"}),
altsrc.NewStringFlag(&cli.StringFlag{Name:"twilio-verify-service",Aliases:[]string{"twilio_verify_service"},EnvVars:[]string{"NTFY_TWILIO_VERIFY_SERVICE"},Usage:"Twilio Verify service ID, used for phone number verification"}),
altsrc.NewStringFlag(&cli.StringFlag{Name:"message-size-limit",Aliases:[]string{"message_size_limit"},EnvVars:[]string{"NTFY_MESSAGE_SIZE_LIMIT"},Value:util.FormatSize(server.DefaultMessageSizeLimit),Usage:"size limit for the message (see docs for limitations)"}),
altsrc.NewStringFlag(&cli.StringFlag{Name:"message-delay-limit",Aliases:[]string{"message_delay_limit"},EnvVars:[]string{"NTFY_MESSAGE_DELAY_LIMIT"},Value:util.FormatDuration(server.DefaultMessageDelayMax),Usage:"max duration a message can be scheduled into the future"}),
altsrc.NewIntFlag(&cli.IntFlag{Name:"global-topic-limit",Aliases:[]string{"global_topic_limit","T"},EnvVars:[]string{"NTFY_GLOBAL_TOPIC_LIMIT"},Value:server.DefaultTotalTopicLimit,Usage:"total number of topics allowed"}),
altsrc.NewIntFlag(&cli.IntFlag{Name:"visitor-subscription-limit",Aliases:[]string{"visitor_subscription_limit"},EnvVars:[]string{"NTFY_VISITOR_SUBSCRIPTION_LIMIT"},Value:server.DefaultVisitorSubscriptionLimit,Usage:"number of subscriptions per visitor"}),
altsrc.NewStringFlag(&cli.StringFlag{Name:"visitor-attachment-total-size-limit",Aliases:[]string{"visitor_attachment_total_size_limit"},EnvVars:[]string{"NTFY_VISITOR_ATTACHMENT_TOTAL_SIZE_LIMIT"},Value:util.FormatSize(server.DefaultVisitorAttachmentTotalSizeLimit),Usage:"total storage limit used for attachments per visitor"}),
altsrc.NewStringFlag(&cli.StringFlag{Name:"visitor-attachment-daily-bandwidth-limit",Aliases:[]string{"visitor_attachment_daily_bandwidth_limit"},EnvVars:[]string{"NTFY_VISITOR_ATTACHMENT_DAILY_BANDWIDTH_LIMIT"},Value:"500M",Usage:"total daily attachment download/upload bandwidth limit per visitor"}),
altsrc.NewIntFlag(&cli.IntFlag{Name:"visitor-request-limit-burst",Aliases:[]string{"visitor_request_limit_burst"},EnvVars:[]string{"NTFY_VISITOR_REQUEST_LIMIT_BURST"},Value:server.DefaultVisitorRequestLimitBurst,Usage:"initial limit of requests per visitor"}),
altsrc.NewStringFlag(&cli.StringFlag{Name:"visitor-request-limit-replenish",Aliases:[]string{"visitor_request_limit_replenish"},EnvVars:[]string{"NTFY_VISITOR_REQUEST_LIMIT_REPLENISH"},Value:util.FormatDuration(server.DefaultVisitorRequestLimitReplenish),Usage:"interval at which burst limit is replenished (one per x)"}),
altsrc.NewStringFlag(&cli.StringFlag{Name:"visitor-request-limit-exempt-hosts",Aliases:[]string{"visitor_request_limit_exempt_hosts"},EnvVars:[]string{"NTFY_VISITOR_REQUEST_LIMIT_EXEMPT_HOSTS"},Value:"",Usage:"hostnames and/or IP addresses of hosts that will be exempt from the visitor request limit"}),
altsrc.NewIntFlag(&cli.IntFlag{Name:"visitor-message-daily-limit",Aliases:[]string{"visitor_message_daily_limit"},EnvVars:[]string{"NTFY_VISITOR_MESSAGE_DAILY_LIMIT"},Value:server.DefaultVisitorMessageDailyLimit,Usage:"max messages per visitor per day, derived from request limit if unset"}),
altsrc.NewIntFlag(&cli.IntFlag{Name:"visitor-email-limit-burst",Aliases:[]string{"visitor_email_limit_burst"},EnvVars:[]string{"NTFY_VISITOR_EMAIL_LIMIT_BURST"},Value:server.DefaultVisitorEmailLimitBurst,Usage:"initial limit of e-mails per visitor"}),
altsrc.NewStringFlag(&cli.StringFlag{Name:"visitor-email-limit-replenish",Aliases:[]string{"visitor_email_limit_replenish"},EnvVars:[]string{"NTFY_VISITOR_EMAIL_LIMIT_REPLENISH"},Value:util.FormatDuration(server.DefaultVisitorEmailLimitReplenish),Usage:"interval at which burst limit is replenished (one per x)"}),
altsrc.NewBoolFlag(&cli.BoolFlag{Name:"behind-proxy",Aliases:[]string{"behind_proxy","P"},EnvVars:[]string{"NTFY_BEHIND_PROXY"},Value:false,Usage:"if set, use X-Forwarded-For header to determine visitor IP address (for rate limiting)"}),
altsrc.NewStringFlag(&cli.StringFlag{Name:"stripe-secret-key",Aliases:[]string{"stripe_secret_key"},EnvVars:[]string{"NTFY_STRIPE_SECRET_KEY"},Value:"",Usage:"key used for the Stripe API communication, this enables payments"}),
altsrc.NewStringFlag(&cli.StringFlag{Name:"stripe-webhook-key",Aliases:[]string{"stripe_webhook_key"},EnvVars:[]string{"NTFY_STRIPE_WEBHOOK_KEY"},Value:"",Usage:"key required to validate the authenticity of incoming webhooks from Stripe"}),
altsrc.NewStringFlag(&cli.StringFlag{Name:"billing-contact",Aliases:[]string{"billing_contact"},EnvVars:[]string{"NTFY_BILLING_CONTACT"},Value:"",Usage:"e-mail or website to display in upgrade dialog (only if payments are enabled)"}),
altsrc.NewBoolFlag(&cli.BoolFlag{Name:"enable-metrics",Aliases:[]string{"enable_metrics"},EnvVars:[]string{"NTFY_ENABLE_METRICS"},Value:false,Usage:"if set, Prometheus metrics are exposed via the /metrics endpoint"}),
altsrc.NewStringFlag(&cli.StringFlag{Name:"metrics-listen-http",Aliases:[]string{"metrics_listen_http"},EnvVars:[]string{"NTFY_METRICS_LISTEN_HTTP"},Usage:"ip:port used to expose the metrics endpoint (implicitly enables metrics)"}),
altsrc.NewStringFlag(&cli.StringFlag{Name:"profile-listen-http",Aliases:[]string{"profile_listen_http"},EnvVars:[]string{"NTFY_PROFILE_LISTEN_HTTP"},Usage:"ip:port used to expose the profiling endpoints (implicitly enables profiling)"}),
altsrc.NewStringFlag(&cli.StringFlag{Name:"web-push-public-key",Aliases:[]string{"web_push_public_key"},EnvVars:[]string{"NTFY_WEB_PUSH_PUBLIC_KEY"},Usage:"public key used for web push notifications"}),
altsrc.NewStringFlag(&cli.StringFlag{Name:"web-push-private-key",Aliases:[]string{"web_push_private_key"},EnvVars:[]string{"NTFY_WEB_PUSH_PRIVATE_KEY"},Usage:"private key used for web push notifications"}),
altsrc.NewStringFlag(&cli.StringFlag{Name:"web-push-file",Aliases:[]string{"web_push_file"},EnvVars:[]string{"NTFY_WEB_PUSH_FILE"},Usage:"file used to store web push subscriptions"}),
altsrc.NewStringFlag(&cli.StringFlag{Name:"web-push-email-address",Aliases:[]string{"web_push_email_address"},EnvVars:[]string{"NTFY_WEB_PUSH_EMAIL_ADDRESS"},Usage:"e-mail address of sender, required to use browser push services"}),
altsrc.NewStringFlag(&cli.StringFlag{Name:"web-push-startup-queries",Aliases:[]string{"web_push_startup_queries"},EnvVars:[]string{"NTFY_WEB_PUSH_STARTUP_QUERIES"},Usage:"queries run when the web push database is initialized"}),
altsrc.NewStringFlag(&cli.StringFlag{Name:"web-push-expiry-duration",Aliases:[]string{"web_push_expiry_duration"},EnvVars:[]string{"NTFY_WEB_PUSH_EXPIRY_DURATION"},Value:util.FormatDuration(server.DefaultWebPushExpiryDuration),Usage:"automatically expire unused subscriptions after this time"}),
altsrc.NewStringFlag(&cli.StringFlag{Name:"web-push-expiry-warning-duration",Aliases:[]string{"web_push_expiry_warning_duration"},EnvVars:[]string{"NTFY_WEB_PUSH_EXPIRY_WARNING_DURATION"},Value:util.FormatDuration(server.DefaultWebPushExpiryWarningDuration),Usage:"send web push warning notification after this time before expiring unused subscriptions"}),
returnerrors.New("if web push is enabled, web-push-private-key, web-push-public-key, web-push-file, web-push-email-address, and base-url should be set. run 'ntfy webpush keys' to generate keys")
returnerrors.New("base-url and upstream-base-url cannot be identical, you'll likely want to set upstream-base-url to https://ntfy.sh, see https://ntfy.sh/docs/config/#ios-instant-notifications")