mirror of
https://github.com/kha7iq/pingme.git
synced 2025-05-15 22:30:11 -07:00
Compare commits
123 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
2d36d68023 | ||
|
6c02fbd8d4 | ||
|
f24407ea7e | ||
|
b9f2293cee | ||
|
4374f0864b | ||
|
fe6ac6a8d0 | ||
|
c663b2da6e | ||
|
8989698d25 | ||
|
daae65b4ba | ||
|
138ff38891 | ||
|
a2a91ace45 | ||
|
9dca2a1b74 | ||
|
7277d3386f | ||
|
5220398da3 | ||
|
98891789cf | ||
|
6629fac687 | ||
|
db4a0fe266 | ||
|
600ce268ac | ||
|
a233a22c70 | ||
|
888b989e67 | ||
|
3ec42b8a4b | ||
|
6786a1d80b | ||
|
5ed11059e0 | ||
|
8b190506ff | ||
|
1fed68e69c | ||
|
ba9185e93a | ||
|
3e3bd04861 | ||
|
c23aa335fc | ||
|
111c27d9cd | ||
|
2e450056eb | ||
|
aea178cb18 | ||
|
300293b85b | ||
|
cb0531d66f | ||
|
4338ba4056 | ||
|
ab93bcc203 | ||
|
ab46bee38b | ||
|
e69a3b2191 | ||
|
dd970e43e2 | ||
|
a6485a2702 | ||
|
f9d0d5a93d | ||
|
4c363e1192 | ||
|
fa26243b53 | ||
|
b6ee47a24e | ||
|
ba7070ecc9 | ||
|
b841854e09 | ||
|
93ecd78272 | ||
|
63cda17e2a | ||
|
6e4c0db81f | ||
|
03e380461f | ||
|
e0047ea5e5 | ||
|
0a4a7214dc | ||
|
ee370d6757 | ||
|
0962d5564a | ||
|
091884f87d | ||
|
53b4fc8027 | ||
|
2dece09025 | ||
|
c5eb07430f | ||
|
51a59136f5 | ||
|
628a168de1 | ||
|
a17856f676 | ||
|
26e80fe0d3 | ||
|
3ef520a81d | ||
|
af7215241a | ||
|
3c0d418dcd | ||
|
ae9a050ac0 | ||
|
3e9d841f3e | ||
|
551ee5fff1 | ||
|
6429da287d | ||
|
b91a2fbc7a | ||
|
689e2ad34f | ||
|
34a6e8971c | ||
|
df5427b85a | ||
|
68d59176bd | ||
|
b20d74f335 | ||
|
ee6f51722e | ||
|
24242b5da2 | ||
|
76105ec7ad | ||
|
efac11a3ef | ||
|
7186e5dd47 | ||
|
b85a045a45 | ||
|
a663aad3ee | ||
|
28d78e458f | ||
|
29e664a8b5 | ||
|
3cfd2b25be | ||
|
024b150b43 | ||
|
e34eba00b5 | ||
|
62c2904649 | ||
|
6c6c6d4d64 | ||
|
6d911e50d8 | ||
|
c8424e5716 | ||
|
b8d81d1705 | ||
|
c3069f648d | ||
|
6c133a0a43 | ||
|
65daa77273 | ||
|
623bf4c269 | ||
|
db7af57b30 | ||
|
36a6d8abbd | ||
|
a4146c8a79 | ||
|
c5377f52ad | ||
|
0e2992e4aa | ||
|
14f5a03201 | ||
|
0e516540ca | ||
|
5238fe068e | ||
|
f0c2c37837 | ||
|
1baaebb915 | ||
|
f143bd45f8 | ||
|
918b61b61d | ||
|
d7734f9e79 | ||
|
89e42393d7 | ||
|
cd8854d045 | ||
|
3856679955 | ||
|
1d8a14e7d3 | ||
|
fe0840a055 | ||
|
9a7bc8803d | ||
|
c9d3276a81 | ||
|
c7fb4fd8f2 | ||
|
9d825b8d9a | ||
|
e90a965fab | ||
|
63b27b3155 | ||
|
6424ca7bdf | ||
|
ddb40b6751 | ||
|
5a94dd9048 | ||
|
912a191b31 |
22
.github/ISSUE_TEMPLATE/bug_report.md
vendored
22
.github/ISSUE_TEMPLATE/bug_report.md
vendored
@ -5,31 +5,39 @@ about: Create a report to help us improve
|
|||||||
---
|
---
|
||||||
|
|
||||||
**Describe the bug**
|
**Describe the bug**
|
||||||
|
|
||||||
A clear and concise description of what the bug is.
|
A clear and concise description of what the bug is.
|
||||||
|
|
||||||
**To Reproduce**
|
**To Reproduce**
|
||||||
|
|
||||||
Steps to reproduce the behavior:
|
Steps to reproduce the behavior:
|
||||||
|
|
||||||
1. Go to '...'
|
1. Go to '...'
|
||||||
2. Click on '....'
|
2. Click on '....'
|
||||||
3. Scroll down to '....'
|
3. Scroll down to '....'
|
||||||
4. See error
|
4. See error
|
||||||
|
|
||||||
**Expected behavior**
|
**Expected behavior**
|
||||||
|
|
||||||
A clear and concise description of what you expected to happen.
|
A clear and concise description of what you expected to happen.
|
||||||
|
|
||||||
**Screenshots**
|
**Screenshots**
|
||||||
|
|
||||||
If applicable, add screenshots to help explain your problem.
|
If applicable, add screenshots to help explain your problem.
|
||||||
|
|
||||||
**Desktop (please complete the following information):**
|
**Desktop (please complete the following information):**
|
||||||
- OS: [e.g. iOS]
|
|
||||||
- Browser [e.g. chrome, safari]
|
- OS: [e.g. iOS]
|
||||||
- Version [e.g. 22]
|
- Browser [e.g. chrome, safari]
|
||||||
|
- Version [e.g. 22]
|
||||||
|
|
||||||
**Smartphone (please complete the following information):**
|
**Smartphone (please complete the following information):**
|
||||||
- Device: [e.g. iPhone6]
|
|
||||||
- OS: [e.g. iOS8.1]
|
- Device: [e.g. iPhone6]
|
||||||
- Browser [e.g. stock browser, safari]
|
- OS: [e.g. iOS8.1]
|
||||||
- Version [e.g. 22]
|
- Browser [e.g. stock browser, safari]
|
||||||
|
- Version [e.g. 22]
|
||||||
|
|
||||||
**Additional context**
|
**Additional context**
|
||||||
|
|
||||||
Add any other context about the problem here.
|
Add any other context about the problem here.
|
||||||
|
35
.github/ISSUE_TEMPLATE/bug_report.md-e
vendored
35
.github/ISSUE_TEMPLATE/bug_report.md-e
vendored
@ -1,35 +0,0 @@
|
|||||||
---
|
|
||||||
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.
|
|
7
.github/ISSUE_TEMPLATE/feature_request.md
vendored
7
.github/ISSUE_TEMPLATE/feature_request.md
vendored
@ -5,13 +5,18 @@ about: Suggest an idea for this project
|
|||||||
---
|
---
|
||||||
|
|
||||||
**Is your feature request related to a problem? Please describe.**
|
**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**
|
**Describe the solution you'd like**
|
||||||
|
|
||||||
A clear and concise description of what you want to happen.
|
A clear and concise description of what you want to happen.
|
||||||
|
|
||||||
**Describe alternatives you've considered**
|
**Describe alternatives you've considered**
|
||||||
|
|
||||||
A clear and concise description of any alternative solutions or features you've considered.
|
A clear and concise description of any alternative solutions or features you've considered.
|
||||||
|
|
||||||
**Additional context**
|
**Additional context**
|
||||||
|
|
||||||
Add any other context or screenshots about the feature request here.
|
Add any other context or screenshots about the feature request here.
|
||||||
|
17
.github/ISSUE_TEMPLATE/feature_request.md-e
vendored
17
.github/ISSUE_TEMPLATE/feature_request.md-e
vendored
@ -1,17 +0,0 @@
|
|||||||
---
|
|
||||||
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
31
.github/PULL_REQUEST_TEMPLATE.md-e
vendored
@ -1,31 +0,0 @@
|
|||||||
# 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`
|
|
23
.github/aur/pingme-bin/.SRCINFO.template
vendored
Normal file
23
.github/aur/pingme-bin/.SRCINFO.template
vendored
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
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
|
34
.github/aur/pingme-bin/PKGBUILD.template
vendored
Normal file
34
.github/aur/pingme-bin/PKGBUILD.template
vendored
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
# 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}"
|
||||||
|
|
||||||
|
}
|
64
.github/aur/pingme-bin/publish.sh
vendored
Executable file
64
.github/aur/pingme-bin/publish.sh
vendored
Executable file
@ -0,0 +1,64 @@
|
|||||||
|
#!/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
|
13
.github/aur/pingme/.SRCINFO.template
vendored
Normal file
13
.github/aur/pingme/.SRCINFO.template
vendored
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
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
|
27
.github/aur/pingme/PKGBUILD.template
vendored
Normal file
27
.github/aur/pingme/PKGBUILD.template
vendored
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
# 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}"
|
||||||
|
}
|
61
.github/aur/pingme/publish.sh
vendored
Executable file
61
.github/aur/pingme/publish.sh
vendored
Executable file
@ -0,0 +1,61 @@
|
|||||||
|
#!/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
BIN
.github/img/logo.png
vendored
Binary file not shown.
Before Width: | Height: | Size: 32 KiB After Width: | Height: | Size: 25 KiB |
BIN
.github/img/pingme.gif
vendored
BIN
.github/img/pingme.gif
vendored
Binary file not shown.
Before Width: | Height: | Size: 1.5 MiB After Width: | Height: | Size: 1.5 MiB |
68
.github/workflows/build.yml
vendored
68
.github/workflows/build.yml
vendored
@ -2,12 +2,8 @@ name: build
|
|||||||
|
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
# branches:
|
|
||||||
# - 'master'
|
|
||||||
# paths-ignore:
|
|
||||||
# - '**.md'
|
|
||||||
tags:
|
tags:
|
||||||
- 'v*.*.*'
|
- 'v0.[0-9]+.[0-9]'
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
release-pingme:
|
release-pingme:
|
||||||
@ -15,48 +11,56 @@ jobs:
|
|||||||
env:
|
env:
|
||||||
DOCKER_CLI_EXPERIMENTAL: "enabled"
|
DOCKER_CLI_EXPERIMENTAL: "enabled"
|
||||||
steps:
|
steps:
|
||||||
-
|
- name: Checkout
|
||||||
name: Checkout
|
uses: actions/checkout@v4
|
||||||
uses: actions/checkout@v2.3.4
|
|
||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
-
|
|
||||||
name: Set up Go
|
|
||||||
uses: actions/setup-go@v2
|
|
||||||
with:
|
|
||||||
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: Set up Go
|
||||||
name: Docker login GHCR
|
uses: actions/setup-go@v4
|
||||||
|
with:
|
||||||
|
go-version: '>=1.20.0'
|
||||||
|
|
||||||
|
- name: Docker login GHCR
|
||||||
uses: docker/login-action@v1
|
uses: docker/login-action@v1
|
||||||
with:
|
with:
|
||||||
registry: ghcr.io
|
registry: ghcr.io
|
||||||
username: ${{ github.repository_owner }}
|
username: ${{ github.repository_owner }}
|
||||||
password: ${{ secrets.GITHUB_TOKEN }}
|
password: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
-
|
- name: Docker Login DockerHub
|
||||||
name: Docker Login DockerHub
|
|
||||||
uses: docker/login-action@v1
|
uses: docker/login-action@v1
|
||||||
with:
|
with:
|
||||||
username: ${{ secrets.DOCKER_USERNAME }}
|
username: ${{ secrets.DOCKER_USERNAME }}
|
||||||
password: ${{ secrets.DOCKER_PASSWORD }}
|
password: ${{ secrets.DOCKER_PASSWORD }}
|
||||||
|
|
||||||
-
|
- name: Release PingMe
|
||||||
name: Release PingMe
|
uses: goreleaser/goreleaser-action@v3
|
||||||
uses: goreleaser/goreleaser-action@v2
|
|
||||||
with:
|
with:
|
||||||
version: latest
|
version: latest
|
||||||
args: release --rm-dist
|
args: release --clean
|
||||||
env:
|
env:
|
||||||
GITHUB_TOKEN: ${{ secrets.RELEASE_TOKEN }}
|
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
36
.github/workflows/pull_request.yml
vendored
@ -1,36 +0,0 @@
|
|||||||
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
|
|
@ -12,10 +12,15 @@ builds:
|
|||||||
- darwin
|
- darwin
|
||||||
- windows
|
- windows
|
||||||
goarch:
|
goarch:
|
||||||
- 386
|
- "386"
|
||||||
- amd64
|
- amd64
|
||||||
- arm
|
- arm
|
||||||
- arm64
|
- arm64
|
||||||
|
goarm:
|
||||||
|
- "7"
|
||||||
|
ignore:
|
||||||
|
- goos: windows
|
||||||
|
goarch: arm64
|
||||||
mod_timestamp: '{{ .CommitTimestamp }}'
|
mod_timestamp: '{{ .CommitTimestamp }}'
|
||||||
flags:
|
flags:
|
||||||
- -trimpath
|
- -trimpath
|
||||||
@ -30,19 +35,21 @@ changelog:
|
|||||||
exclude: ['^docs:', '^test:', 'Merge pull request', 'Merge branch', 'go mod tidy']
|
exclude: ['^docs:', '^test:', 'Merge pull request', 'Merge branch', 'go mod tidy']
|
||||||
|
|
||||||
archives:
|
archives:
|
||||||
- name_template: '{{ .ProjectName }}_{{ .Os }}_{{ .Arch }}{{ if .Arm }}v{{ .Arm }}{{ end }}'
|
- name_template: >-
|
||||||
replacements:
|
{{ .ProjectName }}_
|
||||||
darwin: Darwin
|
{{- title .Os }}_
|
||||||
linux: Linux
|
{{- if eq .Arch "amd64" }}x86_64
|
||||||
windows: Windows
|
{{- else if eq .Arch "386" }}i386
|
||||||
386: i386
|
{{- else }}{{ .Arch }}{{ end }}
|
||||||
amd64: x86_64
|
|
||||||
format_overrides:
|
format_overrides:
|
||||||
- goos: windows
|
- goos: windows
|
||||||
format: zip
|
format: zip
|
||||||
|
files:
|
||||||
|
- README.md
|
||||||
|
- LICENSE.md
|
||||||
|
|
||||||
brews:
|
brews:
|
||||||
- tap:
|
- repository:
|
||||||
owner: kha7iq
|
owner: kha7iq
|
||||||
name: homebrew-tap
|
name: homebrew-tap
|
||||||
folder: Formula
|
folder: Formula
|
||||||
@ -56,6 +63,7 @@ brews:
|
|||||||
|
|
||||||
nfpms:
|
nfpms:
|
||||||
- file_name_template: '{{ .ProjectName }}_{{ .Arch }}{{ if .Arm }}v{{ .Arm }}{{ end }}'
|
- file_name_template: '{{ .ProjectName }}_{{ .Arch }}{{ if .Arm }}v{{ .Arm }}{{ end }}'
|
||||||
|
maintainer: 'Abdul Khaliq <a.khaliq@outlook.my>'
|
||||||
homepage: pingme.lmno.pk
|
homepage: pingme.lmno.pk
|
||||||
description: PingMe is a CLI tool which provides the ability to send messages or alerts to multiple messaging platforms.
|
description: PingMe is a CLI tool which provides the ability to send messages or alerts to multiple messaging platforms.
|
||||||
license: MIT
|
license: MIT
|
||||||
@ -65,21 +73,11 @@ nfpms:
|
|||||||
dependencies:
|
dependencies:
|
||||||
- git
|
- git
|
||||||
|
|
||||||
# # snapcrafts:
|
scoops:
|
||||||
# # - name_template: '{{ .ProjectName }}_{{ .Arch }}{{ if .Arm }}v{{ .Arm }}{{ end }}'
|
- repository:
|
||||||
# # 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
|
owner: kha7iq
|
||||||
name: scoop-bucket
|
name: scoop-bucket
|
||||||
|
url_template: "https://github.com/kha7iq/pingme/releases/download/{{ .Tag }}/{{ .ArtifactName }}"
|
||||||
homepage: https://pingme.lmno.pk
|
homepage: https://pingme.lmno.pk
|
||||||
description: PingMe is a CLI tool which provides the ability to send messages or alerts to multiple messaging platforms.
|
description: PingMe is a CLI tool which provides the ability to send messages or alerts to multiple messaging platforms.
|
||||||
license: MIT
|
license: MIT
|
||||||
|
@ -67,10 +67,10 @@ members of the project's leadership.
|
|||||||
|
|
||||||
## Attribution
|
## Attribution
|
||||||
|
|
||||||
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
|
This Code of Conduct is adapted from the [Contributor Covenant][homepage],
|
||||||
available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html
|
version 1.4, available at <https://www.contributor-covenant.org/version/1/4/code-of-conduct.html>
|
||||||
|
|
||||||
[homepage]: https://www.contributor-covenant.org
|
[homepage]: https://www.contributor-covenant.org
|
||||||
|
|
||||||
For answers to common questions about this code of conduct, see
|
For answers to common questions about this code of conduct, see
|
||||||
https://www.contributor-covenant.org/faq
|
<https://www.contributor-covenant.org/faq>
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
## Contributing to PingMe
|
# Contributing to PingMe
|
||||||
|
|
||||||
We want to make contributing to this project as easy and transparent as
|
We want to make contributing to this project as easy and transparent as
|
||||||
possible.
|
possible.
|
||||||
|
|
||||||
@ -13,26 +14,30 @@ possible.
|
|||||||
- `service/telegram` - Telegram notification service.
|
- `service/telegram` - Telegram notification service.
|
||||||
- `service/pushover` - Pushover Notification service.
|
- `service/pushover` - Pushover Notification service.
|
||||||
|
|
||||||
- Documentation
|
### Documentation
|
||||||
`docs` - Contains the documentation in Markdown format.
|
|
||||||
|
- `docs` - Contains the documentation in Markdown format.
|
||||||
- `services.md` If you are adding a new service please add documentation to `services.md`.
|
- `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.
|
- `home.md` Is the main page rendered when docs website is loaded.
|
||||||
- `install.md` Contains the installation instructions for different packages.
|
- `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.
|
|
||||||
|
|
||||||
Install
|
Docsify is used for documentation rendering from markdown, you can download
|
||||||
```bash
|
the cli and test locally before opening a pull request.
|
||||||
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
|
## Commits
|
||||||
|
|
||||||
@ -43,7 +48,8 @@ are using Conventional Commits.
|
|||||||
|
|
||||||
<type>[<scope>]: <short summary>
|
<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
|
│ └─> Scope (optional): eg. common, compiler, authentication, core
|
||||||
│
|
│
|
||||||
@ -55,19 +61,21 @@ You can follow the documentation on
|
|||||||
[their website](https://www.conventionalcommits.org).
|
[their website](https://www.conventionalcommits.org).
|
||||||
|
|
||||||
## Pull Requests
|
## Pull Requests
|
||||||
|
|
||||||
We actively welcome your pull requests.
|
We actively welcome your pull requests.
|
||||||
|
|
||||||
1. Fork the repo and create your branch from `master`.
|
1. Fork the repo and create your branch from `master`.
|
||||||
2. If you've added code that should be tested, add tests.
|
2. If you've added code that should be tested, add tests.
|
||||||
3. If you've changed APIs, update the documentation.
|
3. If you've changed APIs, update the documentation.
|
||||||
4. Ensure the test suite passes (`make test`).
|
4. Make sure your code lints (`make lint`).
|
||||||
5. Make sure your code lints (`make lint`).
|
5. Make sure your code is well formatted (`make fmt`).
|
||||||
6. Make sure your code is well formatted (`make fmt`).
|
|
||||||
|
|
||||||
## Issues
|
## Issues
|
||||||
|
|
||||||
We use GitHub issues to track public bugs. Please ensure your description is
|
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.
|
clear and has sufficient instructions to be able to reproduce the issue.
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
By contributing to PingMe, you agree that your contributions will be licensed
|
By contributing to PingMe, you agree that your contributions will be licensed
|
||||||
under the LICENSE file in the root directory of this source tree.
|
under the LICENSE file in the root directory of this source tree.
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
MIT License
|
MIT License
|
||||||
|
|
||||||
Copyright (c) 2021 Khaliq
|
Copyright (c) 2021 Abdul Khaliq <a.khaliq@outlook.my>
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
@ -19,3 +19,4 @@ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
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
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
SOFTWARE.
|
SOFTWARE.
|
||||||
|
|
||||||
|
137
README.md
137
README.md
@ -1,3 +1,5 @@
|
|||||||
|
<!-- markdownlint-disable MD033 -->
|
||||||
|
<!-- markdownlint-disable-next-line -->
|
||||||
<h2 align="center">
|
<h2 align="center">
|
||||||
<br>
|
<br>
|
||||||
<p align="center"><img width=30% src="https://raw.githubusercontent.com/kha7iq/pingme/master/.github/img/logo.png"></p>
|
<p align="center"><img width=30% src="https://raw.githubusercontent.com/kha7iq/pingme/master/.github/img/logo.png"></p>
|
||||||
@ -10,15 +12,12 @@
|
|||||||
<img alt="Release" src="https://img.shields.io/github/v/release/kha7iq/pingme">
|
<img alt="Release" src="https://img.shields.io/github/v/release/kha7iq/pingme">
|
||||||
<a href="https://goreportcard.com/report/github.com/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">
|
<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">
|
<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">
|
<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">
|
<a href="https://github.com/kha7iq/pingme/blob/master/LICENSE.md">
|
||||||
<img alt="License" src="https://img.shields.io/github/license/kha7iq/pingme">
|
<img alt="License" src="https://img.shields.io/github/license/kha7iq/pingme">
|
||||||
<a href="#">
|
<a href="https://github.com/agarrharr/awesome-cli-apps#devops">
|
||||||
<img alt="Go Version" src="https://img.shields.io/github/go-mod/go-version/kha7iq/pingme">
|
<img alt="Awesome" src="https://cdn.rawgit.com/sindresorhus/awesome/d7305f38d29fed78fa85652e3a63e154dd8e8829/media/badge.svg">
|
||||||
<a href="https://pkg.go.dev/github.com/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">
|
<img alt="Go Dev Reference" src="https://img.shields.io/badge/go.dev-reference-007d9c?logo=go&logoColor=white&style=flat">
|
||||||
</p>
|
</p>
|
||||||
@ -30,89 +29,135 @@
|
|||||||
<a href="#github-action">Github Action</a> •
|
<a href="#github-action">Github Action</a> •
|
||||||
<a href="#configuration">Configuration</a> •
|
<a href="#configuration">Configuration</a> •
|
||||||
<a href="#contributing">Contributing</a> •
|
<a href="#contributing">Contributing</a> •
|
||||||
<a href="#show-your-support">Show Your Support</a>
|
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## About
|
## About
|
||||||
|
|
||||||
**PingMe** is a personal project to satisfy my needs of having alerts, most major platforms have integration to send alerts
|
**PingMe** is a personal project to satisfy my needs of having alerts, most
|
||||||
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
|
major platforms have integration to send alerts but its not always useful,
|
||||||
which i can just call from my backup scripts, cron jobs, CI/CD pipelines or from anywhere to send a message with particular information.
|
either you are stuck with one particular platform, or you have to do alot of
|
||||||
And i can ship it everywhere with ease.
|
integrations. I needed a small utility which i can just call from my backup scripts,
|
||||||
Hence, the birth of PingMe.
|
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
|
## Supported services
|
||||||
|
|
||||||
- *Discord*
|
- *Discord*
|
||||||
- *Email*
|
- *Email*
|
||||||
- *Microsoft Teams*
|
- *Gotify*
|
||||||
|
- *Line*
|
||||||
|
- *Mastodon*
|
||||||
- *Mattermost*
|
- *Mattermost*
|
||||||
- *Pushover*
|
- *Microsoft Teams*
|
||||||
- *Pushbullet*
|
- *Pushbullet*
|
||||||
|
- *Pushover*
|
||||||
- *RocketChat*
|
- *RocketChat*
|
||||||
- *Slack*
|
- *Slack*
|
||||||
- *Telegram*
|
- *Telegram*
|
||||||
|
- *Textmagic*
|
||||||
- *Twillio*
|
- *Twillio*
|
||||||
|
- *Zulip*
|
||||||
|
- *Wechat*
|
||||||
|
|
||||||
## Install
|
## Install
|
||||||
|
|
||||||
### MacOS & Linux Homebrew
|
### MacOS & Linux Homebrew
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
brew install kha7iq/tap/pingme
|
brew install kha7iq/tap/pingme
|
||||||
```
|
```
|
||||||
|
|
||||||
## Linux Binary
|
|
||||||
|
## 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`
|
||||||
```bash
|
```bash
|
||||||
wget -q https://github.com/kha7iq/pingme/releases/download/v0.1.6/pingme_Linux_x86_64.tar.gz
|
curl -s https://raw.githubusercontent.com/kha7iq/pingme/master/install.sh | sudo sh
|
||||||
tar -xf pingme_Linux_x86_64.tar.gz
|
```
|
||||||
chmod +x pingme
|
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 && \
|
||||||
sudo mv pingme /usr/local/bin/pingme
|
sudo mv pingme /usr/local/bin/pingme
|
||||||
```
|
```
|
||||||
|
|
||||||
### Go Get
|
|
||||||
```bash
|
|
||||||
go get -u github.com/kha7iq/pingme
|
|
||||||
```
|
|
||||||
|
|
||||||
### Windows
|
### Windows
|
||||||
|
|
||||||
```powershell
|
```powershell
|
||||||
scoop bucket add pingme https://github.com/kha7iq/scoop-bucket.git
|
scoop bucket add pingme https://github.com/kha7iq/scoop-bucket.git
|
||||||
scoop install pingme
|
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 `deb`, `rpm` or `binary` for windows & all other supported platforms.
|
||||||
|
|
||||||
### Docker
|
### Docker
|
||||||
|
|
||||||
Docker container is also available on both dockerhub and github container registry.
|
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.
|
`latest` tag will always pull the latest version available, or you can also download
|
||||||
Checkout [release](https://github.com/kha7iq/pingme/releases) page for available versions.
|
specific version. Checkout [release](https://github.com/kha7iq/pingme/releases)
|
||||||
|
page for available versions.
|
||||||
|
|
||||||
Docker Registry
|
Docker Registry
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
docker pull khaliq/pingme:latest
|
docker pull khaliq/pingme:latest
|
||||||
```
|
```
|
||||||
|
|
||||||
Github Registry
|
Github Registry
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
docker pull ghcr.io/kha7iq/pingme:latest
|
docker pull ghcr.io/kha7iq/pingme:latest
|
||||||
```
|
```
|
||||||
|
|
||||||
Run
|
Run
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
docker run ghcr.io/kha7iq/pingme:latest
|
docker run ghcr.io/kha7iq/pingme:latest
|
||||||
```
|
```
|
||||||
|
|
||||||
## Github Action
|
## Github Action
|
||||||
|
|
||||||
A github action is also available now for this app, you can find it on [Github Market Place](https://github.com/marketplace/actions/pingme-action) or from this [repository](https://github.com/kha7iq/pingme-action) on github.
|
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
|
||||||
Usage examples for workflow are available in the repo.
|
here [Github Repo](https://github.com/kha7iq/pingme-action).
|
||||||
|
```yaml
|
||||||
|
- name: PingMe-Action
|
||||||
|
uses: kha7iq/pingme-action@v1
|
||||||
|
```
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
@ -129,7 +174,8 @@ DESCRIPTION:
|
|||||||
PingMe is a CLI tool which provides the ability to send messages or alerts to multiple
|
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
|
messaging platforms and also email, everything is configurable via environment
|
||||||
variables and command line switches.Currently supported platforms include Slack, Telegram,
|
variables and command line switches.Currently supported platforms include Slack, Telegram,
|
||||||
RocketChat, Discord, Pushover, Mattermost, Microsoft Teams and email address.
|
RocketChat, Discord, Pushover, Mattermost, Pushbullet, Microsoft Teams, Twillio, Mastodon,
|
||||||
|
email address, Line, Gotify and Wechat.
|
||||||
|
|
||||||
COMMANDS:
|
COMMANDS:
|
||||||
telegram Send message to telegram
|
telegram Send message to telegram
|
||||||
@ -141,6 +187,12 @@ COMMANDS:
|
|||||||
email Send an email
|
email Send an email
|
||||||
mattermost Send message to mattermost
|
mattermost Send message to mattermost
|
||||||
pushbullet Send message to pushbullet
|
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
|
help, h Shows a list of commands or help for one command
|
||||||
|
|
||||||
GLOBAL OPTIONS:
|
GLOBAL OPTIONS:
|
||||||
@ -151,17 +203,18 @@ Check [Documentation Page](https://kha7iq.github.io/pingme/#/) for more details.
|
|||||||
|
|
||||||
## Configuration
|
## Configuration
|
||||||
|
|
||||||
All the flags have corresponding environment variables associated with it. You can either provide the value with flags
|
All the flags have corresponding environment variables associated with it. You
|
||||||
or export to a variable.
|
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
|
## 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
|
||||||
|
|
||||||
## Show your support
|
This project is based on amazing library [Notify](https://github.com/nikoksr/notify)
|
||||||
|
|
||||||
Give a ⭐️ if you like this project!
|
|
||||||
|
Binary file not shown.
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 16 KiB |
@ -1,4 +1,5 @@
|
|||||||
<!-- docs/_sidebar.md -->
|
<!-- docs/_sidebar.md -->
|
||||||
|
<!-- markdownlint-disable MD041 -->
|
||||||
|
|
||||||
* [Home](/)
|
* [Home](/)
|
||||||
* [Installation](install.md)
|
* [Installation](install.md)
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
## Contributing to PingMe
|
# Contributing to PingMe
|
||||||
|
|
||||||
We want to make contributing to this project as easy and transparent as
|
We want to make contributing to this project as easy and transparent as
|
||||||
possible.
|
possible.
|
||||||
|
|
||||||
@ -12,27 +13,33 @@ possible.
|
|||||||
- `service/slack` - Slack notification service.
|
- `service/slack` - Slack notification service.
|
||||||
- `service/telegram` - Telegram notification service.
|
- `service/telegram` - Telegram notification service.
|
||||||
- `service/pushover` - Pushover Notification service.
|
- `service/pushover` - Pushover Notification service.
|
||||||
|
- `service/line` - Line notification service.
|
||||||
|
- `service/wechat` - Wechat Official Account notification service.
|
||||||
|
|
||||||
- Documentation
|
### Documentation
|
||||||
`docs` - Contains the documentation in Markdown format.
|
|
||||||
|
- `docs` - Contains the documentation in Markdown format.
|
||||||
- `services.md` If you are adding a new service please add documentation to `services.md`.
|
- `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.
|
- `home.md` Is the main page rendered when docs website is loaded.
|
||||||
- `install.md` Contains the installation instructions for different packages.
|
- `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.
|
|
||||||
|
|
||||||
Install
|
Docsify is used for documentation rendering from markdown, you can download the
|
||||||
```bash
|
cli and test locally before opening a pull request.
|
||||||
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
|
## Commits
|
||||||
|
|
||||||
@ -43,7 +50,8 @@ are using Conventional Commits.
|
|||||||
|
|
||||||
<type>[<scope>]: <short summary>
|
<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
|
│ └─> Scope (optional): eg. common, compiler, authentication, core
|
||||||
│
|
│
|
||||||
@ -55,6 +63,7 @@ You can follow the documentation on
|
|||||||
[their website](https://www.conventionalcommits.org).
|
[their website](https://www.conventionalcommits.org).
|
||||||
|
|
||||||
## Pull Requests
|
## Pull Requests
|
||||||
|
|
||||||
We actively welcome your pull requests.
|
We actively welcome your pull requests.
|
||||||
|
|
||||||
1. Fork the repo and create your branch from `master`.
|
1. Fork the repo and create your branch from `master`.
|
||||||
@ -65,9 +74,11 @@ We actively welcome your pull requests.
|
|||||||
6. Make sure your code is well formatted (`make fmt`).
|
6. Make sure your code is well formatted (`make fmt`).
|
||||||
|
|
||||||
## Issues
|
## Issues
|
||||||
|
|
||||||
We use GitHub issues to track public bugs. Please ensure your description is
|
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.
|
clear and has sufficient instructions to be able to reproduce the issue.
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
By contributing to PingMe, you agree that your contributions will be licensed
|
By contributing to PingMe, you agree that your contributions will be licensed
|
||||||
under the LICENSE file in the root directory of this source tree.
|
under the LICENSE file in the root directory of this source tree.
|
||||||
|
50
docs/home.md
50
docs/home.md
@ -1,3 +1,5 @@
|
|||||||
|
<!-- markdownlint-disable MD033 -->
|
||||||
|
<!-- markdownlint-disable-next-line -->
|
||||||
<h2 align="center">
|
<h2 align="center">
|
||||||
<br>
|
<br>
|
||||||
<p align="center"><img width=20% src="https://raw.githubusercontent.com/kha7iq/pingme/master/.github/img/logo.png"></p>
|
<p align="center"><img width=20% src="https://raw.githubusercontent.com/kha7iq/pingme/master/.github/img/logo.png"></p>
|
||||||
@ -32,48 +34,58 @@
|
|||||||
|
|
||||||
## About
|
## About
|
||||||
|
|
||||||
**PingMe** is a personal project to satisfy my needs of having alerts, most major platforms have integration to send alerts
|
**PingMe** is a personal project to satisfy my needs of having alerts, most
|
||||||
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
|
major platforms have integration to send alerts but it's not always useful,
|
||||||
which i can just call from my backup scripts, cron jobs, CI/CD pipelines or from anywhere to send a message with particular information.
|
either you are stuck with one particular platform, or you have to do alot of
|
||||||
And i can ship it everywhere with ease.
|
integrations. I needed a small app which i can just call from my backup scripts,
|
||||||
Hence, the birth of PingMe.
|
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
|
## Supported services
|
||||||
|
|
||||||
- *Discord*
|
- *Discord*
|
||||||
- *Email*
|
- *Email*
|
||||||
- *Microsoft Teams*
|
- *Gotify*
|
||||||
|
- *Line*
|
||||||
|
- *Mastodon*
|
||||||
- *Mattermost*
|
- *Mattermost*
|
||||||
- *Pushover*
|
- *Matrix*
|
||||||
|
- *Microsoft Teams*
|
||||||
- *Pushbullet*
|
- *Pushbullet*
|
||||||
|
- *Pushover*
|
||||||
- *RocketChat*
|
- *RocketChat*
|
||||||
- *Slack*
|
- *Slack*
|
||||||
- *Telegram*
|
- *Telegram*
|
||||||
|
- *Textmagic*
|
||||||
- *Twillio*
|
- *Twillio*
|
||||||
|
- *Zulip*
|
||||||
|
- *Wechat*
|
||||||
|
|
||||||
## Demo
|
## Demo
|
||||||

|
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
## Contributing
|
## 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 [contribution guide](contribution.md).
|
Contributions, issues and feature requests are welcome!
|
||||||
|
|
||||||
|
|
||||||
|
Feel free to check [issues page](https://github.com/kha7iq/pingme/issues).
|
||||||
|
You can also take a look at the [contribution guide](contribution.md).
|
||||||
|
|
||||||
## Show your support
|
## Show your support
|
||||||
|
|
||||||
Give a ⭐️ if you like this project!
|
Give a ⭐️ if you like this project!
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## Disclaimer
|
## 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.
|
||||||
|
@ -6,7 +6,6 @@
|
|||||||
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
|
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
|
||||||
<meta name="description" content="Description">
|
<meta name="description" content="Description">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0">
|
<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
|
<link
|
||||||
rel="stylesheet"
|
rel="stylesheet"
|
||||||
href="//cdn.jsdelivr.net/npm/docsify-darklight-theme@latest/dist/style.min.css"
|
href="//cdn.jsdelivr.net/npm/docsify-darklight-theme@latest/dist/style.min.css"
|
||||||
@ -19,11 +18,31 @@
|
|||||||
<script>
|
<script>
|
||||||
window.$docsify = {
|
window.$docsify = {
|
||||||
homepage: 'home.md',
|
homepage: 'home.md',
|
||||||
|
siteFont : 'Source Sans Pro',
|
||||||
|
defaultTheme : 'light | dark',
|
||||||
|
codeFontFamily : 'monospace',
|
||||||
logo: '/_media/logo.png',
|
logo: '/_media/logo.png',
|
||||||
loadSidebar: true,
|
loadSidebar: true,
|
||||||
subMaxLevel: 2,
|
subMaxLevel: 2,
|
||||||
name: 'PingMe',
|
name: 'PingMe',
|
||||||
repo: 'https://github.com/kha7iq/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'
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
<!-- Docsify v4 -->
|
<!-- Docsify v4 -->
|
||||||
@ -32,5 +51,7 @@
|
|||||||
src="//cdn.jsdelivr.net/npm/docsify-darklight-theme@latest/dist/index.min.js"
|
src="//cdn.jsdelivr.net/npm/docsify-darklight-theme@latest/dist/index.min.js"
|
||||||
type="text/javascript">
|
type="text/javascript">
|
||||||
</script>
|
</script>
|
||||||
|
<script src="//unpkg.com/prismjs/components/prism-bash.min.js"></script>
|
||||||
|
<script src="//unpkg.com/prismjs/components/prism-yaml.min.js "></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
@ -1,53 +1,82 @@
|
|||||||
|
# Installation
|
||||||
|
|
||||||
## MacOS & Linux Homebrew
|
## MacOS & Linux Homebrew
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
brew install kha7iq/tap/pingme
|
brew install kha7iq/tap/pingme
|
||||||
```
|
```
|
||||||
|
|
||||||
## Linux Binary
|
## 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`
|
||||||
```bash
|
```bash
|
||||||
wget -q https://github.com/kha7iq/pingme/releases/download/v0.1.6/pingme_Linux_x86_64.tar.gz
|
curl -s https://raw.githubusercontent.com/kha7iq/pingme/master/install.sh | sudo sh
|
||||||
tar -xf pingme_Linux_x86_64.tar.gz
|
```
|
||||||
chmod +x pingme
|
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 && \
|
||||||
sudo mv pingme /usr/local/bin/pingme
|
sudo mv pingme /usr/local/bin/pingme
|
||||||
```
|
```
|
||||||
|
|
||||||
## Go Get
|
|
||||||
```bash
|
|
||||||
go get -u github.com/kha7iq/pingme
|
|
||||||
```
|
|
||||||
|
|
||||||
|
|
||||||
## Windows
|
## Windows
|
||||||
|
|
||||||
```powershell
|
```powershell
|
||||||
scoop bucket add pingme https://github.com/kha7iq/scoop-bucket.git
|
scoop bucket add pingme https://github.com/kha7iq/scoop-bucket.git
|
||||||
scoop install pingme
|
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
|
||||||
|
|
||||||
Docker container is also available on both dockerhub and github container registry.
|
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.
|
`latest` tage will always pull the latest version avaialbe, you can also
|
||||||
Checkout [release](https://github.com/kha7iq/pingme/releases) page for available versions.
|
download specific version. Checkout [release](https://github.com/kha7iq/pingme/releases)
|
||||||
|
page for available versions.
|
||||||
|
|
||||||
- Docker Registry
|
- Docker Registry
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
docker pull khaliq/pingme:latest
|
docker pull khaliq/pingme:latest
|
||||||
```
|
```
|
||||||
|
|
||||||
- GitHub Registry
|
- GitHub Registry
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
docker pull ghcr.io/kha7iq/pingme:latest
|
docker pull ghcr.io/kha7iq/pingme:latest
|
||||||
```
|
```
|
||||||
|
|
||||||
- Run
|
- Run
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
docker run ghcr.io/kha7iq/pingme:latest
|
docker run ghcr.io/kha7iq/pingme:latest
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
## GitHub Action
|
## GitHub Action
|
||||||
A github action is also available now for this app, you can find it on [Github Market Place](https://github.com/marketplace/actions/pingme-action) or from this [repository](https://github.com/kha7iq/pingme-action) on github.
|
|
||||||
|
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 examples for workflow are available in the repo.
|
||||||
|
660
docs/services.md
660
docs/services.md
@ -1,22 +1,23 @@
|
|||||||
|
# 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.
|
||||||
|
|
||||||
### Configuration
|
*Flags* take precedence over *variables*
|
||||||
|
|
||||||
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*
|
*Default* value for message title is current *time*
|
||||||
|
|
||||||
|
|
||||||
## Telegram
|
## Telegram
|
||||||
|
|
||||||
Telegram uses bot token to authenticate & send messages to defined channels.
|
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
|
```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
|
- GitHub Action
|
||||||
@ -45,25 +46,79 @@ jobs:
|
|||||||
# slack / telegram / rocketchat / teams / pushover / discord / email
|
# slack / telegram / rocketchat / teams / pushover / discord / email
|
||||||
service: telegram
|
service: telegram
|
||||||
```
|
```
|
||||||
|
|
||||||
- **Variables**
|
- **Variables**
|
||||||
|
|
||||||
|
| Variables | Default Value |
|
||||||
| Variables | Default Value |
|
|
||||||
| -------------------------- | :----------------: |
|
| -------------------------- | :----------------: |
|
||||||
| TELEGRAM_MSG_TITLE | "" |
|
| TELEGRAM_TITLE | "" |
|
||||||
| TELEGRAM_TOKEN | "" |
|
| TELEGRAM_TOKEN | "" |
|
||||||
| TELEGRAM_CHANNELS | "" |
|
| TELEGRAM_CHANNELS | "" |
|
||||||
| TELEGRAM_MESSAGE | "" |
|
| TELEGRAM_MESSAGE | "" |
|
||||||
| TELEGRAM_MSG_TITLE | "" |
|
|
||||||
|
|
||||||
|
## Gotify
|
||||||
|
|
||||||
## RocketChat
|
With gotify you can send push messages to any instance of Gotify server.
|
||||||
RocketChat uses token & userID to authenticate and send messages to defined channels.
|
|
||||||
Multiple channel ids can be used separated by comma ','.
|
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
pingme rocketchat --channel "general,Pingme" --msg ":wave: rocketchat from cli" --userid "123" --token "abcxyz" \
|
pingme gotify \
|
||||||
--url 'localhost:3000' --scheme "http"
|
--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 ','.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
pingme rocketchat \
|
||||||
|
--channel "general,Pingme" \
|
||||||
|
--msg ":wave: rocketchat from cli" \
|
||||||
|
--userid "123" \
|
||||||
|
--token "abcxyz" \
|
||||||
|
--url 'localhost:3000' \
|
||||||
|
--scheme "http"
|
||||||
```
|
```
|
||||||
|
|
||||||
- Github Action
|
- Github Action
|
||||||
@ -92,26 +147,31 @@ jobs:
|
|||||||
ROCKETCHAT_MESSAGE: 'Event is triggered by ${{ github.event_name }}'
|
ROCKETCHAT_MESSAGE: 'Event is triggered by ${{ github.event_name }}'
|
||||||
with:
|
with:
|
||||||
# Chose the messaging platform.
|
# Chose the messaging platform.
|
||||||
# slack / telegram / rocketchat / teams / pushover / discord / email / mattermost
|
# slack / telegram / rocketchat / teams /
|
||||||
|
# pushover / discord / email / mattermost
|
||||||
service: rocketchat
|
service: rocketchat
|
||||||
```
|
```
|
||||||
|
|
||||||
- **Variables**
|
- **Variables**
|
||||||
|
|
||||||
| Variables | Default Value |
|
| Variables | Default Value |
|
||||||
| -------------------------- | :----------------: |
|
| -------------------------- | :----------------: |
|
||||||
| ROCKETCHAT_USERID | "" |
|
| ROCKETCHAT_USERID | "" |
|
||||||
| ROCKETCHAT_TOKEN | "" |
|
| ROCKETCHAT_TOKEN | "" |
|
||||||
| ROCKETCHAT_SERVER_URL | "" |
|
| ROCKETCHAT_SERVER_URL | "" |
|
||||||
| ROCKETCHAT_URL_SCHEME | "https" |
|
| ROCKETCHAT_URL_SCHEME | "https" |
|
||||||
| RTOCKETCHAT_MESSAGE | "" |
|
| RTOCKETCHAT_MESSAGE | "" |
|
||||||
| ROCKETCHAT_TITLE | "" |
|
| ROCKETCHAT_TITLE | "" |
|
||||||
| ROCKETCHAT_CHANNELS | "" |
|
| ROCKETCHAT_CHANNELS | "" |
|
||||||
|
|
||||||
|
|
||||||
## Pushover
|
## Pushover
|
||||||
|
|
||||||
```bash
|
```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
|
- GitHub Action
|
||||||
@ -137,28 +197,35 @@ jobs:
|
|||||||
|
|
||||||
with:
|
with:
|
||||||
# Chose the messaging platform.
|
# Chose the messaging platform.
|
||||||
# slack / telegram / rocketchat / teams / pushover / discord / email
|
# slack / telegram / rocketchat / teams /
|
||||||
|
# pushover / discord / email
|
||||||
service: pushover
|
service: pushover
|
||||||
```
|
```
|
||||||
|
|
||||||
- **Variables**
|
- **Variables**
|
||||||
|
|
||||||
| Variables | Default Value |
|
| Variables | Default Value |
|
||||||
| -------------------------- | :----------------: |
|
| -------------------------- | :----------------: |
|
||||||
| PUSHOVER_TOKEN | "" |
|
| PUSHOVER_TOKEN | "" |
|
||||||
| PUSHOVER_USER | "" |
|
| PUSHOVER_USER | "" |
|
||||||
| PUSHOVER_MESSAGE | "" |
|
| PUSHOVER_MESSAGE | "" |
|
||||||
| PUSHOVER_TITLE | "" |
|
| PUSHOVER_TITLE | "" |
|
||||||
|
|
||||||
## Mattermost
|
## 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
|
Mattermost uses token to authenticate and channel IDs for targets. Destination
|
||||||
can change this with --scheme flag and set it to 'http'.
|
server can be specified as 'example.com' by default the 'https' is used, you
|
||||||
Latest api version 4 is used for interacting with server, this can also be changes with --api flag.
|
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.
|
||||||
You can specify multiple channels by separating the value with ','.
|
You can specify multiple channels by separating the value with ','.
|
||||||
|
|
||||||
```bash
|
```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
|
- GitHub Action
|
||||||
@ -181,33 +248,37 @@ jobs:
|
|||||||
MATTERMOST_TOKEN: ${{ secrets.MATTERMOST_TOKEN }}
|
MATTERMOST_TOKEN: ${{ secrets.MATTERMOST_TOKEN }}
|
||||||
MATTERMOST_SERVER_URL: ${{ secrets.MATTERMOST_SERVER_URL }}
|
MATTERMOST_SERVER_URL: ${{ secrets.MATTERMOST_SERVER_URL }}
|
||||||
MATTERMOST_CHANNELS: ${{ secrets.MATTERMOST_CHANNELS }}
|
MATTERMOST_CHANNELS: ${{ secrets.MATTERMOST_CHANNELS }}
|
||||||
MATTERMOST_CHANNELS: ${{ secrets.MATTERMOST_CHANNELS }}
|
|
||||||
MATTERMOST_TITLE: 'Reference: ${{ github.ref }}'
|
MATTERMOST_TITLE: 'Reference: ${{ github.ref }}'
|
||||||
MATTERMOST_MESSAGE: 'Event is triggered by ${{ github.event_name }}'
|
MATTERMOST_MESSAGE: 'Event is triggered by ${{ github.event_name }}'
|
||||||
with:
|
with:
|
||||||
# Chose the messaging platform.
|
# Chose the messaging platform.
|
||||||
# slack / telegram / rocketchat / teams / pushover / discord / email / mattermost
|
# slack / telegram / rocketchat / teams /
|
||||||
|
# pushover / discord / email / mattermost
|
||||||
service: mattermost
|
service: mattermost
|
||||||
```
|
```
|
||||||
|
|
||||||
- **Variables**
|
- **Variables**
|
||||||
|
|
||||||
| Variables | Default Value |
|
| Variables | Default Value |
|
||||||
| -------------------------- | :----------------: |
|
| -------------------------- | :----------------: |
|
||||||
| MATTERMOST_API_URL | "/api/v4/posts" |
|
| MATTERMOST_API_URL | "/api/v4/posts" |
|
||||||
| MATTERMOST_TOKEN | "" |
|
| MATTERMOST_TOKEN | "" |
|
||||||
| MATTERMOST_SERVER_URL | "" |
|
| MATTERMOST_SERVER_URL | "" |
|
||||||
| MATTERMOST_SCHEME | "https" |
|
| MATTERMOST_SCHEME | "https" |
|
||||||
| MATTERMOST_MESSAGE | "" |
|
| MATTERMOST_MESSAGE | "" |
|
||||||
| MATTERMOST_TITLE | "" |
|
| MATTERMOST_TITLE | "" |
|
||||||
| MATTERMOST_CHANNELS | "" |
|
| MATTERMOST_CHANNELS | "" |
|
||||||
|
|
||||||
## Slack
|
## Slack
|
||||||
|
|
||||||
Slack uses token to authenticate and send messages to defined channels.
|
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
|
```bash
|
||||||
pingme slack --token '123' --channel '1234567890' --msg 'some message'
|
pingme slack \
|
||||||
|
--token '123' \
|
||||||
|
--channel '1234567890' \
|
||||||
|
--msg 'some message'
|
||||||
```
|
```
|
||||||
|
|
||||||
- Github Action
|
- Github Action
|
||||||
@ -233,25 +304,29 @@ jobs:
|
|||||||
SLACK_MESSAGE: 'Event is triggered by ${{ github.event_name }}'
|
SLACK_MESSAGE: 'Event is triggered by ${{ github.event_name }}'
|
||||||
with:
|
with:
|
||||||
# Chose the messaging platform.
|
# Chose the messaging platform.
|
||||||
# slack / telegram / rocketchat / teams / pushover / discord / email
|
# slack / telegram / rocketchat / teams /
|
||||||
|
# pushover / discord / email
|
||||||
service: slack
|
service: slack
|
||||||
```
|
```
|
||||||
|
|
||||||
- **Variables**
|
- **Variables**
|
||||||
|
|
||||||
| Variables | Default Value |
|
| Variables | Default Value |
|
||||||
| -------------------------- | :----------------: |
|
| -------------------------- | :----------------: |
|
||||||
| SLACK_TOKEN | "" |
|
| SLACK_TOKEN | "" |
|
||||||
| SLACK_CHANNELS | "" |
|
| SLACK_CHANNELS | "" |
|
||||||
| SLACK_MESSAGE | "" |
|
| SLACK_MESSAGE | "" |
|
||||||
|
|
||||||
|
|
||||||
## Discord
|
## Discord
|
||||||
|
|
||||||
Discord uses bot token to authenticate & send messages to defined channels.
|
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
|
```bash
|
||||||
pingme discord --token '123' --channel '1234567890' --msg 'some message'
|
pingme discord \
|
||||||
|
--token '123' \
|
||||||
|
--channel '1234567890' \
|
||||||
|
--msg 'some message'
|
||||||
```
|
```
|
||||||
|
|
||||||
- GitHub Action
|
- GitHub Action
|
||||||
@ -277,25 +352,29 @@ jobs:
|
|||||||
DISCORD_MESSAGE: 'Event is triggered by ${{ github.event_name }}'
|
DISCORD_MESSAGE: 'Event is triggered by ${{ github.event_name }}'
|
||||||
with:
|
with:
|
||||||
# Chose the messaging platform.
|
# Chose the messaging platform.
|
||||||
# slack / telegram / rocketchat / teams / pushover / discord / email / mattermost
|
# slack / telegram / rocketchat / teams /
|
||||||
|
# pushover / discord / email / mattermost
|
||||||
service: discord
|
service: discord
|
||||||
```
|
```
|
||||||
|
|
||||||
- **Variables**
|
- **Variables**
|
||||||
|
|
||||||
| Variables | Default Value |
|
| Variables | Default Value |
|
||||||
| -------------------------- | :----------------: |
|
| -------------------------- | :----------------: |
|
||||||
| DISCORD_TOKEN | "" |
|
| DISCORD_TOKEN | "" |
|
||||||
| DISCORD_CHANNELS | "" |
|
| DISCORD_CHANNELS | "" |
|
||||||
| DISCORD_MESSAGE | "" |
|
| DISCORD_MESSAGE | "" |
|
||||||
| DISCORD_MSG_TITLE | "" |
|
| DISCORD_MSG_TITLE | "" |
|
||||||
|
|
||||||
|
|
||||||
## Microsoft Teams
|
## 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
|
```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
|
- GitHub Action
|
||||||
@ -320,27 +399,36 @@ jobs:
|
|||||||
|
|
||||||
with:
|
with:
|
||||||
# Chose the messaging platform.
|
# Chose the messaging platform.
|
||||||
# slack / telegram / rocketchat / teams / pushover / discord / email / mattermost
|
# slack / telegram / rocketchat / teams /
|
||||||
|
# pushover / discord / email / mattermost
|
||||||
service: teams
|
service: teams
|
||||||
```
|
```
|
||||||
|
|
||||||
- **Variables**
|
- **Variables**
|
||||||
|
|
||||||
| Variables | Default Value |
|
| Variables | Default Value |
|
||||||
| -------------------------- | :----------------: |
|
| -------------------------- | :----------------: |
|
||||||
| TEAMS_WEBHOOK | "" |
|
| TEAMS_WEBHOOK | "" |
|
||||||
| TEAMS_MESSAGE | "" |
|
| TEAMS_MESSAGE | "" |
|
||||||
| TEAMS_MSG_TITLE | "" |
|
| TEAMS_MSG_TITLE | "" |
|
||||||
|
|
||||||
## Pushbullet
|
## Pushbullet
|
||||||
|
|
||||||
- SMS
|
- SMS
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
pingme pushbullet --sms true --token "abcdefg" -d "adnroid" --msg "some message" --number "00123456789"
|
pingme pushbullet \
|
||||||
|
--sms true \
|
||||||
|
--token "abcdefg" \
|
||||||
|
-d "android" \
|
||||||
|
--msg "some message" \
|
||||||
|
--number "00123456789"
|
||||||
```
|
```
|
||||||
|
|
||||||
- Push notification
|
- Push notification
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
pingme pushbullet --token "abcdefg" -d "adnroid" --msg "some message"
|
pingme pushbullet --token "abcdefg" -d "android" --msg "some message"
|
||||||
```
|
```
|
||||||
|
|
||||||
- GitHub Action
|
- GitHub Action
|
||||||
@ -366,28 +454,34 @@ jobs:
|
|||||||
|
|
||||||
with:
|
with:
|
||||||
# Chose the messaging platform.
|
# Chose the messaging platform.
|
||||||
# slack / telegram / rocketchat / teams / pushover / discord / email
|
# slack / telegram / rocketchat / teams /
|
||||||
|
# pushover / discord / email
|
||||||
service: pushbullet
|
service: pushbullet
|
||||||
```
|
```
|
||||||
|
|
||||||
- **Variables**
|
- **Variables**
|
||||||
|
|
||||||
| Variables | Default Value |
|
| Variables | Default Value |
|
||||||
| -------------------------- | :----------------: |
|
| -------------------------- | :----------------: |
|
||||||
| PUSHBULLET_TOKEN | "" |
|
| PUSHBULLET_TOKEN | "" |
|
||||||
| PUSHBULLET_DEVICE | "" |
|
| PUSHBULLET_DEVICE | "" |
|
||||||
| PUSHBULLET_NUMBER | "" |
|
| PUSHBULLET_NUMBER | "" |
|
||||||
| PUSHBULLET_MESSAGE | "" |
|
| PUSHBULLET_MESSAGE | "" |
|
||||||
| PUSHBULLET_SMS | "false" |
|
| PUSHBULLET_SMS | "false" |
|
||||||
| PUSHBULLET_TITLE | "" |
|
| PUSHBULLET_TITLE | "" |
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## Twillio SMS
|
## 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
|
```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
|
- GitHub Action
|
||||||
@ -414,40 +508,370 @@ jobs:
|
|||||||
TWILLIO_MESSAGE: 'Event is triggered by ${{ github.event_name }}'
|
TWILLIO_MESSAGE: 'Event is triggered by ${{ github.event_name }}'
|
||||||
with:
|
with:
|
||||||
# Chose the messaging platform.
|
# Chose the messaging platform.
|
||||||
# slack / telegram / rocketchat / teams / pushover / discord / email / mattermost / twillio
|
# slack / telegram / rocketchat / teams /
|
||||||
|
# pushover / discord / email / mattermost / twillio
|
||||||
service: twillio
|
service: twillio
|
||||||
```
|
```
|
||||||
|
|
||||||
- **Variables**
|
- **Variables**
|
||||||
|
|
||||||
| Variables | Default Value |
|
| Variables | Default Value |
|
||||||
| -------------------------- | :----------------: |
|
| -------------------------- | :----------------: |
|
||||||
| TWILLIO_TOKEN | "" |
|
| TWILLIO_TOKEN | "" |
|
||||||
| TWILLIO_ACCOUNT_SID | "" |
|
| TWILLIO_ACCOUNT_SID | "" |
|
||||||
| TWILLIO_SENDER | "" |
|
| TWILLIO_SENDER | "" |
|
||||||
| TWILLIO_RECEIVER | "" |
|
| TWILLIO_RECEIVER | "" |
|
||||||
| TWILLIO_TITLE | "" |
|
| TWILLIO_TITLE | "" |
|
||||||
| TWILLIO_MESSAGE | "" |
|
| TWILLIO_MESSAGE | "" |
|
||||||
|
|
||||||
## Email
|
## Mastodon
|
||||||
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.
|
Mastodon uses application token to authorize and set status.
|
||||||
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
|
```bash
|
||||||
pingme email --rec "example@gmail.com,example@outlook.com" --msg "This is an email from PingMe CLI" --sub "Email from PingMe CLI" \
|
mastodon --url "mastodon.social" --msg "some message" --title "PingMe CLI" --token "123"
|
||||||
--sender "sender@gmail.com" --host "smtp.gmail.com" --port "587" --pass "secretPassword"
|
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
- 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**
|
||||||
|
|
||||||
| Variables | Default Value |
|
| Variables | Default Value |
|
||||||
| -------------------------- | :----------------: |
|
| -------------------------- | :----------------: |
|
||||||
| EMAIL_SENDER | "" |
|
| MASTODON_TOKEN | "" |
|
||||||
| EMAIL_PASSWORD | "" |
|
| MASTODON_SERVER | "" |
|
||||||
| EMAIL_RECEIVER | "" |
|
| MASTODON_TITLE | "" |
|
||||||
| EMAIL_IDENTITY | "" |
|
| MASTODON_MESSAGE | "" |
|
||||||
| EMAIL_HOST | "smtp.gmail.com" |
|
|
||||||
| EMAIL_PORT | "587" |
|
## Zulip
|
||||||
| EMAIL_MESSAGE | "" |
|
|
||||||
| EMAIL_SUBJECT | "" |
|
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 | "" |
|
||||||
|
|
||||||
|
## 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.
|
||||||
|
|
||||||
|
```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"
|
||||||
|
```
|
||||||
|
|
||||||
|
- **Variables**
|
||||||
|
|
||||||
|
| 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 | "" |
|
||||||
|
28
go.mod
28
go.mod
@ -3,10 +3,26 @@ module github.com/kha7iq/pingme
|
|||||||
go 1.16
|
go 1.16
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/cpuguy83/go-md2man/v2 v2.0.0 // indirect
|
github.com/RocketChat/Rocket.Chat.Go.SDK v0.0.0-20220708192748-b73dcb041214 // indirect
|
||||||
github.com/gregdel/pushover v0.0.0-20210216095829-2131362cb888
|
github.com/go-openapi/analysis v0.21.3 // indirect
|
||||||
github.com/nikoksr/notify v0.15.0
|
github.com/go-openapi/runtime v0.24.1 // indirect
|
||||||
github.com/russross/blackfriday/v2 v2.1.0 // indirect
|
github.com/go-openapi/spec v0.20.6 // indirect
|
||||||
github.com/sfreiberg/gotwilio v0.0.0-20201211181435-c426a3710ab5 // indirect
|
github.com/go-openapi/strfmt v0.21.3 // indirect
|
||||||
github.com/urfave/cli/v2 v2.3.0
|
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
|
||||||
)
|
)
|
||||||
|
81
install.sh
Executable file
81
install.sh
Executable file
@ -0,0 +1,81 @@
|
|||||||
|
#!/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
18
main.go
@ -1,13 +1,21 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"github.com/kha7iq/pingme/service/matrix"
|
||||||
"log"
|
"log"
|
||||||
"os"
|
"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/twillio"
|
||||||
|
"github.com/kha7iq/pingme/service/wechat"
|
||||||
|
"github.com/kha7iq/pingme/service/zulip"
|
||||||
|
|
||||||
"github.com/kha7iq/pingme/service/discord"
|
"github.com/kha7iq/pingme/service/discord"
|
||||||
"github.com/kha7iq/pingme/service/email"
|
"github.com/kha7iq/pingme/service/email"
|
||||||
|
"github.com/kha7iq/pingme/service/line"
|
||||||
"github.com/kha7iq/pingme/service/mattermost"
|
"github.com/kha7iq/pingme/service/mattermost"
|
||||||
"github.com/kha7iq/pingme/service/msteams"
|
"github.com/kha7iq/pingme/service/msteams"
|
||||||
"github.com/kha7iq/pingme/service/pushbullet"
|
"github.com/kha7iq/pingme/service/pushbullet"
|
||||||
@ -31,7 +39,8 @@ func main() {
|
|||||||
app.Description = `PingMe is a CLI tool which provides the ability to send messages or alerts to multiple
|
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
|
messaging platforms and also email, everything is configurable via environment
|
||||||
variables and command line switches.Currently supported platforms include Slack, Telegram,
|
variables and command line switches.Currently supported platforms include Slack, Telegram,
|
||||||
RocketChat, Discord, Pushover, Mattermost, Pushbullet, Microsoft Teams and email address.`
|
RocketChat, Discord, Pushover, Mattermost, Pushbullet, Microsoft Teams, Twillio, Mastodon,
|
||||||
|
email address, Line, Gotify and Wechat.`
|
||||||
// app.Commands contains the subcommands as functions which return []*cli.Command.
|
// app.Commands contains the subcommands as functions which return []*cli.Command.
|
||||||
app.Commands = []*cli.Command{
|
app.Commands = []*cli.Command{
|
||||||
telegram.Send(),
|
telegram.Send(),
|
||||||
@ -44,6 +53,13 @@ RocketChat, Discord, Pushover, Mattermost, Pushbullet, Microsoft Teams and email
|
|||||||
mattermost.Send(),
|
mattermost.Send(),
|
||||||
pushbullet.Send(),
|
pushbullet.Send(),
|
||||||
twillio.Send(),
|
twillio.Send(),
|
||||||
|
zulip.Send(),
|
||||||
|
mastodon.Send(),
|
||||||
|
line.Send(),
|
||||||
|
wechat.Send(),
|
||||||
|
gotify.Send(),
|
||||||
|
textmagic.Send(),
|
||||||
|
matrix.Send(),
|
||||||
}
|
}
|
||||||
|
|
||||||
err := app.Run(os.Args)
|
err := app.Run(os.Args)
|
||||||
|
97
service/gotify/gotify.go
Normal file
97
service/gotify/gotify.go
Normal file
@ -0,0 +1,97 @@
|
|||||||
|
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
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
100
service/line/line.go
Normal file
100
service/line/line.go
Normal file
@ -0,0 +1,100 @@
|
|||||||
|
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
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
138
service/mastodon/mastodon.go
Normal file
138
service/mastodon/mastodon.go
Normal file
@ -0,0 +1,138 @@
|
|||||||
|
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
|
||||||
|
}
|
81
service/mastodon/mastodon_test.go
Normal file
81
service/mastodon/mastodon_test.go
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
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)
|
||||||
|
}
|
221
service/matrix/matrix.go
Normal file
221
service/matrix/matrix.go
Normal file
@ -0,0 +1,221 @@
|
|||||||
|
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
|
||||||
|
}
|
@ -49,6 +49,19 @@ type matterMostResponse struct {
|
|||||||
Metadata struct{} `json:"metadata"`
|
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
|
// Send parse values from *cli.context and return *cli.Command
|
||||||
// and send messages to target channels.
|
// and send messages to target channels.
|
||||||
// If multiple channel ids are provided then the string is split with "," separator and
|
// If multiple channel ids are provided then the string is split with "," separator and
|
||||||
@ -118,6 +131,7 @@ You can specify multiple channels by separating the value with ','.`,
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
Action: func(ctx *cli.Context) error {
|
Action: func(ctx *cli.Context) error {
|
||||||
|
initialize()
|
||||||
endPointURL := mattermostOpts.Scheme + "://" + mattermostOpts.ServerURL + mattermostOpts.APIURL
|
endPointURL := mattermostOpts.Scheme + "://" + mattermostOpts.ServerURL + mattermostOpts.APIURL
|
||||||
|
|
||||||
// Create a Bearer string by appending string access token
|
// Create a Bearer string by appending string access token
|
||||||
@ -173,9 +187,7 @@ func sendMattermost(url string, token string, jsonPayload []byte) error {
|
|||||||
req.Header.Set("Authorization", token)
|
req.Header.Set("Authorization", token)
|
||||||
req.Header.Set("Content-Type", "application/json; charset=UTF-8")
|
req.Header.Set("Content-Type", "application/json; charset=UTF-8")
|
||||||
|
|
||||||
// create a new http client and send request to server
|
resp, err := Client.Do(req)
|
||||||
c := &http.Client{Timeout: 10 * time.Second}
|
|
||||||
resp, err := c.Do(req)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
73
service/mattermost/mattermost_test.go
Normal file
73
service/mattermost/mattermost_test.go
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
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)
|
||||||
|
}
|
||||||
|
}
|
@ -16,6 +16,7 @@ type pushOver struct {
|
|||||||
Recipient string
|
Recipient string
|
||||||
Message string
|
Message string
|
||||||
Title string
|
Title string
|
||||||
|
Priority int
|
||||||
}
|
}
|
||||||
|
|
||||||
// Send parse values from *cli.context and return *cli.Command.
|
// Send parse values from *cli.context and return *cli.Command.
|
||||||
@ -61,10 +62,27 @@ All configuration options are also available via environment variables.`,
|
|||||||
Usage: "Title of the message.",
|
Usage: "Title of the message.",
|
||||||
EnvVars: []string{"PUSHOVER_TITLE"},
|
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 {
|
Action: func(ctx *cli.Context) error {
|
||||||
app := pushover.New(pushOverOpts.Token)
|
app := pushover.New(pushOverOpts.Token)
|
||||||
message := pushover.NewMessageWithTitle(pushOverOpts.Message, pushOverOpts.Title)
|
|
||||||
|
// 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,
|
||||||
|
}
|
||||||
|
|
||||||
users := strings.Split(pushOverOpts.Recipient, ",")
|
users := strings.Split(pushOverOpts.Recipient, ",")
|
||||||
|
|
||||||
for _, v := range users {
|
for _, v := range users {
|
||||||
|
@ -78,11 +78,11 @@ All configuration options are also available via environment variables.`,
|
|||||||
if len(v) <= 0 {
|
if len(v) <= 0 {
|
||||||
return helpers.ErrChannel
|
return helpers.ErrChannel
|
||||||
}
|
}
|
||||||
k, errStr := strconv.Atoi(v)
|
k, errStr := strconv.ParseInt(v, 10, 64)
|
||||||
if errStr != nil {
|
if errStr != nil {
|
||||||
return errStr
|
return errStr
|
||||||
}
|
}
|
||||||
telegramSvc.AddReceivers(int64(k))
|
telegramSvc.AddReceivers(k)
|
||||||
}
|
}
|
||||||
|
|
||||||
notifier.UseServices(telegramSvc)
|
notifier.UseServices(telegramSvc)
|
||||||
|
98
service/textmagic/textmagic.go
Normal file
98
service/textmagic/textmagic.go
Normal file
@ -0,0 +1,98 @@
|
|||||||
|
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
|
||||||
|
}
|
120
service/wechat/wechat.go
Normal file
120
service/wechat/wechat.go
Normal file
@ -0,0 +1,120 @@
|
|||||||
|
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
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
173
service/zulip/zulip.go
Normal file
173
service/zulip/zulip.go
Normal file
@ -0,0 +1,173 @@
|
|||||||
|
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
|
||||||
|
}
|
181
service/zulip/zulip_test.go
Normal file
181
service/zulip/zulip_test.go
Normal file
@ -0,0 +1,181 @@
|
|||||||
|
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)
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user