1
0
mirror of https://github.com/kha7iq/pingme.git synced 2025-05-16 06:40:12 -07:00

Compare commits

..

No commits in common. "master" and "v0.1.7" have entirely different histories.

44 changed files with 489 additions and 3437 deletions

View File

@ -5,39 +5,31 @@ about: Create a report to help us improve
---
**Describe the bug**
A clear and concise description of what the bug is.
**To Reproduce**
Steps to reproduce the behavior:
1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
4. See error
**Expected behavior**
A clear and concise description of what you expected to happen.
**Screenshots**
If applicable, add screenshots to help explain your problem.
**Desktop (please complete the following information):**
- OS: [e.g. iOS]
- Browser [e.g. chrome, safari]
- Version [e.g. 22]
- OS: [e.g. iOS]
- Browser [e.g. chrome, safari]
- Version [e.g. 22]
**Smartphone (please complete the following information):**
- Device: [e.g. iPhone6]
- OS: [e.g. iOS8.1]
- Browser [e.g. stock browser, safari]
- Version [e.g. 22]
- Device: [e.g. iPhone6]
- OS: [e.g. iOS8.1]
- Browser [e.g. stock browser, safari]
- Version [e.g. 22]
**Additional context**
Add any other context about the problem here.

35
.github/ISSUE_TEMPLATE/bug_report.md-e vendored Normal file
View File

@ -0,0 +1,35 @@
---
name: Bug report
about: Create a report to help us improve
---
**Describe the bug**
A clear and concise description of what the bug is.
**To Reproduce**
Steps to reproduce the behavior:
1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
4. See error
**Expected behavior**
A clear and concise description of what you expected to happen.
**Screenshots**
If applicable, add screenshots to help explain your problem.
**Desktop (please complete the following information):**
- OS: [e.g. iOS]
- Browser [e.g. chrome, safari]
- Version [e.g. 22]
**Smartphone (please complete the following information):**
- Device: [e.g. iPhone6]
- OS: [e.g. iOS8.1]
- Browser [e.g. stock browser, safari]
- Version [e.g. 22]
**Additional context**
Add any other context about the problem here.

View File

@ -5,18 +5,13 @@ about: Suggest an idea for this project
---
**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex.
I'm always frustrated when [...]
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
**Describe the solution you'd like**
A clear and concise description of what you want to happen.
**Describe alternatives you've considered**
A clear and concise description of any alternative solutions or features you've considered.
**Additional context**
Add any other context or screenshots about the feature request here.

View File

@ -0,0 +1,17 @@
---
name: Feature request
about: Suggest an idea for this project
---
**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
**Describe the solution you'd like**
A clear and concise description of what you want to happen.
**Describe alternatives you've considered**
A clear and concise description of any alternative solutions or features you've considered.
**Additional context**
Add any other context or screenshots about the feature request here.

31
.github/PULL_REQUEST_TEMPLATE.md-e vendored Normal file
View File

@ -0,0 +1,31 @@
# Description
Please include a summary of the change and which issue is fixed. Please also include relevant motivation and context. List any dependencies that are required for this change.
Fixes # (issue)
## Type of change
Please delete options that are not relevant.
- [ ] Bug fix (non-breaking change which fixes an issue)
- [ ] New feature (non-breaking change which adds functionality)
- [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected)
- [ ] This change requires a documentation update
# How Has This Been Tested?
Please describe the tests that you ran to verify your changes. Provide instructions so we can reproduce. Please also list any relevant details for your test configuration
- [ ] Running existing tests
- [ ] Created new tests
# Checklist:
- [ ] My code has been linted (`make lint`)
- [ ] I have performed a self-review of my own code
- [ ] I have commented my code, particularly in hard-to-understand areas
- [ ] I have made corresponding changes to the documentation
- [ ] I have added tests that prove my fix is effective or that my feature works
- [ ] New and existing unit tests pass locally with my changes
- [ ] I have rebased my branch to include the latest changes from `master`

View File

@ -1,23 +0,0 @@
pkgbase = pingme-bin
pkgdesc = PingMe is a CLI tool which provides the ability to send messages or alerts to multiple messaging platforms & email (official binary)
pkgver = ${PKGVER}
pkgrel = ${PKGREL}
url = https://pingme.lmno.pk
arch = i686
arch = x86_64
arch = aarch64
license = MIT
optdepends = nfpm: deb and rpm packager
provides = ${_PKGNAME}
conflicts = ${_PKGNAME}
source_x86_64 = ${_PKGNAME}_${pkgver}_linux_x86_64.tar.gz::https://github.com/kha7iq/${_PKGNAME}/releases/download/v${pkgver}/${_PKGNAME}_linux_x86_64.tar.gz")
sha256sums_x86_64 = (${SHA256SUM_X86})
source_i686 = ${_PKGNAME}_${pkgver}_linux_i386.tar.gz::https://github.com/kha7iq/${_PKGNAME}/releases/download/v${pkgver}/${_PKGNAME}_linux_i386.tar.gz")
sha256sums_i686 = (${SHA256SUM_i686})
source_aarch64 = ${_PKGNAME}_${pkgver}_linux_arm64.tar.gz::https://github.com/kha7iq/${_PKGNAME}/releases/download/v${pkgver}/${_PKGNAME}_linux_arm64.tar.gz")
sha256sums_aarch64 = (${SHA256SUM_AARCH64})
pkgname = pingme-bin

View File

@ -1,34 +0,0 @@
# Maintainer: Abdul Khaliq <a.khaliq@outlook.my>
pkgname='pingme-bin'
_pkgname="${pkgname%-bin}"
pkgver=${PKGVER}
pkgrel=${PKGREL}
pkgdesc="PingMe is a CLI tool which provides the ability to send messages or alerts to multiple messaging platforms & email. (official binary)"
url='https://pingme.lmno.pk'
arch=("i686" "x86_64" "aarch64")
license=("MIT")
provides=("${_pkgname}")
conflicts=("${_pkgname}")
depends=()
makedepends=()
optdepends=('nfpm: deb and rpm packager')
_basedownloadurl="https://github.com/kha7iq/${_pkgname}/releases/download/v${pkgver}"
source_x86_64=("${_pkgname}_${pkgver}_linux_x86_64.tar.gz::${_basedownloadurl}/${_pkgname}_linux_x86_64.tar.gz")
sha256sums_x86_64=(${SHA256SUM_X86})
source_i686=("${_pkgname}_${pkgver}_linux_i386.tar.gz::${_basedownloadurl}/${_pkgname}_linux_i386.tar.gz")
sha256sums_i686=(${SHA256SUM_i686})
source_aarch64=("${_pkgname}_${pkgver}_linux_arm64.tar.gz::${_basedownloadurl}/${_pkgname}_linux_arm64.tar.gz")
sha256sums_aarch64=(${SHA256SUM_AARCH64})
package() {
# Bin
rm -f "${pkgdir}/usr/bin/${_pkgname}"
install -Dm755 "${srcdir}/${_pkgname}" "${pkgdir}/usr/bin/${_pkgname}"
}

View File

