diff --git a/.github/workflows/pull_request.yml b/.github/workflows/pull_request.yml new file mode 100644 index 0000000..9cc4b59 --- /dev/null +++ b/.github/workflows/pull_request.yml @@ -0,0 +1,36 @@ +on: pull_request + +env: + PUSHOVER_TOKEN: ${{ secrets.PUSHOVER_TOKEN }} + PUSHOVER_USER: ${{ secrets.PUSHOVER_USER }} + +jobs: + lint-code: + runs-on: ubuntu-latest + name: Perform Checks + steps: + - name: Checkout + uses: actions/checkout@v2 + + - name: golangci-lint + uses: golangci/golangci-lint-action@v2 + with: + version: v1.29 + + - name: Notify on failure + uses: kha7iq/pingme-action@v1 + if: failure() + env: + PUSHOVER_TITLE: '🟢 New Request: ${{ github.ref }}' + PUSHOVER_MESSAGE: 'Event is triggerd by ${{ github.event_name }} Checks ❌ ${{ job.status }}' + with: + service: pushover + + - name: Notify on success + uses: kha7iq/pingme-action@v1 + if: success() + env: + PUSHOVER_TITLE: '🟢 New Request: ${{ github.ref }}' + PUSHOVER_MESSAGE: 'Event is triggerd by ${{ github.event_name }} Checks ✅ ${{ job.status }}' + with: + service: pushover diff --git a/.golangci.yml b/.golangci.yml new file mode 100644 index 0000000..8a7a0f9 --- /dev/null +++ b/.golangci.yml @@ -0,0 +1,71 @@ +linters-settings: + depguard: + list-type: blacklist + funlen: + lines: 120 + statements: 50 + gci: + local-prefixes: github.com/golangci/golangci-lint + goconst: + min-len: 2 + min-occurrences: 2 + gocyclo: + min-complexity: 15 + goimports: + local-prefixes: github.com/golangci/golangci-lint + golint: + min-confidence: 0 + govet: + check-shadowing: true + settings: + printf: + funcs: + - (github.com/golangci/golangci-lint/pkg/logutils.Log).Infof + - (github.com/golangci/golangci-lint/pkg/logutils.Log).Warnf + - (github.com/golangci/golangci-lint/pkg/logutils.Log).Errorf + - (github.com/golangci/golangci-lint/pkg/logutils.Log).Fatalf + lll: + line-length: 140 + maligned: + suggest-new: true + misspell: + locale: US + nolintlint: + allow-leading-space: true # don't require machine-readable nolint directives (i.e. with no leading space) + allow-unused: false # report any unused nolint directives + require-explanation: false # don't require an explanation for nolint directives + require-specific: false # don't require nolint directives to be specific about which linter is being skipped + +linters: + disable-all: true + enable: + - bodyclose + - deadcode + - depguard + - dogsled + - errcheck + - funlen + - gochecknoinits + - goconst + - gocyclo + - gofmt + - goimports + - golint + - goprintffuncname + - gosec + - gosimple + - govet + - ineffassign + - lll + - misspell + - nakedret + - rowserrcheck + - staticcheck + - structcheck + - stylecheck + - typecheck + - unconvert + - unparam + - unused + - varcheck + - whitespace diff --git a/.goreleaser.yaml b/.goreleaser.yaml index fa6ba45..086b712 100644 --- a/.goreleaser.yaml +++ b/.goreleaser.yaml @@ -40,9 +40,6 @@ archives: format_overrides: - goos: windows format: zip - files: - - README.md - - LICENSE.md brews: - tap: diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md index 5c07c54..b4df6c3 100644 --- a/CODE_OF_CONDUCT.md +++ b/CODE_OF_CONDUCT.md @@ -3,7 +3,7 @@ ## Our Pledge In the interest of fostering an open and welcoming environment, we as -contributors and maintainers pledge to making participation in our project and +contributors and maintainers pledge to making participation in our project, and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, sex characteristics, gender identity and expression, level of experience, education, socio-economic status, nationality, personal diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index fa10bfc..2ee5658 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -4,19 +4,20 @@ possible. ## Project structure -- `main` - Contains definitions for the underlying notification services. - - `cmd/discord` - Discord notification service. - - `cmd/email` - Email notification service. - - `cmd/msteams` - Microsoft Teams notification service. - - `cmd/rocketchat` - RocketChat notification service. - - `cmd/slack` - Slack notification service. - - `cmd/telegram` - Telegram notification service +- `service` - Contains definitions for the underlying notification services. + - `service/discord` - Discord notification service. + - `service/email` - Email notification service. + - `service/msteams` - Microsoft Teams notification service. + - `service/rocketchat` - RocketChat notification service. + - `service/slack` - Slack notification service. + - `service/telegram` - Telegram notification service. + - `service/pushover` - Pushover Notification service. - Documentation - `docs` - Contains the documentation in markdown format. - - `services.md` If you are adding a new service please add documentaiton to `services.md`. + `docs` - Contains the documentation in Markdown format. + - `services.md` If you are adding a new service please add documentation to `services.md`. - `home.md` Is the main page rendered when docs website is loaded. - - `install.md` Contains the install instructions for different packages. + - `install.md` Contains the installation instructions for different packages. - Checking Locally - Docsify is used for documentation rendering from markdown, you can download diff --git a/Makefile b/Makefile index 6028a13..f4d0a6e 100644 --- a/Makefile +++ b/Makefile @@ -28,7 +28,6 @@ test: # gofumports and gci all go files fmt: find . -name '*.go' -not -wholename './vendor/*' | while read -r file; do gofumports -w "$$file"; done - gci -w -local github.com/kha7iq/pingme . .PHONY: fmt # Run all the linters diff --git a/README.md b/README.md index 8884e8e..a39b09e 100644 --- a/README.md +++ b/README.md @@ -24,14 +24,13 @@

- AboutDocumentationSupported ServicesInstallGithub ActionConfigurationContributing • - Show Your Support • + Show Your Support