@ -1,64 +0,0 @@
#!/usr/bin/env bash
set -e
WD=$(cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd)
PKGNAME=$(basename $WD)
repo="kha7iq/pingme"
export _PKGNAME="${PKGNAME%-bin}"
ROOT=${WD%/.github/aur/$PKGNAME}
LOCKFILE=/tmp/aur-$PKGNAME.lock
exec 100>$LOCKFILE || exit 0
flock -n 100 || exit 0
trap "rm -f $LOCKFILE" EXIT
export PKGVER=$(curl -s https://api.github.com/repos/$repo/releases/latest | grep -o '"tag_name": "v[^"]*' | cut -d'"' -f4 | sed 's/^v//')
echo "Publishing to AUR as version ${PKGVER}"
cd $WD
export GIT_SSH_COMMAND="ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no"
if [ -z "$AUR_SSH_PRIVATE_KEY" ]
then
echo "\$AUR_SSH_PRIVATE_KEY is not set"
else
eval $(ssh-agent -s)
ssh-add <(echo "$AUR_SSH_PRIVATE_KEY")
fi
GITDIR=$(mktemp -d /tmp/aur-$PKGNAME-XXX)
trap "rm -rf $GITDIR" EXIT
git clone aur@aur.archlinux.org:$PKGNAME $GITDIR 2>&1
CURRENT_PKGVER=$(cat $GITDIR/.SRCINFO | grep pkgver | awk '{ print $3 }')
CURRENT_PKGREL=$(cat $GITDIR/.SRCINFO | grep pkgrel | awk '{ print $3 }')
if [[ "${CURRENT_PKGVER}" == "${PKGVER}" ]]; then
export PKGREL=$((CURRENT_PKGREL+1))
else
export PKGREL=1
fi
export SHA256SUM_X86=$(curl -sL https://github.com/kha7iq/${_PKGNAME}/releases/download/v${PKGVER}/${_PKGNAME}_linux_x86_64.tar.gz | sha256sum | awk '{ print $1 }')
export SHA256SUM_i686=$(curl -sL https://github.com/kha7iq/${_PKGNAME}/releases/download/v${PKGVER}/${_PKGNAME}_linux_i386.tar.gz | sha256sum | awk '{ print $1 }')
export SHA256SUM_AARCH64=$(curl -sL https://github.com/kha7iq/$_PKGNAME/releases/download/v${PKGVER}/${_PKGNAME}_linux_arm64.tar.gz | sha256sum | awk '{ print $1 }')
envsubst '$PKGVER $PKGREL $_PKGNAME $SHA256SUM_X86 $SHA256SUM_i686 $SHA256SUM_AARCH64' < .SRCINFO.template > $GITDIR/.SRCINFO
envsubst '$PKGVER $PKGREL $SHA256SUM_X86 $SHA256SUM_i686 $SHA256SUM_AARCH64' < PKGBUILD.template > $GITDIR/PKGBUILD
cd $GITDIR
git config user.name "kha7iq"
git config user.email "a.khaliq@outlook.my"
git add -A
if [ -z "$(git status --porcelain)" ]; then
echo "No changes."
else
git commit -m "Updated to version v${PKGVER} release ${PKGREL}"
git push origin master
fi

View File

@ -1,13 +0,0 @@
pkgbase = pingme
pkgdesc = PingMe is a CLI tool which provides the ability to send messages or alerts to multiple messaging platforms & email
pkgver = ${PKGVER}
pkgrel = ${PKGREL}
url = https://pingme.lmno.pk
arch = i686
arch = x86_64
arch = aarch64
license = MIT
makedepends = go
source = pingme-${pkgver}.tar.gz::https://github.com/kha7iq/${pkgname}/archive/v${pkgver}.tar.gz
pkgname = pingme

View File

@ -1,27 +0,0 @@
# Maintainer: André Kugland <kugland@gmail.com>
pkgname=pingme
pkgver=${PKGVER}
pkgrel=${PKGREL}
pkgdesc="PingMe is a CLI tool which provides the ability to send messages or alerts to multiple messaging platforms & email."
url='https://pingme.lmno.pk'
arch=("i686" "x86_64" "aarch64")
license=("MIT")
makedepends=('go>=1.16')
source=(
"${pkgname}-${pkgver}.tar.gz::https://github.com/kha7iq/${pkgname}/archive/v${pkgver}.tar.gz"
)
sha256sums=(
${SHA256SUM}
)
build() {
cd "${pkgname}-${pkgver}"
export CGO_LDFLAGS="$LDFLAGS"
go build -ldflags "-linkmode=external -s -w -X main.Version=${pkgver}" -o ${pkgname} .
}
package() {
cd "${pkgname}-${pkgver}"
install -Dm755 ${pkgname} "${pkgdir}/usr/bin/${pkgname}"
}

View File

@ -1,61 +0,0 @@
#!/usr/bin/env bash
set -e
WD=$(cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd)
PKGNAME=$(basename $WD)
ROOT=${WD%/.github/aur/$PKGNAME}
repo="kha7iq/pingme"
LOCKFILE=/tmp/aur-$PKGNAME.lock
exec 100>$LOCKFILE || exit 0
flock -n 100 || exit 0
trap "rm -f $LOCKFILE" EXIT
export PKGVER=$(curl -s https://api.github.com/repos/$repo/releases/latest | grep -o '"tag_name": "v[^"]*' | cut -d'"' -f4 | sed 's/^v//')
echo "Publishing to AUR as version ${PKGVER}"
cd $WD
export GIT_SSH_COMMAND="ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no"
if [ -z "$AUR_SSH_PRIVATE_KEY" ]
then
echo "\$AUR_SSH_PRIVATE_KEY is not set"
else
eval $(ssh-agent -s)
ssh-add <(echo "$AUR_SSH_PRIVATE_KEY")
fi
GITDIR=$(mktemp -d /tmp/aur-$PKGNAME-XXX)
trap "rm -rf $GITDIR" EXIT
git clone aur@aur.archlinux.org:$PKGNAME $GITDIR 2>&1
CURRENT_PKGVER=$(cat $GITDIR/.SRCINFO | grep pkgver | awk '{ print $3 }')
CURRENT_PKGREL=$(cat $GITDIR/.SRCINFO | grep pkgrel | awk '{ print $3 }')
if [[ "${CURRENT_PKGVER}" == "${PKGVER}" ]]; then
export PKGREL=$((CURRENT_PKGREL+1))
else
export PKGREL=1
fi
export SHA256SUM=$(curl -sL https://github.com/kha7iq/${PKGNAME}/archive/v$PKGVER.tar.gz | sha256sum | awk '{ print $1 }')
envsubst '$PKGVER $PKGREL $SHA256SUM' < .SRCINFO.template > $GITDIR/.SRCINFO
envsubst '$PKGVER $PKGREL $SHA256SUM' < PKGBUILD.template > $GITDIR/PKGBUILD
cd $GITDIR
git config user.name "kha7iq"
git config user.email "a.khaliq@outlook.my"
git add -A
if [ -z "$(git status --porcelain)" ]; then
echo "No changes."
else
git commit -m "Updated to version v${PKGVER} release ${PKGREL}"
git push origin master
fi

BIN
.github/img/logo.png vendored

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

After

Width:  |  Height:  |  Size: 32 KiB

BIN
.github/img/pingme.gif vendored

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 MiB

After

Width:  |  Height:  |  Size: 1.5 MiB

View File

@ -2,8 +2,12 @@ name: build
on:
push:
# branches:
# - 'master'
# paths-ignore:
# - '**.md'
tags:
- 'v0.[0-9]+.[0-9]'
- 'v*.*.*'
jobs:
release-pingme:
@ -11,56 +15,48 @@ jobs:
env:
DOCKER_CLI_EXPERIMENTAL: "enabled"
steps:
- name: Checkout
uses: actions/checkout@v4
-
name: Checkout
uses: actions/checkout@v2.3.4
with:
fetch-depth: 0
- name: Set up Go
uses: actions/setup-go@v4
-
name: Set up Go
uses: actions/setup-go@v2
with:
go-version: '>=1.20.0'
go-version: '1.16'
-
name: Cache Go modules
uses: actions/cache@v2.1.5
with:
path: ~/go/pkg/mod
key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
restore-keys: |
${{ runner.os }}-go-
-
name: Diff
run: git diff
- name: Docker login GHCR
-
name: Docker login GHCR
uses: docker/login-action@v1
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Docker Login DockerHub
-
name: Docker Login DockerHub
uses: docker/login-action@v1
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Release PingMe
uses: goreleaser/goreleaser-action@v3
-
name: Release PingMe
uses: goreleaser/goreleaser-action@v2
with:
version: latest
args: release --clean
args: release --rm-dist
env:
GITHUB_TOKEN: ${{ secrets.RELEASE_TOKEN }}
AUR_SSH_PRIVATE_KEY: ${{ secrets.AUR_SSH_PRIVATE_KEY }}
- name: Notify on failure
uses: kha7iq/pingme-action@v1
if: failure()
env:
TELEGRAM_TOKEN: ${{ secrets.TELEGRAM_TOKEN }}
TELEGRAM_CHANNELS: ${{ secrets.TELEGRAM_CHANNELS }}
TELEGRAM_TITLE: '🟢 New Release: ${{ github.ref }}'
TELEGRAM_MESSAGE: 'Event is triggered by ${{ github.event_name }} ❌ ${{ job.status }}'
with:
service: telegram
- name: Notify on success
uses: kha7iq/pingme-action@v1
if: success()
env:
TELEGRAM_TOKEN: ${{ secrets.TELEGRAM_TOKEN }}
TELEGRAM_CHANNELS: ${{ secrets.TELEGRAM_CHANNELS }}
TELEGRAM_TITLE: '🟢 New Release: ${{ github.ref }}'
TELEGRAM_MESSAGE: 'Event is triggered by ${{ github.event_name }} ✅ ${{ job.status }}'
with:
service: telegram

36
.github/workflows/pull_request.yml vendored Normal file
View File

@ -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

View File

@ -12,15 +12,10 @@ builds:
- darwin
- windows
goarch:
- "386"
- 386
- amd64
- arm
- arm64
goarm:
- "7"
ignore:
- goos: windows
goarch: arm64
mod_timestamp: '{{ .CommitTimestamp }}'
flags:
- -trimpath
@ -35,21 +30,19 @@ changelog:
exclude: ['^docs:', '^test:', 'Merge pull request', 'Merge branch', 'go mod tidy']
archives:
- name_template: >-
{{ .ProjectName }}_
{{- title .Os }}_
{{- if eq .Arch "amd64" }}x86_64
{{- else if eq .Arch "386" }}i386
{{- else }}{{ .Arch }}{{ end }}
- name_template: '{{ .ProjectName }}_{{ .Os }}_{{ .Arch }}{{ if .Arm }}v{{ .Arm }}{{ end }}'
replacements:
darwin: Darwin
linux: Linux
windows: Windows
386: i386
amd64: x86_64
format_overrides:
- goos: windows
format: zip
files:
- README.md
- LICENSE.md
brews:
- repository:
- tap:
owner: kha7iq
name: homebrew-tap
folder: Formula
@ -63,7 +56,6 @@ brews:
nfpms:
- file_name_template: '{{ .ProjectName }}_{{ .Arch }}{{ if .Arm }}v{{ .Arm }}{{ end }}'
maintainer: 'Abdul Khaliq <a.khaliq@outlook.my>'
homepage: pingme.lmno.pk
description: PingMe is a CLI tool which provides the ability to send messages or alerts to multiple messaging platforms.
license: MIT
@ -73,11 +65,21 @@ nfpms:
dependencies:
- git
scoops:
- repository:
# # snapcrafts:
# # - name_template: '{{ .ProjectName }}_{{ .Arch }}{{ if .Arm }}v{{ .Arm }}{{ end }}'
# # summary: PingMe is a CLI tool which provides the ability to send messages
# # description: |
# # PingMe is a CLI tool which provides the ability to send messages
# # or alerts to multiple messaging platforms.
# # grade: stable
# # confinement: classic
# # publish: false
scoop:
url_template: "https://github.com/kha7iq/pingme/releases/download/{{ .Tag }}/{{ .ArtifactName }}"
bucket:
owner: kha7iq
name: scoop-bucket
url_template: "https://github.com/kha7iq/pingme/releases/download/{{ .Tag }}/{{ .ArtifactName }}"
homepage: https://pingme.lmno.pk
description: PingMe is a CLI tool which provides the ability to send messages or alerts to multiple messaging platforms.
license: MIT

View File

@ -67,10 +67,10 @@ members of the project's leadership.
## Attribution
This Code of Conduct is adapted from the [Contributor Covenant][homepage],
version 1.4, available at <https://www.contributor-covenant.org/version/1/4/code-of-conduct.html>
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html
[homepage]: https://www.contributor-covenant.org
For answers to common questions about this code of conduct, see
<https://www.contributor-covenant.org/faq>
https://www.contributor-covenant.org/faq

View File

@ -1,5 +1,4 @@
# Contributing to PingMe
## Contributing to PingMe
We want to make contributing to this project as easy and transparent as
possible.
@ -14,30 +13,26 @@ possible.
- `service/telegram` - Telegram notification service.
- `service/pushover` - Pushover Notification service.
### Documentation
- `docs` - Contains the documentation in Markdown format.
- 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
- Checking Locally
- Docsify is used for documentation rendering from markdown, you can download
the cli and test locally before opening a pull request.
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
```
### Install
```bash
npm i docsify-cli -g
# yarn global add docsify-cli
```
### Serve locally
```bash
docsify serve docs
```
## Commits
@ -48,8 +43,7 @@ are using Conventional Commits.
<type>[<scope>]: <short summary>
│ │ │
│ │ └─> Summary in present tense. Not capitalized. No
| | period at the end.
│ │ └─> Summary in present tense. Not capitalized. No period at the end.
│ │
│ └─> Scope (optional): eg. common, compiler, authentication, core
@ -61,21 +55,19 @@ 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. Make sure your code lints (`make lint`).
5. Make sure your code is well formatted (`make fmt`).
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.

View File

@ -1,6 +1,6 @@
MIT License
Copyright (c) 2021 Abdul Khaliq <a.khaliq@outlook.my>
Copyright (c) 2021 Khaliq
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
@ -19,4 +19,3 @@ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

137
README.md
View File

@ -1,5 +1,3 @@
<!-- markdownlint-disable MD033 -->
<!-- markdownlint-disable-next-line -->
<h2 align="center">
<br>
<p align="center"><img width=30% src="https://raw.githubusercontent.com/kha7iq/pingme/master/.github/img/logo.png"></p>
@ -12,12 +10,15 @@
<img alt="Release" src="https://img.shields.io/github/v/release/kha7iq/pingme">
<a href="https://goreportcard.com/report/github.com/kha7iq/pingme">
<img alt="Go Report Card" src="https://goreportcard.com/badge/github.com/kha7iq/pingme">
<a href="#">
<img alt="Build" src="https://img.shields.io/github/workflow/status/kha7iq/pingme/goreleaser">
<a href="https://github.com/kha7iq/pingme/issues">
<img alt="GitHub issues" src="https://img.shields.io/github/issues/kha7iq/pingme?style=flat-square&logo=github&logoColor=white">
<a href="https://github.com/kha7iq/pingme/blob/master/LICENSE.md">
<img alt="License" src="https://img.shields.io/github/license/kha7iq/pingme">
<a href="https://github.com/agarrharr/awesome-cli-apps#devops">
<img alt="Awesome" src="https://cdn.rawgit.com/sindresorhus/awesome/d7305f38d29fed78fa85652e3a63e154dd8e8829/media/badge.svg">
<a href="#">
<img alt="Go Version" src="https://img.shields.io/github/go-mod/go-version/kha7iq/pingme">
<a href="https://pkg.go.dev/github.com/kha7iq/pingme">
<img alt="Go Dev Reference" src="https://img.shields.io/badge/go.dev-reference-007d9c?logo=go&logoColor=white&style=flat">
</p>
@ -29,135 +30,89 @@
<a href="#github-action">Github Action</a>
<a href="#configuration">Configuration</a>
<a href="#contributing">Contributing</a>
<a href="#show-your-support">Show Your Support</a>
</p>
---
## 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 utility 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.
**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
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.
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.
## Supported services
- *Discord*
- *Email*
- *Gotify*
- *Line*
- *Mastodon*
- *Mattermost*
- *Microsoft Teams*
- *Pushbullet*
- *Mattermost*
- *Pushover*
- *Pushbullet*
- *RocketChat*
- *Slack*
- *Telegram*
- *Textmagic*
- *Twillio*
- *Zulip*
- *Wechat*
## Install
### MacOS & Linux Homebrew
```bash
brew install kha7iq/tap/pingme
```
## Shell Script
By default pingme is going to be installed at `/usr/bin/` sudo is requried for this operation.
If you would like to provide a custom install path you can do so as input to script. i.e `./install.sh $HOME/bin`
## Linux Binary
```bash
curl -s https://raw.githubusercontent.com/kha7iq/pingme/master/install.sh | sudo sh
```
or
```bash
curl -sL https://bit.ly/installpm | sudo sh
```
## Linux
* AUR
```bash
# build from sources
yay -S pingme
# binary
yay -S pingme-bin
```
## Manual
```bash
# Chose desired version, architecture & target os
export PINGME_VERSION="0.2.6"
export ARCH="x86_64"
export OS="Linux"
wget -q https://github.com/kha7iq/pingme/releases/download/v${PINGME_VERSION}/pingme_${OS}_${ARCH}.tar.gz && \
tar -xf pingme_${OS}_${ARCH}.tar.gz && \
chmod +x pingme && \
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
```
### Windows
```powershell
scoop bucket add pingme https://github.com/kha7iq/scoop-bucket.git
scoop install pingme
```
Alternatively you can head over to [release pages](https://github.com/kha7iq/pingme/releases)
and download `deb`, `rpm` or `binary` for windows & all other supported platforms.
Alternatively you can head over to [release pages](https://github.com/kha7iq/pingme/releases) and download the binary for windows & all other supported platforms.
### Docker
Docker container is also available on both dockerhub and github container registry.
`latest` tag will always pull the latest version available, or you can also download
specific version. Checkout [release](https://github.com/kha7iq/pingme/releases)
page for available versions.
`latest` tage will always pull the latest version avaialbe, you can also download specific version.
Checkout [release](https://github.com/kha7iq/pingme/releases) page for available versions.
Docker Registry
```bash
docker pull khaliq/pingme:latest
```
Github Registry
```bash
docker pull ghcr.io/kha7iq/pingme:latest
```
Run
```bash
docker run ghcr.io/kha7iq/pingme:latest
```
## Github Action
A github action is available for integration with your workflows, you can find it on
[Github Market Place](https://github.com/marketplace/actions/pingme-action) or
here [Github Repo](https://github.com/kha7iq/pingme-action).
```yaml
- name: PingMe-Action
uses: kha7iq/pingme-action@v1
```
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.
## Usage
@ -174,8 +129,7 @@ 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, Pushbullet, Microsoft Teams, Twillio, Mastodon,
email address, Line, Gotify and Wechat.
RocketChat, Discord, Pushover, Mattermost, Microsoft Teams and email address.
COMMANDS:
telegram Send message to telegram
@ -187,12 +141,6 @@ COMMANDS:
email Send an email
mattermost Send message to mattermost
pushbullet Send message to pushbullet
twillio Send sms via twillio
zulip Send message to zulip
mastodon Set status message for mastodon
line Send message to line messenger
wechat Send message to wechat official account
gotify Send push notification to gotify server
help, h Shows a list of commands or help for one command
GLOBAL OPTIONS:
@ -203,18 +151,17 @@ Check [Documentation Page](https://kha7iq.github.io/pingme/#/) for more details.
## Configuration
All the flags have corresponding environment variables associated with it. You
can either provide the value with flags or export to a variable.
All the flags have corresponding environment variables associated with it. You can either provide the value with flags
or export to a variable.
View the [Documentation Page](https://kha7iq.github.io/pingme/#/) for more details.
View the [Documentation Page](https://kha7iq.github.io/pingme/#/) for more
details.
## Contributing
Contributions, issues and feature requests are welcome!<br/>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!<br/>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).
## Acknowledgments
This project is based on amazing library [Notify](https://github.com/nikoksr/notify)
## Show your support
Give a ⭐️ if you like this project!

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 20 KiB

View File

@ -1,5 +1,4 @@
<!-- docs/_sidebar.md -->
<!-- markdownlint-disable MD041 -->
* [Home](/)
* [Installation](install.md)

View File

@ -1,5 +1,4 @@
# Contributing to PingMe
## Contributing to PingMe
We want to make contributing to this project as easy and transparent as
possible.
@ -13,33 +12,27 @@ possible.
- `service/slack` - Slack notification service.
- `service/telegram` - Telegram notification service.
- `service/pushover` - Pushover Notification service.
- `service/line` - Line notification service.
- `service/wechat` - Wechat Official Account notification service.
### Documentation
- `docs` - Contains the documentation in Markdown format.
- 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
- Checking Locally
- Docsify is used for documentation rendering from markdown, you can download
the cli and test locally before opening a pull request.
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
```
### Install
```bash
npm i docsify-cli -g
# yarn global add docsify-cli
```
### Serve locally
```bash
docsify serve docs
```
## Commits
@ -50,8 +43,7 @@ are using Conventional Commits.
<type>[<scope>]: <short summary>
│ │ │
│ │ └─> Summary in present tense. Not capitalized. No
| | period at the end.
│ │ └─> Summary in present tense. Not capitalized. No period at the end.
│ │
│ └─> Scope (optional): eg. common, compiler, authentication, core
@ -63,7 +55,6 @@ 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`.
@ -74,11 +65,9 @@ We actively welcome your pull requests.
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.

View File

@ -1,5 +1,3 @@
<!-- markdownlint-disable MD033 -->
<!-- markdownlint-disable-next-line -->
<h2 align="center">
<br>
<p align="center"><img width=20% src="https://raw.githubusercontent.com/kha7iq/pingme/master/.github/img/logo.png"></p>
@ -34,58 +32,48 @@
## About
**PingMe** is a personal project to satisfy my needs of having alerts, most
major platforms have integration to send alerts 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.
**PingMe** is a personal project to satisfy my needs of having alerts, most major platforms have integration to send alerts
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.
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.
## Supported services
- *Discord*
- *Email*
- *Gotify*
- *Line*
- *Mastodon*
- *Mattermost*
- *Matrix*
- *Microsoft Teams*
- *Pushbullet*
- *Mattermost*
- *Pushover*
- *Pushbullet*
- *RocketChat*
- *Slack*
- *Telegram*
- *Textmagic*
- *Twillio*
- *Zulip*
- *Wechat*
## Demo
![Demo](https://raw.githubusercontent.com/kha7iq/pingme/master/.github/img/pingme.gif)
## Contributing
Contributions, issues and feature requests are welcome!
Contributions, issues and feature requests are welcome!<br />Feel free to check [issues page](https://github.com/kha7iq/pingme/issues). You can also take a look at the [contribution guide](contribution.md).
Feel free to check [issues page](https://github.com/kha7iq/pingme/issues).
You can also take a look at the [contribution guide](contribution.md).
## Show your support
Give a ⭐️ if you like this project!
## Disclaimer
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.
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.
Spamming through the use of this library **may get you permanently banned** on most supported platforms.

View File

@ -6,6 +6,7 @@
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
<meta name="description" content="Description">
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0">
<link rel="stylesheet" href="//cdn.jsdelivr.net/npm/docsify@4/lib/themes/vue.css">
<link
rel="stylesheet"
href="//cdn.jsdelivr.net/npm/docsify-darklight-theme@latest/dist/style.min.css"
@ -18,31 +19,11 @@
<script>
window.$docsify = {
homepage: 'home.md',
siteFont : 'Source Sans Pro',
defaultTheme : 'light | dark',
codeFontFamily : 'monospace',
logo: '/_media/logo.png',
loadSidebar: true,
subMaxLevel: 2,
name: 'PingMe',
repo: 'https://github.com/kha7iq/pingme',
darklightTheme: {
siteFont : 'PT Sans',
defaultTheme : 'dark | light',
codeFontFamily : 'Roboto Mono, Monaco, courier, monospace',
bodyFontSize : '16px',
dark: {
accent: '#ffa500',
background: '#282C34',
codeTextColor : '#b4b4b4',
codeBackgroundColor : '#353A44',
coverBackground : '#161B22'
},
light: {
accent: '#008080',
coverBackground : '#f0f0f0'
}
}
repo: 'https://github.com/kha7iq/pingme'
}
</script>
<!-- Docsify v4 -->
@ -51,7 +32,5 @@
src="//cdn.jsdelivr.net/npm/docsify-darklight-theme@latest/dist/index.min.js"
type="text/javascript">
</script>
<script src="//unpkg.com/prismjs/components/prism-bash.min.js"></script>
<script src="//unpkg.com/prismjs/components/prism-yaml.min.js "></script>
</body>
</html>

View File

@ -1,82 +1,53 @@
# Installation
## MacOS & Linux Homebrew
```bash
brew install kha7iq/tap/pingme
```
## Shell Script
By default pingme is going to be installed at `/usr/bin/` sudo is requried for this operation.
If you would like to provide a custom install path you can do so as input to script. i.e `./install.sh $HOME/bin`
## Linux Binary
```bash
curl -s https://raw.githubusercontent.com/kha7iq/pingme/master/install.sh | sudo sh
```
or
```bash
curl -sL https://bit.ly/installpm | sudo sh
```
## Linux
* AUR
```bash
yay -S pingme-bin
```
## Manual
```bash
# Chose desired version, architecture & target os
export PINGME_VERSION="0.2.4"
export ARCH="x86_64"
export OS="Linux"
wget -q https://github.com/kha7iq/pingme/releases/download/v${PINGME_VERSION}/pingme_${OS}_${ARCH}.tar.gz && \
tar -xf pingme_${OS}_${ARCH}.tar.gz && \
chmod +x pingme && \
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
```
## Windows
## Go Get
```bash
go get -u github.com/kha7iq/pingme
```
## Windows
```powershell
scoop bucket add pingme https://github.com/kha7iq/scoop-bucket.git
scoop install pingme
```
Alternatively you can head over to [release pages](https://github.com/kha7iq/pingme/releases)
and download the binary for windows & all other supported platforms.
Alternatively you can head over to [release pages](https://github.com/kha7iq/pingme/releases) and download the binary for windows & all other supported platforms.
## Docker
Docker container is also available on both dockerhub and github container registry.
`latest` tage will always pull the latest version avaialbe, you can also
download specific version. Checkout [release](https://github.com/kha7iq/pingme/releases)
page for available versions.
`latest` tage will always pull the latest version avaialbe, you can also download specific version.
Checkout [release](https://github.com/kha7iq/pingme/releases) page for available versions.
- Docker Registry
```bash
docker pull khaliq/pingme:latest
```
- GitHub Registry
```bash
docker pull ghcr.io/kha7iq/pingme:latest
```
- Run
```bash
docker run ghcr.io/kha7iq/pingme:latest
```
## 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.
## 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.

View File

@ -1,23 +1,22 @@
# Configuration
All the flags have corresponding environment variables associated with them. You
can either provide the value with flags or export to a variable. You can view
the corresponding variable with `--help` flag.
*Flags* take precedence over *variables*
### Configuration
All the flags have crosponding enviornment variables assosiated with it. You can either provide the value with flags
or export to a variable. You can view the crosponding variable to each with --help flag.
*Flags* take presedance over *variables*
*Default* value for message title is current *time*
## Telegram
## Telegram
Telegram uses bot token to authenticate & send messages to defined channels.
Multiple channel IDs can be used separated by comma ','.
Multiple channel ids can be used separated by comma ','.
```bash
pingme telegram \
--token "0125:AAFHvnYf_ABC" \
--msg "This is a new message ✈" \
--channel="-1001001001,-1002002001"
pingme telegram --token "0125:AAFHvnYf_ABC" --msg "This is a new message ✈" --channel="-1001001001,-1002002001"
```
- GitHub Action
@ -46,79 +45,25 @@ jobs:
# slack / telegram / rocketchat / teams / pushover / discord / email
service: telegram
```
- **Variables**
| Variables | Default Value |
| Variables | Default Value |
| -------------------------- | :----------------: |
| TELEGRAM_TITLE | "" |
| TELEGRAM_TOKEN | "" |
| TELEGRAM_CHANNELS | "" |
| TELEGRAM_MESSAGE | "" |
| TELEGRAM_MSG_TITLE | "" |
| TELEGRAM_TOKEN | "" |
| TELEGRAM_CHANNELS | "" |
| TELEGRAM_MESSAGE | "" |
| TELEGRAM_MSG_TITLE | "" |
## Gotify
With gotify you can send push messages to any instance of Gotify server.
```bash
pingme gotify \
--url 'https://example.com' \
--token 'tokenabc' \
--title 'some title' \
--msg 'some message' \
--priority 5
```
- 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:
GOTIFY_TOKEN: ${{ secrets.GOTIFY_TOKEN }}
GOTIFY_URL: "example.com"
GOTIFY_TITLE: 'Reference: ${{ github.ref }}'
GOTIFY_MESSAGE: 'Event is triggered by ${{ github.event_name }}'
with:
# Chose the messaging platform.
# slack / telegram / rocketchat / teams / pushover / discord / email
service: gotify
```
- **Variables**
| Variables | Default Value |
| -------------------------- | :----------------: |
| GOTIFY_URL | "" |
| GOTIFY_TOKEN | "" |
| GOTIFY_PRIORITY | "5" |
| GOTIFY_MESSAGE | "" |
| GOTIFY_TITLE | "Server Time" |
## RocketChat
RocketChat uses token & userID to authenticate and send messages to defined
channels. Multiple channel IDs can be used separated by comma ','.
RocketChat uses token & userID to authenticate and send messages to defined channels.
Multiple channel ids can be used separated by comma ','.
```bash
pingme rocketchat \
--channel "general,Pingme" \
--msg ":wave: rocketchat from cli" \
--userid "123" \
--token "abcxyz" \
--url 'localhost:3000' \
--scheme "http"
pingme rocketchat --channel "general,Pingme" --msg ":wave: rocketchat from cli" --userid "123" --token "abcxyz" \
--url 'localhost:3000' --scheme "http"
```
- Github Action
@ -147,31 +92,26 @@ jobs:
ROCKETCHAT_MESSAGE: 'Event is triggered by ${{ github.event_name }}'
with:
# Chose the messaging platform.
# slack / telegram / rocketchat / teams /
# pushover / discord / email / mattermost
# slack / telegram / rocketchat / teams / pushover / discord / email / mattermost
service: rocketchat
```
- **Variables**
| Variables | Default Value |
| Variables | Default Value |
| -------------------------- | :----------------: |
| ROCKETCHAT_USERID | "" |
| ROCKETCHAT_TOKEN | "" |
| ROCKETCHAT_SERVER_URL | "" |
| ROCKETCHAT_URL_SCHEME | "https" |
| RTOCKETCHAT_MESSAGE | "" |
| ROCKETCHAT_TITLE | "" |
| ROCKETCHAT_CHANNELS | "" |
| ROCKETCHAT_USERID | "" |
| ROCKETCHAT_TOKEN | "" |
| ROCKETCHAT_SERVER_URL | "" |
| ROCKETCHAT_URL_SCHEME | "https" |
| RTOCKETCHAT_MESSAGE | "" |
| ROCKETCHAT_TITLE | "" |
| ROCKETCHAT_CHANNELS | "" |
## Pushover
```bash
pingme pushover \
--token '123' \
--user '12345567' \
--title 'some title' \
--msg 'some message'
pingme pushover --token '123' --user '12345567' --title 'some title' --msg 'some message'
```
- GitHub Action
@ -197,35 +137,28 @@ jobs:
with:
# Chose the messaging platform.
# slack / telegram / rocketchat / teams /
# pushover / discord / email
# slack / telegram / rocketchat / teams / pushover / discord / email
service: pushover
```
- **Variables**
| Variables | Default Value |
| Variables | Default Value |
| -------------------------- | :----------------: |
| PUSHOVER_TOKEN | "" |
| PUSHOVER_USER | "" |
| PUSHOVER_MESSAGE | "" |
| PUSHOVER_TITLE | "" |
| PUSHOVER_TOKEN | "" |
| PUSHOVER_USER | "" |
| PUSHOVER_MESSAGE | "" |
| PUSHOVER_TITLE | "" |
## Mattermost
Mattermost uses token to authenticate and channel IDs for targets. Destination
server can be specified as 'example.com' by default the 'https' is used, you
can change this with --scheme flag and set it to 'http'. Latest api version 4
is used for interacting with server, this can also be changed with --api flag.
Mattermost uses token to authenticate and channel ids for targets.
Destination server can be specified as 'example.com' by default the 'https' is used, you
can change this with --scheme flag and set it to 'http'.
Latest api version 4 is used for interacting with server, this can also be changes with --api flag.
You can specify multiple channels by separating the value with ','.
```bash
pingme mattermost \
--token '123' \
--channel '12345,567' \
--url 'localhost' \
--scheme 'http' \
--msg 'some message'
pingme mattermost --token '123' --channel '12345,567' --url 'localhost' --scheme 'http' --msg 'some message'
```
- GitHub Action
@ -248,37 +181,33 @@ jobs:
MATTERMOST_TOKEN: ${{ secrets.MATTERMOST_TOKEN }}
MATTERMOST_SERVER_URL: ${{ secrets.MATTERMOST_SERVER_URL }}
MATTERMOST_CHANNELS: ${{ secrets.MATTERMOST_CHANNELS }}
MATTERMOST_CHANNELS: ${{ secrets.MATTERMOST_CHANNELS }}
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
# slack / telegram / rocketchat / teams / pushover / discord / email / mattermost
service: mattermost
```
- **Variables**
| Variables | Default Value |
| Variables | Default Value |
| -------------------------- | :----------------: |
| MATTERMOST_API_URL | "/api/v4/posts" |
| MATTERMOST_TOKEN | "" |
| MATTERMOST_SERVER_URL | "" |
| MATTERMOST_SCHEME | "https" |
| MATTERMOST_MESSAGE | "" |
| MATTERMOST_TITLE | "" |
| MATTERMOST_CHANNELS | "" |
| MATTERMOST_API_URL | "/api/v4/posts" |
| MATTERMOST_TOKEN | "" |
| MATTERMOST_SERVER_URL | "" |
| MATTERMOST_SCHEME | "https" |
| MATTERMOST_MESSAGE | "" |
| MATTERMOST_TITLE | "" |
| MATTERMOST_CHANNELS | "" |
## Slack
Slack uses token to authenticate and send messages to defined channels.
Multiple channel IDs can be used separated by comma ','.
Multiple channel ids can be used separated by comma ','.
```bash
pingme slack \
--token '123' \
--channel '1234567890' \
--msg 'some message'
pingme slack --token '123' --channel '1234567890' --msg 'some message'
```
- Github Action
@ -304,29 +233,25 @@ jobs:
SLACK_MESSAGE: 'Event is triggered by ${{ github.event_name }}'
with:
# Chose the messaging platform.
# slack / telegram / rocketchat / teams /
# pushover / discord / email
# slack / telegram / rocketchat / teams / pushover / discord / email
service: slack
```
- **Variables**
| Variables | Default Value |
| Variables | Default Value |
| -------------------------- | :----------------: |
| SLACK_TOKEN | "" |
| SLACK_CHANNELS | "" |
| SLACK_MESSAGE | "" |
| SLACK_TOKEN | "" |
| SLACK_CHANNELS | "" |
| SLACK_MESSAGE | "" |
## Discord
Discord uses bot token to authenticate & send messages to defined channels.
Multiple channel IDs can be used separated by comma ','.
Multiple channel ids can be used separated by comma ','.
```bash
pingme discord \
--token '123' \
--channel '1234567890' \
--msg 'some message'
pingme discord --token '123' --channel '1234567890' --msg 'some message'
```
- GitHub Action
@ -352,29 +277,25 @@ jobs:
DISCORD_MESSAGE: 'Event is triggered by ${{ github.event_name }}'
with:
# Chose the messaging platform.
# slack / telegram / rocketchat / teams /
# pushover / discord / email / mattermost
# slack / telegram / rocketchat / teams / pushover / discord / email / mattermost
service: discord
```
- **Variables**
| Variables | Default Value |
| Variables | Default Value |
| -------------------------- | :----------------: |
| DISCORD_TOKEN | "" |
| DISCORD_CHANNELS | "" |
| DISCORD_MESSAGE | "" |
| DISCORD_MSG_TITLE | "" |
| DISCORD_TOKEN | "" |
| DISCORD_CHANNELS | "" |
| DISCORD_MESSAGE | "" |
| DISCORD_MSG_TITLE | "" |
## Microsoft Teams
Teams uses webhooks to send messages, you can add multiple webhooks separated
by comma ',' or you can add permissions for multiple channels to single webhook.
Teams uses webhooks to send messages, you can add multiple webhooks separated by comma ',' or
you can add permissions for multiple channels to single webhook.
```bash
pingme teams \
--webhook 'https://example.webhook.office.com/xx' \
--msg 'some message'
pingme teams --webhook 'https://example.webhook.office.com/xx' --msg 'some message'
```
- GitHub Action
@ -399,36 +320,27 @@ jobs:
with:
# Chose the messaging platform.
# slack / telegram / rocketchat / teams /
# pushover / discord / email / mattermost
# slack / telegram / rocketchat / teams / pushover / discord / email / mattermost
service: teams
```
- **Variables**
| Variables | Default Value |
| Variables | Default Value |
| -------------------------- | :----------------: |
| TEAMS_WEBHOOK | "" |
| TEAMS_MESSAGE | "" |
| TEAMS_MSG_TITLE | "" |
| TEAMS_WEBHOOK | "" |
| TEAMS_MESSAGE | "" |
| TEAMS_MSG_TITLE | "" |
## Pushbullet
- SMS
```bash
pingme pushbullet \
--sms true \
--token "abcdefg" \
-d "android" \
--msg "some message" \
--number "00123456789"
pingme pushbullet --sms true --token "abcdefg" -d "adnroid" --msg "some message" --number "00123456789"
```
- Push notification
```bash
pingme pushbullet --token "abcdefg" -d "android" --msg "some message"
pingme pushbullet --token "abcdefg" -d "adnroid" --msg "some message"
```
- GitHub Action
@ -454,34 +366,28 @@ jobs:
with:
# Chose the messaging platform.
# slack / telegram / rocketchat / teams /
# pushover / discord / email
# slack / telegram / rocketchat / teams / pushover / discord / email
service: pushbullet
```
- **Variables**
| Variables | Default Value |
| Variables | Default Value |
| -------------------------- | :----------------: |
| PUSHBULLET_TOKEN | "" |
| PUSHBULLET_DEVICE | "" |
| PUSHBULLET_NUMBER | "" |
| PUSHBULLET_MESSAGE | "" |
| PUSHBULLET_SMS | "false" |
| PUSHBULLET_TITLE | "" |
| 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.
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'
pingme twillio --token 'tokenabc' --account 'sid123' --sender '+140001442' --receiver '+140001442'' --msg 'some message'
```
- GitHub Action
@ -508,370 +414,40 @@ jobs:
TWILLIO_MESSAGE: 'Event is triggered by ${{ github.event_name }}'
with:
# Chose the messaging platform.
# slack / telegram / rocketchat / teams /
# pushover / discord / email / mattermost / twillio
# slack / telegram / rocketchat / teams / pushover / discord / email / mattermost / twillio
service: twillio
```
- **Variables**
| Variables | Default Value |
| Variables | Default Value |
| -------------------------- | :----------------: |
| TWILLIO_TOKEN | "" |
| TWILLIO_ACCOUNT_SID | "" |
| TWILLIO_SENDER | "" |
| TWILLIO_RECEIVER | "" |
| TWILLIO_TITLE | "" |
| TWILLIO_MESSAGE | "" |
## Mastodon
Mastodon uses application token to authorize and set status.
```bash
mastodon --url "mastodon.social" --msg "some message" --title "PingMe CLI" --token "123"
```
- 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:
MASTODON_TOKEN: ${{ secrets.MASTODON_TOKEN }}
MASTODON_SERVER: 'mastodon.social'
MASTODON_TITLE: 'Reference: ${{ github.ref }}'
MASTODON_MESSAGE: 'Event is triggered by ${{ github.event_name }}'
with:
service: mastodon
```
- **Variables**
| Variables | Default Value |
| -------------------------- | :----------------: |
| MASTODON_TOKEN | "" |
| MASTODON_SERVER | "" |
| MASTODON_TITLE | "" |
| MASTODON_MESSAGE | "" |
## Zulip
Zulip uses bot email and token for authentication, and sends messages to particular topic.
```bash
pingme zulip
--email 'john.doe@email.com' \
--api-key '12345567' \
--to 'london' \
--type 'stream' \
--topic 'some topic' \
--msg 'content of 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:
ZULIP_DOMAIN: ${{ secrets.ZULIP_DOMAIN }}
ZULIP_BOT_EMAIL_ADDRESS: ${{ secrets.ZULIP_BOT_EMAIL_ADDRESS }}
ZULIP_BOT_API_KEY: ${{ secrets.ZULIP_BOT_API_KEY }}
ZULIP_MSG_TYPE: 'stream'
ZULIP_STREAM_NAME: 'general'
ZULIP_TOPIC: 'Reference: ${{ github.ref }}'
ZULIP_MESSAGE: 'Event is triggered by ${{ github.event_name }}'
with:
service: zulip
```
- **Variables**
| Variables | Default Value |
| -------------------------- | :----------------: |
| ZULIP_DOMAIN | "" |
| ZULIP_BOT_EMAIL_ADDRESS | "" |
| ZULIP_BOT_API_KEY | "" |
| ZULIP_MSG_TYPE | "" |
| ZULIP_STREAM_NAME | "" |
| ZULIP_TOPIC | "" |
| ZULIP_MESSAGE | "" |
## Line
Line uses channel secret and token for authentication, and sends messages.
```bash
pingme line
--secret 'secretxxx' \
--token '12345567' \
--receivers 'ab1234545xx' \
--msg 'content of 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:
LINE_SECRET: ${{ secrets.LINE_SECRET }}
LINE_TOKEN: ${{ secrets.LINE_TOKEN }}
LINE_RECEIVER_IDS: 'ab1235xxx8'
LINE_MSG_TITLE: 'Reference: ${{ github.ref }}'
LINE_MESSAGE: 'Event is triggered by ${{ github.event_name }}'
with:
service: line
```
- **Variables**
| Variables | Default Value |
| -------------------------- | :----------------: |
| LINE_SECRET | "" |
| LINE_TOKEN | "" |
| LINE_RECEIVER_IDS | "" |
| LINE_MSG_TITLE | "" |
| LINE_MESSAGE | "" |
| TWILLIO_TOKEN | "" |
| TWILLIO_ACCOUNT_SID | "" |
| TWILLIO_SENDER | "" |
| TWILLIO_RECEIVER | "" |
| TWILLIO_TITLE | "" |
| TWILLIO_MESSAGE | "" |
## Email
Email uses username & password to authenticate for sending emails. SMTP
hostname i.e smtp.gmail.com and port i.e (587) should be provided as well for
the server. Multiple email IDs can be used separated by comma ',' as receiver
email address. All configuration options are also available via environment
variables. Check configuration section.
Email uses username & password to authenticate for sending emails.
SMTP hostname i.e smtp.gmail.com and port i.e (587) should be provided as well for the server.
Multiple email ids can be used separated by comma ',' as receiver email address.
All configuration options are also available via environment variables check configuration section.
```bash
pingme email \
--rec "example@gmail.com,example@outlook.com" \
--msg "This is an email from PingMe CLI" \
--sub "Email from PingMe CLI" \
--sender "sender@gmail.com" \
--host "smtp.gmail.com" \
--port "587" \
--pass "secretPassword"
```
pingme email --rec "example@gmail.com,example@outlook.com" --msg "This is an email from PingMe CLI" --sub "Email from PingMe CLI" \
--sender "sender@gmail.com" --host "smtp.gmail.com" --port "587" --pass "secretPassword"
```
- **Variables**
| Variables | Default Value |
| Variables | Default Value |
| -------------------------- | :----------------: |
| EMAIL_SENDER | "" |
| EMAIL_PASSWORD | "" |
| EMAIL_RECEIVER | "" |
| EMAIL_IDENTITY | "" |
| EMAIL_HOST | "smtp.gmail.com" |
| EMAIL_PORT | "587" |
| EMAIL_MESSAGE | "" |
| EMAIL_SUBJECT | "" |
## Wechat Official Account
Wechat uses appid, appsecret, chatbot server token and encoding AES key for authentication, and sends messages.
```bash
pingme wechat
--appid "xxxxxxxx" \
--appsecret 'xxxxxxxxxx' \
--token 'xxxxxxxxxx' \
--aes 'IGNORED-IN-SANDBOX' \
--msg 'content of message' \
--receivers 'some receivers'
```
- 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:
WECHAT_APPID: ${{ secrets.WECHAT_APPID }}
WECHAT_APPSECRET: ${{ secrets.WECHAT_APPSECRET }}
WECHAT_TOKEN: ${{ secrets.WECHAT_TOKEN }}
WECHAT_ENCODINGAESKEY: ${{ secrets.WECHAT_ENCODINGAESKEY }}
WECHAT_RECEIVER_IDS: ${{ secrets.WECHAT_RECEIVER_IDS }}
WECHAT_MSG_TITLE: 'Reference: ${{ github.ref }}'
WECHAT_MESSAGE: 'Event is triggered by ${{ github.event_name }}'
with:
service: wechat
```
- **Variables**
| Variables | Default Value |
| -------------------------- | :----------------: |
| WECHAT_APPID | "" |
| WECHAT_APPSECRET | "" |
| WECHAT_TOKEN | "" |
| WECHAT_ENCODINGAESKEY | "" |
| WECHAT_RECEIVER_IDS | "" |
| WECHAT_MSG_TITLE | "" |
| WECHAT_MESSAGE | "" |
## TextMagic
TextMagic allows you to send SMS to multiple receivers provided by comma separated string.
```bash
pingme textmagic \
--token 'tokenabc' \
--user 'sid123' \
--title 'message title' \
--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:
TEXTMAGIC_USER: ${{ secrets.TEXTMAGIC_USER }}
TEXTMAGIC_TOKEN: ${{ secrets.TEXTMAGIC_TOKEN }}
TEXTMAGIC_TITLE: 'Reference: ${{ github.ref }}'
TEXTMAGIC_MESSAGE: 'Event is triggered by ${{ github.event_name }}'
TEXTMAGIC_RECEIVER: ${{ secrets.TEXTMAGIC_RECEIVER }}
with:
# Chose the messaging platform.
# slack / telegram / rocketchat / teams /
# pushover / discord / email / mattermost / textmagic
service: textmagic
```
- **Variables**
| Variables | Default Value |
| -------------------------- | :----------------: |
| TEXTMAGIC_USER | "" |
| TEXTMAGIC_TOKEN | "" |
| TEXTMAGIC_TITLE | "" |
| TEXTMAGIC_MESSAGE | "" |
| TEXTMAGIC_RECEIVER | "" |
## Matrix
Matrix uses either username and password, or an access token for authentication. Tokens will be used first, if not
present, username and password will be used. Similarly for --room, if not present, room will be determined using roomId
and domain.
```bash
pingme matrix \
--username 'matrix username' \
--password 'password' \
--token 'access token' \
--url 'https://matrix-client.matrix.org' \
--serverName 'server1.matrix.org' \
--room 'LRovrjPJaRChcTKgoK:matrix.org' \
--roomId 'LRovrjPJaRChcTKgoK' \
--domain 'matrix.org' \
--msg 'some message' \
--autoJoin
```
- 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:
MATRIX_USERNAME: ${{ secrets.MATRIX_USERNAME }}
MATRIX_PASSWORD: ${{ secrets.MATRIX_PASSWORD }}
MATRIX_ACCESS_TOKEN: ${{ secrets.MATRIX_ACCESS_TOKEN }}
MATRIX_SERVER_URL: ${{ secrets.MATRIX_SERVER_URL }}
MATRIX_SERVER_NAME: ${{ secrets.MATRIX_SERVER_NAME }}
MATRIX_ROOM: ${{ secrets.MATRIX_ROOM }}
MATRIX_ROOM_ID: ${{ secrets.MATRIX_ROOM_ID }}
MATRIX_DOMAIN: ${{ secrets.MATRIX_DOMAIN }}
MATRIX_MESSAGE: 'Event is triggered by ${{ github.event_name }}'
MATRIX_AUTO_JOIN: ${{ secrets.MATRIX_AUTO_JOIN }}
with:
# Chose the messaging platform.
# slack / telegram / rocketchat / teams /
# pushover / discord / email / mattermost / textmagic / matrix
service: matrix
```
- **Variables**
| Variables | Default Value |
|--------------------| :----------------: |
| MATRIX_USERNAME | "" |
| MATRIX_PASSWORD | "" |
| MATRIX_ACCESS_TOKEN | "" |
| MATRIX_SERVER_URL | "" |
| MATRIX_SERVER_NAME | "" |
| MATRIX_ROOM | "" |
| MATRIX_ROOM_ID | "" |
| MATRIX_DOMAIN | "" |
| MATRIX_MESSAGE | "" |
| MATRIX_AUTO_JOIN | "" |
| EMAIL_SENDER | "" |
| EMAIL_PASSWORD | "" |
| EMAIL_RECEIVER | "" |
| EMAIL_IDENTITY | "" |
| EMAIL_HOST | "smtp.gmail.com" |
| EMAIL_PORT | "587" |
| EMAIL_MESSAGE | "" |
| EMAIL_SUBJECT | "" |

28
go.mod
View File

@ -3,26 +3,10 @@ module github.com/kha7iq/pingme
go 1.16
require (
github.com/RocketChat/Rocket.Chat.Go.SDK v0.0.0-20220708192748-b73dcb041214 // indirect
github.com/go-openapi/analysis v0.21.3 // indirect
github.com/go-openapi/runtime v0.24.1 // indirect
github.com/go-openapi/spec v0.20.6 // indirect
github.com/go-openapi/strfmt v0.21.3 // indirect
github.com/go-openapi/validate v0.22.0 // indirect
github.com/gorilla/schema v1.4.1 // indirect
github.com/gorilla/websocket v1.5.0 // indirect
github.com/gotify/go-api-client/v2 v2.0.4
github.com/gregdel/pushover v1.1.0
github.com/matrix-org/gomatrix v0.0.0-20210324163249-be2af5ef2e16
github.com/mitchellh/mapstructure v1.5.0 // indirect
github.com/nikoksr/notify v0.27.0
github.com/sfreiberg/gotwilio v1.0.0
github.com/silenceper/wechat/v2 v2.1.3
github.com/slack-go/slack v0.11.0 // indirect
github.com/spf13/cast v1.5.0 // indirect
github.com/stretchr/testify v1.8.0
github.com/textmagic/textmagic-rest-go-v2/v2 v2.0.3361 // indirect
github.com/urfave/cli/v2 v2.11.0
golang.org/x/net v0.38.0 // indirect
golang.org/x/oauth2 v0.0.0-20220630143837-2104d58473e0 // indirect
github.com/cpuguy83/go-md2man/v2 v2.0.0 // indirect
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
)

957
go.sum

File diff suppressed because it is too large Load Diff

View File

@ -1,81 +0,0 @@
#!/bin/sh
# Usage: [sudo] [BINDIR=/usr/local/bin] ./install.sh [<BINDIR>]
#
# Example:
# 1. sudo ./install.sh /usr/local/bin
# 2. sudo ./install.sh /usr/bin
# 3. ./install.sh $HOME/usr/bin
# 4. BINDIR=$HOME/usr/bin ./install.sh
#
# Default BINDIR=/usr/bin
set -euf
if [ -n "${DEBUG-}" ]; then
set -x
fi
: ${BINDIR:="/usr/bin"}
if [ $# -gt 0 ]; then
BINDIR=$1
fi
_can_install() {
if [ ! -d "${BINDIR}" ]; then
mkdir -p "${BINDIR}" 2> /dev/null
fi
[ -d "${BINDIR}" ] && [ -w "${BINDIR}" ]
}
if ! _can_install && [ "$(id -u)" != 0 ]; then
printf "Run script as sudo\n"
exit 1
fi
if ! _can_install; then
printf -- "Can't install to %s\n" "${BINDIR}"
exit 1
fi
machine=$(uname -m)
case $machine in
armv7*)
machine="arm"
;;
aarch64)
machine="arm64"
;;
esac
case $(uname -s) in
Linux)
os="Linux"
;;
Darwin)
os="macOS"
;;
*)
printf "OS not supported\n"
exit 1
;;
esac
printf "Fetching latest version\n"
latest="$(curl -sL 'https://api.github.com/repos/kha7iq/pingme/releases/latest' | grep 'tag_name' | grep --only 'v[0-9\.]\+' | cut -c 2-)"
tempFolder="/tmp/pingme_v${latest}"
printf -- "Found version %s\n" "${latest}"
mkdir -p "${tempFolder}" 2> /dev/null
printf -- "Downloading pingme_%s_%s_%s.tar.gz\n" "${latest}" "${os}" "${machine}"
curl -sL -o "${tempFolder}/pingme.tar.gz" "https://github.com/kha7iq/pingme/releases/download/v${latest}/pingme_${os}_${machine}.tar.gz"
printf -- "Installing...\n"
tar -C "${tempFolder}" -xf "${tempFolder}/pingme.tar.gz"
install -m755 "${tempFolder}/pingme" "${BINDIR}/pingme"
printf "Cleaning up temp files\n"
rm -rf "${tempFolder}"
printf -- "Successfully installed pingme into %s/\n" "${BINDIR}"

18
main.go
View File

@ -1,21 +1,13 @@
package main
import (
"github.com/kha7iq/pingme/service/matrix"
"log"
"os"
"github.com/kha7iq/pingme/service/gotify"
"github.com/kha7iq/pingme/service/textmagic"
"github.com/kha7iq/pingme/service/mastodon"
"github.com/kha7iq/pingme/service/twillio"
"github.com/kha7iq/pingme/service/wechat"
"github.com/kha7iq/pingme/service/zulip"
"github.com/kha7iq/pingme/service/discord"
"github.com/kha7iq/pingme/service/email"
"github.com/kha7iq/pingme/service/line"
"github.com/kha7iq/pingme/service/mattermost"
"github.com/kha7iq/pingme/service/msteams"
"github.com/kha7iq/pingme/service/pushbullet"
@ -39,8 +31,7 @@ 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, Pushbullet, Microsoft Teams, Twillio, Mastodon,
email address, Line, Gotify and Wechat.`
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{
telegram.Send(),
@ -53,13 +44,6 @@ email address, Line, Gotify and Wechat.`
mattermost.Send(),
pushbullet.Send(),
twillio.Send(),
zulip.Send(),
mastodon.Send(),
line.Send(),
wechat.Send(),
gotify.Send(),
textmagic.Send(),
matrix.Send(),
}
err := app.Run(os.Args)

View File

@ -1,97 +0,0 @@
package gotify
import (
"log"
"net/http"
"net/url"
"github.com/kha7iq/pingme/service/helpers"
"github.com/gotify/go-api-client/v2/auth"
"github.com/gotify/go-api-client/v2/client/message"
"github.com/gotify/go-api-client/v2/gotify"
"github.com/gotify/go-api-client/v2/models"
"github.com/urfave/cli/v2"
)
// Gotify struct holds data parsed via flags for the service
type Gotify struct {
URL string
Token string
Priority int
Title string
Message string
}
// Send parse values from *cli.context and return *cli.Command
func Send() *cli.Command {
var gotifyOpts Gotify
return &cli.Command{
Name: "gotify",
Usage: "Send push notification to gotify server",
UsageText: "pingme gotify --url 'https://example.com' --token 'tokenabc' --title 'some title' " +
" --msg 'some message' --priority 5",
Description: `With gotify you can send messages to any Gotify server`,
Flags: []cli.Flag{
&cli.StringFlag{
Destination: &gotifyOpts.Token,
Name: "token",
Aliases: []string{"t"},
Required: true,
Usage: "Application token of gotify server",
EnvVars: []string{"GOTIFY_TOKEN"},
},
&cli.StringFlag{
Destination: &gotifyOpts.URL,
Name: "url",
Required: true,
Aliases: []string{"u"},
Usage: "Gotify server Endpoint",
EnvVars: []string{"GOTIFY_URL"},
},
&cli.StringFlag{
Destination: &gotifyOpts.Message,
Name: "msg",
Aliases: []string{"m"},
Usage: "Message content",
EnvVars: []string{"GOTIFY_MESSAGE"},
},
&cli.StringFlag{
Destination: &gotifyOpts.Title,
Name: "title",
Usage: "Title of the message.",
Value: helpers.TimeValue,
EnvVars: []string{"GOTIFY_TITLE"},
},
&cli.IntFlag{
Destination: &gotifyOpts.Priority,
Name: "priority",
Aliases: []string{"p"},
Usage: "Message priority i.e 1-7",
Value: 5,
EnvVars: []string{"GOTIFY_PRIORITY"},
},
},
Action: func(ctx *cli.Context) error {
serverURL, err := url.Parse(gotifyOpts.URL)
if err != nil {
return err
}
c := gotify.NewClient(serverURL, &http.Client{})
params := message.NewCreateMessageParams()
params.Body = &models.MessageExternal{
Title: gotifyOpts.Title,
Message: gotifyOpts.Message,
Priority: gotifyOpts.Priority,
}
_, err = c.Message.CreateMessage(params, auth.TokenAuth(gotifyOpts.Token))
if err != nil {
return err
}
log.Println("Successfully sent!")
return nil
},
}
}

View File

@ -1,100 +0,0 @@
package line
import (
"context"
"log"
"strings"
"github.com/kha7iq/pingme/service/helpers"
"github.com/nikoksr/notify"
"github.com/nikoksr/notify/service/line"
"github.com/urfave/cli/v2"
)
// Line struct holds data parsed via flags for the service
type Line struct {
Secret string
Token string
Message string
Receivers string
Title string
}
// Send parses values from *cli.context and returns a *cli.Command.
// Values include channel secret, channel access token, receiver IDs (group or user), Message and Title.
// If multiple receiver IDs are provided, then the string is split with "," separator and each receiver ID is added to the receiver.
func Send() *cli.Command {
var lineOpts Line
return &cli.Command{
Name: "line",
Usage: "Send message to line messenger",
Description: `Line messenger uses a channel secret and
a channel access token to authenticate & send messages
through line to various receivers.`,
UsageText: "pingme line --secret '123' --token '123' --msg 'some message' --receivers '123,456,789'",
Flags: []cli.Flag{
&cli.StringFlag{
Destination: &lineOpts.Secret,
Name: "secret",
Required: true,
Usage: "Channel secret.",
EnvVars: []string{"LINE_SECRET"},
},
&cli.StringFlag{
Destination: &lineOpts.Token,
Name: "token",
Required: true,
Usage: "Channel access token.",
EnvVars: []string{"LINE_TOKEN"},
},
&cli.StringFlag{
Destination: &lineOpts.Message,
Name: "msg",
Required: true,
Usage: "Message content.",
EnvVars: []string{"LINE_MESSAGE"},
},
&cli.StringFlag{
Destination: &lineOpts.Title,
Name: "title",
Value: helpers.TimeValue,
Usage: "Message title.",
EnvVars: []string{"LINE_MSG_TITLE"},
},
&cli.StringFlag{
Destination: &lineOpts.Receivers,
Name: "receivers",
Required: true,
Usage: "Comma-separated list of user or group receiver IDs.",
EnvVars: []string{"LINE_RECEIVER_IDS"},
},
},
Action: func(ctx *cli.Context) error {
notifier := notify.New()
lineSvc, err := line.New(lineOpts.Secret, lineOpts.Token)
if err != nil {
return err
}
// Add receiver IDs
recv := strings.Split(lineOpts.Receivers, ",")
for _, r := range recv {
lineSvc.AddReceivers(r)
}
notifier.UseServices(lineSvc)
if err := notifier.Send(
context.Background(),
lineOpts.Title,
lineOpts.Message,
); err != nil {
return err
}
log.Println("Successfully sent!")
return nil
},
}
}

View File

@ -1,138 +0,0 @@
package mastodon
import (
"bytes"
"encoding/json"
"fmt"
"log"
"net/http"
"time"
"github.com/urfave/cli/v2"
)
// Mastodon struct holds data parsed via flags for the service
type Mastodon struct {
Title string
Token string
ServerURL string
Message string
}
// HTTPClient interface
type HTTPClient interface {
Do(req *http.Request) (*http.Response, error)
}
var Client HTTPClient
func initialize() {
// create a new http client
Client = &http.Client{
Timeout: 10 * time.Second,
}
}
// Send parse values from *cli.context and return *cli.Command
// and sets a status message for mastodon.
func Send() *cli.Command {
var mastodonOpts Mastodon
return &cli.Command{
Name: "mastodon",
Usage: "Set status message for mastodon",
UsageText: "pingme mastodon --token '123' --url 'mastodon.social' --title 'PingMe' " +
"--msg 'some message'",
Description: `Mastodon uses application token to authorize and sets a status message`,
Flags: []cli.Flag{
&cli.StringFlag{
Destination: &mastodonOpts.Token,
Name: "token",
Aliases: []string{"t"},
Required: true,
Usage: "Application token for authorization.",
EnvVars: []string{"MASTODON_TOKEN"},
},
&cli.StringFlag{
Destination: &mastodonOpts.Message,
Name: "msg",
Aliases: []string{"m"},
Usage: "Message content.",
EnvVars: []string{"MASTODON_MESSAGE"},
},
&cli.StringFlag{
Destination: &mastodonOpts.Title,
Name: "title",
Usage: "Title of the message.",
EnvVars: []string{"MASTODON_TITLE"},
},
&cli.StringFlag{
Destination: &mastodonOpts.ServerURL,
Name: "url",
Aliases: []string{"u"},
Value: "mastodon.social",
Required: true,
Usage: "URL of mastodon server i.e mastodon.social",
EnvVars: []string{"MASTODON_SERVER"},
},
},
Action: func(ctx *cli.Context) error {
initialize()
endPointURL := "https://" + mastodonOpts.ServerURL + "/api/v1/statuses/"
// Create a Bearer string by appending string access token
bearer := "Bearer " + mastodonOpts.Token
fullMessage := mastodonOpts.Title + "\n" + mastodonOpts.Message
if err := sendMastodon(endPointURL, bearer, fullMessage); err != nil {
return fmt.Errorf("failed to send message\n[ERROR] - %v", err)
}
return nil
},
}
}
// sendMastodon function take the server url , authorization token
// and message string to set the status.
func sendMastodon(url string, token string, msg string) error {
reqBody, err := json.Marshal(map[string]string{
"status": msg,
})
if err != nil {
return err
}
// Create a new request using http
req, err := http.NewRequest("POST", url, bytes.NewBuffer(reqBody))
if err != nil {
return err
}
// add authorization header to the request
req.Header.Set("Authorization", token)
req.Header.Set("Content-Type", "application/json; charset=UTF-8")
// send request to server
resp, err := Client.Do(req)
if err != nil {
return err
}
defer resp.Body.Close()
// decode response received from server
var data map[string]interface{}
err = json.NewDecoder(resp.Body).Decode(&data)
if err != nil {
return err
}
// check if server returned an error
checkErr, ok := data["error"]
if ok {
return fmt.Errorf("%v", checkErr)
}
log.Printf("Success!!\nVisibility: %v\nURL: %v\n", data["visibility"], data["url"])
return nil
}

View File

@ -1,81 +0,0 @@
package mastodon
import (
"bytes"
"encoding/json"
"io/ioutil"
"net/http"
"testing"
"github.com/stretchr/testify/assert"
)
const url, token = "server-url", "token"
// MockClient is the mock client
type MockClient struct {
MockDo func(req *http.Request) (*http.Response, error)
}
// Do function implements HTTPClient
func (m *MockClient) Do(req *http.Request) (*http.Response, error) {
return m.MockDo(req)
}
func TestSendMessage_Success(t *testing.T) {
successResponse, _ := json.Marshal(map[string]interface{}{
"success": true,
})
r := ioutil.NopCloser(bytes.NewReader(successResponse))
Client = &MockClient{
MockDo: func(req *http.Request) (*http.Response, error) {
assert.Equal(t, url, req.URL.Path)
assert.Equal(t, token, req.Header.Get("Authorization"))
return &http.Response{
StatusCode: 200,
Body: r,
}, nil
},
}
m := Mastodon{
ServerURL: url,
Token: token,
Message: "message",
}
err := sendMastodon(m.ServerURL, m.Token, m.Message)
assert.Nil(t, err)
}
func TestSendMessage_Failure(t *testing.T) {
successResponse, _ := json.Marshal(map[string]interface{}{
"error": true,
})
r := ioutil.NopCloser(bytes.NewReader(successResponse))
Client = &MockClient{
MockDo: func(req *http.Request) (*http.Response, error) {
assert.Equal(t, url, req.URL.Path)
assert.Equal(t, token, req.Header.Get("Authorization"))
return &http.Response{
StatusCode: 400,
Body: r,
}, nil
},
}
m := Mastodon{
ServerURL: url,
Token: token,
Message: "message",
}
err := sendMastodon(m.ServerURL, m.Token, m.Message)
assert.NotNil(t, err)
}

View File

@ -1,221 +0,0 @@
package matrix
import (
"fmt"
"github.com/matrix-org/gomatrix"
"github.com/urfave/cli/v2"
"strings"
)
type matrixPingMe struct {
Username string
Password string
Token string
Url string
ServerName string
Room string
RoomID string
Domain string
Message string
AutoJoin bool
}
func Send() *cli.Command {
var matrix matrixPingMe
return &cli.Command{
Name: "matrix",
Usage: "Send message via matrix",
UsageText: "pingme matrix --token 'syt_YW...E2qD' --room 'LRovrjPJaRChcTKgoK:matrix.org' " +
"--url 'matrix-client.matrix.org' --autoJoin --msg 'Hello, Matrix!'",
Flags: []cli.Flag{
&cli.StringFlag{
Destination: &matrix.Username,
Name: "username",
Aliases: []string{"u"},
Usage: "Matrix username",
EnvVars: []string{"MATRIX_USER"},
},
&cli.StringFlag{
Destination: &matrix.Password,
Name: "password",
Aliases: []string{"p"},
Usage: "Matrix password",
EnvVars: []string{"MATRIX_PASSWORD"},
},
&cli.StringFlag{
Destination: &matrix.Token,
Name: "token",
Aliases: []string{"t"},
Usage: "Matrix access token. Can be used instead of username+password",
EnvVars: []string{"MATRIX_ACCESS_TOKEN"},
},
&cli.StringFlag{
Destination: &matrix.Url,
Name: "url",
Usage: "Matrix server URL",
EnvVars: []string{"MATRIX_SERVER_URL"},
},
&cli.StringFlag{
Destination: &matrix.ServerName,
Name: "serverName",
Usage: "Can be provided if requests should be routed via a particular server",
EnvVars: []string{"MATRIX_SERVER_NAME"},
},
&cli.StringFlag{
Destination: &matrix.Room,
Name: "room",
Usage: "Matrix room to send the message to, in the format <roomId>:<domain>",
EnvVars: []string{"MATRIX_ROOM"},
},
&cli.StringFlag{
Destination: &matrix.RoomID,
Name: "roomId",
Usage: "Matrix room ID to send the message to. The exclamation mark at the beginning can be excluded.",
EnvVars: []string{"MATRIX_ROOM_ID"},
},
&cli.StringFlag{
Destination: &matrix.Domain,
Name: "domain",
Usage: "Used in conjunction with room ID to get the desired room",
EnvVars: []string{"MATRIX_DOMAIN"},
},
&cli.StringFlag{
Destination: &matrix.Message,
Name: "msg",
Aliases: []string{"m"},
Required: true,
Usage: "Message to send to matrix",
EnvVars: []string{"MATRIX_MESSAGE"},
},
&cli.BoolFlag{
Destination: &matrix.AutoJoin,
Name: "autoJoin",
Usage: "If enabled, will automatically join the specified room if not already joined",
EnvVars: []string{"MATRIX_AUTO_JOIN"},
},
},
Action: func(ctx *cli.Context) error {
// Login
client, err := matrix.login()
if err != nil {
return fmt.Errorf("failed to login to matrix: %v", err)
}
// Parse and set variables
err = matrix.setupVars()
if err != nil {
return err
}
// If necessary, join the given room
err = matrix.joinRoomIfNecessary(client)
if err != nil {
return err
}
// Send the message
_, err = client.SendText(matrix.Room, matrix.Message)
if err != nil {
return fmt.Errorf("failed to send matrix text: %v", err)
}
return nil
},
}
}
/*
setupVars will ensure the room ID begins with an exclamation mark and set the room string if not
already set, using the room ID and domain. If the room string, room id and domain are not set,
an error will be thrown.
*/
func (m *matrixPingMe) setupVars() error {
// Format the room ID
if !strings.HasPrefix(m.RoomID, "!") {
m.RoomID = "!" + m.RoomID
}
// Create the matrix room string if not already provided
if m.Room == "" {
if m.RoomID == "" || m.Domain == "" {
return fmt.Errorf("matrix room, or room ID and domain must be provided")
}
m.Room = fmt.Sprintf("%s:%s", m.RoomID, m.Domain)
}
return nil
}
/*
joinRoomIfNecessary gets all the joined rooms and checks if the desired room is in the list.
If not, and autoJoin is set to true - will attempt to join the room. If autoJoin is set to
false, an error will be thrown
*/
func (m *matrixPingMe) joinRoomIfNecessary(client *gomatrix.Client) error {
// Get already joined rooms
joined, err := client.JoinedRooms()
if err != nil {
return fmt.Errorf("failed to get joined rooms: %v", err)
}
// Check if we've already joined the desired room
foundRoom := false
for _, room := range joined.JoinedRooms {
if room == m.Room {
foundRoom = true
break
}
}
// If not, try auto join the room
if !foundRoom {
if !m.AutoJoin {
return fmt.Errorf("not joined room '%s' and --autoJoin is set to false", m.Room)
}
_, err = client.JoinRoom(m.Room, m.ServerName, nil)
if err != nil {
return fmt.Errorf("failed to auto join room '%s': %v", m.Room, err)
}
}
return nil
}
/*
login creates a gomatrix.Client instance, connecting to the given URL, using the provided login details
*/
func (m *matrixPingMe) login() (*gomatrix.Client, error) {
// Create a client instance
client, err := gomatrix.NewClient(m.Url, "", "")
if err != nil {
return nil, fmt.Errorf("failed to create matrix client: %v", err)
}
// Attempt to log in with whatever login details were provided.
// Or, throw an error if no login details were given
var resp *gomatrix.RespLogin
if m.Token != "" {
resp, err = client.Login(&gomatrix.ReqLogin{
Type: "m.login.token",
Token: m.Token,
})
if err != nil {
return nil, err
}
} else if m.Username != "" && m.Password != "" {
resp, err = client.Login(&gomatrix.ReqLogin{
Type: "m.login.password",
User: m.Username,
Password: m.Password,
})
if err != nil {
return nil, err
}
} else {
return nil, fmt.Errorf("no token, or username and password provided")
}
// Set the access token for this session
client.SetCredentials(resp.UserID, resp.AccessToken)
m.Token = resp.AccessToken
return client, nil
}

View File

@ -49,19 +49,6 @@ type matterMostResponse struct {
Metadata struct{} `json:"metadata"`
}
// HTTPClient interface
type HTTPClient interface {
Do(req *http.Request) (*http.Response, error)
}
var Client HTTPClient
func initialize() {
Client = &http.Client{
Timeout: 10 * time.Second,
}
}
// 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
@ -131,7 +118,6 @@ You can specify multiple channels by separating the value with ','.`,
},
},
Action: func(ctx *cli.Context) error {
initialize()
endPointURL := mattermostOpts.Scheme + "://" + mattermostOpts.ServerURL + mattermostOpts.APIURL
// Create a Bearer string by appending string access token
@ -187,7 +173,9 @@ func sendMattermost(url string, token string, jsonPayload []byte) error {
req.Header.Set("Authorization", token)
req.Header.Set("Content-Type", "application/json; charset=UTF-8")
resp, err := Client.Do(req)
// create a new http client and send request to server
c := &http.Client{Timeout: 10 * time.Second}
resp, err := c.Do(req)
if err != nil {
return err
}

View File

@ -1,73 +0,0 @@
package mattermost
import (
"bytes"
"encoding/json"
"io/ioutil"
"net/http"
"strings"
"testing"
"github.com/stretchr/testify/assert"
)
// MockDoType
type MockDoType func(req *http.Request) (*http.Response, error)
// MockClient is the mock client
type MockClient struct {
MockDo MockDoType
}
// Overriding what the Do function should "do" in our MockClient
func (m *MockClient) Do(req *http.Request) (*http.Response, error) {
return m.MockDo(req)
}
func TestSendMessage_Success(t *testing.T) {
// build our response JSON
successResponse, _ := json.Marshal(matterMostResponse{
ID: "1",
Message: "Success",
})
// create a new reader with that JSON
r := ioutil.NopCloser(bytes.NewReader(successResponse))
Client = &MockClient{
MockDo: func(*http.Request) (*http.Response, error) {
return &http.Response{
StatusCode: 200,
Body: r,
}, nil
},
}
mattermostOpts := matterMost{
Title: "title",
Token: "token",
ServerURL: "url",
Scheme: "https",
APIURL: "api-url",
Message: "hello",
ChanIDs: "1",
}
endPointURL := mattermostOpts.Scheme + "://" + mattermostOpts.ServerURL + mattermostOpts.APIURL
// Create a Bearer string by appending string access token
bearer := "Bearer " + mattermostOpts.Token
fullMessage := mattermostOpts.Title + "\n" + mattermostOpts.Message
ids := strings.Split(mattermostOpts.ChanIDs, ",")
for _, v := range ids {
assert.Equal(t, 1, len(v))
jsonData, err := toJSON(v, fullMessage)
assert.Nil(t, err)
err = sendMattermost(endPointURL, bearer, jsonData)
assert.Nil(t, err)
}
}

View File

@ -16,7 +16,6 @@ type pushOver struct {
Recipient string
Message string
Title string
Priority int
}
// Send parse values from *cli.context and return *cli.Command.
@ -62,27 +61,10 @@ All configuration options are also available via environment variables.`,
Usage: "Title of the message.",
EnvVars: []string{"PUSHOVER_TITLE"},
},
&cli.IntFlag{
Destination: &pushOverOpts.Priority,
Name: "priority",
Aliases: []string{"p"},
Value: 0,
Usage: "Priority of the message.",
EnvVars: []string{"PUSHOVER_PRIORITY"},
},
},
Action: func(ctx *cli.Context) error {
app := pushover.New(pushOverOpts.Token)
// message := &pushover.Message{Title: pushOverOpts.Title, Message: pushOverOpts.Message, Priority: pushOverOpts.Priority}
message := &pushover.Message{Title: pushOverOpts.Title,
Message: pushOverOpts.Message,
Priority: pushOverOpts.Priority,
Retry: 60,
Expire: 3600,
}
message := pushover.NewMessageWithTitle(pushOverOpts.Message, pushOverOpts.Title)
users := strings.Split(pushOverOpts.Recipient, ",")
for _, v := range users {

View File

@ -78,11 +78,11 @@ All configuration options are also available via environment variables.`,
if len(v) <= 0 {
return helpers.ErrChannel
}
k, errStr := strconv.ParseInt(v, 10, 64)
k, errStr := strconv.Atoi(v)
if errStr != nil {
return errStr
}
telegramSvc.AddReceivers(k)
telegramSvc.AddReceivers(int64(k))
}
notifier.UseServices(telegramSvc)

View File

@ -1,98 +0,0 @@
package textmagic
import (
"context"
"fmt"
"strings"
"github.com/nikoksr/notify"
"github.com/nikoksr/notify/service/textmagic"
"github.com/urfave/cli/v2"
)
//TextMagic struct describes required data needed to integrate with TextMagic
type TextMagic struct {
Token string
User string
Subject string
Message string
Receiver string
}
//Send method sends a message via TextMagic service
func Send() *cli.Command {
var textMagicOpts TextMagic
return &cli.Command{
Name: "textmagic",
Usage: "Send message via TextMagic",
UsageText: "pingme textmagic --token 'tokenabc' --user 'sid123' " +
"--title 'foo' --receiver '+140001442' --msg 'some message'",
Description: `textmagic 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: &textMagicOpts.Token,
Name: "token",
Usage: "TextMagic token",
Aliases: []string{"t"},
Required: true,
EnvVars: []string{"TEXTMAGIC_TOKEN"},
},
&cli.StringFlag{
Destination: &textMagicOpts.User,
Name: "user",
Usage: "TextMagic user",
Aliases: []string{"u"},
Required: true,
EnvVars: []string{"TEXTMAGIC_USER"},
},
&cli.StringFlag{
Destination: &textMagicOpts.Subject,
Name: "title",
Usage: "Title of the message",
EnvVars: []string{"TEXTMAGIC_TITLE"},
},
&cli.StringFlag{
Destination: &textMagicOpts.Receiver,
Name: "receiver",
Usage: "Receiver(s) of the message",
Aliases: []string{"r"},
Required: true,
EnvVars: []string{"TEXTMAGIC_RECEIVER"},
},
&cli.StringFlag{
Destination: &textMagicOpts.Message,
Name: "msg",
Usage: "Message to send",
Aliases: []string{"m"},
Required: true,
EnvVars: []string{"TEXTMAGIC_MESSAGE"},
},
},
Action: func(c *cli.Context) error {
textMagicService := textmagic.New(textMagicOpts.User, textMagicOpts.Token)
receivers, err := getReceivers(textMagicOpts.Receiver)
if err != nil {
return fmt.Errorf("invalid receivers provided, %w", err)
}
textMagicService.AddReceivers(receivers...)
notifier := notify.New()
notifier.UseServices(textMagicService)
err = notifier.Send(context.Background(), textMagicOpts.Subject, textMagicOpts.Message)
if err != nil {
return fmt.Errorf("could not send textMagic message, %w", err)
}
return nil
},
}
}
func getReceivers(receivers string) ([]string, error) {
if len(receivers) == 0 {
return nil, fmt.Errorf("no receivers found")
}
r := strings.Split(receivers, ",")
return r, nil
}

View File

@ -1,120 +0,0 @@
package wechat
import (
"context"
"log"
"strings"
"github.com/kha7iq/pingme/service/helpers"
"github.com/nikoksr/notify"
"github.com/nikoksr/notify/service/wechat"
"github.com/silenceper/wechat/v2/cache"
"github.com/urfave/cli/v2"
)
// Wechat struct holds data parsed via flags for the service.
type Wechat struct {
AppID string
AppSecret string
Token string
EncodingAESKey string
Title string
Message string
Receivers string
}
// Send parse values from *cli.context and return *cli.Command.
// Values include wechat official account id, secret, server token, encoding AES key,
// Message, Title, and Receivers.
// If multiple receivers are provided then the string is split with "," separator and
// each receiverID is added to receiver.
func Send() *cli.Command {
var wechatOpts Wechat
return &cli.Command{
Name: "wechat",
Usage: "Send message to wechat official account",
Description: `Wechat sends message to Wechat Official Account using appid, appsecrete
and server token to authenticate
AND then send messages to defined account.
Multiple receiverss can be used separated by comma.`,
UsageText: "pingme wechat --appid '123' --appsecret '123' --token '123' --aes '123' --msg 'some message' --receivers 'aaa,bbb,ccc'",
Flags: []cli.Flag{
&cli.StringFlag{
Destination: &wechatOpts.AppID,
Name: "appid",
Required: true,
Usage: "AppID of wechat official account.",
EnvVars: []string{"WECHAT_APPID"},
},
&cli.StringFlag{
Destination: &wechatOpts.AppSecret,
Name: "appsecret",
Required: true,
Usage: "AppSecret of wechat official account.",
EnvVars: []string{"WECHAT_APPSECRET"},
},
&cli.StringFlag{
Destination: &wechatOpts.Token,
Name: "token",
Required: true,
Usage: "Token of server used for sending message.",
EnvVars: []string{"WECHAT_TOKEN"},
},
&cli.StringFlag{
Destination: &wechatOpts.EncodingAESKey,
Name: "aes",
Required: true,
Usage: "Encoding AES Key of server used for sending message.",
EnvVars: []string{"WECHAT_ENCODING_AES_KEY"},
},
&cli.StringFlag{
Destination: &wechatOpts.Receivers,
Name: "receivers",
Required: true,
Usage: "Comma-separated list of receiver IDs.",
EnvVars: []string{"WECHAT_RECEIVERS"},
},
&cli.StringFlag{
Destination: &wechatOpts.Message,
Name: "msg",
Required: true,
Usage: "Message content.",
EnvVars: []string{"WECHAT_MESSAGE"},
},
&cli.StringFlag{
Destination: &wechatOpts.Title,
Name: "title",
Value: helpers.TimeValue,
Usage: "Title of the message.",
EnvVars: []string{"WECHAT_TITLE"},
},
},
Action: func(ctx *cli.Context) error {
wechatSvc := wechat.New(&wechat.Config{
AppID: wechatOpts.AppID,
AppSecret: wechatOpts.AppSecret,
Token: wechatOpts.Token,
EncodingAESKey: wechatOpts.EncodingAESKey,
Cache: cache.NewMemory(),
})
// Add receiver IDs
recv := strings.Split(wechatOpts.Receivers, ",")
for _, r := range recv {
wechatSvc.AddReceivers(r)
}
notifier := notify.New()
notifier.UseServices(wechatSvc)
err := notifier.Send(context.Background(), wechatOpts.Title, wechatOpts.Message)
if err != nil {
log.Fatalf("notifier.Send() failed: %s", err.Error())
}
log.Println("Successfully sent!")
return nil
},
}
}