--- @@ -45,7 +44,7 @@ And i can ship it everywhere with ease. Hence, the birth of PingMe. Everything is configurable via environment variables, and you can simply export the logs or messages to a variable which will be sent -as message. And most of all this serves as a swiss army knife sort of tool which supports multiple platforms. +as message, and most of all this serves as a swiss army knife sort of tool which supports multiple platforms. @@ -53,20 +52,29 @@ as message. And most of all this serves as a swiss army knife sort of tool which - *Discord* - *Email* - *Microsoft Teams* +- *Mattermost* +- *Pushover* +- *Pushbullet* - *RocketChat* - *Slack* - *Telegram* -- *Pushover* -- *Mattermost* - +- *Twillio* ## Install -### Linux & MacOs +### MacOS & Linux Homebrew ```bash brew install kha7iq/tap/pingme ``` +## Linux Binary +```bash +wget -q https://github.com/kha7iq/pingme/releases/download/v0.1.6/pingme_Linux_x86_64.tar.gz +tar -xf pingme_Linux_x86_64.tar.gz +chmod +x pingme +sudo mv pingme /usr/local/bin/pingme +``` + ### Go Get ```bash go get -u github.com/kha7iq/pingme @@ -91,7 +99,7 @@ Docker Registry ```bash docker pull khaliq/pingme:latest ``` -Gighub Registry +Github Registry ```bash docker pull ghcr.io/kha7iq/pingme:latest ``` @@ -132,6 +140,7 @@ COMMANDS: pushover Send message to pushover email Send an email mattermost Send message to mattermost + pushbullet Send message to pushbullet help, h Shows a list of commands or help for one command GLOBAL OPTIONS: diff --git a/docs/_sidebar.md b/docs/_sidebar.md index aee2dc3..a7e297e 100644 --- a/docs/_sidebar.md +++ b/docs/_sidebar.md @@ -3,4 +3,5 @@ * [Home](/) * [Installation](install.md) * [Services & Usage](services.md) +* [Contribution](contribution.md) \ No newline at end of file diff --git a/docs/contribution.md b/docs/contribution.md new file mode 100644 index 0000000..2ee5658 --- /dev/null +++ b/docs/contribution.md @@ -0,0 +1,73 @@ +## Contributing to PingMe +We want to make contributing to this project as easy and transparent as +possible. + +## Project structure + +- `service` - Contains definitions for the underlying notification services. + - `service/discord` - Discord notification service. + - `service/email` - Email notification service. + - `service/msteams` - Microsoft Teams notification service. + - `service/rocketchat` - RocketChat notification service. + - `service/slack` - Slack notification service. + - `service/telegram` - Telegram notification service. + - `service/pushover` - Pushover Notification service. + +- Documentation + `docs` - Contains the documentation in Markdown format. + - `services.md` If you are adding a new service please add documentation to `services.md`. + - `home.md` Is the main page rendered when docs website is loaded. + - `install.md` Contains the installation instructions for different packages. + + - Checking Locally + - Docsify is used for documentation rendering from markdown, you can download + the cli and test locally before opening a pull request. + + Install + ```bash + npm i docsify-cli -g + # yarn global add docsify-cli + ``` + Serve locally + ```bash + docsify serve docs + ``` + + +## Commits + +Commit messages should be well formatted, and to make that "standardized", we +are using Conventional Commits. + +```shell + + []: + │ │ │ + │ │ └─> Summary in present tense. Not capitalized. No period at the end. + │ │ + │ └─> Scope (optional): eg. common, compiler, authentication, core + │ + └─> Type: chore, docs, feat, fix, refactor, style, or test. + +``` + +You can follow the documentation on +[their website](https://www.conventionalcommits.org). + +## Pull Requests +We actively welcome your pull requests. + +1. Fork the repo and create your branch from `master`. +2. If you've added code that should be tested, add tests. +3. If you've changed APIs, update the documentation. +4. Ensure the test suite passes (`make test`). +5. Make sure your code lints (`make lint`). +6. Make sure your code is well formatted (`make fmt`). + +## Issues +We use GitHub issues to track public bugs. Please ensure your description is +clear and has sufficient instructions to be able to reproduce the issue. + +## License +By contributing to PingMe, you agree that your contributions will be licensed +under the LICENSE file in the root directory of this source tree. diff --git a/docs/home.md b/docs/home.md index cd24cdc..e77bdd9 100644 --- a/docs/home.md +++ b/docs/home.md @@ -33,24 +33,26 @@ ## About **PingMe** is a personal project to satisfy my needs of having alerts, most major platforms have integration to send alerts -but its not always useful, either you are stuck with one particular platform, or you have to do alot of integrations. I needed a small app +but it's not always useful, either you are stuck with one particular platform, or you have to do alot of integrations. I needed a small app which i can just call from my backup scripts, cron jobs, CI/CD pipelines or from anywhere to send a message with particular information. And i can ship it everywhere with ease. Hence, the birth of PingMe. Everything is configurable via environment variables, and you can simply export the logs or messages to a variable which will be sent -as message. And most of all this serves as a swiss army knife sort of tool which supports multiple platforms. +as message, and most of all this serves as a swiss army knife sort of tool which supports multiple platforms. ## Supported services - *Discord* - *Email* - *Microsoft Teams* +- *Mattermost* +- *Pushover* +- *Pushbullet* - *RocketChat* - *Slack* - *Telegram* -- *Pushover* -- *Mattermost* +- *Twillio* @@ -60,7 +62,7 @@ as message. And most of all this serves as a swiss army knife sort of tool which ## Contributing -Contributions, issues and feature requests are welcome!
Feel free to check [issues page](https://github.com/kha7iq/pingme/issues). You can also take a look at the [contributing guide](https://github.com/kha7iq/pingme/blob/master/CONTRIBUTING.md). +Contributions, issues and feature requests are welcome!
Feel free to check [issues page](https://github.com/kha7iq/pingme/issues). You can also take a look at the [contribution guide](contribution.md). @@ -72,6 +74,6 @@ Give a ⭐️ if you like this project! ## Disclaimer -Any misuse of this utilify is your own liability and responsibility and cannot be attributed to the authors of this library. See [license](LICENSE) for more. +Any misuse of this utility is your own liability and responsibility and cannot be attributed to the authors of this library. See [license](https://github.com/kha7iq/pingme/blob/master/LICENSE.md) for more. Spamming through the use of this library **may get you permanently banned** on most supported platforms. diff --git a/docs/install.md b/docs/install.md index 63a2870..94818c5 100644 --- a/docs/install.md +++ b/docs/install.md @@ -1,9 +1,17 @@ -## Linux & MacOs +## MacOS & Linux Homebrew ```bash brew install kha7iq/tap/pingme ``` +## Linux Binary +```bash +wget -q https://github.com/kha7iq/pingme/releases/download/v0.1.6/pingme_Linux_x86_64.tar.gz +tar -xf pingme_Linux_x86_64.tar.gz +chmod +x pingme +sudo mv pingme /usr/local/bin/pingme +``` + ## Go Get ```bash go get -u github.com/kha7iq/pingme @@ -29,7 +37,7 @@ Checkout [release](https://github.com/kha7iq/pingme/releases) page for available ```bash docker pull khaliq/pingme:latest ``` -- Github Registry +- GitHub Registry ```bash docker pull ghcr.io/kha7iq/pingme:latest ``` @@ -39,7 +47,7 @@ docker run ghcr.io/kha7iq/pingme:latest ``` -## Github Action +## GitHub Action A github action is also available now for this app, you can find it on [Github Market Place](https://github.com/marketplace/actions/pingme-action) or from this [repository](https://github.com/kha7iq/pingme-action) on github. Usage examples for workflow are available in the repo. diff --git a/docs/services.md b/docs/services.md index 1d893e4..e63046a 100644 --- a/docs/services.md +++ b/docs/services.md @@ -19,7 +19,7 @@ Multiple channel ids can be used separated by comma ','. pingme telegram --token "0125:AAFHvnYf_ABC" --msg "This is a new message ✈" --channel="-1001001001,-1002002001" ``` -- Github Action +- GitHub Action ```yaml on: [push] @@ -37,8 +37,8 @@ jobs: env: TELEGRAM_TOKEN: ${{ secrets.TELEGRAM_TOKEN }} TELEGRAM_CHANNELS: ${{ secrets.TELEGRAM_CHANNELS }} - TELEGRAM_TITLE: 'Refrence: ${{ github.ref }}' - TELEGRAM_MESSAGE: 'Event is triggerd by ${{ github.event_name }}' + TELEGRAM_TITLE: 'Reference: ${{ github.ref }}' + TELEGRAM_MESSAGE: 'Event is triggered by ${{ github.event_name }}' with: # Chose the messaging platform. @@ -88,8 +88,8 @@ jobs: ROCKETCHAT_SERVER_URL: ${{ secrets.ROCKETCHAT_SERVER_URL }} ROCKETCHAT_CHANNELS: ${{ secrets.ROCKETCHAT_CHANNELS }} ROCKETCHAT_URL_SCHEME: "https" - ROCKETCHAT_TITLE: 'Refrence: ${{ github.ref }}' - ROCKETCHAT_MESSAGE: 'Event is triggerd by ${{ github.event_name }}' + ROCKETCHAT_TITLE: 'Reference: ${{ github.ref }}' + ROCKETCHAT_MESSAGE: 'Event is triggered by ${{ github.event_name }}' with: # Chose the messaging platform. # slack / telegram / rocketchat / teams / pushover / discord / email / mattermost @@ -114,7 +114,7 @@ jobs: pingme pushover --token '123' --user '12345567' --title 'some title' --msg 'some message' ``` -- Github Action +- GitHub Action ```yaml on: [push] @@ -132,8 +132,8 @@ jobs: env: PUSHOVER_TOKEN: ${{ secrets.PUSHOVER_TOKEN }} PUSHOVER_USER: ${{ secrets.PUSHOVER_USER }} - PUSHOVER_TITLE: 'Refrence: ${{ github.ref }}' - PUSHOVER_MESSAGE: 'Event is triggerd by ${{ github.event_name }}' + PUSHOVER_TITLE: 'Reference: ${{ github.ref }}' + PUSHOVER_MESSAGE: 'Event is triggered by ${{ github.event_name }}' with: # Chose the messaging platform. @@ -161,7 +161,7 @@ You can specify multiple channels by separating the value with ','. pingme mattermost --token '123' --channel '12345,567' --url 'localhost' --scheme 'http' --msg 'some message' ``` -- Github Action +- GitHub Action ```yaml on: @@ -179,11 +179,11 @@ jobs: uses: kha7iq/pingme-action@v1 env: MATTERMOST_TOKEN: ${{ secrets.MATTERMOST_TOKEN }} - ROCKETCHAT_SERVER_URL: ${{ secrets.ROCKETCHAT_SERVER_URL }} + MATTERMOST_SERVER_URL: ${{ secrets.MATTERMOST_SERVER_URL }} MATTERMOST_CHANNELS: ${{ secrets.MATTERMOST_CHANNELS }} MATTERMOST_CHANNELS: ${{ secrets.MATTERMOST_CHANNELS }} - MATTERMOST_TITLE: 'Refrence: ${{ github.ref }}' - MATTERMOST_MESSAGE: 'Event is triggerd by ${{ github.event_name }}' + MATTERMOST_TITLE: 'Reference: ${{ github.ref }}' + MATTERMOST_MESSAGE: 'Event is triggered by ${{ github.event_name }}' with: # Chose the messaging platform. # slack / telegram / rocketchat / teams / pushover / discord / email / mattermost @@ -227,10 +227,10 @@ jobs: - name: Ping me On uses: kha7iq/pingme-action@v1 env: - PUSHOVER_TOKEN: ${{ secrets.SLACK_TOKEN }} + SLACK_TOKEN: ${{ secrets.SLACK_TOKEN }} SLACK_CHANNELS: ${{ secrets.SLACK_CHANNELS }} - SLACK_MSG_TITLE: 'Refrence: ${{ github.ref }}' - SLACK_MESSAGE: 'Event is triggerd by ${{ github.event_name }}' + SLACK_MSG_TITLE: 'Reference: ${{ github.ref }}' + SLACK_MESSAGE: 'Event is triggered by ${{ github.event_name }}' with: # Chose the messaging platform. # slack / telegram / rocketchat / teams / pushover / discord / email @@ -254,7 +254,7 @@ Multiple channel ids can be used separated by comma ','. pingme discord --token '123' --channel '1234567890' --msg 'some message' ``` -- Github Action +- GitHub Action ```yaml on: @@ -273,8 +273,8 @@ jobs: env: DISCORD_CHANNELS: ${{ secrets.DISCORD_CHANNELS }} DISCORD_TOKEN: ${{ secrets.DISCORD_TOKEN }} - DISCORD_TITLE: 'Refrence: ${{ github.ref }}' - DISCORD_MESSAGE: 'Event is triggerd by ${{ github.event_name }}' + DISCORD_TITLE: 'Reference: ${{ github.ref }}' + DISCORD_MESSAGE: 'Event is triggered by ${{ github.event_name }}' with: # Chose the messaging platform. # slack / telegram / rocketchat / teams / pushover / discord / email / mattermost @@ -298,7 +298,7 @@ you can add permissions for multiple channels to single webhook. pingme teams --webhook 'https://example.webhook.office.com/xx' --msg 'some message' ``` -- Github Action +- GitHub Action ```yaml on: [push] @@ -315,9 +315,8 @@ jobs: uses: kha7iq/pingme-action@v1 env: TEAMS_WEBHOOK: ${{ secrets.TEAMS_WEBHOOK }} - TELEGRAM_CHANNELS: ${{ secrets.TELEGRAM_CHANNELS }} - TEAMS_MSG_TITLE: 'Refrence: ${{ github.ref }}' - TEAMS_MESSAGE: 'Event is triggerd by ${{ github.event_name }}' + TEAMS_MSG_TITLE: 'Reference: ${{ github.ref }}' + TEAMS_MESSAGE: 'Event is triggered by ${{ github.event_name }}' with: # Chose the messaging platform. @@ -332,6 +331,102 @@ jobs: | TEAMS_MESSAGE | "" | | TEAMS_MSG_TITLE | "" | +## Pushbullet + +- SMS +```bash +pingme pushbullet --sms true --token "abcdefg" -d "adnroid" --msg "some message" --number "00123456789" +``` + +- Push notification +```bash +pingme pushbullet --token "abcdefg" -d "adnroid" --msg "some message" +``` + +- GitHub Action + +```yaml +on: [push] + +jobs: + pingme-job: + runs-on: ubuntu-latest + name: PingMe + steps: + - name: Checkout + uses: actions/checkout@v2 + + - name: Ping me On + uses: kha7iq/pingme-action@v1 + env: + PUSHBULLET_TOKEN: ${{ secrets.PUSHBULLET_TOKEN }} + PUSHBULLET_DEVICE: ${{ secrets.PUSHBULLET_DEVICE }} + PUSHBULLET_TITLE: 'Reference: ${{ github.ref }}' + PUSHBULLET_MESSAGE: 'Event is triggered by ${{ github.event_name }}' + + with: + # Chose the messaging platform. + # slack / telegram / rocketchat / teams / pushover / discord / email + service: pushbullet +``` + +- **Variables** + +| Variables | Default Value | +| -------------------------- | :----------------: | +| PUSHBULLET_TOKEN | "" | +| PUSHBULLET_DEVICE | "" | +| PUSHBULLET_NUMBER | "" | +| PUSHBULLET_MESSAGE | "" | +| PUSHBULLET_SMS | "false" | +| PUSHBULLET_TITLE | "" | + + + +## Twillio SMS +SMS can be sent via twillio to multiple numbers, you can add multiple receivers separated by a comma. + +```bash + pingme twillio --token 'tokenabc' --account 'sid123' --sender '+140001442' --receiver '+140001442'' --msg 'some message' +``` + +- GitHub Action + +```yaml +on: [push] + +jobs: + pingme-job: + runs-on: ubuntu-latest + name: PingMe + steps: + - name: Checkout + uses: actions/checkout@v2 + + - name: Ping me On + uses: kha7iq/pingme-action@v1 + env: + TWILLIO_TOKEN: ${{ secrets.TWILLIO_TOKEN }} + TWILLIO_ACCOUNT_SID: ${{ secrets.TWILLIO_ACCOUNT_SID }} + TWILLIO_SENDER: ${{ secrets.TWILLIO_SENDER }} + TWILLIO_RECEIVER: ${{ secrets.TWILLIO_RECEIVER }} + TWILLIO_TITLE: 'Reference: ${{ github.ref }}' + TWILLIO_MESSAGE: 'Event is triggered by ${{ github.event_name }}' + with: + # Chose the messaging platform. + # slack / telegram / rocketchat / teams / pushover / discord / email / mattermost / twillio + service: twillio +``` +- **Variables** + +| Variables | Default Value | +| -------------------------- | :----------------: | +| TWILLIO_TOKEN | "" | +| TWILLIO_ACCOUNT_SID | "" | +| TWILLIO_SENDER | "" | +| TWILLIO_RECEIVER | "" | +| TWILLIO_TITLE | "" | +| TWILLIO_MESSAGE | "" | ## Email Email uses username & password to authenticate for sending emails. diff --git a/go.mod b/go.mod index 92ba9aa..5bb0762 100644 --- a/go.mod +++ b/go.mod @@ -7,5 +7,6 @@ require ( github.com/gregdel/pushover v0.0.0-20210216095829-2131362cb888 github.com/nikoksr/notify v0.15.0 github.com/russross/blackfriday/v2 v2.1.0 // indirect + github.com/sfreiberg/gotwilio v0.0.0-20201211181435-c426a3710ab5 // indirect github.com/urfave/cli/v2 v2.3.0 ) diff --git a/go.sum b/go.sum index 5df3046..728a3da 100644 --- a/go.sum +++ b/go.sum @@ -32,6 +32,7 @@ github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:ma github.com/cpuguy83/go-md2man/v2 v2.0.0 h1:EoUDS0afbrsXAZ9YQ9jdu/mZ2sXgT1/2yyNng4PGlyM= github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= +github.com/cschomburg/go-pushbullet v0.0.0-20171206132031-67759df45fbb h1:7X9nrm+LNWdxzQOiCjy0G51rNUxbH35IDHCjAMvogyM= github.com/cschomburg/go-pushbullet v0.0.0-20171206132031-67759df45fbb/go.mod h1:RfQ9wji3fjcSEsQ+uFCtIh3+BXgcZum8Kt3JxvzYzlk= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= @@ -40,6 +41,8 @@ github.com/deckarep/golang-set v1.7.1/go.mod h1:93vsz/8Wt4joVM7c2AVqh+YRMiUSc14y github.com/dghubble/go-twitter v0.0.0-20201011215211-4b180d0cc78d/go.mod h1:xfg4uS5LEzOj8PgZV7SQYRHbG7jPUnelEiaAVJxmhJE= github.com/dghubble/oauth1 v0.7.0/go.mod h1:8pFdfPkv/jr8mkChVbNVuJ0suiHe278BtWI4Tk1ujxk= github.com/dghubble/sling v1.3.0/go.mod h1:XXShWaBWKzNLhu2OxikSNFrlsvowtz4kyRuXUG7oQKY= +github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM= +github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/facebookgo/ensure v0.0.0-20160127193407-b4ab57deab51/go.mod h1:Yg+htXGokKKdzcwhuNDwVvN+uBxDGXJ7G/VN1d8fa64= @@ -70,11 +73,14 @@ github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMyw github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-querystring v1.0.0 h1:Xkwi/a1rcvNg1PPYe5vI8GbeBY/jrVuDX5ASuANWTrk= github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/gopackage/ddp v0.0.0-20170117053602-652027933df4 h1:4EZlYQIiyecYJlUbVkFXCXHz1QPhVXcHnQKAzBTPfQo= github.com/gopackage/ddp v0.0.0-20170117053602-652027933df4/go.mod h1:lEO7XoHJ/xNRBCxrn4h/CEB67h0kW1B0t4ooP2yrjUA= github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= +github.com/gorilla/schema v1.1.0 h1:CamqUDOFUBqzrvxuz2vEwo8+SUdwsluFh7IlzJh30LY= +github.com/gorilla/schema v1.1.0/go.mod h1:kgLaKoK1FELgZqMAVxx/5cbj0kT+57qxUrAlIO2eleU= github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc= @@ -87,6 +93,8 @@ github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfC github.com/jordan-wright/email v4.0.1-0.20210109023952-943e75fe5223+incompatible h1:jdpOPRN1zP63Td1hDQbZW73xKmzDvZHzVdNYxhnTMDA= github.com/jordan-wright/email v4.0.1-0.20210109023952-943e75fe5223+incompatible/go.mod h1:1c7szIrayyPPB/987hsnvNzLushdWf4o/79s3P08L8A= github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= @@ -123,7 +131,10 @@ github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/sendgrid/rest v2.6.3+incompatible/go.mod h1:kXX7q3jZtJXK5c5qK83bSGMdV6tsOE70KbHoqJls4lE= github.com/sendgrid/sendgrid-go v3.8.0+incompatible/go.mod h1:QRQt+LX/NmgVEvmdRw0VT/QgUn499+iza2FnDca9fg8= +github.com/sfreiberg/gotwilio v0.0.0-20201211181435-c426a3710ab5 h1:76NN4jha0iT2Qwfth8Xf8q2LlQEG7jiZ86dFDKHN9l8= +github.com/sfreiberg/gotwilio v0.0.0-20201211181435-c426a3710ab5/go.mod h1:dhtsjtHOWmTLjCOyNloce1diOIs9H1mvVmcOG7qmZUc= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= +github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= github.com/skip2/go-qrcode v0.0.0-20190110000554-dc11ecdae0a9/go.mod h1:PLPIyL7ikehBD1OAjmKKiOEhbvWyHGaNDjquXMcYABo= github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e/go.mod h1:XV66xRDqSt+GTGFMVlhk3ULuV0y9ZmzeVGR4mloJI3M= @@ -132,6 +143,7 @@ github.com/slack-go/slack v0.8.1/go.mod h1:FGqNzJBmxIsZURAxh2a8D21AnOVvvXZvGligs github.com/sony/sonyflake v1.0.0 h1:MpU6Ro7tfXwgn2l5eluf9xQvQJDROTBImNCfRXn/YeM= github.com/sony/sonyflake v1.0.0/go.mod h1:Jv3cfhf/UFtolOTTRd3q4Nl6ENqM+KfyZ5PseKfZGF4= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.3.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= @@ -175,6 +187,8 @@ golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5h golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= diff --git a/main.go b/main.go index 36064b5..3a79a81 100644 --- a/main.go +++ b/main.go @@ -4,7 +4,17 @@ import ( "log" "os" - "github.com/kha7iq/pingme/cmd" + "github.com/kha7iq/pingme/service/twillio" + + "github.com/kha7iq/pingme/service/discord" + "github.com/kha7iq/pingme/service/email" + "github.com/kha7iq/pingme/service/mattermost" + "github.com/kha7iq/pingme/service/msteams" + "github.com/kha7iq/pingme/service/pushbullet" + "github.com/kha7iq/pingme/service/pushover" + "github.com/kha7iq/pingme/service/rocketchat" + "github.com/kha7iq/pingme/service/slack" + "github.com/kha7iq/pingme/service/telegram" "github.com/urfave/cli/v2" ) @@ -12,7 +22,7 @@ import ( // Version variable is used for semVer var Version string -// main with combile all the function into commands +// main with combine all the function into commands func main() { app := cli.NewApp() app.Name = "PingMe" @@ -21,17 +31,19 @@ func main() { app.Description = `PingMe is a CLI tool which provides the ability to send messages or alerts to multiple messaging platforms and also email, everything is configurable via environment variables and command line switches.Currently supported platforms include Slack, Telegram, -RocketChat, Discord, Pushover, Mattermost, Microsoft Teams and email address.` +RocketChat, Discord, Pushover, Mattermost, Pushbullet, Microsoft Teams and email address.` // app.Commands contains the subcommands as functions which return []*cli.Command. app.Commands = []*cli.Command{ - cmd.SendToTelegram(), - cmd.SendToRocketChat(), - cmd.SendToSlack(), - cmd.SendToDiscord(), - cmd.SendToTeams(), - cmd.SendToPushOver(), - cmd.SendToEmail(), - cmd.SendToMattermost(), + telegram.Send(), + rocketchat.Send(), + slack.Send(), + discord.Send(), + msteams.Send(), + pushover.Send(), + email.Send(), + mattermost.Send(), + pushbullet.Send(), + twillio.Send(), } err := app.Run(os.Args) diff --git a/cmd/discord.go b/service/discord/discord.go similarity index 89% rename from cmd/discord.go rename to service/discord/discord.go index d83f11a..1b654c1 100644 --- a/cmd/discord.go +++ b/service/discord/discord.go @@ -1,4 +1,4 @@ -package cmd +package discord import ( "context" @@ -6,6 +6,8 @@ import ( "log" "strings" + "github.com/kha7iq/pingme/service/helpers" + "github.com/nikoksr/notify" "github.com/nikoksr/notify/service/discord" "github.com/urfave/cli/v2" @@ -19,11 +21,11 @@ type discordPingMe struct { Title string } -// SendToDiscord parse values from *cli.context and return *cli.Command. +// Send parse values from *cli.context and return *cli.Command. // Values include discord bot token, userID, channelIDs, Message and Title. // If multiple channels are provided then the string is split with "," separator and // each channelID is added to receiver. -func SendToDiscord() *cli.Command { +func Send() *cli.Command { var discordOpts discordPingMe return &cli.Command{ Name: "discord", @@ -56,7 +58,7 @@ All configuration options are also available via environment variables.`, &cli.StringFlag{ Destination: &discordOpts.Title, Name: "title", - Value: TimeValue, + Value: helpers.TimeValue, Usage: "Title of the message.", EnvVars: []string{"DISCORD_MSG_TITLE"}, }, @@ -66,13 +68,13 @@ All configuration options are also available via environment variables.`, discordSvc := discord.New() if err := discordSvc.AuthenticateWithBotToken(discordOpts.Token); err != nil { - return fmt.Errorf("unable to authenticate %v\n", err) + return fmt.Errorf("unable to authenticate %v", err) } chn := strings.Split(discordOpts.Channel, ",") for _, v := range chn { if len(v) <= 0 { - return fmt.Errorf(EmptyChannel) + return helpers.ErrChannel } discordSvc.AddReceivers(v) diff --git a/cmd/email.go b/service/email/email.go similarity index 94% rename from cmd/email.go rename to service/email/email.go index fda5267..aae64e2 100644 --- a/cmd/email.go +++ b/service/email/email.go @@ -1,11 +1,12 @@ -package cmd +package email import ( "context" - "fmt" "log" "strings" + "github.com/kha7iq/pingme/service/helpers" + "github.com/nikoksr/notify" "github.com/nikoksr/notify/service/mail" "github.com/urfave/cli/v2" @@ -23,12 +24,12 @@ type email struct { Identity string } -// SendToEmail parse values from *cli.context and return *cli.Command. +// Send parses values from *cli.context and return *cli.Command. // SendAddress is used for authentication with smtp server, host and port is required // the default value for port is set to "587" and host as "smtp.gmail.com" // If multiple ReceiverAddress are provided then the string value is split with "," separator and // each ReceiverAddress is added to receiver. -func SendToEmail() *cli.Command { +func Send() *cli.Command { var emailOpts email return &cli.Command{ Name: "email", @@ -98,7 +99,7 @@ All configuration options are also available via environment variables.`, &cli.StringFlag{ Destination: &emailOpts.Subject, Name: "sub", - Value: TimeValue, + Value: helpers.TimeValue, Usage: "Subject of the email", EnvVars: []string{"EMAIL_SUBJECT"}, }, @@ -111,7 +112,7 @@ All configuration options are also available via environment variables.`, chn := strings.Split(emailOpts.ReceiverAddress, ",") for _, v := range chn { if len(v) <= 0 { - return fmt.Errorf(EmptyChannel) + return helpers.ErrChannel } emailSvc.AddReceivers(v) diff --git a/service/helpers/helper.go b/service/helpers/helper.go new file mode 100644 index 0000000..2779475 --- /dev/null +++ b/service/helpers/helper.go @@ -0,0 +1,13 @@ +package helpers + +import ( + "errors" + "time" +) + +var ( + // ErrChannel variable holds default error message if no channel is provided. + ErrChannel = errors.New("target channel or id can not be empty") + // TimeValue holds current date and time in unix format. + TimeValue = "⏰ " + time.Now().Format(time.UnixDate) +) diff --git a/cmd/mattermost.go b/service/mattermost/mattermost.go similarity index 92% rename from cmd/mattermost.go rename to service/mattermost/mattermost.go index 9f374ce..bc8566d 100644 --- a/cmd/mattermost.go +++ b/service/mattermost/mattermost.go @@ -1,4 +1,4 @@ -package cmd +package mattermost import ( "bytes" @@ -9,6 +9,8 @@ import ( "strings" "time" + "github.com/kha7iq/pingme/service/helpers" + "github.com/urfave/cli/v2" ) @@ -18,7 +20,7 @@ type matterMost struct { Token string ServerURL string Scheme string - ApiURL string + APIURL string Message string ChanIDs string } @@ -47,11 +49,11 @@ type matterMostResponse struct { Metadata struct{} `json:"metadata"` } -// SendToMattermost parse values from *cli.context and return *cli.Command +// Send parse values from *cli.context and return *cli.Command // and send messages to target channels. // If multiple channel ids are provided then the string is split with "," separator and // message is sent to each channel. -func SendToMattermost() *cli.Command { +func Send() *cli.Command { var mattermostOpts matterMost return &cli.Command{ Name: "mattermost", @@ -87,7 +89,7 @@ You can specify multiple channels by separating the value with ','.`, &cli.StringFlag{ Destination: &mattermostOpts.Title, Name: "title", - Value: TimeValue, + Value: helpers.TimeValue, Usage: "Title of the message.", EnvVars: []string{"MATTERMOST_TITLE"}, }, @@ -108,7 +110,7 @@ You can specify multiple channels by separating the value with ','.`, EnvVars: []string{"MATTERMOST_SCHEME"}, }, &cli.StringFlag{ - Destination: &mattermostOpts.ApiURL, + Destination: &mattermostOpts.APIURL, Name: "api", Value: "/api/v4/posts", Usage: "Unless using older version of api default is fine.", @@ -116,7 +118,7 @@ You can specify multiple channels by separating the value with ','.`, }, }, Action: func(ctx *cli.Context) error { - endPointURL := mattermostOpts.Scheme + "://" + mattermostOpts.ServerURL + mattermostOpts.ApiURL + endPointURL := mattermostOpts.Scheme + "://" + mattermostOpts.ServerURL + mattermostOpts.APIURL // Create a Bearer string by appending string access token bearer := "Bearer " + mattermostOpts.Token @@ -126,10 +128,10 @@ You can specify multiple channels by separating the value with ','.`, ids := strings.Split(mattermostOpts.ChanIDs, ",") for _, v := range ids { if len(v) == 0 { - return fmt.Errorf(EmptyChannel) + return helpers.ErrChannel } - jsonData, err := toJson(v, fullMessage) + jsonData, err := toJSON(v, fullMessage) if err != nil { return fmt.Errorf("error parsing json\n[ERROR] - %v", err) } @@ -137,7 +139,6 @@ You can specify multiple channels by separating the value with ','.`, if err := sendMattermost(endPointURL, bearer, jsonData); err != nil { return fmt.Errorf("failed to send message\n[ERROR] - %v", err) } - } return nil }, @@ -145,8 +146,7 @@ You can specify multiple channels by separating the value with ','.`, } // toJson takes strings and convert them to json byte array -func toJson(channel string, msg string) ([]byte, error) { - +func toJSON(channel string, msg string) ([]byte, error) { m := make(map[string]string, 2) m["channel_id"] = channel m["message"] = msg diff --git a/cmd/msteams.go b/service/msteams/msteams.go similarity index 90% rename from cmd/msteams.go rename to service/msteams/msteams.go index 78cead2..e109441 100644 --- a/cmd/msteams.go +++ b/service/msteams/msteams.go @@ -1,11 +1,12 @@ -package cmd +package msteams import ( "context" - "fmt" "log" "strings" + "github.com/kha7iq/pingme/service/helpers" + "github.com/nikoksr/notify" msteams2 "github.com/nikoksr/notify/service/msteams" "github.com/urfave/cli/v2" @@ -18,11 +19,11 @@ type msTeams struct { Title string } -// SendToTeams parse values from *cli.context and return *cli.Command. +// Send parse values from *cli.context and return *cli.Command. // Values include Ms Teams Webhook, Message and Title. // If multiple webhooks are provided then the string is split with "," separator and // each webhook is added to receiver. -func SendToTeams() *cli.Command { +func Send() *cli.Command { var msTeamOpt msTeams return &cli.Command{ Name: "teams", @@ -48,7 +49,7 @@ you can add permissions for multiple channels to single webhook.`, &cli.StringFlag{ Destination: &msTeamOpt.Title, Name: "title", - Value: TimeValue, + Value: helpers.TimeValue, Usage: "Title of the message.", EnvVars: []string{"TEAMS_MSG_TITLE"}, }, @@ -60,10 +61,9 @@ you can add permissions for multiple channels to single webhook.`, chn := strings.Split(msTeamOpt.Webhook, ",") for _, v := range chn { if len(v) <= 0 { - return fmt.Errorf(EmptyChannel) + return helpers.ErrChannel } teamsSvc.AddReceivers(v) - } notifier.UseServices(teamsSvc) diff --git a/service/pushbullet/pushbullet.go b/service/pushbullet/pushbullet.go new file mode 100644 index 0000000..a358c0a --- /dev/null +++ b/service/pushbullet/pushbullet.go @@ -0,0 +1,136 @@ +package pushbullet + +import ( + "context" + "log" + "strings" + + "github.com/kha7iq/pingme/service/helpers" + + "github.com/nikoksr/notify" + "github.com/nikoksr/notify/service/pushbullet" + "github.com/urfave/cli/v2" +) + +// pushBullet struct holds data parsed via flags for pushbullet service. +type pushBullet struct { + Token string + Message string + Title string + Device string + PhoneNumber string + SMS bool +} + +// Send parse values from *cli.context and return *cli.Command. +// Values include pushbullet token, Device, phone number, Message and Title. +// If multiple devices are provided they the string is split with "," separator and +// each device is added to receiver. +func Send() *cli.Command { + var pushBulletOpts pushBullet + return &cli.Command{ + Name: "pushbullet", + Usage: "Send message to pushbullet", + Description: `Pushbullet uses API token to authenticate & send messages to defined devices. +Multiple device nicknames or numbers can be used separated by comma.`, + UsageText: "pingme pushbullet --token '123' --device 'Web123, myAndroid' --msg 'some message'\n" + + "pingme pushbullet --token '123' --sms true --device 'Web123' --msg 'some message' --number '00123456789'", + Flags: []cli.Flag{ + &cli.StringFlag{ + Destination: &pushBulletOpts.Token, + Name: "token", + Aliases: []string{"t"}, + Required: true, + Usage: "Token of pushbullet api used for sending message.", + EnvVars: []string{"PUSHBULLET_TOKEN"}, + }, + &cli.StringFlag{ + Destination: &pushBulletOpts.Device, + Name: "device", + Aliases: []string{"d"}, + Required: true, + Usage: "Device's nickname of pushbullet.", + EnvVars: []string{"PUSHBULLET_DEVICE"}, + }, + &cli.StringFlag{ + Destination: &pushBulletOpts.PhoneNumber, + Name: "number", + Aliases: []string{"n"}, + Usage: "Target phone number", + EnvVars: []string{"PUSHBULLET_NUMBER"}, + }, + &cli.StringFlag{ + Destination: &pushBulletOpts.Message, + Name: "msg", + Aliases: []string{"m"}, + Usage: "Message content.", + EnvVars: []string{"PUSHBULLET_MESSAGE"}, + }, + &cli.StringFlag{ + Destination: &pushBulletOpts.Title, + Name: "title", + Value: helpers.TimeValue, + Usage: "Title of the message.", + EnvVars: []string{"PUSHBULLET_TITLE"}, + }, + &cli.BoolFlag{ + Destination: &pushBulletOpts.SMS, + Name: "sms", + Value: false, + Usage: "To send sms message set the value to 'true'", + EnvVars: []string{"PUSHBULLET_SMS"}, + }, + }, + Action: func(ctx *cli.Context) error { + notifier := notify.New() + + switch pushBulletOpts.SMS { + case true: + pushBulletSmsSvc, err := pushbullet.NewSMS(pushBulletOpts.Token, pushBulletOpts.Device) + if err != nil { + return err + } + devices := strings.Split(pushBulletOpts.PhoneNumber, ",") + for _, v := range devices { + if len(v) <= 0 { + return helpers.ErrChannel + } + pushBulletSmsSvc.AddReceivers(v) + + notifier.UseServices(pushBulletSmsSvc) + + if err := notifier.Send( + context.Background(), + pushBulletOpts.Title, + pushBulletOpts.Message, + ); err != nil { + return err + } + } + default: + pushBulletSvc := pushbullet.New(pushBulletOpts.Token) + + devices := strings.Split(pushBulletOpts.Device, ",") + for _, v := range devices { + if len(v) <= 0 { + return helpers.ErrChannel + } + pushBulletSvc.AddReceivers(v) + } + + notifier.UseServices(pushBulletSvc) + + if err := notifier.Send( + context.Background(), + pushBulletOpts.Title, + pushBulletOpts.Message, + ); err != nil { + return err + } + } + + log.Println("Successfully sent!") + return nil + }, + } +} diff --git a/cmd/pushover.go b/service/pushover/pushover.go similarity index 91% rename from cmd/pushover.go rename to service/pushover/pushover.go index dfed0e7..3d4adb1 100644 --- a/cmd/pushover.go +++ b/service/pushover/pushover.go @@ -1,10 +1,11 @@ -package cmd +package pushover import ( - "fmt" "log" "strings" + "github.com/kha7iq/pingme/service/helpers" + "github.com/gregdel/pushover" "github.com/urfave/cli/v2" ) @@ -17,11 +18,11 @@ type pushOver struct { Title string } -// SendToPushOver parse values from *cli.context and return *cli.Command. +// Send parse values from *cli.context and return *cli.Command. // Values include token, users, Message and Title. // If multiple users are provided then the string is split with "," separator and // each user is added to receiver. -func SendToPushOver() *cli.Command { +func Send() *cli.Command { var pushOverOpts pushOver return &cli.Command{ Name: "pushover", @@ -56,7 +57,7 @@ All configuration options are also available via environment variables.`, &cli.StringFlag{ Destination: &pushOverOpts.Title, Name: "title", - Value: TimeValue, + Value: helpers.TimeValue, Usage: "Title of the message.", EnvVars: []string{"PUSHOVER_TITLE"}, }, @@ -68,7 +69,7 @@ All configuration options are also available via environment variables.`, for _, v := range users { if len(v) == 0 { - return fmt.Errorf(EmptyChannel) + return helpers.ErrChannel } recipient := pushover.NewRecipient(v) responsePushOver, err := app.SendMessage(message, recipient) diff --git a/cmd/rocketchat.go b/service/rocketchat/rocketchat.go similarity index 85% rename from cmd/rocketchat.go rename to service/rocketchat/rocketchat.go index e024208..7efcfba 100644 --- a/cmd/rocketchat.go +++ b/service/rocketchat/rocketchat.go @@ -1,11 +1,10 @@ -package cmd +package rocketchat import ( "context" - "fmt" "strings" - "time" + "github.com/kha7iq/pingme/service/helpers" "github.com/nikoksr/notify" "github.com/nikoksr/notify/service/rocketchat" "github.com/urfave/cli/v2" @@ -13,7 +12,7 @@ import ( type rocketChat struct { Token string - UserId string + UserID string Message string Channel string Title string @@ -21,17 +20,11 @@ type rocketChat struct { Scheme string } -var ( - // EmptyChannel variable holds default error message if no channel is provided. - EmptyChannel = "channel name or id can not be empty" - TimeValue = "⏰ " + time.Now().Format(time.UnixDate) -) - -// SendToRocketChat parse values from *cli.context and return *cli.Command. +// Send parse values from *cli.context and return *cli.Command. // Values include rocketchat token, , UserId, channelIDs, ServerURL, Scheme, Message and Title. // If multiple channels are provided then the string is split with "," separator and // each channelID is added to receiver. -func SendToRocketChat() *cli.Command { +func Send() *cli.Command { var rocketChatOpts rocketChat return &cli.Command{ Name: "rocketchat", @@ -43,7 +36,7 @@ All configuration options are also available via environment variables.`, " --channel 'alert' --msg 'some message'", Flags: []cli.Flag{ &cli.StringFlag{ - Destination: &rocketChatOpts.UserId, + Destination: &rocketChatOpts.UserID, Name: "userid", Aliases: []string{"id"}, Required: true, @@ -90,7 +83,7 @@ All configuration options are also available via environment variables.`, &cli.StringFlag{ Destination: &rocketChatOpts.Title, Name: "title", - Value: TimeValue, + Value: helpers.TimeValue, Usage: "Title of the message", EnvVars: []string{"ROCKETCHAT_TITLE"}, }, @@ -99,14 +92,14 @@ All configuration options are also available via environment variables.`, notifier := notify.New() rocketChatSvc, err := rocketchat.New(rocketChatOpts.ServerURL, rocketChatOpts.Scheme, - rocketChatOpts.UserId, rocketChatOpts.Token) + rocketChatOpts.UserID, rocketChatOpts.Token) if err != nil { return err } chn := strings.Split(rocketChatOpts.Channel, ",") for _, v := range chn { if len(v) <= 0 { - return fmt.Errorf(EmptyChannel) + return helpers.ErrChannel } rocketChatSvc.AddReceivers(v) diff --git a/cmd/slack.go b/service/slack/slack.go similarity index 91% rename from cmd/slack.go rename to service/slack/slack.go index d47d77e..4cc5709 100644 --- a/cmd/slack.go +++ b/service/slack/slack.go @@ -1,11 +1,12 @@ -package cmd +package slack import ( "context" - "fmt" "log" "strings" + "github.com/kha7iq/pingme/service/helpers" + "github.com/nikoksr/notify" "github.com/nikoksr/notify/service/slack" "github.com/urfave/cli/v2" @@ -19,11 +20,11 @@ type slackPingMe struct { Title string } -// SendToSlack parse values from *cli.context and return *cli.Command. +// Send parse values from *cli.context and return *cli.Command. // Values include slack token, channelIDs, Message and Title. // If multiple channels are provided then the string is split with "," separator and // each channelID is added to receiver. -func SendToSlack() *cli.Command { +func Send() *cli.Command { var slackOpts slackPingMe return &cli.Command{ Name: "slack", @@ -59,7 +60,7 @@ All configuration options are also available via environment variables.`, &cli.StringFlag{ Destination: &slackOpts.Title, Name: "title", - Value: TimeValue, + Value: helpers.TimeValue, Usage: "Title of the message.", EnvVars: []string{"SLACK_MSG_TITLE"}, }, @@ -70,7 +71,7 @@ All configuration options are also available via environment variables.`, chn := strings.Split(slackOpts.Channel, ",") for _, v := range chn { if len(v) <= 0 { - return fmt.Errorf(EmptyChannel) + return helpers.ErrChannel } slackSvc.AddReceivers(v) diff --git a/cmd/telegram.go b/service/telegram/telegram.go similarity index 89% rename from cmd/telegram.go rename to service/telegram/telegram.go index c843452..ecd5c21 100644 --- a/cmd/telegram.go +++ b/service/telegram/telegram.go @@ -1,12 +1,13 @@ -package cmd +package telegram import ( "context" - "fmt" "log" "strconv" "strings" + "github.com/kha7iq/pingme/service/helpers" + "github.com/nikoksr/notify" "github.com/nikoksr/notify/service/telegram" "github.com/urfave/cli/v2" @@ -20,11 +21,11 @@ type teleGram struct { Title string } -// SendToTelegram parse values from *cli.context and return *cli.Command. +// Send parse values from *cli.context and return *cli.Command. // Values include telegram token, channelIDs, Message and Title. // If multiple channels are provided they the string is split with "," separator and // each channelID is added to receiver. -func SendToTelegram() *cli.Command { +func Send() *cli.Command { var telegramOpts teleGram return &cli.Command{ Name: "telegram", @@ -60,7 +61,7 @@ All configuration options are also available via environment variables.`, &cli.StringFlag{ Destination: &telegramOpts.Title, Name: "title", - Value: TimeValue, + Value: helpers.TimeValue, Usage: "Title of the message.", EnvVars: []string{"TELEGRAM_TITLE"}, }, @@ -75,11 +76,11 @@ All configuration options are also available via environment variables.`, chn := strings.Split(telegramOpts.Channel, ",") for _, v := range chn { if len(v) <= 0 { - return fmt.Errorf(EmptyChannel) + return helpers.ErrChannel } - k, err := strconv.Atoi(v) - if err != nil { - log.Println(err) + k, errStr := strconv.Atoi(v) + if errStr != nil { + return errStr } telegramSvc.AddReceivers(int64(k)) } diff --git a/service/twillio/twillio.go b/service/twillio/twillio.go new file mode 100644 index 0000000..066024c --- /dev/null +++ b/service/twillio/twillio.go @@ -0,0 +1,102 @@ +package twillio + +import ( + "log" + "strings" + + "github.com/kha7iq/pingme/service/helpers" + "github.com/sfreiberg/gotwilio" + "github.com/urfave/cli/v2" +) + +// Twillio struct holds data parsed via flags for the service +type Twillio struct { + Title string + Token string + AccountSid string + Sender string + Receiver string + Message string +} + +// Send parse values from *cli.context and return *cli.Command +// and send messages to target numbers. +// If multiple receivers are provided then the string is split with "," separator and +// message is sent to each number. +func Send() *cli.Command { + var twillioOpts Twillio + return &cli.Command{ + Name: "twillio", + Usage: "Send sms via twillio", + UsageText: "pingme twillio --token 'tokenabc' --account 'sid123' " + + "--sender '+140001442' --receiver '+140001442'' --msg 'some message'", + Description: `Twillio provides ability to send sms to multiple numbers. +You can specify multiple receivers by separating the value with a comma.`, + Flags: []cli.Flag{ + &cli.StringFlag{ + Destination: &twillioOpts.Token, + Name: "token", + Aliases: []string{"t"}, + Required: true, + Usage: "Auth token for twillio account.", + EnvVars: []string{"TWILLIO_TOKEN"}, + }, + &cli.StringFlag{ + Destination: &twillioOpts.AccountSid, + Name: "account", + Required: true, + Aliases: []string{"a"}, + Usage: "Twillio account sid", + EnvVars: []string{"TWILLIO_ACCOUNT_SID"}, + }, + &cli.StringFlag{ + Destination: &twillioOpts.Message, + Name: "msg", + Aliases: []string{"m"}, + Usage: "Message content.", + EnvVars: []string{"TWILLIO_MESSAGE"}, + }, + &cli.StringFlag{ + Destination: &twillioOpts.Title, + Name: "title", + Usage: "Title of the message.", + EnvVars: []string{"TWILLIO_TITLE"}, + }, + &cli.StringFlag{ + Destination: &twillioOpts.Sender, + Name: "sender", + Aliases: []string{"s"}, + Usage: "Sender's phone number", + EnvVars: []string{"TWILLIO_SENDER"}, + }, + &cli.StringFlag{ + Destination: &twillioOpts.Receiver, + Name: "receiver", + Aliases: []string{"r"}, + Usage: "Receiver's phone number", + EnvVars: []string{"TWILLIO_RECEIVER"}, + }, + }, + Action: func(ctx *cli.Context) error { + client := gotwilio.NewTwilioClient(twillioOpts.AccountSid, twillioOpts.Token) + fullMessage := twillioOpts.Title + "\n" + twillioOpts.Message + + numbers := strings.Split(twillioOpts.Receiver, ",") + for _, v := range numbers { + if len(v) == 0 { + return helpers.ErrChannel + } + + _, exception, err := client.SendSMS(twillioOpts.Sender, twillioOpts.Receiver, fullMessage, "", "") + if err != nil { + return err + } + if exception != nil { + return exception + } + } + log.Println("Successfully sent!") + return nil + }, + } +}