View File

@ -1,173 +0,0 @@
package zulip
import (
"encoding/json"
"errors"
"log"
"net/http"
"net/url"
"strings"
"time"
"github.com/urfave/cli/v2"
)
// Zulip holds all the necessary options to use zulip
type Zulip struct {
ZBot
Type string
To string
Topic string
Content string
Domain string
}
type ZBot struct {
EmailID string
APIKey string
}
type ZResponse struct {
ID int `json:"id"`
Message string `json:"msg"`
Result string `json:"result"`
Code string `json:"code"`
}
// HTTPClient interface
type HTTPClient interface {
Do(req *http.Request) (*http.Response, error)
}
var Client HTTPClient
func initialize() {
Client = &http.Client{
Timeout: 10 * time.Second,
}
}
func Send() *cli.Command {
var zulipOpts Zulip
return &cli.Command{
Name: "zulip",
Usage: "Send message to zulip",
UsageText: "pingme zulip --email 'john.doe@email.com' --api-key '12345567' --to 'london' --type 'stream' " +
"--topic 'some topic' --content 'content of the message'",
Description: `Zulip uses token and email to authenticate and ids for users or streams.
You can specify multiple userIds by separating the value with ','.`,
Flags: []cli.Flag{
&cli.StringFlag{
Destination: &zulipOpts.Domain,
Name: "domain",
Aliases: []string{},
Required: true,
Usage: "Your zulip domain",
EnvVars: []string{"ZULIP_DOMAIN"},
},
&cli.StringFlag{
Destination: &zulipOpts.EmailID,
Name: "email",
Aliases: []string{},
Required: true,
Usage: "Email ID of the bot",
EnvVars: []string{"ZULIP_BOT_EMAIL_ADDRESS"},
},
&cli.StringFlag{
Destination: &zulipOpts.APIKey,
Name: "api-key",
Aliases: []string{},
Required: true,
Usage: "API Key of the bot",
EnvVars: []string{"ZULIP_BOT_API_KEY"},
},
&cli.StringFlag{
Destination: &zulipOpts.Type,
Name: "type",
Aliases: []string{},
Usage: "The type of message to be sent. private for a private message and stream for a stream message.",
EnvVars: []string{"ZULIP_MSG_TYPE"},
},
&cli.StringFlag{
Destination: &zulipOpts.To,
Name: "to",
Aliases: []string{},
Usage: "For stream messages, the name of the stream. For private messages, csv of email addresses",
EnvVars: []string{"ZULIP_STREAM_NAME"},
},
&cli.StringFlag{
Destination: &zulipOpts.Topic,
Name: "topic",
Aliases: []string{},
Usage: "The topic of the message. Only required for stream messages 'type=stream', ignored otherwise.",
EnvVars: []string{"ZULIP_TOPIC"},
},
&cli.StringFlag{
Destination: &zulipOpts.Content,
Name: "msg",
Aliases: []string{},
Required: true,
Usage: "The content of the message.",
EnvVars: []string{"ZULIP_MESSAGE"},
},
},
Action: func(ctx *cli.Context) error {
initialize()
resp, err := SendZulipMessage(zulipOpts.Domain, zulipOpts)
if err != nil {
return err
}
if resp.Result == "success" {
log.Printf("Server Reply ID: %v\nResult: %v\n", resp.ID, resp.Result)
}
return errors.New(resp.Message)
},
}
}
func getTo(messageType string, to string) string {
if messageType == "stream" {
return to
}
privateTo, _ := json.Marshal(strings.Split(to, ","))
return string(privateTo)
}
// SendZulipMessage function takes the zulip domain and zulip bot
// type, to, topic and content in the form of json byte array and sends
// message to zulip.
func SendZulipMessage(zulipDomain string, zulipOpts Zulip) (*ZResponse, error) {
data := url.Values{}
data.Set("type", zulipOpts.Type)
data.Set("to", getTo(zulipOpts.Type, zulipOpts.To))
data.Set("topic", zulipOpts.Topic)
data.Set("content", zulipOpts.Content)
var response ZResponse
endPointURL := "https://" + zulipDomain + "/api/v1/messages"
// Create a new request using http
req, err := http.NewRequest("POST", endPointURL, strings.NewReader(data.Encode()))
if err != nil {
return nil, err
}
zulipBot := zulipOpts.ZBot
req.SetBasicAuth(zulipBot.EmailID, zulipBot.APIKey)
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
resp, err := Client.Do(req)
if err != nil {
return nil, err
}
defer resp.Body.Close()
// decode response sent from server
err = json.NewDecoder(resp.Body).Decode(&response)
if err != nil {
return nil, err
}
return &response, nil
}

View File

@ -1,181 +0,0 @@
package zulip_test
import (
"bytes"
"encoding/json"
"io/ioutil"
"net/http"
"testing"
"github.com/kha7iq/pingme/service/zulip"
"github.com/stretchr/testify/assert"
)
// MockDoType
type MockDoType func(req *http.Request) (*http.Response, error)
// MockClient is the mock client
type MockClient struct {
MockDo MockDoType
}
// Overriding what the Do function should "do" in our MockClient
func (m *MockClient) Do(req *http.Request) (*http.Response, error) {
return m.MockDo(req)
}
func TestSendMessage_Success(t *testing.T) {
// build our response JSON
successResponse, _ := json.Marshal(zulip.ZResponse{
ID: 1,
Message: "",
Result: "success",
Code: "",
})
// create a new reader with that JSON
r := ioutil.NopCloser(bytes.NewReader(successResponse))
zulip.Client = &MockClient{
MockDo: func(*http.Request) (*http.Response, error) {
return &http.Response{
StatusCode: 200,
Body: r,
}, nil
},
}
z := zulip.Zulip{
ZBot: zulip.ZBot{
EmailID: "test@test.com",
APIKey: "api-key",
},
Type: "stream",
To: "general",
Topic: "test",
Content: "test content",
Domain: "user.zulipchat.com",
}
resp, err := zulip.SendZulipMessage(z.Domain, z)
assert.Nil(t, err)
assert.Equal(t, "success", resp.Result)
}
func TestSendMessageStream_Fail(t *testing.T) {
// build our response JSON
failureResponse, _ := json.Marshal(zulip.ZResponse{
Message: "Stream 'nonexistent_stream' does not exist",
Result: "error",
Code: "STREAM_DOES_NOT_EXIST",
})
// create a new reader with that JSON
r := ioutil.NopCloser(bytes.NewReader(failureResponse))
zulip.Client = &MockClient{
MockDo: func(*http.Request) (*http.Response, error) {
return &http.Response{
StatusCode: 404,
Body: r,
}, nil
},
}
z := zulip.Zulip{
ZBot: zulip.ZBot{
EmailID: "test@test.com",
APIKey: "api-key",
},
Type: "stream",
To: "general",
Topic: "test",
Content: "test content",
Domain: "user.zulipchat.com",
}
resp, err := zulip.SendZulipMessage(z.Domain, z)
assert.Nil(t, err)
assert.Equal(t, "error", resp.Result)
}
func TestSendMessagePrivate_Fail(t *testing.T) {
// build our response JSON
failureResponse, _ := json.Marshal(zulip.ZResponse{
Message: "some error",
Result: "error",
Code: "BAD_REQUEST",
})
// create a new reader with that JSON
r := ioutil.NopCloser(bytes.NewReader(failureResponse))
zulip.Client = &MockClient{
MockDo: func(*http.Request) (*http.Response, error) {
return &http.Response{
StatusCode: 404,
Body: r,
}, nil
},
}
z := zulip.Zulip{
ZBot: zulip.ZBot{
EmailID: "test@test.com",
APIKey: "api-key",
},
Type: "private",
To: "1,2",
Topic: "test",
Content: "test content",
Domain: "user.zulipchat.com",
}
resp, err := zulip.SendZulipMessage(z.Domain, z)
assert.Nil(t, err)
assert.Equal(t, "error", resp.Result)
}
func TestSendMessagePrivate_Success(t *testing.T) {
// build our response JSON
successResponse, _ := json.Marshal(zulip.ZResponse{
Message: "",
Result: "success",
ID: 1,
})
// create a new reader with that JSON
r := ioutil.NopCloser(bytes.NewReader(successResponse))
zulip.Client = &MockClient{
MockDo: func(*http.Request) (*http.Response, error) {
return &http.Response{
StatusCode: 200,
Body: r,
}, nil
},
}
z := zulip.Zulip{
ZBot: zulip.ZBot{
EmailID: "test@test.com",
APIKey: "api-key",
},
Type: "private",
To: "1,2",
Topic: "test",
Content: "test content",
Domain: "user.zulipchat.com",
}
resp, err := zulip.SendZulipMessage(z.Domain, z)
assert.Nil(t, err)
assert.Equal(t, "success", resp.Result)
}