Compare commits
123 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
e3d8fe4fd8 | ||
![]() |
23d8742f0d | ||
![]() |
3b6a8be07b | ||
![]() |
71a5b72aff | ||
![]() |
213bf349c3 | ||
![]() |
a94fe55886 | ||
![]() |
9b22f16497 | ||
![]() |
2977a5957e | ||
![]() |
f70d1c897a | ||
![]() |
a4a3525265 | ||
![]() |
a6dd8446e4 | ||
![]() |
7bf9e1cfb3 | ||
![]() |
f291832a77 | ||
![]() |
1fee323247 | ||
![]() |
a41accd033 | ||
![]() |
37f7caf7f3 | ||
![]() |
5847f7758c | ||
![]() |
bce736993e | ||
![]() |
5636992446 | ||
![]() |
f996a2b7ae | ||
![]() |
587de96ab3 | ||
![]() |
80eb1cd202 | ||
![]() |
bbf594c815 | ||
![]() |
2f0f2ee40d | ||
![]() |
96022d3aaf | ||
![]() |
8eb5e3cbf8 | ||
![]() |
ddc2625934 | ||
![]() |
7f7ca697a0 | ||
![]() |
900375679b | ||
![]() |
9440b9e313 | ||
![]() |
393f9e998b | ||
![]() |
ba0bfe70a8 | ||
![]() |
3c4a3e3f75 | ||
![]() |
274fb09ed4 | ||
![]() |
d44598a900 | ||
![]() |
c9cfa59f54 | ||
![]() |
7062234331 | ||
![]() |
9754569525 | ||
![]() |
52a071e34d | ||
![]() |
2d8f749e36 | ||
![]() |
a18cb74f03 | ||
![]() |
6c442e239d | ||
![]() |
eaf92fca4d | ||
![]() |
06b7bad714 | ||
![]() |
19eec2ed03 | ||
![]() |
d99c54343a | ||
![]() |
308a110000 | ||
![]() |
4f406b2ce6 | ||
![]() |
e564c555d7 | ||
![]() |
f7ec9af9e8 | ||
![]() |
4d93a774ce | ||
![]() |
2595dd30bf | ||
![]() |
9190365289 | ||
![]() |
57794b3b9f | ||
![]() |
3c36f651be | ||
![]() |
8e6ddadba2 | ||
![]() |
8a87a71927 | ||
![]() |
0047e6f523 | ||
![]() |
7183095a28 | ||
![]() |
13c90893c7 | ||
![]() |
976fbcd07f | ||
![]() |
d97b077e85 | ||
![]() |
8950575bfb | ||
![]() |
11fc4c286f | ||
![]() |
8d08e348a9 | ||
![]() |
a18807f19e | ||
![]() |
29f658fd3c | ||
![]() |
a30bb8fed0 | ||
![]() |
092ca1cd67 | ||
![]() |
0df2539641 | ||
![]() |
0f2d8a599c | ||
![]() |
54b3143a1d | ||
![]() |
148f7d2a91 | ||
![]() |
1aa662f763 | ||
![]() |
0b86b88de7 | ||
![]() |
98033b1ba7 | ||
![]() |
2b7eab629d | ||
![]() |
0e4973e15c | ||
![]() |
af0acf0dae | ||
![]() |
76e5fe5a87 | ||
![]() |
802c80f40c | ||
![]() |
a51c5bd905 | ||
![]() |
8c68556f52 | ||
![]() |
cca1ea2404 | ||
![]() |
281016a501 | ||
![]() |
d4acdf2f89 | ||
![]() |
0951e75c85 | ||
![]() |
6b017b226a | ||
![]() |
9e3bd7398c | ||
![]() |
79f764c7a8 | ||
![]() |
b5dc4353fb | ||
![]() |
2fbac73c29 | ||
![]() |
6616d105d1 | ||
![]() |
6b4b19194e | ||
![]() |
9785edd263 | ||
![]() |
2a0bc11b68 | ||
![]() |
dd0325a88d | ||
![]() |
20783c0978 | ||
![]() |
3f06a40bd5 | ||
![]() |
68f43985ad | ||
![]() |
915ca8f817 | ||
![]() |
a65a81610b | ||
![]() |
8eb6ed5639 | ||
![]() |
795a8705c3 | ||
![]() |
3af0dc3b3a | ||
![]() |
9cf9b958a3 | ||
![]() |
3ac2ba8d5a | ||
![]() |
d893421c7b | ||
![]() |
250b3bb579 | ||
![]() |
e9edbfc051 | ||
![]() |
e343db6f72 | ||
![]() |
4d57d66f85 | ||
![]() |
54ed6320c2 | ||
![]() |
23083f3ae0 | ||
![]() |
1985873494 | ||
![]() |
8ae5917659 | ||
![]() |
c91bfd08d8 | ||
![]() |
49110a5872 | ||
![]() |
c01c8edeb8 | ||
![]() |
ff8cf067b8 | ||
![]() |
1420f68050 | ||
![]() |
c0be3e585a | ||
![]() |
3049ef9151 |
1
.github/ISSUE_TEMPLATE/Bug_report.md
vendored
1
.github/ISSUE_TEMPLATE/Bug_report.md
vendored
@@ -1,6 +1,7 @@
|
||||
---
|
||||
name: Bug report
|
||||
about: Create a report to help us improve. (Check the FAQ on the wiki first)
|
||||
labels: bug
|
||||
|
||||
---
|
||||
|
||||
|
1
.github/ISSUE_TEMPLATE/Feature_request.md
vendored
1
.github/ISSUE_TEMPLATE/Feature_request.md
vendored
@@ -1,6 +1,7 @@
|
||||
---
|
||||
name: Feature request
|
||||
about: Suggest an idea for this project
|
||||
labels: enhancement
|
||||
|
||||
---
|
||||
|
||||
|
57
.github/workflows/development.yml
vendored
Normal file
57
.github/workflows/development.yml
vendored
Normal file
@@ -0,0 +1,57 @@
|
||||
name: Development
|
||||
on: [push, pull_request]
|
||||
jobs:
|
||||
lint:
|
||||
name: golangci-lint
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
fetch-depth: 20
|
||||
- name: Run golangci-lint
|
||||
uses: golangci/golangci-lint-action@v1
|
||||
with:
|
||||
version: v1.27
|
||||
args: "-v --new-from-rev HEAD~1"
|
||||
test-build-upload:
|
||||
strategy:
|
||||
matrix:
|
||||
go-version: [1.13.x, 1.14.x]
|
||||
platform: [ubuntu-latest]
|
||||
runs-on: ${{ matrix.platform }}
|
||||
steps:
|
||||
- name: Install Go
|
||||
uses: actions/setup-go@v2
|
||||
with:
|
||||
go-version: ${{ matrix.go-version }}
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- name: Test
|
||||
run: go test ./... -mod=vendor
|
||||
- name: Build
|
||||
run: |
|
||||
mkdir -p output/{win,lin,arm,mac}
|
||||
VERSION=$(git describe --tags)
|
||||
GOOS=linux GOARCH=amd64 go build -mod=vendor -ldflags "-s -X main.githash=$(git log --pretty=format:'%h' -n 1)" -o output/lin/matterbridge-$VERSION-linux-amd64
|
||||
GOOS=windows GOARCH=amd64 go build -mod=vendor -ldflags "-s -X main.githash=$(git log --pretty=format:'%h' -n 1)" -o output/win/matterbridge-$VERSION-windows-amd64.exe
|
||||
GOOS=darwin GOARCH=amd64 go build -mod=vendor -ldflags "-s -X main.githash=$(git log --pretty=format:'%h' -n 1)" -o output/mac/matterbridge-$VERSION-darwin-amd64
|
||||
- name: Upload linux 64-bit
|
||||
if: startsWith(matrix.go-version,'1.14')
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: matterbridge-linux-64bit
|
||||
path: output/lin
|
||||
- name: Upload windows 64-bit
|
||||
if: startsWith(matrix.go-version,'1.14')
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: matterbridge-windows-64bit
|
||||
path: output/win
|
||||
- name: Upload darwin 64-bit
|
||||
if: startsWith(matrix.go-version,'1.14')
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: matterbridge-darwin-64bit
|
||||
path: output/mac
|
@@ -23,7 +23,7 @@ run:
|
||||
# default value is empty list, but next dirs are always skipped independently
|
||||
# from this option's value:
|
||||
# vendor$, third_party$, testdata$, examples$, Godeps$, builtin$
|
||||
skip-dirs:
|
||||
skip-dirs: gateway/bridgemap$
|
||||
|
||||
# which files to skip: they will be analyzed, but issues from them
|
||||
# won't be reported. Default value is empty list, but there is
|
||||
@@ -175,6 +175,11 @@ linters:
|
||||
- maligned
|
||||
- prealloc
|
||||
- wsl
|
||||
- gomnd
|
||||
- godox
|
||||
- goerr113
|
||||
- testpackage
|
||||
- godot
|
||||
|
||||
|
||||
# rules to deal with reported isues
|
||||
|
56
.travis.yml
56
.travis.yml
@@ -1,56 +0,0 @@
|
||||
language: go
|
||||
go_import_path: github.com/42wim/matterbridge
|
||||
|
||||
# We have everything vendored so this helps TravisCI not run `go get ...`.
|
||||
install: true
|
||||
|
||||
git:
|
||||
depth: 200
|
||||
|
||||
notifications:
|
||||
email: false
|
||||
|
||||
branches:
|
||||
only:
|
||||
- master
|
||||
- /.*/
|
||||
|
||||
jobs:
|
||||
include:
|
||||
- stage: lint
|
||||
# Run linting in one Go environment only.
|
||||
script: ./ci/lint.sh
|
||||
go: 1.13.x
|
||||
env:
|
||||
- GO111MODULE=on
|
||||
- GOLANGCI_VERSION="v1.21.0"
|
||||
- stage: test
|
||||
# Run tests in a combination of Go environments.
|
||||
script: ./ci/test.sh
|
||||
go: 1.12.x
|
||||
env:
|
||||
- GO111MODULE=off
|
||||
- script: ./ci/test.sh
|
||||
go: 1.12.x
|
||||
env:
|
||||
- GO111MODULE=on
|
||||
- script: ./ci/test.sh
|
||||
go: 1.13.x
|
||||
env:
|
||||
- GO111MODULE=on
|
||||
- REPORT_COVERAGE=1
|
||||
- BINDEPLOY=1
|
||||
|
||||
before_deploy: /bin/bash ci/bintray.sh
|
||||
|
||||
deploy:
|
||||
on:
|
||||
all_branches: true
|
||||
condition: $BINDEPLOY = 1
|
||||
provider: bintray
|
||||
edge:
|
||||
branch: v1.8.47
|
||||
file: ci/deploy.json
|
||||
user: 42wim
|
||||
key:
|
||||
secure: "CeXXe6JOmt7HYR81MdWLua0ltQHhDdkIeRGBFbgd7hkb1wi8eF9DgpAcQrTso8NIlHNZmSAP46uhFgsRvkuezzX0ygalZ7DCJyAyn3sAMEh+UQSHV1WGThRehTtidqRGjetzsIGSwdrJOWil+XTfbO1Z8DGzfakhSuAZka8CM4BAoe3YeP9rYK8h+84x0GHfczvsLtXZ3mWLvQuwe4pK6+ItBCUg0ae7O7ZUpWHy0xQQkkWztY/6RAzXfaG7DuGjIw+20fhx3WOXRNpHCtZ6Bc3qERCpk0s1HhlQWlrN9wDaFTBWYwlvSnNgvxxMbNXJ6RrRJ0l0bA7FUswYwyroxhzrGLdzWDg8dHaQkypocngdalfhpsnoO9j3ApJhomUFJ3UoEq5nOGRUrKn8MPi+dP0zE4kNQ3e4VNa1ufNrvfpWolMg3xh8OXuhQdD5wIM5zFAbRJLqWSCVAjPq4DDPecmvXBOlIial7oa312lN5qnBnUjvAcxszZ+FUyDHT1Grxzna4tMwxY9obPzZUzm7359AOCCwIQFVB8GLqD2nwIstcXS0zGRz+fhviPipHuBa02q5bGUZwmkvrSNab0s8Jo7pCrel2Rz3nWPKaiCfq2WjbW1CLheSMkOQrjsdUd1hhbqNWFPUjJPInTc77NAKCfm5runv5uyowRLh4NNd0sI="
|
17
Dockerfile
17
Dockerfile
@@ -1,11 +1,16 @@
|
||||
FROM alpine:edge
|
||||
ENTRYPOINT ["/bin/matterbridge"]
|
||||
FROM alpine:edge AS builder
|
||||
|
||||
COPY . /go/src/github.com/42wim/matterbridge
|
||||
RUN apk update && apk add go git gcc musl-dev ca-certificates mailcap \
|
||||
RUN apk update && apk add go git gcc musl-dev \
|
||||
&& cd /go/src/github.com/42wim/matterbridge \
|
||||
&& export GOPATH=/go \
|
||||
&& go get \
|
||||
&& go build -x -ldflags "-X main.githash=$(git log --pretty=format:'%h' -n 1)" -o /bin/matterbridge \
|
||||
&& rm -rf /go \
|
||||
&& apk del --purge git go gcc musl-dev
|
||||
&& go build -x -ldflags "-X main.githash=$(git log --pretty=format:'%h' -n 1)" -o /bin/matterbridge
|
||||
|
||||
FROM alpine:edge
|
||||
RUN apk --no-cache add ca-certificates mailcap
|
||||
COPY --from=builder /bin/matterbridge /bin/matterbridge
|
||||
RUN mkdir /etc/matterbridge \
|
||||
&& touch /etc/matterbridge/matterbridge.toml \
|
||||
&& ln -sf /matterbridge.toml /etc/matterbridge/matterbridge.toml
|
||||
ENTRYPOINT ["/bin/matterbridge", "-conf", "/etc/matterbridge/matterbridge.toml"]
|
||||
|
86
README.md
86
README.md
@@ -9,26 +9,26 @@ Letting people be where they want to be.<br />
|
||||
|
||||
<sup>
|
||||
|
||||
[Discord][mb-discord] |
|
||||
[Gitter][mb-gitter] |
|
||||
[IRC][mb-irc] |
|
||||
[Discord][mb-discord] |
|
||||
[Keybase][mb-keybase] |
|
||||
[Matrix][mb-matrix] |
|
||||
[Slack][mb-slack] |
|
||||
[Mattermost][mb-mattermost] |
|
||||
[MSTeams][mb-msteams] |
|
||||
[Rocket.Chat][mb-rocketchat] |
|
||||
[XMPP][mb-xmpp] |
|
||||
[Slack][mb-slack] |
|
||||
[Telegram][mb-telegram] |
|
||||
[Twitch][mb-twitch] |
|
||||
[WhatsApp][mb-whatsapp] |
|
||||
[XMPP][mb-xmpp] |
|
||||
[Zulip][mb-zulip] |
|
||||
[Telegram][mb-telegram] |
|
||||
[Keybase][mb-keybase] |
|
||||
And more...
|
||||
</sup>
|
||||
|
||||
---
|
||||
|
||||
[](https://github.com/42wim/matterbridge/releases/latest)
|
||||
[](https://bintray.com/42wim/nightly/Matterbridge/_latestVersion)
|
||||
[](https://codeclimate.com/github/42wim/matterbridge/maintainability)
|
||||
[](https://codeclimate.com/github/42wim/matterbridge/test_coverage)<br />
|
||||
|
||||
@@ -86,29 +86,32 @@ And more...
|
||||
|
||||
### Natively supported
|
||||
|
||||
- [Mattermost](https://github.com/mattermost/mattermost-server/) 4.x, 5.x
|
||||
- [IRC](http://www.mirc.com/servers.html)
|
||||
- [XMPP](https://xmpp.org)
|
||||
- [Gitter](https://gitter.im)
|
||||
- [Slack](https://slack.com)
|
||||
- [Discord](https://discordapp.com)
|
||||
- [Telegram](https://telegram.org)
|
||||
- [Rocket.chat](https://rocket.chat)
|
||||
- [Matrix](https://matrix.org)
|
||||
- [Steam](https://store.steampowered.com/)
|
||||
- [Twitch](https://twitch.tv)
|
||||
- [Ssh-chat](https://github.com/shazow/ssh-chat)
|
||||
- [WhatsApp](https://www.whatsapp.com/)
|
||||
- [Zulip](https://zulipchat.com)
|
||||
- [Gitter](https://gitter.im)
|
||||
- [IRC](http://www.mirc.com/servers.html)
|
||||
- [Keybase](https://keybase.io)
|
||||
- [Matrix](https://matrix.org)
|
||||
- [Mattermost](https://github.com/mattermost/mattermost-server/) 4.x, 5.x
|
||||
- [Microsoft Teams](https://teams.microsoft.com)
|
||||
- [Nextcloud Talk](https://nextcloud.com/talk/)
|
||||
- [Rocket.chat](https://rocket.chat)
|
||||
- [Slack](https://slack.com)
|
||||
- [Ssh-chat](https://github.com/shazow/ssh-chat)
|
||||
- [Steam](https://store.steampowered.com/)
|
||||
- [Telegram](https://telegram.org)
|
||||
- [Twitch](https://twitch.tv)
|
||||
- [WhatsApp](https://www.whatsapp.com/)
|
||||
- [XMPP](https://xmpp.org)
|
||||
- [Zulip](https://zulipchat.com)
|
||||
|
||||
### 3rd party via matterbridge api
|
||||
|
||||
- [Discourse](https://github.com/DeclanHoare/matterbabble)
|
||||
- [Facebook messenger](https://github.com/VictorNine/fbridge)
|
||||
- [Minecraft](https://github.com/elytra/MatterLink)
|
||||
- [Reddit](https://github.com/bonehurtingjuice/mattereddit)
|
||||
- [Facebook messenger](https://github.com/VictorNine/fbridge)
|
||||
- [Discourse](https://github.com/DeclanHoare/matterbabble)
|
||||
- [Counter-Strike, half-life and more](https://forums.alliedmods.net/showthread.php?t=319430)
|
||||
- [MatterAMXX](https://github.com/GabeIggy/MatterAMXX)
|
||||
|
||||
### API
|
||||
|
||||
@@ -128,17 +131,18 @@ Used by the projects below. Feel free to make a PR to add your project to this l
|
||||
|
||||
Questions or want to test on your favorite platform? Join below:
|
||||
|
||||
- [Discord][mb-discord]
|
||||
- [Gitter][mb-gitter]
|
||||
- [IRC][mb-irc]
|
||||
- [Discord][mb-discord]
|
||||
- [Keybase][mb-keybase]
|
||||
- [Matrix][mb-matrix]
|
||||
- [Slack][mb-slack]
|
||||
- [Mattermost][mb-mattermost]
|
||||
- [Rocket.Chat][mb-rocketchat]
|
||||
- [XMPP][mb-xmpp] (matterbridge@conference.jabber.de)
|
||||
- [Twitch][mb-twitch]
|
||||
- [Zulip][mb-zulip]
|
||||
- [Slack][mb-slack]
|
||||
- [Telegram][mb-telegram]
|
||||
- [Twitch][mb-twitch]
|
||||
- [XMPP][mb-xmpp] (matterbridge@conference.jabber.de)
|
||||
- [Zulip][mb-zulip]
|
||||
|
||||
## Screenshots
|
||||
|
||||
@@ -148,14 +152,15 @@ See https://github.com/42wim/matterbridge/wiki
|
||||
|
||||
### Binaries
|
||||
|
||||
- Latest stable release [v1.16.5](https://github.com/42wim/matterbridge/releases/latest)
|
||||
- Development releases (follows master) can be downloaded [here](https://dl.bintray.com/42wim/nightly/)
|
||||
- Latest stable release [v1.18.0](https://github.com/42wim/matterbridge/releases/latest)
|
||||
- Development releases (follows master) can be downloaded [here](https://github.com/42wim/matterbridge/actions) selecting the latest green build and then artifacts.
|
||||
|
||||
To install or upgrade just download the latest [binary](https://github.com/42wim/matterbridge/releases/latest) and follow the instructions on the [howto](https://github.com/42wim/matterbridge/wiki/How-to-create-your-config) for a step by step walkthrough for creating your configuration.
|
||||
|
||||
### Packages
|
||||
|
||||
- [Overview](https://repology.org/metapackage/matterbridge/versions)
|
||||
- [snap](https://snapcraft.io/matterbridge)
|
||||
|
||||
## Building
|
||||
|
||||
@@ -303,6 +308,7 @@ See [FAQ](https://github.com/42wim/matterbridge/wiki/FAQ)
|
||||
- https://kopano.com/blog/matterbridge-bridging-mattermost-chat/
|
||||
- https://www.stitcher.com/s/?eid=52382713
|
||||
- https://daniele.tech/2019/02/how-to-use-matterbridge-to-connect-2-different-slack-workspaces/
|
||||
- https://userlinux.net/mattermost-and-matterbridge.html
|
||||
|
||||
## Thanks
|
||||
|
||||
@@ -321,30 +327,32 @@ Matterbridge wouldn't exist without these libraries:
|
||||
- gops - https://github.com/google/gops
|
||||
- gozulipbot - https://github.com/ifo/gozulipbot
|
||||
- irc - https://github.com/lrstanley/girc
|
||||
- mattermost - https://github.com/mattermost/mattermost-server
|
||||
- keybase - https://github.com/keybase/go-keybase-chat-bot
|
||||
- matrix - https://github.com/matrix-org/gomatrix
|
||||
- sshchat - https://github.com/shazow/ssh-chat
|
||||
- mattermost - https://github.com/mattermost/mattermost-server
|
||||
- msgraph.go - https://github.com/yaegashi/msgraph.go
|
||||
- slack - https://github.com/nlopes/slack
|
||||
- sshchat - https://github.com/shazow/ssh-chat
|
||||
- steam - https://github.com/Philipp15b/go-steam
|
||||
- telegram - https://github.com/go-telegram-bot-api/telegram-bot-api
|
||||
- xmpp - https://github.com/mattn/go-xmpp
|
||||
- whatsapp - https://github.com/Rhymen/go-whatsapp/
|
||||
- zulip - https://github.com/ifo/gozulipbot
|
||||
- tengo - https://github.com/d5/tengo
|
||||
- keybase - https://github.com/keybase/go-keybase-chat-bot
|
||||
- whatsapp - https://github.com/Rhymen/go-whatsapp/
|
||||
- xmpp - https://github.com/mattn/go-xmpp
|
||||
- zulip - https://github.com/ifo/gozulipbot
|
||||
|
||||
<!-- Links -->
|
||||
|
||||
[mb-discord]: https://discord.gg/AkKPtrQ
|
||||
[mb-gitter]: https://gitter.im/42wim/matterbridge
|
||||
[mb-irc]: https://webchat.freenode.net/?channels=matterbridgechat
|
||||
[mb-discord]: https://discord.gg/AkKPtrQ
|
||||
[mb-keybase]: https://keybase.io/team/matterbridge
|
||||
[mb-matrix]: https://riot.im/app/#/room/#matterbridge:matrix.org
|
||||
[mb-slack]: https://join.slack.com/matterbridgechat/shared_invite/MjEwODMxNjU1NDMwLTE0OTk2MTU3NTMtMzZkZmRiNDZhOA
|
||||
[mb-mattermost]: https://framateam.org/signup_user_complete/?id=tfqm33ggop8x3qgu4boeieta6e
|
||||
[mb-msteams]: https://teams.microsoft.com/join/hj92x75gd3y7
|
||||
[mb-rocketchat]: https://open.rocket.chat/channel/matterbridge
|
||||
[mb-xmpp]: https://inverse.chat/
|
||||
[mb-slack]: https://join.slack.com/matterbridgechat/shared_invite/MjEwODMxNjU1NDMwLTE0OTk2MTU3NTMtMzZkZmRiNDZhOA
|
||||
[mb-telegram]: https://t.me/Matterbridge
|
||||
[mb-twitch]: https://www.twitch.tv/matterbridge
|
||||
[mb-whatsapp]: https://www.whatsapp.com/
|
||||
[mb-keybase]: https://keybase.io
|
||||
[mb-xmpp]: https://inverse.chat/
|
||||
[mb-zulip]: https://matterbridge.zulipchat.com/register/
|
||||
[mb-telegram]: https://t.me/Matterbridge
|
||||
|
@@ -8,9 +8,10 @@ import (
|
||||
|
||||
"github.com/42wim/matterbridge/bridge"
|
||||
"github.com/42wim/matterbridge/bridge/config"
|
||||
"github.com/gorilla/websocket"
|
||||
"github.com/labstack/echo/v4"
|
||||
"github.com/labstack/echo/v4/middleware"
|
||||
"github.com/zfjagann/golang-ring"
|
||||
ring "github.com/zfjagann/golang-ring"
|
||||
)
|
||||
|
||||
type API struct {
|
||||
@@ -41,9 +42,17 @@ func New(cfg *bridge.Config) bridge.Bridger {
|
||||
return key == b.GetString("Token"), nil
|
||||
}))
|
||||
}
|
||||
|
||||
// Set RemoteNickFormat to a sane default
|
||||
if !b.IsKeySet("RemoteNickFormat") {
|
||||
b.Log.Debugln("RemoteNickFormat is unset, defaulting to \"{NICK}\"")
|
||||
b.Config.Config.Viper().Set(b.GetConfigKey("RemoteNickFormat"), "{NICK}")
|
||||
}
|
||||
|
||||
e.GET("/api/health", b.handleHealthcheck)
|
||||
e.GET("/api/messages", b.handleMessages)
|
||||
e.GET("/api/stream", b.handleStream)
|
||||
e.GET("/api/websocket", b.handleWebsocket)
|
||||
e.POST("/api/message", b.handlePostMessage)
|
||||
go func() {
|
||||
if b.GetString("BindAddress") == "" {
|
||||
@@ -106,13 +115,17 @@ func (b *API) handleMessages(c echo.Context) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (b *API) handleStream(c echo.Context) error {
|
||||
c.Response().Header().Set(echo.HeaderContentType, echo.MIMEApplicationJSON)
|
||||
c.Response().WriteHeader(http.StatusOK)
|
||||
greet := config.Message{
|
||||
func (b *API) getGreeting() config.Message {
|
||||
return config.Message{
|
||||
Event: config.EventAPIConnected,
|
||||
Timestamp: time.Now(),
|
||||
}
|
||||
}
|
||||
|
||||
func (b *API) handleStream(c echo.Context) error {
|
||||
c.Response().Header().Set(echo.HeaderContentType, echo.MIMEApplicationJSON)
|
||||
c.Response().WriteHeader(http.StatusOK)
|
||||
greet := b.getGreeting()
|
||||
if err := json.NewEncoder(c.Response()).Encode(greet); err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -128,3 +141,52 @@ func (b *API) handleStream(c echo.Context) error {
|
||||
time.Sleep(200 * time.Millisecond)
|
||||
}
|
||||
}
|
||||
|
||||
func (b *API) handleWebsocketMessage(message config.Message) {
|
||||
message.Channel = "api"
|
||||
message.Protocol = "api"
|
||||
message.Account = b.Account
|
||||
message.ID = ""
|
||||
message.Timestamp = time.Now()
|
||||
|
||||
b.Log.Debugf("Sending websocket message from %s on %s to gateway", message.Username, "api")
|
||||
b.Remote <- message
|
||||
}
|
||||
|
||||
func (b *API) writePump(conn *websocket.Conn) {
|
||||
for {
|
||||
msg := b.Messages.Dequeue()
|
||||
if msg != nil {
|
||||
err := conn.WriteJSON(msg)
|
||||
if err != nil {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (b *API) readPump(conn *websocket.Conn) {
|
||||
for {
|
||||
message := config.Message{}
|
||||
err := conn.ReadJSON(&message)
|
||||
if err != nil {
|
||||
break
|
||||
}
|
||||
b.handleWebsocketMessage(message)
|
||||
}
|
||||
}
|
||||
|
||||
func (b *API) handleWebsocket(c echo.Context) error {
|
||||
conn, err := websocket.Upgrade(c.Response().Writer, c.Request(), nil, 1024, 1024)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
greet := b.getGreeting()
|
||||
_ = conn.WriteJSON(greet)
|
||||
|
||||
go b.writePump(conn)
|
||||
go b.readPump(conn)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
@@ -4,6 +4,7 @@ import (
|
||||
"log"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/42wim/matterbridge/bridge/config"
|
||||
"github.com/sirupsen/logrus"
|
||||
@@ -74,6 +75,7 @@ func (b *Bridge) joinChannels(channels map[string]config.ChannelInfo, exists map
|
||||
for ID, channel := range channels {
|
||||
if !exists[ID] {
|
||||
b.Log.Infof("%s: joining %s (ID: %s)", b.Account, channel.Name, ID)
|
||||
time.Sleep(time.Duration(b.GetInt("JoinDelay")) * time.Millisecond)
|
||||
err := b.JoinChannel(channel)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -84,8 +86,16 @@ func (b *Bridge) joinChannels(channels map[string]config.ChannelInfo, exists map
|
||||
return nil
|
||||
}
|
||||
|
||||
func (b *Bridge) GetConfigKey(key string) string {
|
||||
return b.Account + "." + key
|
||||
}
|
||||
|
||||
func (b *Bridge) IsKeySet(key string) bool {
|
||||
return b.Config.IsKeySet(b.GetConfigKey(key)) || b.Config.IsKeySet("general."+key)
|
||||
}
|
||||
|
||||
func (b *Bridge) GetBool(key string) bool {
|
||||
val, ok := b.Config.GetBool(b.Account + "." + key)
|
||||
val, ok := b.Config.GetBool(b.GetConfigKey(key))
|
||||
if !ok {
|
||||
val, _ = b.Config.GetBool("general." + key)
|
||||
}
|
||||
@@ -93,7 +103,7 @@ func (b *Bridge) GetBool(key string) bool {
|
||||
}
|
||||
|
||||
func (b *Bridge) GetInt(key string) int {
|
||||
val, ok := b.Config.GetInt(b.Account + "." + key)
|
||||
val, ok := b.Config.GetInt(b.GetConfigKey(key))
|
||||
if !ok {
|
||||
val, _ = b.Config.GetInt("general." + key)
|
||||
}
|
||||
@@ -101,7 +111,7 @@ func (b *Bridge) GetInt(key string) int {
|
||||
}
|
||||
|
||||
func (b *Bridge) GetString(key string) string {
|
||||
val, ok := b.Config.GetString(b.Account + "." + key)
|
||||
val, ok := b.Config.GetString(b.GetConfigKey(key))
|
||||
if !ok {
|
||||
val, _ = b.Config.GetString("general." + key)
|
||||
}
|
||||
@@ -109,7 +119,7 @@ func (b *Bridge) GetString(key string) string {
|
||||
}
|
||||
|
||||
func (b *Bridge) GetStringSlice(key string) []string {
|
||||
val, ok := b.Config.GetStringSlice(b.Account + "." + key)
|
||||
val, ok := b.Config.GetStringSlice(b.GetConfigKey(key))
|
||||
if !ok {
|
||||
val, _ = b.Config.GetStringSlice("general." + key)
|
||||
}
|
||||
@@ -117,7 +127,7 @@ func (b *Bridge) GetStringSlice(key string) []string {
|
||||
}
|
||||
|
||||
func (b *Bridge) GetStringSlice2D(key string) [][]string {
|
||||
val, ok := b.Config.GetStringSlice2D(b.Account + "." + key)
|
||||
val, ok := b.Config.GetStringSlice2D(b.GetConfigKey(key))
|
||||
if !ok {
|
||||
val, _ = b.Config.GetStringSlice2D("general." + key)
|
||||
}
|
||||
|
@@ -3,6 +3,8 @@ package config
|
||||
import (
|
||||
"bytes"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
@@ -76,19 +78,23 @@ type Protocol struct {
|
||||
BindAddress string // mattermost, slack // DEPRECATED
|
||||
Buffer int // api
|
||||
Charset string // irc
|
||||
ClientID string // msteams
|
||||
ColorNicks bool // only irc for now
|
||||
Debug bool // general
|
||||
DebugLevel int // only for irc now
|
||||
DisableWebPagePreview bool // telegram
|
||||
EditSuffix string // mattermost, slack, discord, telegram, gitter
|
||||
EditDisable bool // mattermost, slack, discord, telegram, gitter
|
||||
HTMLDisable bool // matrix
|
||||
IconURL string // mattermost, slack
|
||||
IgnoreFailureOnStart bool // general
|
||||
IgnoreNicks string // all protocols
|
||||
IgnoreMessages string // all protocols
|
||||
Jid string // xmpp
|
||||
JoinDelay string // all protocols
|
||||
Label string // all protocols
|
||||
Login string // mattermost, matrix
|
||||
LogFile string // general
|
||||
MediaDownloadBlackList []string
|
||||
MediaDownloadPath string // Basically MediaServerUpload, but instead of uploading it, just write it to a file on the same server.
|
||||
MediaDownloadSize int // all protocols
|
||||
@@ -124,6 +130,7 @@ type Protocol struct {
|
||||
RemoteNickFormat string // all protocols
|
||||
RunCommands []string // IRC
|
||||
Server string // IRC,mattermost,XMPP,discord
|
||||
SessionFile string // msteams,whatsapp
|
||||
ShowJoinPart bool // all protocols
|
||||
ShowTopicChange bool // slack
|
||||
ShowUserTyping bool // slack
|
||||
@@ -131,13 +138,17 @@ type Protocol struct {
|
||||
SkipTLSVerify bool // IRC, mattermost
|
||||
SkipVersionCheck bool // mattermost
|
||||
StripNick bool // all protocols
|
||||
StripMarkdown bool // irc
|
||||
SyncTopic bool // slack
|
||||
TengoModifyMessage string // general
|
||||
Team string // mattermost, keybase
|
||||
TeamID string // msteams
|
||||
TenantID string // msteams
|
||||
Token string // gitter, slack, discord, api
|
||||
Topic string // zulip
|
||||
URL string // mattermost, slack // DEPRECATED
|
||||
UseAPI bool // mattermost, slack
|
||||
UseLocalAvatar []string // discord
|
||||
UseSASL bool // IRC
|
||||
UseTLS bool // IRC
|
||||
UseDiscriminator bool // discord
|
||||
@@ -210,6 +221,7 @@ type BridgeValues struct {
|
||||
type Config interface {
|
||||
Viper() *viper.Viper
|
||||
BridgeValues() *BridgeValues
|
||||
IsKeySet(key string) bool
|
||||
GetBool(key string) (bool, bool)
|
||||
GetInt(key string) (int, bool)
|
||||
GetString(key string) (string, bool)
|
||||
@@ -235,7 +247,17 @@ func NewConfig(rootLogger *logrus.Logger, cfgfile string) Config {
|
||||
logger.Fatalf("Failed to read configuration file: %#v", err)
|
||||
}
|
||||
|
||||
mycfg := newConfigFromString(logger, input)
|
||||
cfgtype := detectConfigType(cfgfile)
|
||||
mycfg := newConfigFromString(logger, input, cfgtype)
|
||||
if mycfg.cv.General.LogFile != "" {
|
||||
logfile, err := os.OpenFile(mycfg.cv.General.LogFile, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0600)
|
||||
if err == nil {
|
||||
logger.Info("Opening log file ", mycfg.cv.General.LogFile)
|
||||
rootLogger.Out = logfile
|
||||
} else {
|
||||
logger.Warn("Failed to open ", mycfg.cv.General.LogFile)
|
||||
}
|
||||
}
|
||||
if mycfg.cv.General.MediaDownloadSize == 0 {
|
||||
mycfg.cv.General.MediaDownloadSize = 1000000
|
||||
}
|
||||
@@ -246,14 +268,26 @@ func NewConfig(rootLogger *logrus.Logger, cfgfile string) Config {
|
||||
return mycfg
|
||||
}
|
||||
|
||||
// detectConfigType detects JSON and YAML formats, defaults to TOML.
|
||||
func detectConfigType(cfgfile string) string {
|
||||
fileExt := filepath.Ext(cfgfile)
|
||||
switch fileExt {
|
||||
case ".json":
|
||||
return "json"
|
||||
case ".yaml", ".yml":
|
||||
return "yaml"
|
||||
}
|
||||
return "toml"
|
||||
}
|
||||
|
||||
// NewConfigFromString instantiates a new configuration based on the specified string.
|
||||
func NewConfigFromString(rootLogger *logrus.Logger, input []byte) Config {
|
||||
logger := rootLogger.WithFields(logrus.Fields{"prefix": "config"})
|
||||
return newConfigFromString(logger, input)
|
||||
return newConfigFromString(logger, input, "toml")
|
||||
}
|
||||
|
||||
func newConfigFromString(logger *logrus.Entry, input []byte) *config {
|
||||
viper.SetConfigType("toml")
|
||||
func newConfigFromString(logger *logrus.Entry, input []byte, cfgtype string) *config {
|
||||
viper.SetConfigType(cfgtype)
|
||||
viper.SetEnvPrefix("matterbridge")
|
||||
viper.SetEnvKeyReplacer(strings.NewReplacer(".", "_", "-", "_"))
|
||||
viper.AutomaticEnv()
|
||||
@@ -281,6 +315,12 @@ func (c *config) Viper() *viper.Viper {
|
||||
return c.v
|
||||
}
|
||||
|
||||
func (c *config) IsKeySet(key string) bool {
|
||||
c.RLock()
|
||||
defer c.RUnlock()
|
||||
return c.v.IsSet(key)
|
||||
}
|
||||
|
||||
func (c *config) GetBool(key string) (bool, bool) {
|
||||
c.RLock()
|
||||
defer c.RUnlock()
|
||||
@@ -340,6 +380,11 @@ type TestConfig struct {
|
||||
Overrides map[string]interface{}
|
||||
}
|
||||
|
||||
func (c *TestConfig) IsKeySet(key string) bool {
|
||||
_, ok := c.Overrides[key]
|
||||
return ok || c.Config.IsKeySet(key)
|
||||
}
|
||||
|
||||
func (c *TestConfig) GetBool(key string) (bool, bool) {
|
||||
val, ok := c.Overrides[key]
|
||||
if ok {
|
||||
|
@@ -10,7 +10,7 @@ import (
|
||||
"github.com/42wim/matterbridge/bridge"
|
||||
"github.com/42wim/matterbridge/bridge/config"
|
||||
"github.com/42wim/matterbridge/bridge/helper"
|
||||
"github.com/bwmarrin/discordgo"
|
||||
"github.com/matterbridge/discordgo"
|
||||
)
|
||||
|
||||
const MessageLength = 1950
|
||||
@@ -21,6 +21,7 @@ type Bdiscord struct {
|
||||
c *discordgo.Session
|
||||
|
||||
nick string
|
||||
userID string
|
||||
guildID string
|
||||
webhookID string
|
||||
webhookToken string
|
||||
@@ -33,6 +34,8 @@ type Bdiscord struct {
|
||||
membersMutex sync.RWMutex
|
||||
userMemberMap map[string]*discordgo.Member
|
||||
nickMemberMap map[string]*discordgo.Member
|
||||
webhookCache map[string]string
|
||||
webhookMutex sync.RWMutex
|
||||
}
|
||||
|
||||
func New(cfg *bridge.Config) bridge.Bridger {
|
||||
@@ -40,6 +43,7 @@ func New(cfg *bridge.Config) bridge.Bridger {
|
||||
b.userMemberMap = make(map[string]*discordgo.Member)
|
||||
b.nickMemberMap = make(map[string]*discordgo.Member)
|
||||
b.channelInfoMap = make(map[string]*config.ChannelInfo)
|
||||
b.webhookCache = make(map[string]string)
|
||||
if b.GetString("WebhookURL") != "" {
|
||||
b.Log.Debug("Configuring Discord Incoming Webhook")
|
||||
b.webhookID, b.webhookToken = b.splitURL(b.GetString("WebhookURL"))
|
||||
@@ -92,6 +96,7 @@ func (b *Bdiscord) Connect() error {
|
||||
}
|
||||
serverName := strings.Replace(b.GetString("Server"), "ID:", "", -1)
|
||||
b.nick = userinfo.Username
|
||||
b.userID = userinfo.ID
|
||||
b.channelsMutex.Lock()
|
||||
for _, guild := range guilds {
|
||||
if guild.Name == serverName || guild.ID == serverName {
|
||||
@@ -114,30 +119,37 @@ func (b *Bdiscord) Connect() error {
|
||||
b.Log.Infof("Server=\"%s\" # Server ID", guild.ID)
|
||||
}
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
b.channelsMutex.RLock()
|
||||
if b.GetString("WebhookURL") == "" {
|
||||
for _, channel := range b.channels {
|
||||
b.Log.Debugf("found channel %#v", channel)
|
||||
}
|
||||
} else {
|
||||
b.canEditWebhooks = true
|
||||
for _, channel := range b.channels {
|
||||
b.Log.Debugf("found channel %#v; verifying PermissionManageWebhooks", channel)
|
||||
perms, permsErr := b.c.State.UserChannelPermissions(userinfo.ID, channel.ID)
|
||||
manageWebhooks := discordgo.PermissionManageWebhooks
|
||||
if permsErr != nil || perms&manageWebhooks != manageWebhooks {
|
||||
b.Log.Warnf("Can't manage webhooks in channel \"%s\"", channel.Name)
|
||||
b.canEditWebhooks = false
|
||||
manageWebhooks := discordgo.PermissionManageWebhooks
|
||||
var channelsDenied []string
|
||||
for _, info := range b.Channels {
|
||||
id := b.getChannelID(info.Name) // note(qaisjp): this readlocks channelsMutex
|
||||
b.Log.Debugf("Verifying PermissionManageWebhooks for %s with ID %s", info.ID, id)
|
||||
|
||||
perms, permsErr := b.c.UserChannelPermissions(userinfo.ID, id)
|
||||
if permsErr != nil {
|
||||
b.Log.Warnf("Failed to check PermissionManageWebhooks in channel \"%s\": %s", info.Name, permsErr.Error())
|
||||
} else if perms&manageWebhooks == manageWebhooks {
|
||||
continue
|
||||
}
|
||||
channelsDenied = append(channelsDenied, fmt.Sprintf("%#v", info.Name))
|
||||
}
|
||||
|
||||
b.canEditWebhooks = len(channelsDenied) == 0
|
||||
if b.canEditWebhooks {
|
||||
b.Log.Info("Can manage webhooks; will edit channel for global webhook on send")
|
||||
} else {
|
||||
b.Log.Warn("Can't manage webhooks; won't edit channel for global webhook on send")
|
||||
b.Log.Warn("Can't manage webhooks in channels: ", strings.Join(channelsDenied, ", "))
|
||||
}
|
||||
}
|
||||
b.channelsMutex.RUnlock()
|
||||
@@ -179,6 +191,8 @@ func (b *Bdiscord) JoinChannel(channel config.ChannelInfo) error {
|
||||
func (b *Bdiscord) Send(msg config.Message) (string, error) {
|
||||
b.Log.Debugf("=> Receiving %#v", msg)
|
||||
|
||||
origMsgID := msg.ID
|
||||
|
||||
channelID := b.getChannelID(msg.Channel)
|
||||
if channelID == "" {
|
||||
return "", fmt.Errorf("Could not find channelID for %v", msg.Channel)
|
||||
@@ -215,12 +229,13 @@ func (b *Bdiscord) Send(msg config.Message) (string, error) {
|
||||
// Use webhook to send the message
|
||||
if wID != "" && msg.Event != config.EventMsgDelete {
|
||||
// skip events
|
||||
if msg.Event != "" && msg.Event != config.EventJoinLeave && msg.Event != config.EventTopicChange {
|
||||
if msg.Event != "" && msg.Event != config.EventUserAction && msg.Event != config.EventJoinLeave && msg.Event != config.EventTopicChange {
|
||||
return "", nil
|
||||
}
|
||||
|
||||
// If we are editing a message, delete the old message
|
||||
if msg.ID != "" {
|
||||
msg.ID = b.getCacheID(msg.ID)
|
||||
b.Log.Debugf("Deleting edited webhook message")
|
||||
err := b.c.ChannelMessageDelete(channelID, msg.ID)
|
||||
if err != nil {
|
||||
@@ -264,6 +279,8 @@ func (b *Bdiscord) Send(msg config.Message) (string, error) {
|
||||
if msg == nil {
|
||||
return "", nil
|
||||
}
|
||||
|
||||
b.updateCacheID(origMsgID, msg.ID)
|
||||
return msg.ID, nil
|
||||
}
|
||||
|
||||
@@ -274,6 +291,7 @@ func (b *Bdiscord) Send(msg config.Message) (string, error) {
|
||||
if msg.ID == "" {
|
||||
return "", nil
|
||||
}
|
||||
msg.ID = b.getCacheID(msg.ID)
|
||||
err := b.c.ChannelMessageDelete(channelID, msg.ID)
|
||||
return "", err
|
||||
}
|
||||
@@ -380,6 +398,19 @@ func (b *Bdiscord) webhookSend(msg *config.Message, webhookID, token string) (*d
|
||||
err error
|
||||
)
|
||||
|
||||
// If avatar is unset, check if UseLocalAvatar contains the message's
|
||||
// account or protocol, and if so, try to find a local avatar
|
||||
if msg.Avatar == "" {
|
||||
for _, val := range b.GetStringSlice("UseLocalAvatar") {
|
||||
if msg.Protocol == val || msg.Account == val {
|
||||
if avatar := b.findAvatar(msg); avatar != "" {
|
||||
msg.Avatar = avatar
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// WebhookParams can have either `Content` or `File`.
|
||||
|
||||
// We can't send empty messages.
|
||||
@@ -429,3 +460,11 @@ func (b *Bdiscord) webhookSend(msg *config.Message, webhookID, token string) (*d
|
||||
}
|
||||
return res, err
|
||||
}
|
||||
|
||||
func (b *Bdiscord) findAvatar(m *config.Message) string {
|
||||
member, err := b.getGuildMemberByNick(m.Username)
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
return member.User.AvatarURL("")
|
||||
}
|
||||
|
@@ -2,7 +2,7 @@ package bdiscord
|
||||
|
||||
import (
|
||||
"github.com/42wim/matterbridge/bridge/config"
|
||||
"github.com/bwmarrin/discordgo"
|
||||
"github.com/matterbridge/discordgo"
|
||||
)
|
||||
|
||||
func (b *Bdiscord) messageDelete(s *discordgo.Session, m *discordgo.MessageDelete) { //nolint:unparam
|
||||
@@ -36,6 +36,11 @@ func (b *Bdiscord) messageTyping(s *discordgo.Session, m *discordgo.TypingStart)
|
||||
return
|
||||
}
|
||||
|
||||
// Ignore our own typing messages
|
||||
if m.UserID == b.userID {
|
||||
return
|
||||
}
|
||||
|
||||
rmsg := config.Message{Account: b.Account, Event: config.EventUserTyping}
|
||||
rmsg.Channel = b.getChannelName(m.ChannelID)
|
||||
b.Remote <- rmsg
|
||||
@@ -90,12 +95,12 @@ func (b *Bdiscord) messageCreate(s *discordgo.Session, m *discordgo.MessageCreat
|
||||
// set channel name
|
||||
rmsg.Channel = b.getChannelName(m.ChannelID)
|
||||
|
||||
// set username
|
||||
if !b.GetBool("UseUserName") {
|
||||
fromWebhook := m.WebhookID != ""
|
||||
if !fromWebhook && !b.GetBool("UseUserName") {
|
||||
rmsg.Username = b.getNick(m.Author, m.GuildID)
|
||||
} else {
|
||||
rmsg.Username = m.Author.Username
|
||||
if b.GetBool("UseDiscriminator") {
|
||||
if !fromWebhook && b.GetBool("UseDiscriminator") {
|
||||
rmsg.Username += "#" + m.Author.Discriminator
|
||||
}
|
||||
}
|
||||
@@ -103,7 +108,7 @@ func (b *Bdiscord) messageCreate(s *discordgo.Session, m *discordgo.MessageCreat
|
||||
// if we have embedded content add it to text
|
||||
if b.GetBool("ShowEmbeds") && m.Message.Embeds != nil {
|
||||
for _, embed := range m.Message.Embeds {
|
||||
rmsg.Text = rmsg.Text + "embed: " + embed.Title + " - " + embed.Description + " - " + embed.URL + "\n"
|
||||
rmsg.Text += handleEmbed(embed)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -119,6 +124,9 @@ func (b *Bdiscord) messageCreate(s *discordgo.Session, m *discordgo.MessageCreat
|
||||
rmsg.Event = config.EventUserAction
|
||||
}
|
||||
|
||||
// Replace emotes
|
||||
rmsg.Text = replaceEmotes(rmsg.Text)
|
||||
|
||||
b.Log.Debugf("<= Sending message from %s on %s to gateway", m.Author.Username, b.Account)
|
||||
b.Log.Debugf("<= Message is %#v", rmsg)
|
||||
b.Remote <- rmsg
|
||||
@@ -192,3 +200,33 @@ func (b *Bdiscord) memberRemove(s *discordgo.Session, m *discordgo.GuildMemberRe
|
||||
b.Log.Debugf("<= Message is %#v", rmsg)
|
||||
b.Remote <- rmsg
|
||||
}
|
||||
|
||||
func handleEmbed(embed *discordgo.MessageEmbed) string {
|
||||
var t []string
|
||||
var result string
|
||||
|
||||
t = append(t, embed.Title)
|
||||
t = append(t, embed.Description)
|
||||
t = append(t, embed.URL)
|
||||
|
||||
i := 0
|
||||
for _, e := range t {
|
||||
if e == "" {
|
||||
continue
|
||||
}
|
||||
|
||||
i++
|
||||
if i == 1 {
|
||||
result += " embed: " + e
|
||||
continue
|
||||
}
|
||||
|
||||
result += " - " + e
|
||||
}
|
||||
|
||||
if result != "" {
|
||||
result += "\n"
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
58
bridge/discord/handlers_test.go
Normal file
58
bridge/discord/handlers_test.go
Normal file
@@ -0,0 +1,58 @@
|
||||
package bdiscord
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/matterbridge/discordgo"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestHandleEmbed(t *testing.T) {
|
||||
testcases := map[string]struct {
|
||||
embed *discordgo.MessageEmbed
|
||||
result string
|
||||
}{
|
||||
"allempty": {
|
||||
embed: &discordgo.MessageEmbed{},
|
||||
result: "",
|
||||
},
|
||||
"one": {
|
||||
embed: &discordgo.MessageEmbed{
|
||||
Title: "blah",
|
||||
},
|
||||
result: " embed: blah\n",
|
||||
},
|
||||
"two": {
|
||||
embed: &discordgo.MessageEmbed{
|
||||
Title: "blah",
|
||||
Description: "blah2",
|
||||
},
|
||||
result: " embed: blah - blah2\n",
|
||||
},
|
||||
"three": {
|
||||
embed: &discordgo.MessageEmbed{
|
||||
Title: "blah",
|
||||
Description: "blah2",
|
||||
URL: "blah3",
|
||||
},
|
||||
result: " embed: blah - blah2 - blah3\n",
|
||||
},
|
||||
"twob": {
|
||||
embed: &discordgo.MessageEmbed{
|
||||
Description: "blah2",
|
||||
URL: "blah3",
|
||||
},
|
||||
result: " embed: blah2 - blah3\n",
|
||||
},
|
||||
"oneb": {
|
||||
embed: &discordgo.MessageEmbed{
|
||||
URL: "blah3",
|
||||
},
|
||||
result: " embed: blah3\n",
|
||||
},
|
||||
}
|
||||
|
||||
for name, tc := range testcases {
|
||||
assert.Equalf(t, tc.result, handleEmbed(tc.embed), "Testcases %s", name)
|
||||
}
|
||||
}
|
@@ -6,7 +6,7 @@ import (
|
||||
"strings"
|
||||
"unicode"
|
||||
|
||||
"github.com/bwmarrin/discordgo"
|
||||
"github.com/matterbridge/discordgo"
|
||||
)
|
||||
|
||||
func (b *Bdiscord) getNick(user *discordgo.User, guildID string) string {
|
||||
@@ -137,6 +137,7 @@ var (
|
||||
// See https://discordapp.com/developers/docs/reference#message-formatting.
|
||||
channelMentionRE = regexp.MustCompile("<#[0-9]+>")
|
||||
userMentionRE = regexp.MustCompile("@[^@\n]{1,32}")
|
||||
emoteRE = regexp.MustCompile(`<a?(:\w+:)\d+>`)
|
||||
)
|
||||
|
||||
func (b *Bdiscord) replaceChannelMentions(text string) string {
|
||||
@@ -182,9 +183,14 @@ func (b *Bdiscord) replaceUserMentions(text string) string {
|
||||
return userMentionRE.ReplaceAllStringFunc(text, replaceUserMentionFunc)
|
||||
}
|
||||
|
||||
func replaceEmotes(text string) string {
|
||||
return emoteRE.ReplaceAllString(text, "$1")
|
||||
}
|
||||
|
||||
func (b *Bdiscord) replaceAction(text string) (string, bool) {
|
||||
if strings.HasPrefix(text, "_") && strings.HasSuffix(text, "_") {
|
||||
return text[1 : len(text)-1], true
|
||||
length := len(text)
|
||||
if length > 1 && text[0] == '_' && text[length-1] == '_' {
|
||||
return text[1 : length-1], true
|
||||
}
|
||||
return text, false
|
||||
}
|
||||
@@ -203,6 +209,40 @@ func (b *Bdiscord) splitURL(url string) (string, string) {
|
||||
return webhookURLSplit[webhookIdxID], webhookURLSplit[webhookIdxToken]
|
||||
}
|
||||
|
||||
// getcacheID tries to find a corresponding msgID in the webhook cache.
|
||||
// if not found returns the original request.
|
||||
func (b *Bdiscord) getCacheID(msgID string) string {
|
||||
b.webhookMutex.RLock()
|
||||
defer b.webhookMutex.RUnlock()
|
||||
for k, v := range b.webhookCache {
|
||||
if msgID == k {
|
||||
return v
|
||||
}
|
||||
}
|
||||
return msgID
|
||||
}
|
||||
|
||||
// updateCacheID updates the cache so that the newID takes the place of
|
||||
// the original ID. This is used for edit/deletes in combination with webhooks
|
||||
// as editing a message via webhook means deleting the message and creating a
|
||||
// new message (with a new ID). This ID needs to be set instead of the original ID
|
||||
func (b *Bdiscord) updateCacheID(origID, newID string) {
|
||||
b.webhookMutex.Lock()
|
||||
match := false
|
||||
for k, v := range b.webhookCache {
|
||||
if v == origID {
|
||||
delete(b.webhookCache, k)
|
||||
b.webhookCache[origID] = newID
|
||||
match = true
|
||||
continue
|
||||
}
|
||||
}
|
||||
if !match && origID != "" {
|
||||
b.webhookCache[origID] = newID
|
||||
}
|
||||
b.webhookMutex.Unlock()
|
||||
}
|
||||
|
||||
func enumerateUsernames(s string) []string {
|
||||
onlySpace := true
|
||||
for _, r := range s {
|
||||
|
@@ -180,7 +180,7 @@ func ClipMessage(text string, length int) string {
|
||||
|
||||
// ParseMarkdown takes in an input string as markdown and parses it to html
|
||||
func ParseMarkdown(input string) string {
|
||||
extensions := parser.HardLineBreak
|
||||
extensions := parser.HardLineBreak | parser.NoIntraEmphasis
|
||||
markdownParser := parser.NewWithExtensions(extensions)
|
||||
renderer := html.NewRenderer(html.RendererOptions{
|
||||
Flags: 0,
|
||||
|
@@ -10,8 +10,8 @@ import (
|
||||
|
||||
"github.com/42wim/matterbridge/bridge/config"
|
||||
"github.com/42wim/matterbridge/bridge/helper"
|
||||
"github.com/dfordsoft/golib/ic"
|
||||
"github.com/lrstanley/girc"
|
||||
"github.com/missdeer/golib/ic"
|
||||
"github.com/paulrosania/go-charset/charset"
|
||||
"github.com/saintfish/chardet"
|
||||
|
||||
@@ -54,12 +54,12 @@ func (b *Birc) handleFiles(msg *config.Message) bool {
|
||||
for _, f := range msg.Extra["file"] {
|
||||
fi := f.(config.FileInfo)
|
||||
if fi.Comment != "" {
|
||||
msg.Text += fi.Comment + ": "
|
||||
msg.Text += fi.Comment + " : "
|
||||
}
|
||||
if fi.URL != "" {
|
||||
msg.Text = fi.URL
|
||||
if fi.Comment != "" {
|
||||
msg.Text = fi.Comment + ": " + fi.URL
|
||||
msg.Text = fi.Comment + " : " + fi.URL
|
||||
}
|
||||
}
|
||||
b.Local <- config.Message{Text: msg.Text, Username: msg.Username, Channel: msg.Channel, Event: msg.Event}
|
||||
|
@@ -14,6 +14,7 @@ import (
|
||||
"github.com/42wim/matterbridge/bridge/config"
|
||||
"github.com/42wim/matterbridge/bridge/helper"
|
||||
"github.com/lrstanley/girc"
|
||||
stripmd "github.com/writeas/go-strip-markdown"
|
||||
|
||||
// We need to import the 'data' package as an implicit dependency.
|
||||
// See: https://godoc.org/github.com/paulrosania/go-charset/charset
|
||||
@@ -156,6 +157,10 @@ func (b *Birc) Send(msg config.Message) (string, error) {
|
||||
}
|
||||
|
||||
var msgLines []string
|
||||
if b.GetBool("StripMarkdown") {
|
||||
msg.Text = stripmd.Strip(msg.Text)
|
||||
}
|
||||
|
||||
if b.GetBool("MessageSplit") {
|
||||
msgLines = helper.GetSubLines(msg.Text, b.MessageLength)
|
||||
} else {
|
||||
@@ -167,12 +172,8 @@ func (b *Birc) Send(msg config.Message) (string, error) {
|
||||
return "", nil
|
||||
}
|
||||
|
||||
b.Local <- config.Message{
|
||||
Text: msgLines[i],
|
||||
Username: msg.Username,
|
||||
Channel: msg.Channel,
|
||||
Event: msg.Event,
|
||||
}
|
||||
msg.Text = msgLines[i]
|
||||
b.Local <- msg
|
||||
}
|
||||
return "", nil
|
||||
}
|
||||
@@ -205,7 +206,7 @@ func (b *Birc) doSend() {
|
||||
for msg := range b.Local {
|
||||
<-throttle.C
|
||||
username := msg.Username
|
||||
if b.GetBool("Colornicks") {
|
||||
if b.GetBool("Colornicks") && len(username) > 1 {
|
||||
checksum := crc32.ChecksumIEEE([]byte(msg.Username))
|
||||
colorCode := checksum%14 + 2 // quick fix - prevent white or black color codes
|
||||
username = fmt.Sprintf("\x03%02d%s\x0F", colorCode, msg.Username)
|
||||
@@ -249,6 +250,8 @@ func (b *Birc) getClient() (*girc.Client, error) {
|
||||
SSL: b.GetBool("UseTLS"),
|
||||
TLSConfig: &tls.Config{InsecureSkipVerify: b.GetBool("SkipTLSVerify"), ServerName: server}, //nolint:gosec
|
||||
PingDelay: time.Minute,
|
||||
// skip gIRC internal rate limiting, since we have our own throttling
|
||||
AllowFlood: true,
|
||||
})
|
||||
return i, nil
|
||||
}
|
||||
|
@@ -4,7 +4,7 @@ import (
|
||||
"strconv"
|
||||
|
||||
"github.com/42wim/matterbridge/bridge/config"
|
||||
"github.com/keybase/go-keybase-chat-bot/kbchat"
|
||||
"github.com/keybase/go-keybase-chat-bot/kbchat/types/chat1"
|
||||
)
|
||||
|
||||
func (b *Bkeybase) handleKeybase() {
|
||||
@@ -20,7 +20,7 @@ func (b *Bkeybase) handleKeybase() {
|
||||
b.Log.Errorf("failed to read message: %s", err.Error())
|
||||
}
|
||||
|
||||
if msg.Message.Content.Type != "text" {
|
||||
if msg.Message.Content.TypeName != "text" {
|
||||
continue
|
||||
}
|
||||
|
||||
@@ -34,7 +34,7 @@ func (b *Bkeybase) handleKeybase() {
|
||||
}()
|
||||
}
|
||||
|
||||
func (b *Bkeybase) handleMessage(msg kbchat.Message) {
|
||||
func (b *Bkeybase) handleMessage(msg chat1.MsgSummary) {
|
||||
b.Log.Debugf("== Receiving event: %#v", msg)
|
||||
if msg.Channel.TopicName != b.channel || msg.Channel.Name != b.team {
|
||||
return
|
||||
@@ -45,10 +45,10 @@ func (b *Bkeybase) handleMessage(msg kbchat.Message) {
|
||||
// TODO download avatar
|
||||
|
||||
// Create our message
|
||||
rmsg := config.Message{Username: msg.Sender.Username, Text: msg.Content.Text.Body, UserID: msg.Sender.Uid, Channel: msg.Channel.TopicName, ID: strconv.Itoa(msg.MsgID), Account: b.Account}
|
||||
rmsg := config.Message{Username: msg.Sender.Username, Text: msg.Content.Text.Body, UserID: string(msg.Sender.Uid), Channel: msg.Channel.TopicName, ID: strconv.Itoa(int(msg.Id)), Account: b.Account}
|
||||
|
||||
// Text must be a string
|
||||
if msg.Content.Type != "text" {
|
||||
if msg.Content.TypeName != "text" {
|
||||
b.Log.Errorf("message is not text")
|
||||
return
|
||||
}
|
||||
|
@@ -90,16 +90,17 @@ func (b *Bkeybase) Send(msg config.Message) (string, error) {
|
||||
return "", err
|
||||
}
|
||||
|
||||
_, _ = b.kbc.SendAttachmentByTeam(b.team, fpath, fcaption, &b.channel)
|
||||
_, _ = b.kbc.SendAttachmentByTeam(b.team, &b.channel, fpath, fcaption)
|
||||
}
|
||||
|
||||
return "", nil
|
||||
}
|
||||
|
||||
// Send regular message
|
||||
resp, err := b.kbc.SendMessageByTeamName(b.team, msg.Username+msg.Text, &b.channel)
|
||||
text := msg.Username + msg.Text
|
||||
resp, err := b.kbc.SendMessageByTeamName(b.team, &b.channel, text)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return strconv.Itoa(resp.Result.MsgID), err
|
||||
return strconv.Itoa(int(*resp.Result.MessageID)), err
|
||||
}
|
||||
|
@@ -124,6 +124,14 @@ func (b *Bmatrix) Send(msg config.Message) (string, error) {
|
||||
return resp.EventID, err
|
||||
}
|
||||
|
||||
if b.GetBool("HTMLDisable") {
|
||||
resp, err := b.mc.SendText(channel, msg.Username+msg.Text)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return resp.EventID, err
|
||||
}
|
||||
|
||||
username := html.EscapeString(msg.Username)
|
||||
// check if we have a </tag>. if we have, we don't escape HTML. #696
|
||||
if b.htmlTag.MatchString(msg.Username) {
|
||||
@@ -172,10 +180,15 @@ func (b *Bmatrix) handleEvent(ev *matrix.Event) {
|
||||
return
|
||||
}
|
||||
|
||||
// TODO download avatar
|
||||
|
||||
// Create our message
|
||||
rmsg := config.Message{Username: ev.Sender[1:], Channel: channel, Account: b.Account, UserID: ev.Sender, ID: ev.ID}
|
||||
rmsg := config.Message{
|
||||
Username: ev.Sender[1:],
|
||||
Channel: channel,
|
||||
Account: b.Account,
|
||||
UserID: ev.Sender,
|
||||
ID: ev.ID,
|
||||
Avatar: b.getAvatarURL(ev.Sender),
|
||||
}
|
||||
|
||||
// Text must be a string
|
||||
if rmsg.Text, ok = ev.Content["body"].(string); !ok {
|
||||
@@ -358,3 +371,17 @@ func (b *Bmatrix) containsAttachment(content map[string]interface{}) bool {
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// getAvatarURL returns the avatar URL of the specified sender
|
||||
func (b *Bmatrix) getAvatarURL(sender string) string {
|
||||
mxcURL, err := b.mc.GetSenderAvatarURL(sender)
|
||||
if err != nil {
|
||||
b.Log.Errorf("getAvatarURL failed: %s", err)
|
||||
return ""
|
||||
}
|
||||
url := strings.ReplaceAll(mxcURL, "mxc://", b.GetString("Server")+"/_matrix/media/r0/thumbnail/")
|
||||
if url != "" {
|
||||
url += "?width=37&height=37&method=crop"
|
||||
}
|
||||
return url
|
||||
}
|
||||
|
101
bridge/msteams/handler.go
Normal file
101
bridge/msteams/handler.go
Normal file
@@ -0,0 +1,101 @@
|
||||
package bmsteams
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"strings"
|
||||
|
||||
"github.com/42wim/matterbridge/bridge/config"
|
||||
"github.com/42wim/matterbridge/bridge/helper"
|
||||
|
||||
msgraph "github.com/yaegashi/msgraph.go/beta"
|
||||
)
|
||||
|
||||
func (b *Bmsteams) findFile(weburl string) (string, error) {
|
||||
itemRB, err := b.gc.GetDriveItemByURL(b.ctx, weburl)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
itemRB.Workbook().Worksheets()
|
||||
b.gc.Workbooks()
|
||||
item, err := itemRB.Request().Get(b.ctx)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
if url, ok := item.GetAdditionalData("@microsoft.graph.downloadUrl"); ok {
|
||||
return url.(string), nil
|
||||
}
|
||||
return "", nil
|
||||
}
|
||||
|
||||
// handleDownloadFile handles file download
|
||||
func (b *Bmsteams) handleDownloadFile(rmsg *config.Message, filename, weburl string) error {
|
||||
realURL, err := b.findFile(weburl)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// Actually download the file.
|
||||
data, err := helper.DownloadFile(realURL)
|
||||
if err != nil {
|
||||
return fmt.Errorf("download %s failed %#v", weburl, err)
|
||||
}
|
||||
|
||||
// If a comment is attached to the file(s) it is in the 'Text' field of the teams messge event
|
||||
// and should be added as comment to only one of the files. We reset the 'Text' field to ensure
|
||||
// that the comment is not duplicated.
|
||||
comment := rmsg.Text
|
||||
rmsg.Text = ""
|
||||
helper.HandleDownloadData(b.Log, rmsg, filename, comment, weburl, data, b.General)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (b *Bmsteams) handleAttachments(rmsg *config.Message, msg msgraph.ChatMessage) {
|
||||
for _, a := range msg.Attachments {
|
||||
//remove the attachment tags from the text
|
||||
rmsg.Text = attachRE.ReplaceAllString(rmsg.Text, "")
|
||||
|
||||
//handle a code snippet (code block)
|
||||
if *a.ContentType == "application/vnd.microsoft.card.codesnippet" {
|
||||
b.handleCodeSnippet(rmsg, a)
|
||||
continue
|
||||
}
|
||||
|
||||
//handle the download
|
||||
err := b.handleDownloadFile(rmsg, *a.Name, *a.ContentURL)
|
||||
if err != nil {
|
||||
b.Log.Errorf("download of %s failed: %s", *a.Name, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
type AttachContent struct {
|
||||
Language string `json:"language"`
|
||||
CodeSnippetURL string `json:"codeSnippetUrl"`
|
||||
}
|
||||
|
||||
func (b *Bmsteams) handleCodeSnippet(rmsg *config.Message, attach msgraph.ChatMessageAttachment) {
|
||||
var content AttachContent
|
||||
err := json.Unmarshal([]byte(*attach.Content), &content)
|
||||
if err != nil {
|
||||
b.Log.Errorf("unmarshal codesnippet failed: %s", err)
|
||||
return
|
||||
}
|
||||
s := strings.Split(content.CodeSnippetURL, "/")
|
||||
if len(s) != 13 {
|
||||
b.Log.Errorf("codesnippetUrl has unexpected size: %s", content.CodeSnippetURL)
|
||||
return
|
||||
}
|
||||
resp, err := b.gc.Teams().Request().Client().Get(content.CodeSnippetURL)
|
||||
if err != nil {
|
||||
b.Log.Errorf("retrieving snippet content failed:%s", err)
|
||||
return
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
res, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
b.Log.Errorf("reading snippet data failed: %s", err)
|
||||
return
|
||||
}
|
||||
rmsg.Text = rmsg.Text + "\n```" + content.Language + "\n" + string(res) + "\n```\n"
|
||||
}
|
224
bridge/msteams/msteams.go
Normal file
224
bridge/msteams/msteams.go
Normal file
@@ -0,0 +1,224 @@
|
||||
package bmsteams
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"os"
|
||||
"regexp"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/42wim/matterbridge/bridge"
|
||||
"github.com/42wim/matterbridge/bridge/config"
|
||||
"github.com/davecgh/go-spew/spew"
|
||||
|
||||
"github.com/mattn/godown"
|
||||
msgraph "github.com/yaegashi/msgraph.go/beta"
|
||||
"github.com/yaegashi/msgraph.go/msauth"
|
||||
|
||||
"golang.org/x/oauth2"
|
||||
)
|
||||
|
||||
var defaultScopes = []string{"openid", "profile", "offline_access", "Group.Read.All", "Group.ReadWrite.All"}
|
||||
var attachRE = regexp.MustCompile(`<attachment id=.*?attachment>`)
|
||||
|
||||
type Bmsteams struct {
|
||||
gc *msgraph.GraphServiceRequestBuilder
|
||||
ctx context.Context
|
||||
botID string
|
||||
*bridge.Config
|
||||
}
|
||||
|
||||
func New(cfg *bridge.Config) bridge.Bridger {
|
||||
return &Bmsteams{Config: cfg}
|
||||
}
|
||||
|
||||
func (b *Bmsteams) Connect() error {
|
||||
tokenCachePath := b.GetString("sessionFile")
|
||||
if tokenCachePath == "" {
|
||||
tokenCachePath = "msteams_session.json"
|
||||
}
|
||||
ctx := context.Background()
|
||||
m := msauth.NewManager()
|
||||
m.LoadFile(tokenCachePath) //nolint:errcheck
|
||||
ts, err := m.DeviceAuthorizationGrant(ctx, b.GetString("TenantID"), b.GetString("ClientID"), defaultScopes, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = m.SaveFile(tokenCachePath)
|
||||
if err != nil {
|
||||
b.Log.Errorf("Couldn't save sessionfile in %s: %s", tokenCachePath, err)
|
||||
}
|
||||
// make file readable only for matterbridge user
|
||||
err = os.Chmod(tokenCachePath, 0600)
|
||||
if err != nil {
|
||||
b.Log.Errorf("Couldn't change permissions for %s: %s", tokenCachePath, err)
|
||||
}
|
||||
httpClient := oauth2.NewClient(ctx, ts)
|
||||
graphClient := msgraph.NewClient(httpClient)
|
||||
b.gc = graphClient
|
||||
b.ctx = ctx
|
||||
|
||||
err = b.setBotID()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
b.Log.Info("Connection succeeded")
|
||||
return nil
|
||||
}
|
||||
|
||||
func (b *Bmsteams) Disconnect() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (b *Bmsteams) JoinChannel(channel config.ChannelInfo) error {
|
||||
go func(name string) {
|
||||
for {
|
||||
err := b.poll(name)
|
||||
if err != nil {
|
||||
b.Log.Errorf("polling failed for %s: %s. retrying in 5 seconds", name, err)
|
||||
}
|
||||
time.Sleep(time.Second * 5)
|
||||
}
|
||||
}(channel.Name)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (b *Bmsteams) Send(msg config.Message) (string, error) {
|
||||
b.Log.Debugf("=> Receiving %#v", msg)
|
||||
if msg.ParentID != "" && msg.ParentID != "msg-parent-not-found" {
|
||||
return b.sendReply(msg)
|
||||
}
|
||||
if msg.ParentID == "msg-parent-not-found" {
|
||||
msg.ParentID = ""
|
||||
msg.Text = fmt.Sprintf("[thread]: %s", msg.Text)
|
||||
}
|
||||
ct := b.gc.Teams().ID(b.GetString("TeamID")).Channels().ID(msg.Channel).Messages().Request()
|
||||
text := msg.Username + msg.Text
|
||||
content := &msgraph.ItemBody{Content: &text}
|
||||
rmsg := &msgraph.ChatMessage{Body: content}
|
||||
res, err := ct.Add(b.ctx, rmsg)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return *res.ID, nil
|
||||
}
|
||||
|
||||
func (b *Bmsteams) sendReply(msg config.Message) (string, error) {
|
||||
ct := b.gc.Teams().ID(b.GetString("TeamID")).Channels().ID(msg.Channel).Messages().ID(msg.ParentID).Replies().Request()
|
||||
// Handle prefix hint for unthreaded messages.
|
||||
|
||||
text := msg.Username + msg.Text
|
||||
content := &msgraph.ItemBody{Content: &text}
|
||||
rmsg := &msgraph.ChatMessage{Body: content}
|
||||
res, err := ct.Add(b.ctx, rmsg)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return *res.ID, nil
|
||||
}
|
||||
|
||||
func (b *Bmsteams) getMessages(channel string) ([]msgraph.ChatMessage, error) {
|
||||
ct := b.gc.Teams().ID(b.GetString("TeamID")).Channels().ID(channel).Messages().Request()
|
||||
rct, err := ct.Get(b.ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
b.Log.Debugf("got %#v messages", len(rct))
|
||||
return rct, nil
|
||||
}
|
||||
|
||||
//nolint:gocognit
|
||||
func (b *Bmsteams) poll(channelName string) error {
|
||||
msgmap := make(map[string]time.Time)
|
||||
b.Log.Debug("getting initial messages")
|
||||
res, err := b.getMessages(channelName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, msg := range res {
|
||||
msgmap[*msg.ID] = *msg.CreatedDateTime
|
||||
if msg.LastModifiedDateTime != nil {
|
||||
msgmap[*msg.ID] = *msg.LastModifiedDateTime
|
||||
}
|
||||
}
|
||||
time.Sleep(time.Second * 5)
|
||||
b.Log.Debug("polling for messages")
|
||||
for {
|
||||
res, err := b.getMessages(channelName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for i := len(res) - 1; i >= 0; i-- {
|
||||
msg := res[i]
|
||||
if mtime, ok := msgmap[*msg.ID]; ok {
|
||||
if mtime == *msg.CreatedDateTime && msg.LastModifiedDateTime == nil {
|
||||
continue
|
||||
}
|
||||
if msg.LastModifiedDateTime != nil && mtime == *msg.LastModifiedDateTime {
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
if b.GetBool("debug") {
|
||||
b.Log.Debug("Msg dump: ", spew.Sdump(msg))
|
||||
}
|
||||
|
||||
// skip non-user message for now.
|
||||
if msg.From.User == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
if *msg.From.User.ID == b.botID {
|
||||
b.Log.Debug("skipping own message")
|
||||
msgmap[*msg.ID] = *msg.CreatedDateTime
|
||||
continue
|
||||
}
|
||||
|
||||
msgmap[*msg.ID] = *msg.CreatedDateTime
|
||||
if msg.LastModifiedDateTime != nil {
|
||||
msgmap[*msg.ID] = *msg.LastModifiedDateTime
|
||||
}
|
||||
b.Log.Debugf("<= Sending message from %s on %s to gateway", *msg.From.User.DisplayName, b.Account)
|
||||
text := b.convertToMD(*msg.Body.Content)
|
||||
rmsg := config.Message{
|
||||
Username: *msg.From.User.DisplayName,
|
||||
Text: text,
|
||||
Channel: channelName,
|
||||
Account: b.Account,
|
||||
Avatar: "",
|
||||
UserID: *msg.From.User.ID,
|
||||
ID: *msg.ID,
|
||||
Extra: make(map[string][]interface{}),
|
||||
}
|
||||
|
||||
b.handleAttachments(&rmsg, msg)
|
||||
b.Log.Debugf("<= Message is %#v", rmsg)
|
||||
b.Remote <- rmsg
|
||||
}
|
||||
time.Sleep(time.Second * 5)
|
||||
}
|
||||
}
|
||||
|
||||
func (b *Bmsteams) setBotID() error {
|
||||
req := b.gc.Me().Request()
|
||||
r, err := req.Get(b.ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
b.botID = *r.ID
|
||||
return nil
|
||||
}
|
||||
|
||||
func (b *Bmsteams) convertToMD(text string) string {
|
||||
if !strings.Contains(text, "<div>") {
|
||||
return text
|
||||
}
|
||||
var sb strings.Builder
|
||||
err := godown.Convert(&sb, strings.NewReader(text), nil)
|
||||
if err != nil {
|
||||
b.Log.Errorf("Couldn't convert message to markdown %s", text)
|
||||
return text
|
||||
}
|
||||
return sb.String()
|
||||
}
|
114
bridge/nctalk/nctalk.go
Normal file
114
bridge/nctalk/nctalk.go
Normal file
@@ -0,0 +1,114 @@
|
||||
package nctalk
|
||||
|
||||
import (
|
||||
"context"
|
||||
"strconv"
|
||||
|
||||
"github.com/42wim/matterbridge/bridge"
|
||||
"github.com/42wim/matterbridge/bridge/config"
|
||||
|
||||
talk "gomod.garykim.dev/nc-talk"
|
||||
"gomod.garykim.dev/nc-talk/ocs"
|
||||
"gomod.garykim.dev/nc-talk/room"
|
||||
"gomod.garykim.dev/nc-talk/user"
|
||||
)
|
||||
|
||||
type Btalk struct {
|
||||
user *user.TalkUser
|
||||
rooms []Broom
|
||||
*bridge.Config
|
||||
}
|
||||
|
||||
func New(cfg *bridge.Config) bridge.Bridger {
|
||||
return &Btalk{Config: cfg}
|
||||
}
|
||||
|
||||
type Broom struct {
|
||||
room *room.TalkRoom
|
||||
ctx context.Context
|
||||
ctxCancel context.CancelFunc
|
||||
}
|
||||
|
||||
func (b *Btalk) Connect() error {
|
||||
b.Log.Info("Connecting")
|
||||
b.user = talk.NewUser(b.GetString("Server"), b.GetString("Login"), b.GetString("Password"))
|
||||
_, err := b.user.Capabilities()
|
||||
if err != nil {
|
||||
b.Log.Error("Cannot Connect")
|
||||
return err
|
||||
}
|
||||
b.Log.Info("Connected")
|
||||
return nil
|
||||
}
|
||||
|
||||
func (b *Btalk) Disconnect() error {
|
||||
for _, r := range b.rooms {
|
||||
r.ctxCancel()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (b *Btalk) JoinChannel(channel config.ChannelInfo) error {
|
||||
newRoom := Broom{
|
||||
room: talk.NewRoom(b.user, channel.Name),
|
||||
}
|
||||
newRoom.ctx, newRoom.ctxCancel = context.WithCancel(context.Background())
|
||||
c, err := newRoom.room.ReceiveMessages(newRoom.ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
b.rooms = append(b.rooms, newRoom)
|
||||
go func() {
|
||||
for msg := range c {
|
||||
// ignore messages that are one of the following
|
||||
// * not a message from a user
|
||||
// * from ourselves
|
||||
if msg.MessageType != ocs.MessageComment || msg.ActorID == b.user.User {
|
||||
continue
|
||||
}
|
||||
remoteMessage := config.Message{
|
||||
Text: msg.Message,
|
||||
Channel: newRoom.room.Token,
|
||||
Username: msg.ActorDisplayName,
|
||||
UserID: msg.ActorID,
|
||||
Account: b.Account,
|
||||
}
|
||||
// It is possible for the ID to not be set on older versions of Talk so we only set it if
|
||||
// the ID is not blank
|
||||
if msg.ID != 0 {
|
||||
remoteMessage.ID = strconv.Itoa(msg.ID)
|
||||
}
|
||||
b.Log.Debugf("<= Message is %#v", remoteMessage)
|
||||
b.Remote <- remoteMessage
|
||||
}
|
||||
}()
|
||||
return nil
|
||||
}
|
||||
|
||||
func (b *Btalk) Send(msg config.Message) (string, error) {
|
||||
r := b.getRoom(msg.Channel)
|
||||
if r == nil {
|
||||
b.Log.Errorf("Could not find room for %v", msg.Channel)
|
||||
return "", nil
|
||||
}
|
||||
|
||||
// Talk currently only supports sending normal messages
|
||||
if msg.Event != "" {
|
||||
return "", nil
|
||||
}
|
||||
sentMessage, err := r.room.SendMessage(msg.Username + msg.Text)
|
||||
if err != nil {
|
||||
b.Log.Errorf("Could not send message to room %v from %v: %v", msg.Channel, msg.Username, err)
|
||||
return "", nil
|
||||
}
|
||||
return strconv.Itoa(sentMessage.ID), nil
|
||||
}
|
||||
|
||||
func (b *Btalk) getRoom(token string) *Broom {
|
||||
for _, r := range b.rooms {
|
||||
if r.room.Token == token {
|
||||
return &r
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
@@ -2,6 +2,7 @@ package brocketchat
|
||||
|
||||
import (
|
||||
"github.com/42wim/matterbridge/bridge/config"
|
||||
"github.com/matterbridge/Rocket.Chat.Go.SDK/models"
|
||||
)
|
||||
|
||||
func (b *Brocketchat) handleRocket() {
|
||||
@@ -38,6 +39,23 @@ func (b *Brocketchat) handleRocketHook(messages chan *config.Message) {
|
||||
}
|
||||
}
|
||||
|
||||
func (b *Brocketchat) handleStatusEvent(ev models.Message, rmsg *config.Message) bool {
|
||||
switch ev.Type {
|
||||
case "":
|
||||
// this is a normal message, no processing needed
|
||||
// return true so the message is not dropped
|
||||
return true
|
||||
case sUserJoined, sUserLeft:
|
||||
rmsg.Event = config.EventJoinLeave
|
||||
return true
|
||||
case sRoomChangedTopic:
|
||||
rmsg.Event = config.EventTopicChange
|
||||
return true
|
||||
}
|
||||
b.Log.Debugf("Dropping message with unknown type: %s", ev.Type)
|
||||
return false
|
||||
}
|
||||
|
||||
func (b *Brocketchat) handleRocketClient(messages chan *config.Message) {
|
||||
for message := range b.messageChan {
|
||||
// skip messages with same ID, apparently messages get duplicated for an unknown reason
|
||||
@@ -59,7 +77,12 @@ func (b *Brocketchat) handleRocketClient(messages chan *config.Message) {
|
||||
UserID: message.User.ID,
|
||||
ID: message.ID,
|
||||
}
|
||||
messages <- rmsg
|
||||
|
||||
// handleStatusEvent returns false if the message should be dropped
|
||||
// in that case it is probably some modification to the channel we do not want to relay
|
||||
if b.handleStatusEvent(m, rmsg) {
|
||||
messages <- rmsg
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -29,6 +29,12 @@ type Brocketchat struct {
|
||||
sync.RWMutex
|
||||
}
|
||||
|
||||
const (
|
||||
sUserJoined = "uj"
|
||||
sUserLeft = "ul"
|
||||
sRoomChangedTopic = "room_changed_topic"
|
||||
)
|
||||
|
||||
func New(cfg *bridge.Config) bridge.Bridger {
|
||||
newCache, err := lru.New(100)
|
||||
if err != nil {
|
||||
|
@@ -1,18 +1,22 @@
|
||||
package bslack
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"html"
|
||||
"time"
|
||||
|
||||
"github.com/42wim/matterbridge/bridge/config"
|
||||
"github.com/42wim/matterbridge/bridge/helper"
|
||||
"github.com/nlopes/slack"
|
||||
"github.com/slack-go/slack"
|
||||
)
|
||||
|
||||
// ErrEventIgnored is for events that should be ignored
|
||||
var ErrEventIgnored = errors.New("this event message should ignored")
|
||||
|
||||
func (b *Bslack) handleSlack() {
|
||||
messages := make(chan *config.Message)
|
||||
if b.GetString(incomingWebhookConfig) != "" {
|
||||
if b.GetString(incomingWebhookConfig) != "" && b.GetString(tokenConfig) == "" {
|
||||
b.Log.Debugf("Choosing webhooks based receiving")
|
||||
go b.handleMatterHook(messages)
|
||||
} else {
|
||||
@@ -53,7 +57,9 @@ func (b *Bslack) handleSlackClient(messages chan *config.Message) {
|
||||
continue
|
||||
}
|
||||
rmsg, err := b.handleTypingEvent(ev)
|
||||
if err != nil {
|
||||
if err == ErrEventIgnored {
|
||||
continue
|
||||
} else if err != nil {
|
||||
b.Log.Errorf("%#v", err)
|
||||
continue
|
||||
}
|
||||
@@ -87,7 +93,7 @@ func (b *Bslack) handleSlackClient(messages chan *config.Message) {
|
||||
b.Log.Errorf("Connection failed %#v %#v", ev.Error(), ev.ErrorObj)
|
||||
case *slack.MemberJoinedChannelEvent:
|
||||
b.users.populateUser(ev.User)
|
||||
case *slack.HelloEvent, *slack.LatencyReport:
|
||||
case *slack.HelloEvent, *slack.LatencyReport, *slack.ConnectingEvent:
|
||||
continue
|
||||
default:
|
||||
b.Log.Debugf("Unhandled incoming event: %T", ev)
|
||||
@@ -124,11 +130,11 @@ func (b *Bslack) skipMessageEvent(ev *slack.MessageEvent) bool {
|
||||
}
|
||||
}
|
||||
|
||||
// Skip any messages that we made ourselves or from 'slackbot' (see #527).
|
||||
if ev.Username == sSlackBotUser ||
|
||||
(b.rtm != nil && ev.Username == b.si.User.Name) ||
|
||||
(len(ev.Attachments) > 0 && ev.Attachments[0].CallbackID == "matterbridge_"+b.uuid) {
|
||||
return true
|
||||
// Check for our callback ID
|
||||
hasOurCallbackID := false
|
||||
if len(ev.Blocks.BlockSet) == 1 {
|
||||
block, ok := ev.Blocks.BlockSet[0].(*slack.SectionBlock)
|
||||
hasOurCallbackID = ok && block.BlockID == "matterbridge_"+b.uuid
|
||||
}
|
||||
|
||||
if ev.SubMessage != nil {
|
||||
@@ -143,6 +149,16 @@ func (b *Bslack) skipMessageEvent(ev *slack.MessageEvent) bool {
|
||||
if ev.SubType == "message_replied" && ev.Hidden {
|
||||
return true
|
||||
}
|
||||
if len(ev.SubMessage.Blocks.BlockSet) == 1 {
|
||||
block, ok := ev.SubMessage.Blocks.BlockSet[0].(*slack.SectionBlock)
|
||||
hasOurCallbackID = ok && block.BlockID == "matterbridge_"+b.uuid
|
||||
}
|
||||
}
|
||||
|
||||
// Skip any messages that we made ourselves or from 'slackbot' (see #527).
|
||||
if ev.Username == sSlackBotUser ||
|
||||
(b.rtm != nil && ev.Username == b.si.User.Name) || hasOurCallbackID {
|
||||
return true
|
||||
}
|
||||
|
||||
if len(ev.Files) > 0 {
|
||||
@@ -270,6 +286,9 @@ func (b *Bslack) handleAttachments(ev *slack.MessageEvent, rmsg *config.Message)
|
||||
}
|
||||
|
||||
func (b *Bslack) handleTypingEvent(ev *slack.UserTypingEvent) (*config.Message, error) {
|
||||
if ev.User == b.si.User.ID {
|
||||
return nil, ErrEventIgnored
|
||||
}
|
||||
channelInfo, err := b.channels.getChannelByID(ev.Channel)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@@ -7,8 +7,8 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/42wim/matterbridge/bridge/config"
|
||||
"github.com/nlopes/slack"
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/slack-go/slack"
|
||||
)
|
||||
|
||||
// populateReceivedMessage shapes the initial Matterbridge message that we will forward to the
|
||||
|
@@ -5,7 +5,7 @@ import (
|
||||
|
||||
"github.com/42wim/matterbridge/bridge"
|
||||
"github.com/42wim/matterbridge/matterhook"
|
||||
"github.com/nlopes/slack"
|
||||
"github.com/slack-go/slack"
|
||||
)
|
||||
|
||||
type BLegacy struct {
|
||||
|
@@ -13,8 +13,8 @@ import (
|
||||
"github.com/42wim/matterbridge/bridge/helper"
|
||||
"github.com/42wim/matterbridge/matterhook"
|
||||
lru "github.com/hashicorp/golang-lru"
|
||||
"github.com/nlopes/slack"
|
||||
"github.com/rs/xid"
|
||||
"github.com/slack-go/slack"
|
||||
)
|
||||
|
||||
type Bslack struct {
|
||||
@@ -64,6 +64,7 @@ const (
|
||||
editSuffixConfig = "EditSuffix"
|
||||
iconURLConfig = "iconurl"
|
||||
noSendJoinConfig = "nosendjoinpart"
|
||||
messageLength = 3000
|
||||
)
|
||||
|
||||
func New(cfg *bridge.Config) bridge.Bridger {
|
||||
@@ -194,6 +195,7 @@ func (b *Bslack) Send(msg config.Message) (string, error) {
|
||||
b.Log.Debugf("=> Receiving %#v", msg)
|
||||
}
|
||||
|
||||
msg.Text = helper.ClipMessage(msg.Text, messageLength)
|
||||
msg.Text = b.replaceCodeFence(msg.Text)
|
||||
|
||||
// Make a action /me of the message
|
||||
@@ -202,7 +204,7 @@ func (b *Bslack) Send(msg config.Message) (string, error) {
|
||||
}
|
||||
|
||||
// Use webhook to send the message
|
||||
if b.GetString(outgoingWebhookConfig) != "" {
|
||||
if b.GetString(outgoingWebhookConfig) != "" && b.GetString(tokenConfig) == "" {
|
||||
return "", b.sendWebhook(msg)
|
||||
}
|
||||
return b.sendRTM(msg)
|
||||
@@ -408,7 +410,6 @@ func (b *Bslack) editMessage(msg *config.Message, channelInfo *slack.Channel) (b
|
||||
}
|
||||
messageOptions := b.prepareMessageOptions(msg)
|
||||
for {
|
||||
messageOptions = append(messageOptions, slack.MsgOptionText(msg.Text, false))
|
||||
_, _, _, err := b.rtm.UpdateMessage(channelInfo.ID, msg.ID, messageOptions...)
|
||||
if err == nil {
|
||||
return true, nil
|
||||
@@ -427,11 +428,6 @@ func (b *Bslack) postMessage(msg *config.Message, channelInfo *slack.Channel) (s
|
||||
return "", nil
|
||||
}
|
||||
messageOptions := b.prepareMessageOptions(msg)
|
||||
messageOptions = append(
|
||||
messageOptions,
|
||||
slack.MsgOptionText(msg.Text, false),
|
||||
slack.MsgOptionEnableLinkUnfurl(),
|
||||
)
|
||||
for {
|
||||
_, id, err := b.rtm.PostMessage(channelInfo.ID, messageOptions...)
|
||||
if err == nil {
|
||||
@@ -497,8 +493,6 @@ func (b *Bslack) prepareMessageOptions(msg *config.Message) []slack.MsgOption {
|
||||
}
|
||||
|
||||
var attachments []slack.Attachment
|
||||
// add a callback ID so we can see we created it
|
||||
attachments = append(attachments, slack.Attachment{CallbackID: "matterbridge_" + b.uuid})
|
||||
// add file attachments
|
||||
attachments = append(attachments, b.createAttach(msg.Extra)...)
|
||||
// add slack attachments (from another slack bridge)
|
||||
@@ -509,6 +503,19 @@ func (b *Bslack) prepareMessageOptions(msg *config.Message) []slack.MsgOption {
|
||||
}
|
||||
|
||||
var opts []slack.MsgOption
|
||||
opts = append(opts,
|
||||
// provide regular text field (fallback used in Slack notifications, etc.)
|
||||
slack.MsgOptionText(msg.Text, false),
|
||||
|
||||
// add a callback ID so we can see we created it
|
||||
slack.MsgOptionBlocks(slack.NewSectionBlock(
|
||||
slack.NewTextBlockObject(slack.MarkdownType, msg.Text, false, false),
|
||||
nil, nil,
|
||||
slack.SectionBlockOptionBlockID("matterbridge_"+b.uuid),
|
||||
)),
|
||||
|
||||
slack.MsgOptionEnableLinkUnfurl(),
|
||||
)
|
||||
opts = append(opts, slack.MsgOptionAttachments(attachments...))
|
||||
opts = append(opts, slack.MsgOptionPostMessageParameters(params))
|
||||
return opts
|
||||
|
@@ -8,8 +8,8 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/42wim/matterbridge/bridge/config"
|
||||
"github.com/nlopes/slack"
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/slack-go/slack"
|
||||
)
|
||||
|
||||
const minimumRefreshInterval = 10 * time.Second
|
||||
|
@@ -39,22 +39,32 @@ func (b *Btelegram) handleGroups(rmsg *config.Message, message *tgbotapi.Message
|
||||
|
||||
// handleForwarded handles forwarded messages
|
||||
func (b *Btelegram) handleForwarded(rmsg *config.Message, message *tgbotapi.Message) {
|
||||
if message.ForwardFrom != nil {
|
||||
usernameForward := ""
|
||||
if b.GetBool("UseFirstName") {
|
||||
if message.ForwardDate == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
if message.ForwardFrom == nil {
|
||||
rmsg.Text = "Forwarded from " + unknownUser + ": " + rmsg.Text
|
||||
return
|
||||
}
|
||||
|
||||
usernameForward := ""
|
||||
if b.GetBool("UseFirstName") {
|
||||
usernameForward = message.ForwardFrom.FirstName
|
||||
}
|
||||
|
||||
if usernameForward == "" {
|
||||
usernameForward = message.ForwardFrom.UserName
|
||||
if usernameForward == "" {
|
||||
usernameForward = message.ForwardFrom.FirstName
|
||||
}
|
||||
if usernameForward == "" {
|
||||
usernameForward = message.ForwardFrom.UserName
|
||||
if usernameForward == "" {
|
||||
usernameForward = message.ForwardFrom.FirstName
|
||||
}
|
||||
}
|
||||
if usernameForward == "" {
|
||||
usernameForward = unknownUser
|
||||
}
|
||||
rmsg.Text = "Forwarded from " + usernameForward + ": " + rmsg.Text
|
||||
}
|
||||
|
||||
if usernameForward == "" {
|
||||
usernameForward = unknownUser
|
||||
}
|
||||
|
||||
rmsg.Text = "Forwarded from " + usernameForward + ": " + rmsg.Text
|
||||
}
|
||||
|
||||
// handleQuoting handles quoting of previous messages
|
||||
@@ -95,7 +105,7 @@ func (b *Btelegram) handleUsername(rmsg *config.Message, message *tgbotapi.Messa
|
||||
}
|
||||
}
|
||||
// only download avatars if we have a place to upload them (configured mediaserver)
|
||||
if b.General.MediaServerUpload != "" {
|
||||
if b.General.MediaServerUpload != "" || (b.General.MediaServerDownload != "" && b.General.MediaDownloadPath != "") {
|
||||
b.handleDownloadAvatar(message.From.ID, rmsg.Channel)
|
||||
}
|
||||
}
|
||||
@@ -312,6 +322,9 @@ func (b *Btelegram) handleEdit(msg *config.Message, chatid int64) (string, error
|
||||
case "Markdown":
|
||||
b.Log.Debug("Using mode markdown")
|
||||
m.ParseMode = tgbotapi.ModeMarkdown
|
||||
case MarkdownV2:
|
||||
b.Log.Debug("Using mode MarkdownV2")
|
||||
m.ParseMode = MarkdownV2
|
||||
}
|
||||
if strings.ToLower(b.GetString("MessageFormat")) == HTMLNick {
|
||||
b.Log.Debug("Using mode HTML - nick only")
|
||||
|
@@ -15,6 +15,7 @@ const (
|
||||
unknownUser = "unknown"
|
||||
HTMLFormat = "HTML"
|
||||
HTMLNick = "htmlnick"
|
||||
MarkdownV2 = "MarkdownV2"
|
||||
)
|
||||
|
||||
type Btelegram struct {
|
||||
@@ -126,6 +127,10 @@ func (b *Btelegram) sendMessage(chatid int64, username, text string) (string, er
|
||||
b.Log.Debug("Using mode markdown")
|
||||
m.ParseMode = tgbotapi.ModeMarkdown
|
||||
}
|
||||
if b.GetString("MessageFormat") == MarkdownV2 {
|
||||
b.Log.Debug("Using mode MarkdownV2")
|
||||
m.ParseMode = MarkdownV2
|
||||
}
|
||||
if strings.ToLower(b.GetString("MessageFormat")) == HTMLNick {
|
||||
b.Log.Debug("Using mode HTML - nick only")
|
||||
m.Text = username + html.EscapeString(text)
|
||||
|
@@ -9,6 +9,7 @@ import (
|
||||
"github.com/42wim/matterbridge/bridge/config"
|
||||
"github.com/42wim/matterbridge/bridge/helper"
|
||||
"github.com/Rhymen/go-whatsapp"
|
||||
"github.com/jpillora/backoff"
|
||||
)
|
||||
|
||||
/*
|
||||
@@ -22,10 +23,43 @@ Check:
|
||||
// HandleError received from WhatsApp
|
||||
func (b *Bwhatsapp) HandleError(err error) {
|
||||
// ignore received invalid data errors. https://github.com/42wim/matterbridge/issues/843
|
||||
if strings.Contains(err.Error(), "error processing data: received invalid data") {
|
||||
// ignore tag 174 errors. https://github.com/42wim/matterbridge/issues/1094
|
||||
if strings.Contains(err.Error(), "error processing data: received invalid data") || strings.Contains(err.Error(), "invalid string with tag 174") {
|
||||
return
|
||||
}
|
||||
b.Log.Errorf("%v", err) // TODO implement proper handling? at least respond to different error types
|
||||
|
||||
switch err.(type) {
|
||||
case *whatsapp.ErrConnectionClosed, *whatsapp.ErrConnectionFailed:
|
||||
b.reconnect(err)
|
||||
default:
|
||||
switch err {
|
||||
case whatsapp.ErrConnectionTimeout:
|
||||
b.reconnect(err)
|
||||
default:
|
||||
b.Log.Errorf("%v", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (b *Bwhatsapp) reconnect(err error) {
|
||||
bf := &backoff.Backoff{
|
||||
Min: time.Second,
|
||||
Max: 5 * time.Minute,
|
||||
Jitter: true,
|
||||
}
|
||||
for {
|
||||
d := bf.Duration()
|
||||
b.Log.Errorf("Connection failed, underlying error: %v", err)
|
||||
b.Log.Infof("Waiting %s...", d)
|
||||
time.Sleep(d)
|
||||
b.Log.Info("Reconnecting...")
|
||||
err := b.conn.Restore()
|
||||
if err == nil {
|
||||
bf.Reset()
|
||||
b.startedAt = uint64(time.Now().Unix())
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// HandleTextMessage sent from WhatsApp, relay it to the brige
|
||||
|
@@ -80,8 +80,33 @@ func (b *Bwhatsapp) getSenderName(senderJid string) string {
|
||||
// if user is not in phone contacts
|
||||
// it is the most obvious scenario unless you sync your phone contacts with some remote updated source
|
||||
// users can change it in their WhatsApp settings -> profile -> click on Avatar
|
||||
return sender.Notify
|
||||
if sender.Notify != "" {
|
||||
return sender.Notify
|
||||
}
|
||||
|
||||
if sender.Short != "" {
|
||||
return sender.Short
|
||||
}
|
||||
}
|
||||
|
||||
// try to reload this contact
|
||||
_, err := b.conn.Contacts()
|
||||
if err != nil {
|
||||
b.Log.Errorf("error on update of contacts: %v", err)
|
||||
}
|
||||
|
||||
if contact, exists := b.conn.Store.Contacts[senderJid]; exists {
|
||||
// Add it to the user map
|
||||
b.users[senderJid] = contact
|
||||
|
||||
if contact.Name != "" {
|
||||
return contact.Name
|
||||
}
|
||||
// if user is not in phone contacts
|
||||
// same as above
|
||||
return contact.Notify
|
||||
}
|
||||
|
||||
return ""
|
||||
}
|
||||
|
||||
|
@@ -67,6 +67,7 @@ func (b *Bwhatsapp) Connect() error {
|
||||
// https://github.com/Rhymen/go-whatsapp#creating-a-connection
|
||||
b.Log.Debugln("Connecting to WhatsApp..")
|
||||
conn, err := whatsapp.NewConn(20 * time.Second)
|
||||
conn.SetClientVersion(0, 4, 2080)
|
||||
if err != nil {
|
||||
return errors.New("failed to connect to WhatsApp: " + err.Error())
|
||||
}
|
||||
|
34
bridge/xmpp/handler.go
Normal file
34
bridge/xmpp/handler.go
Normal file
@@ -0,0 +1,34 @@
|
||||
package bxmpp
|
||||
|
||||
import (
|
||||
"github.com/42wim/matterbridge/bridge/config"
|
||||
"github.com/42wim/matterbridge/bridge/helper"
|
||||
"github.com/matterbridge/go-xmpp"
|
||||
)
|
||||
|
||||
// handleDownloadAvatar downloads the avatar of userid from channel
|
||||
// sends a EVENT_AVATAR_DOWNLOAD message to the gateway if successful.
|
||||
// logs an error message if it fails
|
||||
func (b *Bxmpp) handleDownloadAvatar(avatar xmpp.AvatarData) {
|
||||
rmsg := config.Message{
|
||||
Username: "system",
|
||||
Text: "avatar",
|
||||
Channel: b.parseChannel(avatar.From),
|
||||
Account: b.Account,
|
||||
UserID: avatar.From,
|
||||
Event: config.EventAvatarDownload,
|
||||
Extra: make(map[string][]interface{}),
|
||||
}
|
||||
if _, ok := b.avatarMap[avatar.From]; !ok {
|
||||
b.Log.Debugf("Avatar.From: %s", avatar.From)
|
||||
|
||||
err := helper.HandleDownloadSize(b.Log, &rmsg, avatar.From+".png", int64(len(avatar.Data)), b.General)
|
||||
if err != nil {
|
||||
b.Log.Error(err)
|
||||
return
|
||||
}
|
||||
helper.HandleDownloadData(b.Log, &rmsg, avatar.From+".png", rmsg.Text, "", &avatar.Data, b.General)
|
||||
b.Log.Debugf("Avatar download complete")
|
||||
b.Remote <- rmsg
|
||||
}
|
||||
}
|
30
bridge/xmpp/helpers.go
Normal file
30
bridge/xmpp/helpers.go
Normal file
@@ -0,0 +1,30 @@
|
||||
package bxmpp
|
||||
|
||||
import (
|
||||
"regexp"
|
||||
|
||||
"github.com/42wim/matterbridge/bridge/config"
|
||||
)
|
||||
|
||||
var pathRegex = regexp.MustCompile("[^a-zA-Z0-9]+")
|
||||
|
||||
// GetAvatar constructs a URL for a given user-avatar if it is available in the cache.
|
||||
func getAvatar(av map[string]string, userid string, general *config.Protocol) string {
|
||||
if hash, ok := av[userid]; ok {
|
||||
// NOTE: This does not happen in bridge/helper/helper.go but messes up XMPP
|
||||
id := pathRegex.ReplaceAllString(userid, "_")
|
||||
return general.MediaServerDownload + "/" + hash + "/" + id + ".png"
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (b *Bxmpp) cacheAvatar(msg *config.Message) string {
|
||||
fi := msg.Extra["file"][0].(config.FileInfo)
|
||||
/* if we have a sha we have successfully uploaded the file to the media server,
|
||||
so we can now cache the sha */
|
||||
if fi.SHA != "" {
|
||||
b.Log.Debugf("Added %s to %s in avatarMap", fi.SHA, msg.UserID)
|
||||
b.avatarMap[msg.UserID] = fi.SHA
|
||||
}
|
||||
return ""
|
||||
}
|
@@ -23,12 +23,17 @@ type Bxmpp struct {
|
||||
xmppMap map[string]string
|
||||
connected bool
|
||||
sync.RWMutex
|
||||
|
||||
avatarAvailability map[string]bool
|
||||
avatarMap map[string]string
|
||||
}
|
||||
|
||||
func New(cfg *bridge.Config) bridge.Bridger {
|
||||
return &Bxmpp{
|
||||
Config: cfg,
|
||||
xmppMap: make(map[string]string),
|
||||
Config: cfg,
|
||||
xmppMap: make(map[string]string),
|
||||
avatarAvailability: make(map[string]bool),
|
||||
avatarMap: make(map[string]string),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -67,8 +72,19 @@ func (b *Bxmpp) Send(msg config.Message) (string, error) {
|
||||
if msg.Event == config.EventMsgDelete {
|
||||
return "", nil
|
||||
}
|
||||
|
||||
b.Log.Debugf("=> Receiving %#v", msg)
|
||||
|
||||
if msg.Event == config.EventAvatarDownload {
|
||||
return b.cacheAvatar(&msg), nil
|
||||
}
|
||||
|
||||
// Make a action /me of the message, prepend the username with it.
|
||||
// https://xmpp.org/extensions/xep-0245.html
|
||||
if msg.Event == config.EventUserAction {
|
||||
msg.Username = "/me " + msg.Username
|
||||
}
|
||||
|
||||
// Upload a file (in XMPP case send the upload URL because XMPP has no native upload support).
|
||||
if msg.Extra != nil {
|
||||
for _, rmsg := range helper.HandleExtra(&msg, b.General) {
|
||||
@@ -114,6 +130,9 @@ func (b *Bxmpp) createXMPP() error {
|
||||
ServerName: strings.Split(b.GetString("Jid"), "@")[1],
|
||||
InsecureSkipVerify: b.GetBool("SkipTLSVerify"), // nolint: gosec
|
||||
}
|
||||
|
||||
xmpp.DebugWriter = b.Log.Writer()
|
||||
|
||||
options := xmpp.Options{
|
||||
Host: b.GetString("Server"),
|
||||
User: b.GetString("Jid"),
|
||||
@@ -122,7 +141,6 @@ func (b *Bxmpp) createXMPP() error {
|
||||
StartTLS: true,
|
||||
TLSConfig: tc,
|
||||
Debug: b.GetBool("debug"),
|
||||
Logger: b.Log.Writer(),
|
||||
Session: true,
|
||||
Status: "",
|
||||
StatusMessage: "",
|
||||
@@ -228,6 +246,16 @@ func (b *Bxmpp) handleXMPP() error {
|
||||
event = config.EventTopicChange
|
||||
}
|
||||
|
||||
available, sok := b.avatarAvailability[v.Remote]
|
||||
avatar := ""
|
||||
if !sok {
|
||||
b.Log.Debugf("Requesting avatar data")
|
||||
b.avatarAvailability[v.Remote] = false
|
||||
b.xc.AvatarRequestData(v.Remote)
|
||||
} else if available {
|
||||
avatar = getAvatar(b.avatarMap, v.Remote, b.General)
|
||||
}
|
||||
|
||||
msgID := v.ID
|
||||
if v.ReplaceID != "" {
|
||||
msgID = v.ReplaceID
|
||||
@@ -237,6 +265,7 @@ func (b *Bxmpp) handleXMPP() error {
|
||||
Text: v.Text,
|
||||
Channel: b.parseChannel(v.Remote),
|
||||
Account: b.Account,
|
||||
Avatar: avatar,
|
||||
UserID: v.Remote,
|
||||
ID: msgID,
|
||||
Event: event,
|
||||
@@ -253,6 +282,10 @@ func (b *Bxmpp) handleXMPP() error {
|
||||
b.Log.Debugf("<= Message is %#v", rmsg)
|
||||
b.Remote <- rmsg
|
||||
}
|
||||
case xmpp.AvatarData:
|
||||
b.handleDownloadAvatar(v)
|
||||
b.avatarAvailability[v.From] = true
|
||||
b.Log.Debugf("Avatar for %s is now available", v.From)
|
||||
case xmpp.Presence:
|
||||
// Do nothing.
|
||||
}
|
||||
|
146
changelog.md
146
changelog.md
@@ -1,3 +1,149 @@
|
||||
# v1.18.0
|
||||
|
||||
## New features
|
||||
|
||||
- nctalk: new protocol added. Add Nextcloud Talk support #1167
|
||||
- general: Add an option to log into a file rather than stdout (#1168)
|
||||
- api: Add websocket to API (#970)
|
||||
|
||||
## Enhancements
|
||||
|
||||
- telegram: Fix MarkdownV2 support in Telegram (#1169)
|
||||
- whatsapp: Reload user information when a new contact is detected (whatsapp) (#1160)
|
||||
- api: Add sane RemoteNickFormat default for API (#1157)
|
||||
- irc: Skip gIRC built-in rate limiting (irc) (#1164)
|
||||
- irc: Only colour IRC nicks if there is one. (#1161)
|
||||
- docker: Combine runs to one layer (#1151)
|
||||
|
||||
## Bugfix
|
||||
|
||||
- general: Update dependencies for 1.18.0 release (#1175)
|
||||
|
||||
Discord users are encouraged to upgrade, this release works with the move to the discord.com domain.
|
||||
|
||||
This release couldn't exist without the following contributors:
|
||||
@42wim, @jlu5, @qaisjp, @TheHolyRoger, @SuperSandro2000, @gary-kim, @z3bra, @greenx, @haykam821, @nathanaelhoun
|
||||
|
||||
# v1.17.5
|
||||
|
||||
## Enhancements
|
||||
|
||||
- irc: Add StripMarkdown option (irc). (#1145)
|
||||
- general: Increase debug logging with function,file and linenumber (#1147)
|
||||
- general: Update Dockerfile so inotify works (#1148)
|
||||
- matrix: Add an option to disable sending HTML to matrix. Fixes #1022 (#1135)
|
||||
- xmpp: Implement xep-0245 (xmpp). Closes #1137 (#1144)
|
||||
|
||||
## Bugfix
|
||||
|
||||
- discord: Fix #1120: replaceAction "_" crash (discord) (#1121)
|
||||
- discord: Fix #1049: missing space before embeds (discord) (#1124)
|
||||
- discord: Fix webhook EventUserAction messages being skipped (discord) (#1133)
|
||||
- matrix: Avoid creating invalid url when the user doesn't have an avatar (matrix) (#1130)
|
||||
- msteams: Ignore non-user messages (msteams). Fixes #1141 (#1149)
|
||||
- slack: Do not use webhooks when token is configured (slack) (fixes #1123) (#1134)
|
||||
- telegram: Fix forward from hidden users (telegram). Closes #1131 (#1143)
|
||||
- xmpp: Prevent re-requesting avatar data (xmpp) (#1117)
|
||||
|
||||
This release couldn't exist without the following contributors:
|
||||
@qaisjp, @xnaas, @42wim, @Polynomdivision, @tfve
|
||||
|
||||
# v1.17.4
|
||||
|
||||
## Bugfix
|
||||
|
||||
- general: Lowercase account names. Fixes #1108 (#1110)
|
||||
- msteams: Remove panics and retry polling on failure (msteams). Fixes #1104 (#1105
|
||||
- whatsapp: Update Rhymen/go-whatsapp. Fixes #1107 (#1109) (make whatsapp working again)
|
||||
- discord: Add an ID cache (discord). Fixes #1106 (#1111) (fix delete/edits with webhooks)
|
||||
|
||||
# v1.17.3
|
||||
|
||||
## Enhancements
|
||||
|
||||
- xmpp: Implement User Avatar spoofing of XMPP users #1090
|
||||
- rocketchat: Relay Joins/Topic changes in RocketChat bridge (#1085)
|
||||
- irc: Add JoinDelay option (irc). Fixes #1084 (#1098)
|
||||
- slack: Clip too long messages on 3000 length (slack). Fixes #1081 (#1102)
|
||||
|
||||
## Bugfix
|
||||
|
||||
- general: Fix the behavior of ShowTopicChange and SyncTopic (#1086)
|
||||
- slack: Prevent image/message looping (slack). Fixes #1088 (#1096)
|
||||
- whatsapp: Ignore non-critical errors (whatsapp). Fixes #1094 (#1100)
|
||||
- irc: Add extra space before colon in attachments (irc). Fixes #1089 (#1101)
|
||||
|
||||
This release couldn't exist without the following contributors:
|
||||
@42wim, @ldruschk, @qaisjp, @Polynomdivision
|
||||
|
||||
# v1.17.2
|
||||
|
||||
## Enhancements
|
||||
|
||||
- slack: Update vendor slack-go/slack (#1068)
|
||||
- general: Update vendor d5/tengo (#1066)
|
||||
- general: Clarify terminology used in mapping group chat IDs to channels in config (#1079)
|
||||
|
||||
## Bugfix
|
||||
|
||||
- whatsapp: Update Rhymen/go-whatsapp vendor and whatsapp version (#1078). Fixes Media upload #1074
|
||||
- whatsapp: Reset start timestamp on reconnect (whatsapp). Fixes #1059 (#1064)
|
||||
|
||||
This release couldn't exist without the following contributors:
|
||||
@42wim, @jheiselman
|
||||
|
||||
# v1.17.1
|
||||
|
||||
## Enhancements
|
||||
|
||||
- docker: Remove build dependencies from final image (multistage build) #1057
|
||||
|
||||
## Bugfix
|
||||
|
||||
- general: Don't transmit typing events from ourselves #1056
|
||||
- general: Add support for build tags #1054
|
||||
- discord: Strip extra info from emotes (discord) #1052
|
||||
- msteams: fix macos build: Update vendor yaegashi/msgraph.go to v0.1.2 #1036
|
||||
- whatsapp: Update client version whatsapp. Fixes #1061 #1062
|
||||
|
||||
This release couldn't exist without the following contributors:
|
||||
@awigen, @qaisjp, @42wim
|
||||
|
||||
# v1.17.0
|
||||
|
||||
## New features
|
||||
|
||||
- msteams: new protocol added. Add initial Microsoft Teams support #967
|
||||
See https://github.com/42wim/matterbridge/wiki/MS-Teams-setup for a complete walkthrough
|
||||
- discord: Add ability to procure avatars from the destination bridge #1000
|
||||
- matrix: Add support for avatars from matrix. #1007
|
||||
- general: support JSON and YAML config formats #1045
|
||||
|
||||
## Enhancements
|
||||
|
||||
- discord: Check only bridged channels for PermManageWebhooks #1001
|
||||
- irc: Be less lossy when throttling IRC messages #1004
|
||||
- keybase: updated library #1002, #1019
|
||||
- matrix: Rebase gomatrix vendor with upstream #1006
|
||||
- slack: Use upstream slack-go/slack again #1018
|
||||
- slack: Ignore ConnectingEvent #1041
|
||||
- slack: use blocks not attachments #1048
|
||||
- sshchat: Update vendor shazow/ssh-chat #1029
|
||||
- telegram: added markdownv2 mode for telegram #1037
|
||||
- whatsapp: Implement basic reconnect (whatsapp). Fixes #987 #1003
|
||||
|
||||
## Bugfix
|
||||
|
||||
- discord: Fix webhook permission checks sometimes failing #1043
|
||||
- discord: Fix #1027: warning when handling inbound webhooks #1044
|
||||
- discord: Fix duplicate separator on empty description/url (discord) #1035
|
||||
- matrix: Fix issue with underscores in links #999
|
||||
- slack: Fix #1039: messages sent to Slack being synced back #1046
|
||||
- telegram: Make avatars download work with mediaserverdownload (telegram). Fixes #920
|
||||
|
||||
This release couldn't exist without the following contributors:
|
||||
@qaisjp, @jakubgs, @burner1024, @notpushkin, @MartijnBraam, @42wim
|
||||
|
||||
# v1.16.5
|
||||
|
||||
- Fix version bump
|
||||
|
@@ -1,30 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
set -u -e -x -o pipefail
|
||||
|
||||
go version | grep go1.13 || exit
|
||||
|
||||
VERSION=$(git describe --tags)
|
||||
mkdir ci/binaries
|
||||
GOOS=windows GOARCH=amd64 go build -ldflags "-s -w -X main.githash=$(git log --pretty=format:'%h' -n 1)" -o ci/binaries/matterbridge-$VERSION-windows-amd64.exe
|
||||
GOOS=linux GOARCH=amd64 go build -ldflags "-s -w -X main.githash=$(git log --pretty=format:'%h' -n 1)" -o ci/binaries/matterbridge-$VERSION-linux-amd64
|
||||
GOOS=linux GOARCH=arm go build -ldflags "-s -w -X main.githash=$(git log --pretty=format:'%h' -n 1)" -o ci/binaries/matterbridge-$VERSION-linux-arm
|
||||
GOOS=darwin GOARCH=amd64 go build -ldflags "-s -w -X main.githash=$(git log --pretty=format:'%h' -n 1)" -o ci/binaries/matterbridge-$VERSION-darwin-amd64
|
||||
cd ci
|
||||
cat > deploy.json <<EOF
|
||||
{
|
||||
"package": {
|
||||
"name": "Matterbridge",
|
||||
"repo": "nightly",
|
||||
"subject": "42wim"
|
||||
},
|
||||
"version": {
|
||||
"name": "$VERSION"
|
||||
},
|
||||
"files":
|
||||
[
|
||||
{"includePattern": "ci/binaries/(.*)", "uploadPattern":"\$1"}
|
||||
],
|
||||
"publish": true
|
||||
}
|
||||
EOF
|
||||
|
17
ci/lint.sh
17
ci/lint.sh
@@ -1,17 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
set -u -e -x -o pipefail
|
||||
|
||||
if [[ -n "${GOLANGCI_VERSION-}" ]]; then
|
||||
# Retrieve the golangci-lint linter binary.
|
||||
curl -sfL https://install.goreleaser.com/github.com/golangci/golangci-lint.sh | bash -s -- -b ${GOPATH}/bin ${GOLANGCI_VERSION}
|
||||
fi
|
||||
|
||||
# Run the linter.
|
||||
golangci-lint run
|
||||
|
||||
# if [[ "${GO111MODULE-off}" == "on" ]]; then
|
||||
# # If Go modules are active then check that dependencies are correctly maintained.
|
||||
# go mod tidy
|
||||
# go mod vendor
|
||||
# git diff --exit-code --quiet || (echo "Please run 'go mod tidy' to clean up the 'go.mod' and 'go.sum' files."; false)
|
||||
# fi
|
17
ci/test.sh
17
ci/test.sh
@@ -1,17 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
set -u -e -x -o pipefail
|
||||
|
||||
if [[ -n "${REPORT_COVERAGE+cover}" ]]; then
|
||||
# Retrieve and prepare CodeClimate's test coverage reporter.
|
||||
curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > ./cc-test-reporter
|
||||
chmod +x ./cc-test-reporter
|
||||
./cc-test-reporter before-build
|
||||
fi
|
||||
|
||||
# Run all the tests with the race detector and generate coverage.
|
||||
go test -v -race -coverprofile c.out ./...
|
||||
|
||||
if [[ -n "${REPORT_COVERAGE+cover}" && "${TRAVIS_SECURE_ENV_VARS}" == "true" ]]; then
|
||||
# Upload test coverage to CodeClimate.
|
||||
./cc-test-reporter after-build
|
||||
fi
|
11
gateway/bridgemap/api.go
Normal file
11
gateway/bridgemap/api.go
Normal file
@@ -0,0 +1,11 @@
|
||||
// +build !noapi
|
||||
|
||||
package bridgemap
|
||||
|
||||
import (
|
||||
"github.com/42wim/matterbridge/bridge/api"
|
||||
)
|
||||
|
||||
func init() {
|
||||
FullMap["api"] = api.New
|
||||
}
|
12
gateway/bridgemap/bdiscord.go
Normal file
12
gateway/bridgemap/bdiscord.go
Normal file
@@ -0,0 +1,12 @@
|
||||
// +build !nodiscord
|
||||
|
||||
package bridgemap
|
||||
|
||||
import (
|
||||
bdiscord "github.com/42wim/matterbridge/bridge/discord"
|
||||
)
|
||||
|
||||
func init() {
|
||||
FullMap["discord"] = bdiscord.New
|
||||
UserTypingSupport["discord"] = struct{}{}
|
||||
}
|
11
gateway/bridgemap/bgitter.go
Normal file
11
gateway/bridgemap/bgitter.go
Normal file
@@ -0,0 +1,11 @@
|
||||
// +build !nogitter
|
||||
|
||||
package bridgemap
|
||||
|
||||
import (
|
||||
bgitter "github.com/42wim/matterbridge/bridge/gitter"
|
||||
)
|
||||
|
||||
func init() {
|
||||
FullMap["gitter"] = bgitter.New
|
||||
}
|
11
gateway/bridgemap/birc.go
Normal file
11
gateway/bridgemap/birc.go
Normal file
@@ -0,0 +1,11 @@
|
||||
// +build !noirc
|
||||
|
||||
package bridgemap
|
||||
|
||||
import (
|
||||
birc "github.com/42wim/matterbridge/bridge/irc"
|
||||
)
|
||||
|
||||
func init() {
|
||||
FullMap["irc"] = birc.New
|
||||
}
|
11
gateway/bridgemap/bkeybase.go
Normal file
11
gateway/bridgemap/bkeybase.go
Normal file
@@ -0,0 +1,11 @@
|
||||
// +build !nokeybase
|
||||
|
||||
package bridgemap
|
||||
|
||||
import (
|
||||
bkeybase "github.com/42wim/matterbridge/bridge/keybase"
|
||||
)
|
||||
|
||||
func init() {
|
||||
FullMap["keybase"] = bkeybase.New
|
||||
}
|
11
gateway/bridgemap/bmatrix.go
Normal file
11
gateway/bridgemap/bmatrix.go
Normal file
@@ -0,0 +1,11 @@
|
||||
// +build !nomatrix
|
||||
|
||||
package bridgemap
|
||||
|
||||
import (
|
||||
bmatrix "github.com/42wim/matterbridge/bridge/matrix"
|
||||
)
|
||||
|
||||
func init() {
|
||||
FullMap["matrix"] = bmatrix.New
|
||||
}
|
11
gateway/bridgemap/bmattermost.go
Normal file
11
gateway/bridgemap/bmattermost.go
Normal file
@@ -0,0 +1,11 @@
|
||||
// +build !nomattermost
|
||||
|
||||
package bridgemap
|
||||
|
||||
import (
|
||||
bmattermost "github.com/42wim/matterbridge/bridge/mattermost"
|
||||
)
|
||||
|
||||
func init() {
|
||||
FullMap["mattermost"] = bmattermost.New
|
||||
}
|
11
gateway/bridgemap/bmsteams.go
Normal file
11
gateway/bridgemap/bmsteams.go
Normal file
@@ -0,0 +1,11 @@
|
||||
// +build !nomsteams
|
||||
|
||||
package bridgemap
|
||||
|
||||
import (
|
||||
bmsteams "github.com/42wim/matterbridge/bridge/msteams"
|
||||
)
|
||||
|
||||
func init() {
|
||||
FullMap["msteams"] = bmsteams.New
|
||||
}
|
11
gateway/bridgemap/bnctalk.go
Normal file
11
gateway/bridgemap/bnctalk.go
Normal file
@@ -0,0 +1,11 @@
|
||||
// +build !nonctalk
|
||||
|
||||
package bridgemap
|
||||
|
||||
import (
|
||||
btalk "github.com/42wim/matterbridge/bridge/nctalk"
|
||||
)
|
||||
|
||||
func init() {
|
||||
FullMap["nctalk"] = btalk.New
|
||||
}
|
@@ -2,45 +2,9 @@ package bridgemap
|
||||
|
||||
import (
|
||||
"github.com/42wim/matterbridge/bridge"
|
||||
"github.com/42wim/matterbridge/bridge/api"
|
||||
bdiscord "github.com/42wim/matterbridge/bridge/discord"
|
||||
bgitter "github.com/42wim/matterbridge/bridge/gitter"
|
||||
birc "github.com/42wim/matterbridge/bridge/irc"
|
||||
bkeybase "github.com/42wim/matterbridge/bridge/keybase"
|
||||
bmatrix "github.com/42wim/matterbridge/bridge/matrix"
|
||||
bmattermost "github.com/42wim/matterbridge/bridge/mattermost"
|
||||
brocketchat "github.com/42wim/matterbridge/bridge/rocketchat"
|
||||
bslack "github.com/42wim/matterbridge/bridge/slack"
|
||||
bsshchat "github.com/42wim/matterbridge/bridge/sshchat"
|
||||
bsteam "github.com/42wim/matterbridge/bridge/steam"
|
||||
btelegram "github.com/42wim/matterbridge/bridge/telegram"
|
||||
bwhatsapp "github.com/42wim/matterbridge/bridge/whatsapp"
|
||||
bxmpp "github.com/42wim/matterbridge/bridge/xmpp"
|
||||
bzulip "github.com/42wim/matterbridge/bridge/zulip"
|
||||
)
|
||||
|
||||
var (
|
||||
FullMap = map[string]bridge.Factory{
|
||||
"api": api.New,
|
||||
"discord": bdiscord.New,
|
||||
"gitter": bgitter.New,
|
||||
"irc": birc.New,
|
||||
"mattermost": bmattermost.New,
|
||||
"matrix": bmatrix.New,
|
||||
"rocketchat": brocketchat.New,
|
||||
"slack-legacy": bslack.NewLegacy,
|
||||
"slack": bslack.New,
|
||||
"sshchat": bsshchat.New,
|
||||
"steam": bsteam.New,
|
||||
"telegram": btelegram.New,
|
||||
"whatsapp": bwhatsapp.New,
|
||||
"xmpp": bxmpp.New,
|
||||
"zulip": bzulip.New,
|
||||
"keybase": bkeybase.New,
|
||||
}
|
||||
|
||||
UserTypingSupport = map[string]struct{}{
|
||||
"slack": {},
|
||||
"discord": {},
|
||||
}
|
||||
FullMap = map[string]bridge.Factory{}
|
||||
UserTypingSupport = map[string]struct{}{}
|
||||
)
|
||||
|
11
gateway/bridgemap/brocketchat.go
Normal file
11
gateway/bridgemap/brocketchat.go
Normal file
@@ -0,0 +1,11 @@
|
||||
// +build !norocketchat
|
||||
|
||||
package bridgemap
|
||||
|
||||
import (
|
||||
brocketchat "github.com/42wim/matterbridge/bridge/rocketchat"
|
||||
)
|
||||
|
||||
func init() {
|
||||
FullMap["rocketchat"] = brocketchat.New
|
||||
}
|
13
gateway/bridgemap/bslack.go
Normal file
13
gateway/bridgemap/bslack.go
Normal file
@@ -0,0 +1,13 @@
|
||||
// +build !noslack
|
||||
|
||||
package bridgemap
|
||||
|
||||
import (
|
||||
bslack "github.com/42wim/matterbridge/bridge/slack"
|
||||
)
|
||||
|
||||
func init() {
|
||||
FullMap["slack-legacy"] = bslack.NewLegacy
|
||||
FullMap["slack"] = bslack.New
|
||||
UserTypingSupport["slack"] = struct{}{}
|
||||
}
|
11
gateway/bridgemap/bsshchat.go
Normal file
11
gateway/bridgemap/bsshchat.go
Normal file
@@ -0,0 +1,11 @@
|
||||
// +build !nosshchat
|
||||
|
||||
package bridgemap
|
||||
|
||||
import (
|
||||
bsshchat "github.com/42wim/matterbridge/bridge/sshchat"
|
||||
)
|
||||
|
||||
func init() {
|
||||
FullMap["sshchat"] = bsshchat.New
|
||||
}
|
11
gateway/bridgemap/bsteam.go
Normal file
11
gateway/bridgemap/bsteam.go
Normal file
@@ -0,0 +1,11 @@
|
||||
// +build !nosteam
|
||||
|
||||
package bridgemap
|
||||
|
||||
import (
|
||||
bsteam "github.com/42wim/matterbridge/bridge/steam"
|
||||
)
|
||||
|
||||
func init() {
|
||||
FullMap["steam"] = bsteam.New
|
||||
}
|
11
gateway/bridgemap/btelegram.go
Normal file
11
gateway/bridgemap/btelegram.go
Normal file
@@ -0,0 +1,11 @@
|
||||
// +build !notelegram
|
||||
|
||||
package bridgemap
|
||||
|
||||
import (
|
||||
btelegram "github.com/42wim/matterbridge/bridge/telegram"
|
||||
)
|
||||
|
||||
func init() {
|
||||
FullMap["telegram"] = btelegram.New
|
||||
}
|
11
gateway/bridgemap/bwhatsapp.go
Normal file
11
gateway/bridgemap/bwhatsapp.go
Normal file
@@ -0,0 +1,11 @@
|
||||
// +build !nowhatsapp
|
||||
|
||||
package bridgemap
|
||||
|
||||
import (
|
||||
bwhatsapp "github.com/42wim/matterbridge/bridge/whatsapp"
|
||||
)
|
||||
|
||||
func init() {
|
||||
FullMap["whatsapp"] = bwhatsapp.New
|
||||
}
|
11
gateway/bridgemap/bxmpp.go
Normal file
11
gateway/bridgemap/bxmpp.go
Normal file
@@ -0,0 +1,11 @@
|
||||
// +build !noxmpp
|
||||
|
||||
package bridgemap
|
||||
|
||||
import (
|
||||
bxmpp "github.com/42wim/matterbridge/bridge/xmpp"
|
||||
)
|
||||
|
||||
func init() {
|
||||
FullMap["xmpp"] = bxmpp.New
|
||||
}
|
11
gateway/bridgemap/bzulip.go
Normal file
11
gateway/bridgemap/bzulip.go
Normal file
@@ -0,0 +1,11 @@
|
||||
// +build !nozulip
|
||||
|
||||
package bridgemap
|
||||
|
||||
import (
|
||||
bzulip "github.com/42wim/matterbridge/bridge/zulip"
|
||||
)
|
||||
|
||||
func init() {
|
||||
FullMap["zulip"] = bzulip.New
|
||||
}
|
@@ -108,7 +108,7 @@ func (gw *Gateway) AddBridge(cfg *config.Bridge) error {
|
||||
func (gw *Gateway) checkConfig(cfg *config.Bridge) {
|
||||
match := false
|
||||
for _, key := range gw.Router.Config.Viper().AllKeys() {
|
||||
if strings.HasPrefix(key, cfg.Account) {
|
||||
if strings.HasPrefix(key, strings.ToLower(cfg.Account)) {
|
||||
match = true
|
||||
break
|
||||
}
|
||||
@@ -306,8 +306,6 @@ func (gw *Gateway) ignoreMessage(msg *config.Message) bool {
|
||||
}
|
||||
|
||||
func (gw *Gateway) modifyUsername(msg *config.Message, dest *bridge.Bridge) string {
|
||||
br := gw.Bridges[msg.Account]
|
||||
msg.Protocol = br.Protocol
|
||||
if dest.GetBool("StripNick") {
|
||||
re := regexp.MustCompile("[^a-zA-Z0-9]+")
|
||||
msg.Username = re.ReplaceAllString(msg.Username, "")
|
||||
@@ -315,6 +313,7 @@ func (gw *Gateway) modifyUsername(msg *config.Message, dest *bridge.Bridge) stri
|
||||
nick := dest.GetString("RemoteNickFormat")
|
||||
|
||||
// loop to replace nicks
|
||||
br := gw.Bridges[msg.Account]
|
||||
for _, outer := range br.GetStringSlice2D("ReplaceNicks") {
|
||||
search := outer[0]
|
||||
replace := outer[1]
|
||||
|
@@ -169,7 +169,7 @@ func (gw *Gateway) ignoreEvent(event string, dest *bridge.Bridge) bool {
|
||||
switch event {
|
||||
case config.EventAvatarDownload:
|
||||
// Avatar downloads are only relevant for telegram and mattermost for now
|
||||
if dest.Protocol != "mattermost" && dest.Protocol != "telegram" {
|
||||
if dest.Protocol != "mattermost" && dest.Protocol != "telegram" && dest.Protocol != "xmpp" {
|
||||
return true
|
||||
}
|
||||
case config.EventJoinLeave:
|
||||
@@ -179,7 +179,7 @@ func (gw *Gateway) ignoreEvent(event string, dest *bridge.Bridge) bool {
|
||||
}
|
||||
case config.EventTopicChange:
|
||||
// only relay topic change when used in some way on other side
|
||||
if dest.GetBool("ShowTopicChange") && dest.GetBool("SyncTopic") {
|
||||
if !dest.GetBool("ShowTopicChange") && !dest.GetBool("SyncTopic") {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
@@ -132,6 +132,9 @@ func (r *Router) handleReceive() {
|
||||
r.handleEventFailure(&msg)
|
||||
r.handleEventRejoinChannels(&msg)
|
||||
|
||||
// Set message protocol based on the account it came from
|
||||
msg.Protocol = r.getBridge(msg.Account).Protocol
|
||||
|
||||
filesHandled := false
|
||||
for _, gw := range r.Gateways {
|
||||
// record all the message ID's of the different bridges
|
||||
|
57
go.mod
57
go.mod
@@ -5,36 +5,37 @@ require (
|
||||
github.com/Baozisoftware/qrcode-terminal-go v0.0.0-20170407111555-c0650d8dff0f
|
||||
github.com/Jeffail/gabs v1.1.1 // indirect
|
||||
github.com/Philipp15b/go-steam v1.0.1-0.20190816133340-b04c5a83c1c0
|
||||
github.com/Rhymen/go-whatsapp v0.1.0
|
||||
github.com/bwmarrin/discordgo v0.20.2
|
||||
github.com/d5/tengo/v2 v2.0.2
|
||||
github.com/dfordsoft/golib v0.0.0-20180902042739-76ee6ab99bec
|
||||
github.com/fsnotify/fsnotify v1.4.7
|
||||
github.com/go-telegram-bot-api/telegram-bot-api v4.6.5-0.20181225215658-ec221ba9ea45+incompatible
|
||||
github.com/gomarkdown/markdown v0.0.0-20200127000047-1813ea067497
|
||||
github.com/google/gops v0.3.6
|
||||
github.com/Rhymen/go-whatsapp v0.1.1-0.20200421062035-31e8111ac334
|
||||
github.com/d5/tengo/v2 v2.6.0
|
||||
github.com/davecgh/go-spew v1.1.1
|
||||
github.com/fsnotify/fsnotify v1.4.9
|
||||
github.com/go-telegram-bot-api/telegram-bot-api v1.0.1-0.20200524105306-7434b0456e81
|
||||
github.com/gomarkdown/markdown v0.0.0-20200609195525-3f9352745725
|
||||
github.com/google/gops v0.3.10
|
||||
github.com/gopackage/ddp v0.0.0-20170117053602-652027933df4 // indirect
|
||||
github.com/gorilla/schema v1.1.0
|
||||
github.com/gorilla/websocket v1.4.1
|
||||
github.com/hashicorp/golang-lru v0.5.3
|
||||
github.com/gorilla/websocket v1.4.2
|
||||
github.com/hashicorp/golang-lru v0.5.4
|
||||
github.com/hpcloud/tail v1.0.0 // indirect
|
||||
github.com/jpillora/backoff v1.0.0
|
||||
github.com/keybase/go-keybase-chat-bot v0.0.0-20190816161829-561f10822eb2
|
||||
github.com/labstack/echo/v4 v4.1.13
|
||||
github.com/keybase/go-keybase-chat-bot v0.0.0-20200505163032-5cacf52379da
|
||||
github.com/labstack/echo/v4 v4.1.16
|
||||
github.com/lrstanley/girc v0.0.0-20190801035559-4fc93959e1a7
|
||||
github.com/matterbridge/Rocket.Chat.Go.SDK v0.0.0-20190210153444-cc9d05784d5d
|
||||
github.com/matterbridge/Rocket.Chat.Go.SDK v0.0.0-20200411204219-d5c18ce75048
|
||||
github.com/matterbridge/discordgo v0.21.2-0.20200718144317-01fe5db6c78d
|
||||
github.com/matterbridge/emoji v2.1.1-0.20191117213217-af507f6b02db+incompatible
|
||||
github.com/matterbridge/go-xmpp v0.0.0-20180529212104-cd19799fba91
|
||||
github.com/matterbridge/gomatrix v0.0.0-20191026211822-6fc7accd00ca
|
||||
github.com/matterbridge/go-xmpp v0.0.0-20200418225040-c8a3a57b4050
|
||||
github.com/matterbridge/gomatrix v0.0.0-20200209224845-c2104d7936a6
|
||||
github.com/matterbridge/gozulipbot v0.0.0-20190212232658-7aa251978a18
|
||||
github.com/matterbridge/logrus-prefixed-formatter v0.0.0-20180806162718-01618749af61
|
||||
github.com/matterbridge/logrus-prefixed-formatter v0.5.3-0.20200523233437-d971309a77ba
|
||||
github.com/mattermost/mattermost-server v5.5.0+incompatible
|
||||
github.com/mattn/godown v0.0.0-20200217152941-afc959f6a561
|
||||
github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b // indirect
|
||||
github.com/missdeer/golib v1.0.3
|
||||
github.com/mreiferson/go-httpclient v0.0.0-20160630210159-31f0106b4474 // indirect
|
||||
github.com/mrexodia/wray v0.0.0-20160318003008-78a2c1f284ff // indirect
|
||||
github.com/nelsonken/gomf v0.0.0-20180504123937-a9dd2f9deae9
|
||||
github.com/nicksnyder/go-i18n v1.4.0 // indirect
|
||||
github.com/nlopes/slack v0.6.0
|
||||
github.com/onsi/ginkgo v1.6.0 // indirect
|
||||
github.com/onsi/gomega v1.4.1 // indirect
|
||||
github.com/paulrosania/go-charset v0.0.0-20190326053356-55c9d7a5834c
|
||||
@@ -42,21 +43,21 @@ require (
|
||||
github.com/rs/xid v1.2.1
|
||||
github.com/russross/blackfriday v1.5.2
|
||||
github.com/saintfish/chardet v0.0.0-20120816061221-3af4cd4741ca
|
||||
github.com/shazow/ssh-chat v1.8.2
|
||||
github.com/sirupsen/logrus v1.4.2
|
||||
github.com/spf13/viper v1.6.1
|
||||
github.com/stretchr/testify v1.4.0
|
||||
github.com/technoweenie/multipartstreamer v1.0.1 // indirect
|
||||
github.com/shazow/ssh-chat v1.8.3-0.20200308224626-80ddf1f43a98
|
||||
github.com/sirupsen/logrus v1.6.0
|
||||
github.com/slack-go/slack v0.6.5
|
||||
github.com/spf13/viper v1.7.0
|
||||
github.com/stretchr/testify v1.5.1
|
||||
github.com/writeas/go-strip-markdown v2.0.1+incompatible
|
||||
github.com/x-cray/logrus-prefixed-formatter v0.5.2 // indirect
|
||||
github.com/zfjagann/golang-ring v0.0.0-20190106091943-a88bb6aef447
|
||||
golang.org/x/image v0.0.0-20191214001246-9130b4cfad52
|
||||
github.com/yaegashi/msgraph.go v0.1.3
|
||||
github.com/zfjagann/golang-ring v0.0.0-20190304061218-d34796e0a6c2
|
||||
golang.org/x/image v0.0.0-20200618115811-c13761719519
|
||||
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d
|
||||
gomod.garykim.dev/nc-talk v0.0.1
|
||||
gopkg.in/fsnotify.v1 v1.4.7 // indirect
|
||||
gopkg.in/natefinch/lumberjack.v2 v2.0.0 // indirect
|
||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect
|
||||
)
|
||||
|
||||
replace github.com/nlopes/slack v0.6.0 => github.com/matterbridge/slack v0.1.1-0.20191208194820-95190f11bfb6
|
||||
|
||||
replace github.com/bwmarrin/discordgo v0.20.2 => github.com/matterbridge/discordgo v0.18.1-0.20200109173909-ed873362fa43
|
||||
|
||||
go 1.13
|
||||
|
357
go.sum
357
go.sum
@@ -1,93 +1,139 @@
|
||||
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||
cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU=
|
||||
cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU=
|
||||
cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY=
|
||||
cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc=
|
||||
cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0=
|
||||
cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o=
|
||||
cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE=
|
||||
cloud.google.com/go/firestore v1.1.0/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqClKRT5SZwBmk=
|
||||
cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I=
|
||||
cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw=
|
||||
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
|
||||
github.com/42wim/go-gitter v0.0.0-20170828205020-017310c2d557 h1:IZtuWGfzQnKnCSu+vl8WGLhpVQ5Uvy3rlSwqXSg+sQg=
|
||||
github.com/42wim/go-gitter v0.0.0-20170828205020-017310c2d557/go.mod h1:jL0YSXMs/txjtGJ4PWrmETOk6KUHMDPMshgQZlTeB3Y=
|
||||
github.com/Baozisoftware/qrcode-terminal-go v0.0.0-20170407111555-c0650d8dff0f h1:2dk3eOnYllh+wUOuDhOoC2vUVoJF/5z478ryJ+wzEII=
|
||||
github.com/Baozisoftware/qrcode-terminal-go v0.0.0-20170407111555-c0650d8dff0f/go.mod h1:4a58ifQTEe2uwwsaqbh3i2un5/CBPg+At/qHpt18Tmk=
|
||||
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
|
||||
github.com/Jeffail/gabs v1.1.1 h1:V0uzR08Hj22EX8+8QMhyI9sX2hwRu+/RJhJUmnwda/E=
|
||||
github.com/Jeffail/gabs v1.1.1/go.mod h1:6xMvQMK4k33lb7GUUpaAPh6nKMmemQeg5d4gn7/bOXc=
|
||||
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
|
||||
github.com/Philipp15b/go-steam v1.0.1-0.20190816133340-b04c5a83c1c0 h1:TO7d4rocnNFng6ZQrPe7U6WqHtK5eHEMrgrnnM/72IQ=
|
||||
github.com/Philipp15b/go-steam v1.0.1-0.20190816133340-b04c5a83c1c0/go.mod h1:HuVM+sZFzumUdKPWiz+IlCMb4RdsKdT3T+nQBKL+sYg=
|
||||
github.com/Rhymen/go-whatsapp v0.0.0/go.mod h1:rdQr95g2C1xcOfM7QGOhza58HeI3I+tZ/bbluv7VazA=
|
||||
github.com/Rhymen/go-whatsapp v0.1.0 h1:XTXhFIQ/fx9jKObUnUX2Q+nh58EyeHNhX7DniE8xeuA=
|
||||
github.com/Rhymen/go-whatsapp v0.1.0/go.mod h1:xJSy+okeRjKkQEH/lEYrnekXB3PG33fqL0I6ncAkV50=
|
||||
github.com/Rhymen/go-whatsapp v0.1.1-0.20200421062035-31e8111ac334 h1:kb1zvD+xd+XbPUdQ0lMxnRaQ76N5C9vMAClLi8Dyw1Y=
|
||||
github.com/Rhymen/go-whatsapp v0.1.1-0.20200421062035-31e8111ac334/go.mod h1:o7jjkvKnigfu432dMbQ/w4PH0Yp5u4Y6ysCNjUlcYCk=
|
||||
github.com/Rhymen/go-whatsapp/examples/echo v0.0.0-20190325075644-cc2581bbf24d/go.mod h1:zgCiQtBtZ4P4gFWvwl9aashsdwOcbb/EHOGRmSzM8ME=
|
||||
github.com/Rhymen/go-whatsapp/examples/restoreSession v0.0.0-20190325075644-cc2581bbf24d/go.mod h1:5sCUSpG616ZoSJhlt9iBNI/KXBqrVLcNUJqg7J9+8pU=
|
||||
github.com/Rhymen/go-whatsapp/examples/sendImage v0.0.0-20190325075644-cc2581bbf24d/go.mod h1:RdiyhanVEGXTam+mZ3k6Y3VDCCvXYCwReOoxGozqhHw=
|
||||
github.com/Rhymen/go-whatsapp/examples/sendTextMessages v0.0.0-20190325075644-cc2581bbf24d/go.mod h1:suwzklatySS3Q0+NCxCDh5hYfgXdQUWU1DNcxwAxStM=
|
||||
github.com/StackExchange/wmi v0.0.0-20170410192909-ea383cf3ba6e h1:IHXQQIpxASe3m0Jtcd3XongL+lxHNd5nUmvHxJARUmg=
|
||||
github.com/StackExchange/wmi v0.0.0-20170410192909-ea383cf3ba6e/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg=
|
||||
github.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg=
|
||||
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
||||
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
||||
github.com/alexcesaro/log v0.0.0-20150915221235-61e686294e58 h1:MkpmYfld/S8kXqTYI68DfL8/hHXjHogL120Dy00TIxc=
|
||||
github.com/alexcesaro/log v0.0.0-20150915221235-61e686294e58/go.mod h1:YNfsMyWSs+h+PaYkxGeMVmVCX75Zj/pqdjbu12ciCYE=
|
||||
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
|
||||
github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o=
|
||||
github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY=
|
||||
github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
|
||||
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
|
||||
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
|
||||
github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=
|
||||
github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84=
|
||||
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
|
||||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||
github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
|
||||
github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
|
||||
github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
|
||||
github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
|
||||
github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
|
||||
github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
|
||||
github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
|
||||
github.com/d5/tengo/v2 v2.0.2 h1:3APkPZPc1FExaJoWrN5YzvDqc6GNkQH6ehmCRDmN83I=
|
||||
github.com/d5/tengo/v2 v2.0.2/go.mod h1:XRGjEs5I9jYIKTxly6HCF8oiiilk5E/RYXOZ5b0DZC8=
|
||||
github.com/d5/tengo/v2 v2.6.0 h1:D0cJtpiBzaLJ/Smv6nnUc/LIfO46oKwDx85NZtIRNRI=
|
||||
github.com/d5/tengo/v2 v2.6.0/go.mod h1:XRGjEs5I9jYIKTxly6HCF8oiiilk5E/RYXOZ5b0DZC8=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/dfordsoft/golib v0.0.0-20180902042739-76ee6ab99bec h1:JEUiu7P9smN7zgX87a2zVnnbPPickIM9Gf9OIhsIgWQ=
|
||||
github.com/dfordsoft/golib v0.0.0-20180902042739-76ee6ab99bec/go.mod h1:UGa5M2Sz/Uh13AMse4+RELKCDw7kqgqlTjeGae+7vUY=
|
||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM=
|
||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
|
||||
github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=
|
||||
github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I=
|
||||
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
|
||||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||
github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4=
|
||||
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
|
||||
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
||||
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
|
||||
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
||||
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
|
||||
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
|
||||
github.com/go-ole/go-ole v1.2.1 h1:2lOsA72HgjxAuMlKpFiCbHTvu44PIVkZ5hqm3RSdI/E=
|
||||
github.com/go-ole/go-ole v1.2.1/go.mod h1:7FAglXiTm7HKlQRDeOQ6ZNUHidzCWXuZWq/1dTyBNF8=
|
||||
github.com/go-ole/go-ole v1.2.4/go.mod h1:XCwSNxSkXRo4vlyPy93sltvi/qJq0jqQhjqQNIwKuxM=
|
||||
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
|
||||
github.com/go-telegram-bot-api/telegram-bot-api v4.6.5-0.20181225215658-ec221ba9ea45+incompatible h1:i64CCJcSqkRIkm5OSdZQjZq84/gJsk2zNwHWIRYWlKE=
|
||||
github.com/go-telegram-bot-api/telegram-bot-api v4.6.5-0.20181225215658-ec221ba9ea45+incompatible/go.mod h1:qf9acutJ8cwBUhm1bqgz6Bei9/C/c93FPDljKWwsOgM=
|
||||
github.com/go-telegram-bot-api/telegram-bot-api v1.0.1-0.20200524105306-7434b0456e81 h1:FdZThbRF0R+2qgyBl3KCVNWWBmKm68E+stT3rnQ02Ww=
|
||||
github.com/go-telegram-bot-api/telegram-bot-api v1.0.1-0.20200524105306-7434b0456e81/go.mod h1:lDm2E64X4OjFdBUA4hlN4mEvbSitvhJdKw7rsA8KHgI=
|
||||
github.com/go-test/deep v1.0.4 h1:u2CU3YKy9I2pmu9pX0eq50wCgjfGIt539SqR7FbHiho=
|
||||
github.com/go-test/deep v1.0.4/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA=
|
||||
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
|
||||
github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=
|
||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
||||
github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
||||
github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
||||
github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y=
|
||||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.0 h1:kbxbvI4Un1LUWKxufD+BiE6AEExYYgkQLQmLFqA1LFk=
|
||||
github.com/golang/protobuf v1.3.0/go.mod h1:Qd/q+1AKNOZr9uGQzbzCmRO6sUih6GTPZv6a1/R87v0=
|
||||
github.com/golang/protobuf v1.3.1 h1:YF8+flBXS5eO826T4nzqPrxfhQThhXl0YzfuUPu4SBg=
|
||||
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/gomarkdown/markdown v0.0.0-20200127000047-1813ea067497 h1:wJkj+x9gPYlDyM34C6r3SXPs270coWeh85wu1CsusDo=
|
||||
github.com/gomarkdown/markdown v0.0.0-20200127000047-1813ea067497/go.mod h1:aii0r/K0ZnHv7G0KF7xy1v0A7s2Ljrb5byB7MO5p6TU=
|
||||
github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs=
|
||||
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/gomarkdown/markdown v0.0.0-20200609195525-3f9352745725 h1:X6sZdr+t2E2jwajTy/FfXbmAKPFTYxEq9hiFgzMiuPQ=
|
||||
github.com/gomarkdown/markdown v0.0.0-20200609195525-3f9352745725/go.mod h1:aii0r/K0ZnHv7G0KF7xy1v0A7s2Ljrb5byB7MO5p6TU=
|
||||
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
||||
github.com/google/gops v0.3.6 h1:6akvbMlpZrEYOuoebn2kR+ZJekbZqJ28fJXTs84+8to=
|
||||
github.com/google/gops v0.3.6/go.mod h1:RZ1rH95wsAGX4vMWKmqBOIWynmWisBf4QFdgT/k/xOI=
|
||||
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
github.com/google/gops v0.3.10 h1:M2XZYgfUW+P7AOCLiu4CRb0rQfwnslLyB4B9Mp0vXmE=
|
||||
github.com/google/gops v0.3.10/go.mod h1:38bMPVKFh+1X106CPpbLAWtZIR1+xwgzT9gew0kn6w4=
|
||||
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
|
||||
github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
|
||||
github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
|
||||
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
|
||||
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
|
||||
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
|
||||
github.com/gopackage/ddp v0.0.0-20170117053602-652027933df4 h1:4EZlYQIiyecYJlUbVkFXCXHz1QPhVXcHnQKAzBTPfQo=
|
||||
github.com/gopackage/ddp v0.0.0-20170117053602-652027933df4/go.mod h1:lEO7XoHJ/xNRBCxrn4h/CEB67h0kW1B0t4ooP2yrjUA=
|
||||
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8=
|
||||
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
|
||||
github.com/gorilla/schema v1.1.0 h1:CamqUDOFUBqzrvxuz2vEwo8+SUdwsluFh7IlzJh30LY=
|
||||
github.com/gorilla/schema v1.1.0/go.mod h1:kgLaKoK1FELgZqMAVxx/5cbj0kT+57qxUrAlIO2eleU=
|
||||
github.com/gorilla/websocket v1.2.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
|
||||
github.com/gorilla/websocket v1.4.0 h1:WDFjx/TMzVgy9VdMMQi2K2Emtwi2QcUQsztZ/zLaH/Q=
|
||||
github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
|
||||
github.com/gorilla/websocket v1.4.1 h1:q7AeDBpnBk8AogcD4DSag/Ukw/KV+YhzLj2bP5HvKCM=
|
||||
github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||
github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc=
|
||||
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||
github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
|
||||
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
|
||||
github.com/hashicorp/golang-lru v0.5.3 h1:YPkqC67at8FYaadspW/6uE0COsBxS2656RLEr8Bppgk=
|
||||
github.com/hashicorp/golang-lru v0.5.3/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4=
|
||||
github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q=
|
||||
github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8=
|
||||
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
|
||||
github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=
|
||||
github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60=
|
||||
github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM=
|
||||
github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk=
|
||||
github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU=
|
||||
github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU=
|
||||
github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4=
|
||||
github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
|
||||
github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
|
||||
github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90=
|
||||
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||
github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+lJfyTc=
|
||||
github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4=
|
||||
github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
|
||||
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
|
||||
github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64=
|
||||
github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ=
|
||||
github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I=
|
||||
github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc=
|
||||
github.com/howeyc/gopass v0.0.0-20170109162249-bf9dde6d0d2c/go.mod h1:lADxMC39cJJqL93Duh1xhAs4I2Zs8mKS89XWXFGp9cs=
|
||||
github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI=
|
||||
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
||||
@@ -95,72 +141,82 @@ github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJS
|
||||
github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
|
||||
github.com/jpillora/backoff v1.0.0 h1:uvFg412JmmHBHw7iwprIxkPMI+sGQ4kzOWsMeHnm2EA=
|
||||
github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4=
|
||||
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
|
||||
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
|
||||
github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo=
|
||||
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
|
||||
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
|
||||
github.com/kardianos/osext v0.0.0-20170510131534-ae77be60afb1 h1:PJPDf8OUfOK1bb/NeTKd4f1QXZItOX389VN3B6qC8ro=
|
||||
github.com/kardianos/osext v0.0.0-20170510131534-ae77be60afb1/go.mod h1:1NbS8ALrpOvjt0rHPNLyCIeMtbizbir8U//inJ+zuB8=
|
||||
github.com/keybase/go-keybase-chat-bot v0.0.0-20190816161829-561f10822eb2 h1:zacJswvfPqUSGdcBXJzKvLN/dB1UjDGDvDesMBBzoA4=
|
||||
github.com/keybase/go-keybase-chat-bot v0.0.0-20190816161829-561f10822eb2/go.mod h1:vNc28YFzigVJod0j5EbuTtRIe7swx8vodh2yA4jZ2s8=
|
||||
github.com/keybase/go-ps v0.0.0-20161005175911-668c8856d999 h1:2d+FLQbz4xRTi36DO1qYNUwfORax9XcQ0jhbO81Vago=
|
||||
github.com/keybase/go-ps v0.0.0-20161005175911-668c8856d999/go.mod h1:hY+WOq6m2FpbvyrI93sMaypsttvaIL5nhVR92dTMUcQ=
|
||||
github.com/keybase/go-keybase-chat-bot v0.0.0-20200505163032-5cacf52379da h1:LK+8uBG3kNikj664cjFt88RBmuGmonxkXv2rUVfbqz4=
|
||||
github.com/keybase/go-keybase-chat-bot v0.0.0-20200505163032-5cacf52379da/go.mod h1:xJA+X9ZVyT/irGldcb7q1XnJBq5F9s5H9h2L44Y+poY=
|
||||
github.com/keybase/go-ps v0.0.0-20190827175125-91aafc93ba19/go.mod h1:hY+WOq6m2FpbvyrI93sMaypsttvaIL5nhVR92dTMUcQ=
|
||||
github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
|
||||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGiHgQ4OO8tzTaLawm8vnODuwDk=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.3 h1:CE8S1cTafDpPvMhIxNJKvHsGVBgn1xWYf1NbHQhywc8=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
|
||||
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
|
||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/labstack/echo v3.3.10+incompatible h1:pGRcYk231ExFAyoAjAfD85kQzRJCRI8bbnE7CX5OEgg=
|
||||
github.com/labstack/echo v3.3.10+incompatible/go.mod h1:0INS7j/VjnFxD4E2wkz67b8cVwCLbBmJyDaka6Cmk1s=
|
||||
github.com/labstack/echo/v4 v4.1.13 h1:JYgKq6NQQSaKbQcsOadAKX1kUVLCUzLGwu8sxN5tC34=
|
||||
github.com/labstack/echo/v4 v4.1.13/go.mod h1:3WZNypykZ3tnqpF2Qb4fPg27XDunFqgP3HGDmCMgv7U=
|
||||
github.com/labstack/echo/v4 v4.1.16 h1:8swiwjE5Jkai3RPfZoahp8kjVCRNq+y7Q0hPji2Kz0o=
|
||||
github.com/labstack/echo/v4 v4.1.16/go.mod h1:awO+5TzAjvL8XpibdsfXxPgHr+orhtXZJZIQCVjogKI=
|
||||
github.com/labstack/gommon v0.3.0 h1:JEeO0bvc78PKdyHxloTKiF8BD5iGrH8T6MSeGvSgob0=
|
||||
github.com/labstack/gommon v0.3.0/go.mod h1:MULnywXg0yavhxWKc+lOruYdAhDwPK9wf0OL7NoOu+k=
|
||||
github.com/lrstanley/girc v0.0.0-20190801035559-4fc93959e1a7 h1:BS9tqL0OCiOGuy/CYYk2gc33fxqaqh5/rhqMKu4tcYA=
|
||||
github.com/lrstanley/girc v0.0.0-20190801035559-4fc93959e1a7/go.mod h1:liX5MxHPrwgHaKowoLkYGwbXfYABh1jbZ6FpElbGF1I=
|
||||
github.com/magiconair/properties v1.8.1 h1:ZC2Vc7/ZFkGmsVC9KvOjumD+G5lXy2RtTKyzRKO2BQ4=
|
||||
github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
|
||||
github.com/matterbridge/Rocket.Chat.Go.SDK v0.0.0-20190210153444-cc9d05784d5d h1:F+Sr+C0ojSlYQ37BLylQtSFmyQULe3jbAygcyXQ9mVs=
|
||||
github.com/matterbridge/Rocket.Chat.Go.SDK v0.0.0-20190210153444-cc9d05784d5d/go.mod h1:c6MxwqHD+0HvtAJjsHMIdPCiAwGiQwPRPTp69ACMg8A=
|
||||
github.com/matterbridge/discordgo v0.18.1-0.20200109173909-ed873362fa43 h1:xTcLiEPMp9jVh/lHEPpLc87RZ4sRWRZe0rM578/waOk=
|
||||
github.com/matterbridge/discordgo v0.18.1-0.20200109173909-ed873362fa43/go.mod h1:O9S4p+ofTFwB02em7jkpkV8M3R0/PUVOwN61zSZ0r4Q=
|
||||
github.com/matterbridge/Rocket.Chat.Go.SDK v0.0.0-20200411204219-d5c18ce75048 h1:B9HaistmV+MD8/33BXmZe1zPIn+RImAFVXNNSOrwU2E=
|
||||
github.com/matterbridge/Rocket.Chat.Go.SDK v0.0.0-20200411204219-d5c18ce75048/go.mod h1:c6MxwqHD+0HvtAJjsHMIdPCiAwGiQwPRPTp69ACMg8A=
|
||||
github.com/matterbridge/discordgo v0.21.2-0.20200718144317-01fe5db6c78d h1:NBckP4nw7qVspbt7cOZYsrOrEbq7tATdMjSjc1hW63A=
|
||||
github.com/matterbridge/discordgo v0.21.2-0.20200718144317-01fe5db6c78d/go.mod h1:411nZYv0UMMrtppR5glXop1foboJiFAowy+42U+Ahvw=
|
||||
github.com/matterbridge/emoji v2.1.1-0.20191117213217-af507f6b02db+incompatible h1:oaOqwbg5HxHRxvAbd84ks0Okwoc1ISyUZ87EiVJFhGI=
|
||||
github.com/matterbridge/emoji v2.1.1-0.20191117213217-af507f6b02db+incompatible/go.mod h1:igE6rUAn3jai2wCdsjFHfhUoekjrFthoEjFObKKwSb4=
|
||||
github.com/matterbridge/go-xmpp v0.0.0-20180529212104-cd19799fba91 h1:KzDEcy8eDbTx881giW8a6llsAck3e2bJvMyKvh1IK+k=
|
||||
github.com/matterbridge/go-xmpp v0.0.0-20180529212104-cd19799fba91/go.mod h1:ECDRehsR9TYTKCAsRS8/wLeOk6UUqDydw47ln7wG41Q=
|
||||
github.com/matterbridge/gomatrix v0.0.0-20191026211822-6fc7accd00ca h1:3ypqEpFpt6vg5Sv2xxA8/v4WiSOnWMXW7DqxTxpM4XI=
|
||||
github.com/matterbridge/gomatrix v0.0.0-20191026211822-6fc7accd00ca/go.mod h1:+jWeaaUtXQbBRdKYWfjW6JDDYiI2XXE+3NnTjW5kg8g=
|
||||
github.com/matterbridge/go-xmpp v0.0.0-20200418225040-c8a3a57b4050 h1:kWkP1lXpkvtoNL08jkP3XQH/zvDOEXJpdCJd/DlIvMw=
|
||||
github.com/matterbridge/go-xmpp v0.0.0-20200418225040-c8a3a57b4050/go.mod h1:ECDRehsR9TYTKCAsRS8/wLeOk6UUqDydw47ln7wG41Q=
|
||||
github.com/matterbridge/gomatrix v0.0.0-20200209224845-c2104d7936a6 h1:Kl65VJv38HjYFnnwH+MP6Z8hcJT5UHuSpHVU5vW1HH0=
|
||||
github.com/matterbridge/gomatrix v0.0.0-20200209224845-c2104d7936a6/go.mod h1:+jWeaaUtXQbBRdKYWfjW6JDDYiI2XXE+3NnTjW5kg8g=
|
||||
github.com/matterbridge/gozulipbot v0.0.0-20190212232658-7aa251978a18 h1:fLhwXtWGtfTgZVxHG1lcKjv+re7dRwyyuYFNu69xdho=
|
||||
github.com/matterbridge/gozulipbot v0.0.0-20190212232658-7aa251978a18/go.mod h1:yAjnZ34DuDyPHMPHHjOsTk/FefW4JJjoMMCGt/8uuQA=
|
||||
github.com/matterbridge/logrus-prefixed-formatter v0.0.0-20180806162718-01618749af61 h1:R/MgM/eUyRBQx2FiH6JVmXck8PaAuKfe2M1tWIzW7nE=
|
||||
github.com/matterbridge/logrus-prefixed-formatter v0.0.0-20180806162718-01618749af61/go.mod h1:iXGEotOvwI1R1SjLxRc+BF5rUORTMtE0iMZBT2lxqAU=
|
||||
github.com/matterbridge/slack v0.1.1-0.20191208194820-95190f11bfb6 h1:UvXXR9tHYqJUXZVEtiK2qkEWBXfFneicate5kOshVFk=
|
||||
github.com/matterbridge/slack v0.1.1-0.20191208194820-95190f11bfb6/go.mod h1:2uCJim0Ct2z1Uj+XQq47KCLLC1b/9UTYaZOvDtbZfK4=
|
||||
github.com/matterbridge/logrus-prefixed-formatter v0.5.3-0.20200523233437-d971309a77ba h1:XleOY4IjAEIcxAh+IFwT5JT5Ze3RHiYz6m+4ZfZ0rc0=
|
||||
github.com/matterbridge/logrus-prefixed-formatter v0.5.3-0.20200523233437-d971309a77ba/go.mod h1:iXGEotOvwI1R1SjLxRc+BF5rUORTMtE0iMZBT2lxqAU=
|
||||
github.com/mattermost/mattermost-server v5.5.0+incompatible h1:0wcLGgYtd+YImtLDPf2AOfpBHxbU4suATx+6XKw1XbU=
|
||||
github.com/mattermost/mattermost-server v5.5.0+incompatible/go.mod h1:5L6MjAec+XXQwMIt791Ganu45GKsSiM+I0tLR9wUj8Y=
|
||||
github.com/mattn/go-colorable v0.1.1 h1:G1f5SKeVxmagw/IyvzvtZE4Gybcc4Tr1tf7I8z0XgOg=
|
||||
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
|
||||
github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ=
|
||||
github.com/mattn/go-colorable v0.1.2 h1:/bC9yWikZXAL9uJdulbSfyVNIR3n3trXl+v8+1sx8mU=
|
||||
github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
|
||||
github.com/mattn/go-colorable v0.1.4 h1:snbPLB8fVfU9iwbbo30TPtbLRzwWu6aJS6Xh4eaaviA=
|
||||
github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
|
||||
github.com/mattn/go-isatty v0.0.5 h1:tHXDdz1cpzGaovsTB+TVB8q90WEokoVmfMqoVcrLUgw=
|
||||
github.com/mattn/go-colorable v0.1.6 h1:6Su7aK7lXmJ/U79bYtBjLNaha4Fs1Rg9plHpcH+vvnE=
|
||||
github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
|
||||
github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
|
||||
github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
|
||||
github.com/mattn/go-isatty v0.0.8 h1:HLtExJ+uU2HOZ+wI0Tt5DtUDrx8yhUqDcp7fYERX4CE=
|
||||
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
|
||||
github.com/mattn/go-isatty v0.0.9 h1:d5US/mDsogSGW37IV293h//ZFaeajb69h+EHFsv2xGg=
|
||||
github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ=
|
||||
github.com/mattn/go-isatty v0.0.11 h1:FxPOTFNqGkuDUGi3H/qkUbQO4ZiBa2brKq5r0l8TGeM=
|
||||
github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE=
|
||||
github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY=
|
||||
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
|
||||
github.com/mattn/go-runewidth v0.0.8 h1:3tS41NlGYSmhhe/8fhGRzc+z3AYCw1Fe1WAyLuujKs0=
|
||||
github.com/mattn/go-runewidth v0.0.8/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
|
||||
github.com/mattn/godown v0.0.0-20200217152941-afc959f6a561 h1:0YGo77enc6tJpXQxUeQWs9bPIQPTH1lbOmc5tgRuq4o=
|
||||
github.com/mattn/godown v0.0.0-20200217152941-afc959f6a561/go.mod h1:/ivCKurgV/bx6yqtP/Jtc2Xmrv3beCYBvlfAUl4X5g4=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
|
||||
github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b h1:j7+1HpAFS1zy5+Q4qx1fWh90gTKwiN4QCGoY9TWyyO4=
|
||||
github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE=
|
||||
github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
|
||||
github.com/missdeer/golib v1.0.3 h1:+kz/tn1lXlPS8i+gjHHVAZC8YcgrmfiMTqELyvOwI4g=
|
||||
github.com/missdeer/golib v1.0.3/go.mod h1:Cys1ITPPZxIk2eTcQcKT3jDsBdhICAfrrw+ki/eRXxA=
|
||||
github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc=
|
||||
github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
|
||||
github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI=
|
||||
github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg=
|
||||
github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY=
|
||||
github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
|
||||
github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE=
|
||||
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
||||
github.com/monaco-io/request v1.0.3 h1:FsiIwXCCbHEyWx9A7lgg6JBTMHhHlEEsADsgAOvZ9HA=
|
||||
github.com/monaco-io/request v1.0.3/go.mod h1:EmggwHktBsbJmCgwZXqy7o0H1NNsAstQBWZrFVd3xtQ=
|
||||
github.com/mreiferson/go-httpclient v0.0.0-20160630210159-31f0106b4474 h1:oKIteTqeSpenyTrOVj5zkiyCaflLa8B+CD0324otT+o=
|
||||
github.com/mreiferson/go-httpclient v0.0.0-20160630210159-31f0106b4474/go.mod h1:OQA4XLvDbMgS8P0CevmM4m9Q3Jq4phKUzcocxuGJ5m8=
|
||||
github.com/mrexodia/wray v0.0.0-20160318003008-78a2c1f284ff h1:HLGD5/9UxxfEuO9DtP8gnTmNtMxbPyhYltfxsITel8g=
|
||||
@@ -175,6 +231,7 @@ github.com/onsi/ginkgo v1.6.0 h1:Ix8l273rp3QzYgXSR+c8d1fTG7UPgYkOSELPhiY/YGw=
|
||||
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/gomega v1.4.1 h1:PZSj/UFNaVp3KxrzHOcS7oyuWA7LoOY/77yCTEFu21U=
|
||||
github.com/onsi/gomega v1.4.1/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA=
|
||||
github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
|
||||
github.com/paulrosania/go-charset v0.0.0-20190326053356-55c9d7a5834c h1:P6XGcuPTigoHf4TSu+3D/7QOQ1MbL6alNwrGhcW7sKw=
|
||||
github.com/paulrosania/go-charset v0.0.0-20190326053356-55c9d7a5834c/go.mod h1:YnNlZP7l4MhyGQ4CBRwv6ohZTPrUJJZtEv4ZgADkbs4=
|
||||
github.com/pborman/uuid v0.0.0-20160216163710-c55201b03606 h1:/CPgDYrfeK2LMK6xcUhvI17yO9SlpAdDIJGkhDEgO8A=
|
||||
@@ -186,6 +243,7 @@ github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
|
||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI=
|
||||
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
|
||||
github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso=
|
||||
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
|
||||
@@ -195,26 +253,32 @@ github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y8
|
||||
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||
github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
|
||||
github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU=
|
||||
github.com/rickb777/date v1.12.4 h1:+6IzcCCS/1t17DrmnEvrznyq7nM8vPwir6/UhlyohKw=
|
||||
github.com/rickb777/date v1.12.4/go.mod h1:xP0eo/I5qmUt97yRGClHZfyLZ3ikMw6v6SU5MOGZTE0=
|
||||
github.com/rickb777/plural v1.2.0 h1:5tvEc7UBCZ7l8h/2UeybSkt/uu1DQsZFOFdNevmUhlE=
|
||||
github.com/rickb777/plural v1.2.0/go.mod h1:UdpyWFCGbo3mvK3f/PfZOAOrkjzJlYN/sD46XNWJ+Es=
|
||||
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
|
||||
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
||||
github.com/rs/xid v1.2.1 h1:mhH9Nq+C1fY2l1XIpgxIiUOfNpRBYH1kKcr+qfKgjRc=
|
||||
github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ=
|
||||
github.com/russross/blackfriday v1.5.2 h1:HyvC0ARfnZBqnXwABFeSZHpKvJHJJfPz81GNueLj0oo=
|
||||
github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
|
||||
github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
|
||||
github.com/saintfish/chardet v0.0.0-20120816061221-3af4cd4741ca h1:NugYot0LIVPxTvN8n+Kvkn6TrbMyxQiuvKdEwFdR9vI=
|
||||
github.com/saintfish/chardet v0.0.0-20120816061221-3af4cd4741ca/go.mod h1:uugorj2VCxiV1x+LzaIdVa9b4S4qGAcH6cbhh4qVxOU=
|
||||
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
|
||||
github.com/shazow/rateio v0.0.0-20150116013248-e8e00881e5c1 h1:Lx3BlDGFElJt4u/zKc9A3BuGYbQAGlEFyPuUA3jeMD0=
|
||||
github.com/shazow/rateio v0.0.0-20150116013248-e8e00881e5c1/go.mod h1:vt2jWY/3Qw1bIzle5thrJWucsLuuX9iUNnp20CqCciI=
|
||||
github.com/shazow/ssh-chat v1.8.2 h1:MMso9eWfCnPBelRsusYxKcRBUwHIPEQkR9WrO89II38=
|
||||
github.com/shazow/ssh-chat v1.8.2/go.mod h1:cXTZK/D1zujEwB0y8DIT1GX8rIKjyLDYeWd+jitPX84=
|
||||
github.com/shirou/gopsutil v0.0.0-20180427012116-c95755e4bcd7 h1:80VN+vGkqM773Br/uNNTSheo3KatTgV8IpjIKjvVLng=
|
||||
github.com/shirou/gopsutil v0.0.0-20180427012116-c95755e4bcd7/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA=
|
||||
github.com/shirou/w32 v0.0.0-20160930032740-bb4de0191aa4 h1:udFKJ0aHUL60LboW/A+DfgoHVedieIzIXE8uylPue0U=
|
||||
github.com/shirou/w32 v0.0.0-20160930032740-bb4de0191aa4/go.mod h1:qsXQc7+bwAM3Q1u/4XEfrquwF8Lw7D7y5cD8CuHnfIc=
|
||||
github.com/shazow/ssh-chat v1.8.3-0.20200308224626-80ddf1f43a98 h1:sN07ff+PSRsUNhpSod4uGKAQ+Nc0FXsBPG9FmYMNg4w=
|
||||
github.com/shazow/ssh-chat v1.8.3-0.20200308224626-80ddf1f43a98/go.mod h1:xkTgfD+WP+KR4HuG76oal25BBEeu5kJyi2EOsgiu/4Q=
|
||||
github.com/shirou/gopsutil v2.20.4+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA=
|
||||
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
|
||||
github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4=
|
||||
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
|
||||
github.com/sirupsen/logrus v1.6.0 h1:UBcNElsrwanuuMsnGSlYmtmgbb23qDR5dG+6X6Oo89I=
|
||||
github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88=
|
||||
github.com/skip2/go-qrcode v0.0.0-20190110000554-dc11ecdae0a9 h1:lpEzuenPuO1XNTeikEmvqYFcU37GVLl8SRNblzyvGBE=
|
||||
github.com/skip2/go-qrcode v0.0.0-20190110000554-dc11ecdae0a9/go.mod h1:PLPIyL7ikehBD1OAjmKKiOEhbvWyHGaNDjquXMcYABo=
|
||||
github.com/slack-go/slack v0.6.5 h1:IkDKtJ2IROJNoe3d6mW870/NRKvq2fhLB/Q5XmzWk00=
|
||||
github.com/slack-go/slack v0.6.5/go.mod h1:FGqNzJBmxIsZURAxh2a8D21AnOVvvXZvGligs4npPUM=
|
||||
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM=
|
||||
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
|
||||
github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s=
|
||||
@@ -229,35 +293,40 @@ github.com/spf13/jwalterweatherman v1.0.0 h1:XHEdyB+EcvlqZamSM4ZOMGlc93t6AcsBEu9
|
||||
github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
|
||||
github.com/spf13/pflag v1.0.3 h1:zPAT6CGy6wXeQ7NtTnaTerfKOsV6V6F8agHXFiazDkg=
|
||||
github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
||||
github.com/spf13/viper v1.6.1 h1:VPZzIkznI1YhVMRi6vNFLHSwhnhReBfgTxIPccpfdZk=
|
||||
github.com/spf13/viper v1.6.1/go.mod h1:t3iDnF5Jlj76alVNuyFBk5oUMCvsrkbvZK0WQdfDi5k=
|
||||
github.com/spf13/viper v1.7.0 h1:xVKxvI7ouOI5I+U9s2eeiUfMaWBVoXA3AWskkrqK0VM=
|
||||
github.com/spf13/viper v1.7.0/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.1.1 h1:2vfRuCMp5sSVIDSqO8oNnWJq7mPa6KVP3iPIwFBuy8A=
|
||||
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||
github.com/stretchr/testify v1.5.1 h1:nOGnQDM7FYENwehXlg/kFVnos3rEvtKTjRvOWSzb6H4=
|
||||
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
|
||||
github.com/subosito/gotenv v1.2.0 h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s=
|
||||
github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw=
|
||||
github.com/technoweenie/multipartstreamer v1.0.1 h1:XRztA5MXiR1TIRHxH2uNxXxaIkKQDeX7m2XsSOlQEnM=
|
||||
github.com/technoweenie/multipartstreamer v1.0.1/go.mod h1:jNVxdtShOxzAsukZwTSw6MDx5eUJoiEBsSvzDU9uzog=
|
||||
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
|
||||
github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc=
|
||||
github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
|
||||
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
|
||||
github.com/valyala/fasttemplate v1.0.1 h1:tY9CJiPnMXf1ERmG2EyK7gNUd+c6RKGD0IfU8WdUSz8=
|
||||
github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8=
|
||||
github.com/valyala/fasttemplate v1.1.0 h1:RZqt0yGBsps8NGvLSGW804QQqCUYYLsaOjTVHy1Ocw4=
|
||||
github.com/valyala/fasttemplate v1.1.0/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8=
|
||||
github.com/writeas/go-strip-markdown v2.0.1+incompatible h1:IIqxTM5Jr7RzhigcL6FkrCNfXkvbR+Nbu1ls48pXYcw=
|
||||
github.com/writeas/go-strip-markdown v2.0.1+incompatible/go.mod h1:Rsyu10ZhbEK9pXdk8V6MVnZmTzRG0alMNLMwa0J01fE=
|
||||
github.com/x-cray/logrus-prefixed-formatter v0.5.2 h1:00txxvfBM9muc0jiLIEAkAcIMJzfthRT6usrui8uGmg=
|
||||
github.com/x-cray/logrus-prefixed-formatter v0.5.2/go.mod h1:2duySbKsL6M18s5GU7VPsoEPHyzalCE06qoARUCeBBE=
|
||||
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
|
||||
github.com/xlab/treeprint v0.0.0-20180616005107-d6fb6747feb6 h1:YdYsPAZ2pC6Tow/nPZOPQ96O3hm/ToAkGsPLzedXERk=
|
||||
github.com/xlab/treeprint v0.0.0-20180616005107-d6fb6747feb6/go.mod h1:ce1O1j6UtZfjr22oyGxGLbauSBp2YVXpARAosm7dHBg=
|
||||
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
|
||||
github.com/zfjagann/golang-ring v0.0.0-20190106091943-a88bb6aef447 h1:CHgPZh8bFkZmislPrr/0gd7MciDAX+JJB70A2/5Lvmo=
|
||||
github.com/zfjagann/golang-ring v0.0.0-20190106091943-a88bb6aef447/go.mod h1:0MsIttMJIF/8Y7x0XjonJP7K99t3sR6bjj4m5S4JmqU=
|
||||
github.com/xlab/treeprint v1.0.0/go.mod h1:IoImgRak9i3zJyuxOKUP1v4UZd1tMoKkq/Cimt1uhCg=
|
||||
github.com/yaegashi/msgraph.go v0.1.3 h1:xeknrGbPGqUVvjjtXGuxvesHLNJ6jEfiOtqJToZe0qw=
|
||||
github.com/yaegashi/msgraph.go v0.1.3/go.mod h1:dpty8G9hMEC1xBQeXp6Z2hCXKalqczk2BLvK9me/TUU=
|
||||
github.com/yaegashi/wtz.go v0.0.2/go.mod h1:nOLA5QXsmdkRxBkP5tljhua13ADHCKirLBrzPf4PEJc=
|
||||
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/zfjagann/golang-ring v0.0.0-20190304061218-d34796e0a6c2 h1:UQwvu7FjUEdVYofx0U6bsc5odNE7wa5TSA0fl559GcA=
|
||||
github.com/zfjagann/golang-ring v0.0.0-20190304061218-d34796e0a6c2/go.mod h1:0MsIttMJIF/8Y7x0XjonJP7K99t3sR6bjj4m5S4JmqU=
|
||||
go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
|
||||
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
|
||||
go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
|
||||
go.uber.org/atomic v1.4.0 h1:cxzIVoETapQEqDhQu3QfnvXAV4AlzcvUCxkVUFw3+EU=
|
||||
go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
|
||||
go.uber.org/multierr v1.1.0 h1:HoEmRHQPVSqub6w2z2d2EOVs2fjyFRGyofhKuyDq0QI=
|
||||
@@ -266,66 +335,149 @@ go.uber.org/zap v1.10.0 h1:ORx85nbTijNz8ljznvCMR1ZBIPKFn3jQrag10X2AsuM=
|
||||
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
|
||||
golang.org/dl v0.0.0-20190829154251-82a15e2f2ead/go.mod h1:IUMfjQLJQd4UTqG1Z90tenwKoCX93Gn3MAQJMOSBsDQ=
|
||||
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20181030102418-4d3f4d9ffa16/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20190131182504-b8fe1690c613/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2 h1:VklqNMn3ovrHsnt90PveolxSbWFaJdECFbxSq0Mqo2M=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20190320223903-b7391e95e576/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20191227163750-53104e6ec876 h1:sKJQZMuxjOAR/Uo2LBfU90onWEf1dF4C+0hPJCc9Mpc=
|
||||
golang.org/x/crypto v0.0.0-20191227163750-53104e6ec876/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/image v0.0.0-20191214001246-9130b4cfad52 h1:2fktqPPvDiVEEVT/vSTeoUPXfmRxRaGy6GU8jypvEn0=
|
||||
golang.org/x/image v0.0.0-20191214001246-9130b4cfad52/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
||||
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20200221231518-2aa609cf4a9d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20200709230013-948cd5f35899 h1:DZhuSZLsGlFL4CmhA8BcRA0mnthyA/nZ00AqCUo7vHg=
|
||||
golang.org/x/crypto v0.0.0-20200709230013-948cd5f35899/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
|
||||
golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek=
|
||||
golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY=
|
||||
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
|
||||
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
||||
golang.org/x/image v0.0.0-20200618115811-c13761719519 h1:1e2ufUJNM3lCHEY5jIgac/7UTjd6cgJNdatjPdFWf34=
|
||||
golang.org/x/image v0.0.0-20200618115811-c13761719519/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
||||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
|
||||
golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=
|
||||
golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o=
|
||||
golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
|
||||
golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY=
|
||||
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190522155817-f3200d17e092 h1:4QSRKanuywn15aTZvI/mIDEgPQpswuFndXpOj3rKEco=
|
||||
golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
|
||||
golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553 h1:efeOvDhwQ29Dj3SdAV/MJf8oukgn+8D8WgaCaRMchF8=
|
||||
golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e h1:3G+cUijn7XD+S4eJFddp53Pv7+slrESplyjG25HgL+k=
|
||||
golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d h1:TzXSXBo42m9gQenoE3b9BGiEpg5IG2JkU5FkPIawgtw=
|
||||
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4 h1:YUO/7uOKsKeq9UokNS62b8FYywz3ker1l1vDZRCRefw=
|
||||
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20171017063910-8dbc5d05d6ed/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190321052220-f7bb7a8bee54/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a h1:aYOabOQFp6Vj6W1F80affTUvO9UxmJRx8K0gsfABByQ=
|
||||
golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8 h1:JA8d3MPx/IToSyXZG/RhwYEtfrKO1Fxrqe8KrkiLXKM=
|
||||
golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
|
||||
golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9 h1:YTzHMGlqJu67/uEo1lBv0n3wBXhXNeUbB1XfN2vmTm0=
|
||||
golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
|
||||
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
|
||||
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||
golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||
golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||
golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||
golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||
golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191112195655-aa38f8e97acc/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20200529172331-a64b76657301/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
gomod.garykim.dev/nc-talk v0.0.1 h1:6mgjcAf5/HMkV0CFGeXVfYHG7FAUCQcGR8eg9oM6fCc=
|
||||
gomod.garykim.dev/nc-talk v0.0.1/go.mod h1:0/Ksg0osAYmnWKs1OcCG+gBQ4HU1xiF1699g9B6jWZw=
|
||||
google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
|
||||
google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M=
|
||||
google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
|
||||
google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
|
||||
google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
|
||||
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
||||
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
google.golang.org/appengine v1.6.1 h1:QzqyMA1tlu6CgqCDUtU9V+ZKhLFT2dkJuANu5QaxI3I=
|
||||
google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0=
|
||||
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
||||
google.golang.org/genproto v0.0.0-20180831171423-11092d34479b/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
||||
google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||
google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||
google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||
google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||
google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
|
||||
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
|
||||
google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8=
|
||||
google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
||||
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||
google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
|
||||
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
|
||||
google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
|
||||
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
|
||||
gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4=
|
||||
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
|
||||
gopkg.in/ini.v1 v1.51.0 h1:AQvPpx3LzTDM0AjnIRlVFwFFGC+npRopjZxLJj6gdno=
|
||||
@@ -337,10 +489,13 @@ gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkep
|
||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
|
||||
gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74=
|
||||
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
|
||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.4 h1:/eiJrUcujPVeJ3xlSWaiNi3uSVmDGBK1pDHUHAnao1I=
|
||||
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10=
|
||||
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
rsc.io/goversion v1.0.0 h1:/IhXBiai89TyuerPquiZZ39IQkTfAUbZB2awsyYZ/2c=
|
||||
rsc.io/goversion v1.0.0/go.mod h1:Eih9y/uIBS3ulggl7KNJ09xGSLcuNaLgmvvqa07sgfo=
|
||||
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
|
||||
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
|
||||
rsc.io/goversion v1.2.0/go.mod h1:Eih9y/uIBS3ulggl7KNJ09xGSLcuNaLgmvvqa07sgfo=
|
||||
|
@@ -4,6 +4,7 @@ import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"os"
|
||||
"runtime"
|
||||
"strings"
|
||||
|
||||
"github.com/42wim/matterbridge/bridge/config"
|
||||
@@ -15,7 +16,7 @@ import (
|
||||
)
|
||||
|
||||
var (
|
||||
version = "1.16.5"
|
||||
version = "1.18.0"
|
||||
githash string
|
||||
|
||||
flagConfig = flag.String("conf", "matterbridge.toml", "config file")
|
||||
@@ -50,6 +51,15 @@ func main() {
|
||||
cfg := config.NewConfig(rootLogger, *flagConfig)
|
||||
cfg.BridgeValues().General.Debug = *flagDebug
|
||||
|
||||
// if logging to a file, ensure it is closed when the program terminates
|
||||
// nolint:errcheck
|
||||
defer func() {
|
||||
if f, ok := rootLogger.Out.(*os.File); ok {
|
||||
f.Sync()
|
||||
f.Close()
|
||||
}
|
||||
}()
|
||||
|
||||
r, err := gateway.NewRouter(rootLogger, cfg, bridgemap.FullMap)
|
||||
if err != nil {
|
||||
logger.Fatalf("Starting gateway failed: %s", err)
|
||||
@@ -67,17 +77,31 @@ func setupLogger() *logrus.Logger {
|
||||
Formatter: &prefixed.TextFormatter{
|
||||
PrefixPadding: 13,
|
||||
DisableColors: true,
|
||||
FullTimestamp: true,
|
||||
},
|
||||
Level: logrus.InfoLevel,
|
||||
}
|
||||
if *flagDebug || os.Getenv("DEBUG") == "1" {
|
||||
logger.SetReportCaller(true)
|
||||
logger.Formatter = &prefixed.TextFormatter{
|
||||
PrefixPadding: 13,
|
||||
DisableColors: true,
|
||||
FullTimestamp: false,
|
||||
ForceFormatting: true,
|
||||
PrefixPadding: 13,
|
||||
DisableColors: true,
|
||||
FullTimestamp: false,
|
||||
|
||||
CallerFormatter: func(function, file string) string {
|
||||
return fmt.Sprintf(" [%s:%s]", function, file)
|
||||
},
|
||||
CallerPrettyfier: func(f *runtime.Frame) (string, string) {
|
||||
sp := strings.SplitAfter(f.File, "/matterbridge/")
|
||||
filename := f.File
|
||||
if len(sp) > 1 {
|
||||
filename = sp[1]
|
||||
}
|
||||
s := strings.Split(f.Function, ".")
|
||||
funcName := s[len(s)-1]
|
||||
return funcName, fmt.Sprintf("%s:%d", filename, f.Line)
|
||||
},
|
||||
}
|
||||
|
||||
logger.Level = logrus.DebugLevel
|
||||
logger.WithFields(logrus.Fields{"prefix": "main"}).Info("Enabling debug logging.")
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@@ -14,7 +14,7 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/gorilla/schema"
|
||||
"github.com/nlopes/slack"
|
||||
"github.com/slack-go/slack"
|
||||
)
|
||||
|
||||
// OMessage for mattermost incoming webhook. (send to mattermost)
|
||||
|
1481
vendor/github.com/Rhymen/go-whatsapp/binary/proto/def.pb.go
generated
vendored
1481
vendor/github.com/Rhymen/go-whatsapp/binary/proto/def.pb.go
generated
vendored
File diff suppressed because it is too large
Load Diff
78
vendor/github.com/Rhymen/go-whatsapp/binary/proto/def.proto
generated
vendored
78
vendor/github.com/Rhymen/go-whatsapp/binary/proto/def.proto
generated
vendored
@@ -56,6 +56,8 @@ message Location {
|
||||
}
|
||||
|
||||
message Point {
|
||||
optional int32 xDeprecated = 1;
|
||||
optional int32 yDeprecated = 2;
|
||||
optional double x = 3;
|
||||
optional double y = 4;
|
||||
}
|
||||
@@ -93,6 +95,7 @@ message ContextInfo {
|
||||
optional AdReplyInfo quotedAd = 23;
|
||||
optional MessageKey placeholderKey = 24;
|
||||
optional uint32 expiration = 25;
|
||||
optional int64 ephemeralSettingTimestamp = 26;
|
||||
}
|
||||
|
||||
message SenderKeyDistributionMessage {
|
||||
@@ -136,6 +139,11 @@ message LocationMessage {
|
||||
optional string name = 3;
|
||||
optional string address = 4;
|
||||
optional string url = 5;
|
||||
optional bool isLive = 6;
|
||||
optional uint32 accuracyInMeters = 7;
|
||||
optional float speedInMps = 8;
|
||||
optional uint32 degreesClockwiseFromMagneticNorth = 9;
|
||||
optional string comment = 11;
|
||||
optional bytes jpegThumbnail = 16;
|
||||
optional ContextInfo contextInfo = 17;
|
||||
}
|
||||
@@ -238,9 +246,29 @@ message ProtocolMessage {
|
||||
enum PROTOCOL_MESSAGE_TYPE {
|
||||
REVOKE = 0;
|
||||
EPHEMERAL_SETTING = 3;
|
||||
EPHEMERAL_SYNC_RESPONSE = 4;
|
||||
HISTORY_SYNC_NOTIFICATION = 5;
|
||||
}
|
||||
optional PROTOCOL_MESSAGE_TYPE type = 2;
|
||||
optional uint32 ephemeralExpiration = 4;
|
||||
optional int64 ephemeralSettingTimestamp = 5;
|
||||
optional HistorySyncNotification historySyncNotification = 6;
|
||||
}
|
||||
|
||||
message HistorySyncNotification {
|
||||
optional bytes fileSha256 = 1;
|
||||
optional uint64 fileLength = 2;
|
||||
optional bytes mediaKey = 3;
|
||||
optional bytes fileEncSha256 = 4;
|
||||
optional string directPath = 5;
|
||||
enum HISTORY_SYNC_NOTIFICATION_HISTORYSYNCTYPE {
|
||||
INITIAL_BOOTSTRAP = 0;
|
||||
INITIAL_STATUS_V3 = 1;
|
||||
FULL = 2;
|
||||
RECENT = 3;
|
||||
}
|
||||
optional HISTORY_SYNC_NOTIFICATION_HISTORYSYNCTYPE syncType = 6;
|
||||
optional uint32 chunkOrder = 7;
|
||||
}
|
||||
|
||||
message ContactsArrayMessage {
|
||||
@@ -355,6 +383,8 @@ message StickerMessage {
|
||||
optional int64 mediaKeyTimestamp = 10;
|
||||
optional uint32 firstFrameLength = 11;
|
||||
optional bytes firstFrameSidecar = 12;
|
||||
optional bool isAnimated = 13;
|
||||
optional bytes pngThumbnail = 16;
|
||||
optional ContextInfo contextInfo = 17;
|
||||
}
|
||||
|
||||
@@ -401,6 +431,12 @@ message TemplateButtonReplyMessage {
|
||||
optional uint32 selectedIndex = 4;
|
||||
}
|
||||
|
||||
message CatalogSnapshot {
|
||||
optional ImageMessage catalogImage = 1;
|
||||
optional string title = 2;
|
||||
optional string description = 3;
|
||||
}
|
||||
|
||||
message ProductSnapshot {
|
||||
optional ImageMessage productImage = 1;
|
||||
optional string productId = 2;
|
||||
@@ -417,6 +453,7 @@ message ProductSnapshot {
|
||||
message ProductMessage {
|
||||
optional ProductSnapshot product = 1;
|
||||
optional string businessOwnerJid = 2;
|
||||
optional CatalogSnapshot catalog = 4;
|
||||
optional ContextInfo contextInfo = 17;
|
||||
}
|
||||
|
||||
@@ -513,6 +550,8 @@ message WebFeatures {
|
||||
optional WEB_FEATURES_FLAG templateMessage = 30;
|
||||
optional WEB_FEATURES_FLAG templateMessageInteractivity = 31;
|
||||
optional WEB_FEATURES_FLAG ephemeralMessages = 32;
|
||||
optional WEB_FEATURES_FLAG e2ENotificationSync = 33;
|
||||
optional WEB_FEATURES_FLAG recentStickersV2 = 34;
|
||||
}
|
||||
|
||||
message TabletNotificationsInfo {
|
||||
@@ -537,6 +576,11 @@ message WebNotificationsInfo {
|
||||
}
|
||||
|
||||
message PaymentInfo {
|
||||
enum PAYMENT_INFO_CURRENCY {
|
||||
UNKNOWN_CURRENCY = 0;
|
||||
INR = 1;
|
||||
}
|
||||
optional PAYMENT_INFO_CURRENCY currencyDeprecated = 1;
|
||||
optional uint64 amount1000 = 2;
|
||||
optional string receiverJid = 3;
|
||||
enum PAYMENT_INFO_STATUS {
|
||||
@@ -559,6 +603,37 @@ message PaymentInfo {
|
||||
optional uint64 expiryTimestamp = 7;
|
||||
optional bool futureproofed = 8;
|
||||
optional string currency = 9;
|
||||
enum PAYMENT_INFO_TXNSTATUS {
|
||||
UNKNOWN = 0;
|
||||
PENDING_SETUP = 1;
|
||||
PENDING_RECEIVER_SETUP = 2;
|
||||
INIT = 3;
|
||||
SUCCESS = 4;
|
||||
COMPLETED = 5;
|
||||
FAILED = 6;
|
||||
FAILED_RISK = 7;
|
||||
FAILED_PROCESSING = 8;
|
||||
FAILED_RECEIVER_PROCESSING = 9;
|
||||
FAILED_DA = 10;
|
||||
FAILED_DA_FINAL = 11;
|
||||
REFUNDED_TXN = 12;
|
||||
REFUND_FAILED = 13;
|
||||
REFUND_FAILED_PROCESSING = 14;
|
||||
REFUND_FAILED_DA = 15;
|
||||
EXPIRED_TXN = 16;
|
||||
AUTH_CANCELED = 17;
|
||||
AUTH_CANCEL_FAILED_PROCESSING = 18;
|
||||
AUTH_CANCEL_FAILED = 19;
|
||||
COLLECT_INIT = 20;
|
||||
COLLECT_SUCCESS = 21;
|
||||
COLLECT_FAILED = 22;
|
||||
COLLECT_FAILED_RISK = 23;
|
||||
COLLECT_REJECTED = 24;
|
||||
COLLECT_EXPIRED = 25;
|
||||
COLLECT_CANCELED = 26;
|
||||
COLLECT_CANCELLING = 27;
|
||||
}
|
||||
optional PAYMENT_INFO_TXNSTATUS txnStatus = 10;
|
||||
}
|
||||
|
||||
message WebMessageInfo {
|
||||
@@ -668,4 +743,5 @@ message WebMessageInfo {
|
||||
optional PaymentInfo quotedPaymentInfo = 31;
|
||||
optional uint64 ephemeralStartTimestamp = 32;
|
||||
optional uint32 ephemeralDuration = 33;
|
||||
}
|
||||
}
|
||||
|
||||
|
3
vendor/github.com/Rhymen/go-whatsapp/conn.go
generated
vendored
3
vendor/github.com/Rhymen/go-whatsapp/conn.go
generated
vendored
@@ -90,6 +90,7 @@ type Conn struct {
|
||||
|
||||
longClientName string
|
||||
shortClientName string
|
||||
clientVersion string
|
||||
|
||||
loginSessionLock sync.RWMutex
|
||||
Proxy func(*http.Request) (*url.URL, error)
|
||||
@@ -121,6 +122,7 @@ func NewConn(timeout time.Duration) (*Conn, error) {
|
||||
|
||||
longClientName: "github.com/rhymen/go-whatsapp",
|
||||
shortClientName: "go-whatsapp",
|
||||
clientVersion: "0.1.0",
|
||||
}
|
||||
return wac, wac.connect()
|
||||
}
|
||||
@@ -135,6 +137,7 @@ func NewConnWithProxy(timeout time.Duration, proxy func(*http.Request) (*url.URL
|
||||
|
||||
longClientName: "github.com/rhymen/go-whatsapp",
|
||||
shortClientName: "go-whatsapp",
|
||||
clientVersion: "0.1.0",
|
||||
Proxy: proxy,
|
||||
}
|
||||
return wac, wac.connect()
|
||||
|
2
vendor/github.com/Rhymen/go-whatsapp/go.mod
generated
vendored
2
vendor/github.com/Rhymen/go-whatsapp/go.mod
generated
vendored
@@ -6,7 +6,7 @@ require (
|
||||
github.com/Rhymen/go-whatsapp/examples/sendImage v0.0.0-20190325075644-cc2581bbf24d // indirect
|
||||
github.com/Rhymen/go-whatsapp/examples/sendTextMessages v0.0.0-20190325075644-cc2581bbf24d // indirect
|
||||
github.com/golang/protobuf v1.3.0
|
||||
github.com/gorilla/websocket v1.4.0
|
||||
github.com/gorilla/websocket v1.4.1
|
||||
github.com/pkg/errors v0.8.1
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2
|
||||
)
|
||||
|
3
vendor/github.com/Rhymen/go-whatsapp/go.sum
generated
vendored
3
vendor/github.com/Rhymen/go-whatsapp/go.sum
generated
vendored
@@ -12,8 +12,9 @@ github.com/Rhymen/go-whatsapp/examples/sendTextMessages v0.0.0-20190325075644-cc
|
||||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.0 h1:kbxbvI4Un1LUWKxufD+BiE6AEExYYgkQLQmLFqA1LFk=
|
||||
github.com/golang/protobuf v1.3.0/go.mod h1:Qd/q+1AKNOZr9uGQzbzCmRO6sUih6GTPZv6a1/R87v0=
|
||||
github.com/gorilla/websocket v1.4.0 h1:WDFjx/TMzVgy9VdMMQi2K2Emtwi2QcUQsztZ/zLaH/Q=
|
||||
github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
|
||||
github.com/gorilla/websocket v1.4.1 h1:q7AeDBpnBk8AogcD4DSag/Ukw/KV+YhzLj2bP5HvKCM=
|
||||
github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||
github.com/mattn/go-colorable v0.1.1 h1:G1f5SKeVxmagw/IyvzvtZE4Gybcc4Tr1tf7I8z0XgOg=
|
||||
github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ=
|
||||
github.com/mattn/go-isatty v0.0.5 h1:tHXDdz1cpzGaovsTB+TVB8q90WEokoVmfMqoVcrLUgw=
|
||||
|
116
vendor/github.com/Rhymen/go-whatsapp/media.go
generated
vendored
116
vendor/github.com/Rhymen/go-whatsapp/media.go
generated
vendored
@@ -10,10 +10,8 @@ import (
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"mime/multipart"
|
||||
"net/http"
|
||||
"os"
|
||||
"strings"
|
||||
"net/url"
|
||||
"time"
|
||||
|
||||
"github.com/Rhymen/go-whatsapp/crypto/cbc"
|
||||
@@ -95,7 +93,50 @@ func downloadMedia(url string) (file []byte, mac []byte, err error) {
|
||||
return data[:n-10], data[n-10 : n], nil
|
||||
}
|
||||
|
||||
func (wac *Conn) Upload(reader io.Reader, appInfo MediaType) (url string, mediaKey []byte, fileEncSha256 []byte, fileSha256 []byte, fileLength uint64, err error) {
|
||||
type MediaConn struct {
|
||||
Status int `json:"status"`
|
||||
MediaConn struct {
|
||||
Auth string `json:"auth"`
|
||||
TTL int `json:"ttl"`
|
||||
Hosts []struct {
|
||||
Hostname string `json:"hostname"`
|
||||
IPs []string `json:"ips"`
|
||||
} `json:"hosts"`
|
||||
} `json:"media_conn"`
|
||||
}
|
||||
|
||||
func (wac *Conn) queryMediaConn() (hostname, auth string, ttl int, err error) {
|
||||
queryReq := []interface{}{"query", "mediaConn"}
|
||||
ch, err := wac.writeJson(queryReq)
|
||||
if err != nil {
|
||||
return "", "", 0, err
|
||||
}
|
||||
|
||||
var resp MediaConn
|
||||
select {
|
||||
case r := <-ch:
|
||||
if err = json.Unmarshal([]byte(r), &resp); err != nil {
|
||||
return "", "", 0, fmt.Errorf("error decoding query media conn response: %v", err)
|
||||
}
|
||||
case <-time.After(wac.msgTimeout):
|
||||
return "", "", 0, fmt.Errorf("query media conn timed out")
|
||||
}
|
||||
|
||||
if resp.Status != 200 {
|
||||
return "", "", 0, fmt.Errorf("query media conn responded with %d", resp.Status)
|
||||
}
|
||||
|
||||
return resp.MediaConn.Hosts[0].Hostname, resp.MediaConn.Auth, resp.MediaConn.TTL, nil
|
||||
}
|
||||
|
||||
var mediaTypeMap = map[MediaType]string{
|
||||
MediaImage: "/mms/image",
|
||||
MediaVideo: "/mms/video",
|
||||
MediaDocument: "/mms/document",
|
||||
MediaAudio: "/mms/audio",
|
||||
}
|
||||
|
||||
func (wac *Conn) Upload(reader io.Reader, appInfo MediaType) (downloadURL string, mediaKey []byte, fileEncSha256 []byte, fileSha256 []byte, fileLength uint64, err error) {
|
||||
data, err := ioutil.ReadAll(reader)
|
||||
if err != nil {
|
||||
return "", nil, nil, nil, 0, err
|
||||
@@ -128,67 +169,30 @@ func (wac *Conn) Upload(reader io.Reader, appInfo MediaType) (url string, mediaK
|
||||
sha.Write(append(enc, mac...))
|
||||
fileEncSha256 = sha.Sum(nil)
|
||||
|
||||
var filetype string
|
||||
switch appInfo {
|
||||
case MediaImage:
|
||||
filetype = "image"
|
||||
case MediaAudio:
|
||||
filetype = "audio"
|
||||
case MediaDocument:
|
||||
filetype = "document"
|
||||
case MediaVideo:
|
||||
filetype = "video"
|
||||
hostname, auth, _, err := wac.queryMediaConn()
|
||||
token := base64.URLEncoding.EncodeToString(fileEncSha256)
|
||||
q := url.Values{
|
||||
"auth": []string{auth},
|
||||
"token": []string{token},
|
||||
}
|
||||
path := mediaTypeMap[appInfo]
|
||||
uploadURL := url.URL{
|
||||
Scheme: "https",
|
||||
Host: hostname,
|
||||
Path: fmt.Sprintf("%s/%s", path, token),
|
||||
RawQuery: q.Encode(),
|
||||
}
|
||||
|
||||
uploadReq := []interface{}{"action", "encr_upload", filetype, base64.StdEncoding.EncodeToString(fileEncSha256)}
|
||||
ch, err := wac.writeJson(uploadReq)
|
||||
body := bytes.NewReader(append(enc, mac...))
|
||||
|
||||
req, err := http.NewRequest("POST", uploadURL.String(), body)
|
||||
if err != nil {
|
||||
return "", nil, nil, nil, 0, err
|
||||
}
|
||||
|
||||
var resp map[string]interface{}
|
||||
select {
|
||||
case r := <-ch:
|
||||
if err = json.Unmarshal([]byte(r), &resp); err != nil {
|
||||
return "", nil, nil, nil, 0, fmt.Errorf("error decoding upload response: %v", err)
|
||||
}
|
||||
case <-time.After(wac.msgTimeout):
|
||||
return "", nil, nil, nil, 0, fmt.Errorf("restore session init timed out")
|
||||
}
|
||||
|
||||
if int(resp["status"].(float64)) != 200 {
|
||||
return "", nil, nil, nil, 0, fmt.Errorf("upload responsed with %d", resp["status"])
|
||||
}
|
||||
|
||||
var b bytes.Buffer
|
||||
w := multipart.NewWriter(&b)
|
||||
hashWriter, err := w.CreateFormField("hash")
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "%v\n", err)
|
||||
}
|
||||
io.Copy(hashWriter, strings.NewReader(base64.StdEncoding.EncodeToString(fileEncSha256)))
|
||||
|
||||
fileWriter, err := w.CreateFormFile("file", "blob")
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "%v\n", err)
|
||||
}
|
||||
io.Copy(fileWriter, bytes.NewReader(append(enc, mac...)))
|
||||
err = w.Close()
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "%v\n", err)
|
||||
}
|
||||
|
||||
req, err := http.NewRequest("POST", resp["url"].(string), &b)
|
||||
if err != nil {
|
||||
return "", nil, nil, nil, 0, err
|
||||
}
|
||||
|
||||
req.Header.Set("Content-Type", w.FormDataContentType())
|
||||
req.Header.Set("Origin", "https://web.whatsapp.com")
|
||||
req.Header.Set("Referer", "https://web.whatsapp.com/")
|
||||
|
||||
req.URL.Query().Set("f", "j")
|
||||
|
||||
client := &http.Client{}
|
||||
// Submit the request
|
||||
res, err := client.Do(req)
|
||||
|
6
vendor/github.com/Rhymen/go-whatsapp/read.go
generated
vendored
6
vendor/github.com/Rhymen/go-whatsapp/read.go
generated
vendored
@@ -15,7 +15,10 @@ import (
|
||||
)
|
||||
|
||||
func (wac *Conn) readPump() {
|
||||
defer wac.wg.Done()
|
||||
defer func() {
|
||||
wac.wg.Done()
|
||||
_, _ = wac.Disconnect()
|
||||
}()
|
||||
|
||||
var readErr error
|
||||
var msgType int
|
||||
@@ -31,7 +34,6 @@ func (wac *Conn) readPump() {
|
||||
case <-readerFound:
|
||||
if readErr != nil {
|
||||
wac.handle(&ErrConnectionFailed{Err: readErr})
|
||||
_, _ = wac.Disconnect()
|
||||
return
|
||||
}
|
||||
msg, err := ioutil.ReadAll(reader)
|
||||
|
18
vendor/github.com/Rhymen/go-whatsapp/session.go
generated
vendored
18
vendor/github.com/Rhymen/go-whatsapp/session.go
generated
vendored
@@ -18,7 +18,7 @@ import (
|
||||
)
|
||||
|
||||
//represents the WhatsAppWeb client version
|
||||
var waVersion = []int{0, 3, 3324}
|
||||
var waVersion = []int{0, 4, 2080}
|
||||
|
||||
/*
|
||||
Session contains session individual information. To be able to resume the connection without scanning the qr code
|
||||
@@ -107,10 +107,10 @@ func CheckCurrentServerVersion() ([]int, error) {
|
||||
}
|
||||
|
||||
b64ClientId := base64.StdEncoding.EncodeToString(clientId)
|
||||
login := []interface{}{"admin", "init", waVersion, []string{wac.longClientName, wac.shortClientName}, b64ClientId, true}
|
||||
login := []interface{}{"admin", "init", waVersion, []string{wac.longClientName, wac.shortClientName, wac.clientVersion}, b64ClientId, true}
|
||||
loginChan, err := wac.writeJson(login)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error writing login", err)
|
||||
return nil, fmt.Errorf("error writing login: %s", err.Error())
|
||||
}
|
||||
|
||||
// Retrieve an answer from the websocket
|
||||
@@ -123,7 +123,7 @@ func CheckCurrentServerVersion() ([]int, error) {
|
||||
|
||||
var resp map[string]interface{}
|
||||
if err = json.Unmarshal([]byte(r), &resp); err != nil {
|
||||
return nil, fmt.Errorf("error decoding login", err)
|
||||
return nil, fmt.Errorf("error decoding login: %s", err.Error())
|
||||
}
|
||||
|
||||
// Take the curr property as X.Y.Z and split it into as int slice
|
||||
@@ -141,17 +141,17 @@ func CheckCurrentServerVersion() ([]int, error) {
|
||||
SetClientName sets the long and short client names that are sent to WhatsApp when logging in and displayed in the
|
||||
WhatsApp Web device list. As the values are only sent when logging in, changing them after logging in is not possible.
|
||||
*/
|
||||
func (wac *Conn) SetClientName(long, short string) error {
|
||||
func (wac *Conn) SetClientName(long, short, version string) error {
|
||||
if wac.session != nil && (wac.session.EncKey != nil || wac.session.MacKey != nil) {
|
||||
return fmt.Errorf("cannot change client name after logging in")
|
||||
}
|
||||
wac.longClientName, wac.shortClientName = long, short
|
||||
wac.longClientName, wac.shortClientName, wac.clientVersion = long, short, version
|
||||
return nil
|
||||
}
|
||||
|
||||
/*
|
||||
SetClientVersion sets WhatsApp client version
|
||||
Default value is 0.3.3324
|
||||
Default value is 0.4.2080
|
||||
*/
|
||||
func (wac *Conn) SetClientVersion(major int, minor int, patch int) {
|
||||
waVersion = []int{major, minor, patch}
|
||||
@@ -213,7 +213,7 @@ func (wac *Conn) Login(qrChan chan<- string) (Session, error) {
|
||||
}
|
||||
|
||||
session.ClientId = base64.StdEncoding.EncodeToString(clientId)
|
||||
login := []interface{}{"admin", "init", waVersion, []string{wac.longClientName, wac.shortClientName}, session.ClientId, true}
|
||||
login := []interface{}{"admin", "init", waVersion, []string{wac.longClientName, wac.shortClientName, wac.clientVersion}, session.ClientId, true}
|
||||
loginChan, err := wac.writeJson(login)
|
||||
if err != nil {
|
||||
return session, fmt.Errorf("error writing login: %v\n", err)
|
||||
@@ -369,7 +369,7 @@ func (wac *Conn) Restore() error {
|
||||
wac.listener.Unlock()
|
||||
|
||||
//admin init
|
||||
init := []interface{}{"admin", "init", waVersion, []string{wac.longClientName, wac.shortClientName}, wac.session.ClientId, true}
|
||||
init := []interface{}{"admin", "init", waVersion, []string{wac.longClientName, wac.shortClientName, wac.clientVersion}, wac.session.ClientId, true}
|
||||
initChan, err := wac.writeJson(init)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error writing admin init: %v\n", err)
|
||||
|
6
vendor/github.com/bwmarrin/discordgo/go.mod
generated
vendored
6
vendor/github.com/bwmarrin/discordgo/go.mod
generated
vendored
@@ -1,6 +0,0 @@
|
||||
module github.com/bwmarrin/discordgo
|
||||
|
||||
require (
|
||||
github.com/gorilla/websocket v1.4.0
|
||||
golang.org/x/crypto v0.0.0-20181030102418-4d3f4d9ffa16
|
||||
)
|
4
vendor/github.com/bwmarrin/discordgo/go.sum
generated
vendored
4
vendor/github.com/bwmarrin/discordgo/go.sum
generated
vendored
@@ -1,4 +0,0 @@
|
||||
github.com/gorilla/websocket v1.4.0 h1:WDFjx/TMzVgy9VdMMQi2K2Emtwi2QcUQsztZ/zLaH/Q=
|
||||
github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
|
||||
golang.org/x/crypto v0.0.0-20181030102418-4d3f4d9ffa16 h1:y6ce7gCWtnH+m3dCjzQ1PCuwl28DDIc3VNnvY29DlIA=
|
||||
golang.org/x/crypto v0.0.0-20181030102418-4d3f4d9ffa16/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
7
vendor/github.com/d5/tengo/v2/.goreleaser.yml
generated
vendored
7
vendor/github.com/d5/tengo/v2/.goreleaser.yml
generated
vendored
@@ -11,9 +11,10 @@ builds:
|
||||
- darwin
|
||||
- linux
|
||||
- windows
|
||||
archive:
|
||||
files:
|
||||
- none*
|
||||
archives:
|
||||
-
|
||||
files:
|
||||
- none*
|
||||
checksum:
|
||||
name_template: 'checksums.txt'
|
||||
changelog:
|
||||
|
1
vendor/github.com/d5/tengo/v2/Makefile
generated
vendored
1
vendor/github.com/d5/tengo/v2/Makefile
generated
vendored
@@ -6,6 +6,7 @@ lint:
|
||||
|
||||
test: generate lint
|
||||
go test -race -cover ./...
|
||||
go run ./cmd/tengo -resolve ./testdata/cli/test.tengo
|
||||
|
||||
fmt:
|
||||
go fmt ./...
|
||||
|
40
vendor/github.com/d5/tengo/v2/README.md
generated
vendored
40
vendor/github.com/d5/tengo/v2/README.md
generated
vendored
@@ -5,9 +5,8 @@
|
||||
# The Tengo Language
|
||||
|
||||
[](https://godoc.org/github.com/d5/tengo)
|
||||

|
||||
[](https://goreportcard.com/report/github.com/d5/tengo)
|
||||
[](https://circleci.com/gh/d5/tengo)
|
||||
[](https://sourcegraph.com/github.com/d5/tengo?badge)
|
||||
|
||||
**Tengo is a small, dynamic, fast, secure script language for Go.**
|
||||
|
||||
@@ -52,19 +51,21 @@ fmt.println(sum("", [1, 2, 3])) // "123"
|
||||
|
||||
## Benchmark
|
||||
|
||||
| | fib(35) | fibt(35) | Type |
|
||||
| | fib(35) | fibt(35) | Language (Type) |
|
||||
| :--- | ---: | ---: | :---: |
|
||||
| Go | `48ms` | `3ms` | Go (native) |
|
||||
| [**Tengo**](https://github.com/d5/tengo) | `2,349ms` | `5ms` | VM on Go |
|
||||
| Lua | `1,416ms` | `3ms` | Lua (native) |
|
||||
| [go-lua](https://github.com/Shopify/go-lua) | `4,402ms` | `5ms` | Lua VM on Go |
|
||||
| [GopherLua](https://github.com/yuin/gopher-lua) | `4,023ms` | `5ms` | Lua VM on Go |
|
||||
| Python | `2,588ms` | `26ms` | Python (native) |
|
||||
| [starlark-go](https://github.com/google/starlark-go) | `11,126ms` | `6ms` | Python-like Interpreter on Go |
|
||||
| [gpython](https://github.com/go-python/gpython) | `15,035ms` | `4ms` | Python Interpreter on Go |
|
||||
| [goja](https://github.com/dop251/goja) | `5,089ms` | `5ms` | JS VM on Go |
|
||||
| [otto](https://github.com/robertkrimen/otto) | `68,377ms` | `11ms` | JS Interpreter on Go |
|
||||
| [Anko](https://github.com/mattn/anko) | `92,579ms` | `18ms` | Interpreter on Go |
|
||||
| [**Tengo**](https://github.com/d5/tengo) | `2,931ms` | `4ms` | Tengo (VM) |
|
||||
| [go-lua](https://github.com/Shopify/go-lua) | `4,824ms` | `4ms` | Lua (VM) |
|
||||
| [GopherLua](https://github.com/yuin/gopher-lua) | `5,365ms` | `4ms` | Lua (VM) |
|
||||
| [goja](https://github.com/dop251/goja) | `5,533ms` | `5ms` | JavaScript (VM) |
|
||||
| [starlark-go](https://github.com/google/starlark-go) | `11,495ms` | `5ms` | Starlark (Interpreter) |
|
||||
| [Yaegi](https://github.com/containous/yaegi) | `15,645ms` | `12ms` | Yaegi (Interpreter) |
|
||||
| [gpython](https://github.com/go-python/gpython) | `16,322ms` | `5ms` | Python (Interpreter) |
|
||||
| [otto](https://github.com/robertkrimen/otto) | `73,093ms` | `10ms` | JavaScript (Interpreter) |
|
||||
| [Anko](https://github.com/mattn/anko) | `79,809ms` | `8ms` | Anko (Interpreter) |
|
||||
| - | - | - | - |
|
||||
| Go | `53ms` | `3ms` | Go (Native) |
|
||||
| Lua | `1,612ms` | `3ms` | Lua (Native) |
|
||||
| Python | `2,632ms` | `23ms` | Python 2 (Native) |
|
||||
|
||||
_* [fib(35)](https://github.com/d5/tengobench/blob/master/code/fib.tengo):
|
||||
Fibonacci(35)_
|
||||
@@ -75,6 +76,10 @@ _* See [here](https://github.com/d5/tengobench) for commands/codes used_
|
||||
|
||||
## Quick Start
|
||||
|
||||
```
|
||||
go get github.com/d5/tengo/v2
|
||||
```
|
||||
|
||||
A simple Go example code that compiles/runs Tengo script code with some input/output values:
|
||||
|
||||
```golang
|
||||
@@ -133,3 +138,10 @@ each([a, b, c, d], func(x) {
|
||||
- [Interoperability](https://github.com/d5/tengo/blob/master/docs/interoperability.md)
|
||||
- [Tengo CLI](https://github.com/d5/tengo/blob/master/docs/tengo-cli.md)
|
||||
- [Standard Library](https://github.com/d5/tengo/blob/master/docs/stdlib.md)
|
||||
- Syntax Highlighters: [VSCode](https://github.com/lissein/vscode-tengo), [Atom](https://github.com/d5/tengo-atom)
|
||||
- **Why the name Tengo?** It's from [1Q84](https://en.wikipedia.org/wiki/1Q84).
|
||||
|
||||
##
|
||||
|
||||
:hearts: Like writing Go code? Come work at Skool. [We're hiring!](https://jobs.lever.co/skool)
|
||||
|
||||
|
109
vendor/github.com/d5/tengo/v2/builtins.go
generated
vendored
109
vendor/github.com/d5/tengo/v2/builtins.go
generated
vendored
@@ -13,6 +13,14 @@ var builtinFuncs = []*BuiltinFunction{
|
||||
Name: "append",
|
||||
Value: builtinAppend,
|
||||
},
|
||||
{
|
||||
Name: "delete",
|
||||
Value: builtinDelete,
|
||||
},
|
||||
{
|
||||
Name: "splice",
|
||||
Value: builtinSplice,
|
||||
},
|
||||
{
|
||||
Name: "string",
|
||||
Value: builtinString,
|
||||
@@ -500,3 +508,104 @@ func builtinAppend(args ...Object) (Object, error) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// builtinDelete deletes Map keys
|
||||
// usage: delete(map, "key")
|
||||
// key must be a string
|
||||
func builtinDelete(args ...Object) (Object, error) {
|
||||
argsLen := len(args)
|
||||
if argsLen != 2 {
|
||||
return nil, ErrWrongNumArguments
|
||||
}
|
||||
switch arg := args[0].(type) {
|
||||
case *Map:
|
||||
if key, ok := args[1].(*String); ok {
|
||||
delete(arg.Value, key.Value)
|
||||
return UndefinedValue, nil
|
||||
}
|
||||
return nil, ErrInvalidArgumentType{
|
||||
Name: "second",
|
||||
Expected: "string",
|
||||
Found: args[1].TypeName(),
|
||||
}
|
||||
default:
|
||||
return nil, ErrInvalidArgumentType{
|
||||
Name: "first",
|
||||
Expected: "map",
|
||||
Found: arg.TypeName(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// builtinSplice deletes and changes given Array, returns deleted items.
|
||||
// usage:
|
||||
// deleted_items := splice(array[,start[,delete_count[,item1[,item2[,...]]]])
|
||||
func builtinSplice(args ...Object) (Object, error) {
|
||||
argsLen := len(args)
|
||||
if argsLen == 0 {
|
||||
return nil, ErrWrongNumArguments
|
||||
}
|
||||
|
||||
array, ok := args[0].(*Array)
|
||||
if !ok {
|
||||
return nil, ErrInvalidArgumentType{
|
||||
Name: "first",
|
||||
Expected: "array",
|
||||
Found: args[0].TypeName(),
|
||||
}
|
||||
}
|
||||
arrayLen := len(array.Value)
|
||||
|
||||
var startIdx int
|
||||
if argsLen > 1 {
|
||||
arg1, ok := args[1].(*Int)
|
||||
if !ok {
|
||||
return nil, ErrInvalidArgumentType{
|
||||
Name: "second",
|
||||
Expected: "int",
|
||||
Found: args[1].TypeName(),
|
||||
}
|
||||
}
|
||||
startIdx = int(arg1.Value)
|
||||
if startIdx < 0 || startIdx > arrayLen {
|
||||
return nil, ErrIndexOutOfBounds
|
||||
}
|
||||
}
|
||||
|
||||
delCount := len(array.Value)
|
||||
if argsLen > 2 {
|
||||
arg2, ok := args[2].(*Int)
|
||||
if !ok {
|
||||
return nil, ErrInvalidArgumentType{
|
||||
Name: "third",
|
||||
Expected: "int",
|
||||
Found: args[2].TypeName(),
|
||||
}
|
||||
}
|
||||
delCount = int(arg2.Value)
|
||||
if delCount < 0 {
|
||||
return nil, ErrIndexOutOfBounds
|
||||
}
|
||||
}
|
||||
// if count of to be deleted items is bigger than expected, truncate it
|
||||
if startIdx+delCount > arrayLen {
|
||||
delCount = arrayLen - startIdx
|
||||
}
|
||||
// delete items
|
||||
endIdx := startIdx + delCount
|
||||
deleted := append([]Object{}, array.Value[startIdx:endIdx]...)
|
||||
|
||||
head := array.Value[:startIdx]
|
||||
var items []Object
|
||||
if argsLen > 3 {
|
||||
items = make([]Object, 0, argsLen-3)
|
||||
for i := 3; i < argsLen; i++ {
|
||||
items = append(items, args[i])
|
||||
}
|
||||
}
|
||||
items = append(items, array.Value[endIdx:]...)
|
||||
array.Value = append(head, items...)
|
||||
|
||||
// return deleted items
|
||||
return &Array{Value: deleted}, nil
|
||||
}
|
||||
|
12
vendor/github.com/d5/tengo/v2/bytecode.go
generated
vendored
12
vendor/github.com/d5/tengo/v2/bytecode.go
generated
vendored
@@ -97,6 +97,7 @@ func (b *Bytecode) RemoveDuplicates() {
|
||||
var deduped []Object
|
||||
|
||||
indexMap := make(map[int]int) // mapping from old constant index to new index
|
||||
fns := make(map[*CompiledFunction]int)
|
||||
ints := make(map[int64]int)
|
||||
strings := make(map[string]int)
|
||||
floats := make(map[float64]int)
|
||||
@@ -106,9 +107,14 @@ func (b *Bytecode) RemoveDuplicates() {
|
||||
for curIdx, c := range b.Constants {
|
||||
switch c := c.(type) {
|
||||
case *CompiledFunction:
|
||||
// add to deduped list
|
||||
indexMap[curIdx] = len(deduped)
|
||||
deduped = append(deduped, c)
|
||||
if newIdx, ok := fns[c]; ok {
|
||||
indexMap[curIdx] = newIdx
|
||||
} else {
|
||||
newIdx = len(deduped)
|
||||
fns[c] = newIdx
|
||||
indexMap[curIdx] = newIdx
|
||||
deduped = append(deduped, c)
|
||||
}
|
||||
case *ImmutableMap:
|
||||
modName := inferModuleName(c)
|
||||
newIdx, ok := immutableMaps[modName]
|
||||
|
52
vendor/github.com/d5/tengo/v2/compiler.go
generated
vendored
52
vendor/github.com/d5/tengo/v2/compiler.go
generated
vendored
@@ -44,6 +44,7 @@ type Compiler struct {
|
||||
file *parser.SourceFile
|
||||
parent *Compiler
|
||||
modulePath string
|
||||
importDir string
|
||||
constants []Object
|
||||
symbolTable *SymbolTable
|
||||
scopes []compilationScope
|
||||
@@ -505,7 +506,11 @@ func (c *Compiler) Compile(node parser.Node) error {
|
||||
return err
|
||||
}
|
||||
}
|
||||
c.emit(node, parser.OpCall, len(node.Args))
|
||||
ellipsis := 0
|
||||
if node.Ellipsis.IsValid() {
|
||||
ellipsis = 1
|
||||
}
|
||||
c.emit(node, parser.OpCall, len(node.Args), ellipsis)
|
||||
case *parser.ImportExpr:
|
||||
if node.ModuleName == "" {
|
||||
return c.errorf(node, "empty module name")
|
||||
@@ -520,12 +525,12 @@ func (c *Compiler) Compile(node parser.Node) error {
|
||||
switch v := v.(type) {
|
||||
case []byte: // module written in Tengo
|
||||
compiled, err := c.compileModule(node,
|
||||
node.ModuleName, node.ModuleName, v)
|
||||
node.ModuleName, v, false)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
c.emit(node, parser.OpConstant, c.addConstant(compiled))
|
||||
c.emit(node, parser.OpCall, 0)
|
||||
c.emit(node, parser.OpCall, 0, 0)
|
||||
case Object: // builtin module
|
||||
c.emit(node, parser.OpConstant, c.addConstant(v))
|
||||
default:
|
||||
@@ -537,29 +542,25 @@ func (c *Compiler) Compile(node parser.Node) error {
|
||||
moduleName += ".tengo"
|
||||
}
|
||||
|
||||
modulePath, err := filepath.Abs(moduleName)
|
||||
modulePath, err := filepath.Abs(
|
||||
filepath.Join(c.importDir, moduleName))
|
||||
if err != nil {
|
||||
return c.errorf(node, "module file path error: %s",
|
||||
err.Error())
|
||||
}
|
||||
|
||||
if err := c.checkCyclicImports(node, modulePath); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
moduleSrc, err := ioutil.ReadFile(moduleName)
|
||||
moduleSrc, err := ioutil.ReadFile(modulePath)
|
||||
if err != nil {
|
||||
return c.errorf(node, "module file read error: %s",
|
||||
err.Error())
|
||||
}
|
||||
|
||||
compiled, err := c.compileModule(node,
|
||||
moduleName, modulePath, moduleSrc)
|
||||
compiled, err := c.compileModule(node, modulePath, moduleSrc, true)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
c.emit(node, parser.OpConstant, c.addConstant(compiled))
|
||||
c.emit(node, parser.OpCall, 0)
|
||||
c.emit(node, parser.OpCall, 0, 0)
|
||||
} else {
|
||||
return c.errorf(node, "module '%s' not found", node.ModuleName)
|
||||
}
|
||||
@@ -634,6 +635,11 @@ func (c *Compiler) EnableFileImport(enable bool) {
|
||||
c.allowFileImport = enable
|
||||
}
|
||||
|
||||
// SetImportDir sets the initial import directory path for file imports.
|
||||
func (c *Compiler) SetImportDir(dir string) {
|
||||
c.importDir = dir
|
||||
}
|
||||
|
||||
func (c *Compiler) compileAssign(
|
||||
node parser.Node,
|
||||
lhs, rhs []parser.Expr,
|
||||
@@ -847,8 +853,8 @@ func (c *Compiler) compileForInStmt(stmt *parser.ForInStmt) error {
|
||||
// ... body ...
|
||||
// }
|
||||
//
|
||||
// ":it" is a local variable but will be conflict with other user variables
|
||||
// because character ":" is not allowed.
|
||||
// ":it" is a local variable but it will not conflict with other user variables
|
||||
// because character ":" is not allowed in the variable names.
|
||||
|
||||
// init
|
||||
// :it = iterator(iterable)
|
||||
@@ -893,6 +899,7 @@ func (c *Compiler) compileForInStmt(stmt *parser.ForInStmt) error {
|
||||
if keySymbol.Scope == ScopeGlobal {
|
||||
c.emit(stmt, parser.OpSetGlobal, keySymbol.Index)
|
||||
} else {
|
||||
keySymbol.LocalAssigned = true
|
||||
c.emit(stmt, parser.OpDefineLocal, keySymbol.Index)
|
||||
}
|
||||
}
|
||||
@@ -909,6 +916,7 @@ func (c *Compiler) compileForInStmt(stmt *parser.ForInStmt) error {
|
||||
if valueSymbol.Scope == ScopeGlobal {
|
||||
c.emit(stmt, parser.OpSetGlobal, valueSymbol.Index)
|
||||
} else {
|
||||
valueSymbol.LocalAssigned = true
|
||||
c.emit(stmt, parser.OpDefineLocal, valueSymbol.Index)
|
||||
}
|
||||
}
|
||||
@@ -955,8 +963,9 @@ func (c *Compiler) checkCyclicImports(
|
||||
|
||||
func (c *Compiler) compileModule(
|
||||
node parser.Node,
|
||||
moduleName, modulePath string,
|
||||
modulePath string,
|
||||
src []byte,
|
||||
isFile bool,
|
||||
) (*CompiledFunction, error) {
|
||||
if err := c.checkCyclicImports(node, modulePath); err != nil {
|
||||
return nil, err
|
||||
@@ -967,7 +976,7 @@ func (c *Compiler) compileModule(
|
||||
return compiledModule, nil
|
||||
}
|
||||
|
||||
modFile := c.file.Set().AddFile(moduleName, -1, len(src))
|
||||
modFile := c.file.Set().AddFile(modulePath, -1, len(src))
|
||||
p := parser.NewParser(modFile, src, nil)
|
||||
file, err := p.ParseFile()
|
||||
if err != nil {
|
||||
@@ -984,7 +993,7 @@ func (c *Compiler) compileModule(
|
||||
symbolTable = symbolTable.Fork(false)
|
||||
|
||||
// compile module
|
||||
moduleCompiler := c.fork(modFile, modulePath, symbolTable)
|
||||
moduleCompiler := c.fork(modFile, modulePath, symbolTable, isFile)
|
||||
if err := moduleCompiler.Compile(file); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -1082,10 +1091,16 @@ func (c *Compiler) fork(
|
||||
file *parser.SourceFile,
|
||||
modulePath string,
|
||||
symbolTable *SymbolTable,
|
||||
isFile bool,
|
||||
) *Compiler {
|
||||
child := NewCompiler(file, symbolTable, nil, c.modules, c.trace)
|
||||
child.modulePath = modulePath // module file path
|
||||
child.parent = c // parent to set to current compiler
|
||||
child.allowFileImport = c.allowFileImport
|
||||
child.importDir = c.importDir
|
||||
if isFile && c.importDir != "" {
|
||||
child.importDir = filepath.Dir(modulePath)
|
||||
}
|
||||
return child
|
||||
}
|
||||
|
||||
@@ -1192,6 +1207,7 @@ func (c *Compiler) optimizeFunc(node parser.Node) {
|
||||
var lastOp parser.Opcode
|
||||
var appendReturn bool
|
||||
endPos := len(c.scopes[c.scopeIndex].Instructions)
|
||||
newEndPost := len(newInsts)
|
||||
iterateInstructions(newInsts,
|
||||
func(pos int, opcode parser.Opcode, operands []int) bool {
|
||||
switch opcode {
|
||||
@@ -1204,6 +1220,8 @@ func (c *Compiler) optimizeFunc(node parser.Node) {
|
||||
} else if endPos == operands[0] {
|
||||
// there's a jump instruction that jumps to the end of
|
||||
// function compiler should append "return".
|
||||
copy(newInsts[pos:],
|
||||
MakeInstruction(opcode, newEndPost))
|
||||
appendReturn = true
|
||||
} else {
|
||||
panic(fmt.Errorf("invalid jump position: %d", newDst))
|
||||
|
32
vendor/github.com/d5/tengo/v2/objects.go
generated
vendored
32
vendor/github.com/d5/tengo/v2/objects.go
generated
vendored
@@ -1342,6 +1342,38 @@ func (o *String) BinaryOp(op token.Token, rhs Object) (Object, error) {
|
||||
}
|
||||
return &String{Value: o.Value + rhsStr}, nil
|
||||
}
|
||||
case token.Less:
|
||||
switch rhs := rhs.(type) {
|
||||
case *String:
|
||||
if o.Value < rhs.Value {
|
||||
return TrueValue, nil
|
||||
}
|
||||
return FalseValue, nil
|
||||
}
|
||||
case token.LessEq:
|
||||
switch rhs := rhs.(type) {
|
||||
case *String:
|
||||
if o.Value <= rhs.Value {
|
||||
return TrueValue, nil
|
||||
}
|
||||
return FalseValue, nil
|
||||
}
|
||||
case token.Greater:
|
||||
switch rhs := rhs.(type) {
|
||||
case *String:
|
||||
if o.Value > rhs.Value {
|
||||
return TrueValue, nil
|
||||
}
|
||||
return FalseValue, nil
|
||||
}
|
||||
case token.GreaterEq:
|
||||
switch rhs := rhs.(type) {
|
||||
case *String:
|
||||
if o.Value >= rhs.Value {
|
||||
return TrueValue, nil
|
||||
}
|
||||
return FalseValue, nil
|
||||
}
|
||||
}
|
||||
return nil, ErrInvalidOperator
|
||||
}
|
||||
|
12
vendor/github.com/d5/tengo/v2/parser/expr.go
generated
vendored
12
vendor/github.com/d5/tengo/v2/parser/expr.go
generated
vendored
@@ -111,10 +111,11 @@ func (e *BoolLit) String() string {
|
||||
|
||||
// CallExpr represents a function call expression.
|
||||
type CallExpr struct {
|
||||
Func Expr
|
||||
LParen Pos
|
||||
Args []Expr
|
||||
RParen Pos
|
||||
Func Expr
|
||||
LParen Pos
|
||||
Args []Expr
|
||||
Ellipsis Pos
|
||||
RParen Pos
|
||||
}
|
||||
|
||||
func (e *CallExpr) exprNode() {}
|
||||
@@ -134,6 +135,9 @@ func (e *CallExpr) String() string {
|
||||
for _, e := range e.Args {
|
||||
args = append(args, e.String())
|
||||
}
|
||||
if len(args) > 0 && e.Ellipsis.IsValid() {
|
||||
args[len(args)-1] = args[len(args)-1] + "..."
|
||||
}
|
||||
return e.Func.String() + "(" + strings.Join(args, ", ") + ")"
|
||||
}
|
||||
|
||||
|
2
vendor/github.com/d5/tengo/v2/parser/opcodes.go
generated
vendored
2
vendor/github.com/d5/tengo/v2/parser/opcodes.go
generated
vendored
@@ -120,7 +120,7 @@ var OpcodeOperands = [...][]int{
|
||||
OpImmutable: {},
|
||||
OpIndex: {},
|
||||
OpSliceIndex: {},
|
||||
OpCall: {1},
|
||||
OpCall: {1, 1},
|
||||
OpReturn: {1},
|
||||
OpGetLocal: {1},
|
||||
OpSetLocal: {1},
|
||||
|
17
vendor/github.com/d5/tengo/v2/parser/parser.go
generated
vendored
17
vendor/github.com/d5/tengo/v2/parser/parser.go
generated
vendored
@@ -270,9 +270,13 @@ func (p *Parser) parseCall(x Expr) *CallExpr {
|
||||
p.exprLevel++
|
||||
|
||||
var list []Expr
|
||||
for p.token != token.RParen && p.token != token.EOF {
|
||||
var ellipsis Pos
|
||||
for p.token != token.RParen && p.token != token.EOF && !ellipsis.IsValid() {
|
||||
list = append(list, p.parseExpr())
|
||||
|
||||
if p.token == token.Ellipsis {
|
||||
ellipsis = p.pos
|
||||
p.next()
|
||||
}
|
||||
if !p.expectComma(token.RParen, "call argument") {
|
||||
break
|
||||
}
|
||||
@@ -281,10 +285,11 @@ func (p *Parser) parseCall(x Expr) *CallExpr {
|
||||
p.exprLevel--
|
||||
rparen := p.expect(token.RParen)
|
||||
return &CallExpr{
|
||||
Func: x,
|
||||
LParen: lparen,
|
||||
RParen: rparen,
|
||||
Args: list,
|
||||
Func: x,
|
||||
LParen: lparen,
|
||||
RParen: rparen,
|
||||
Ellipsis: ellipsis,
|
||||
Args: list,
|
||||
}
|
||||
}
|
||||
|
||||
|
13
vendor/github.com/d5/tengo/v2/script.go
generated
vendored
13
vendor/github.com/d5/tengo/v2/script.go
generated
vendored
@@ -3,6 +3,7 @@ package tengo
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"path/filepath"
|
||||
"sync"
|
||||
|
||||
"github.com/d5/tengo/v2/parser"
|
||||
@@ -16,6 +17,7 @@ type Script struct {
|
||||
maxAllocs int64
|
||||
maxConstObjects int
|
||||
enableFileImport bool
|
||||
importDir string
|
||||
}
|
||||
|
||||
// NewScript creates a Script instance with an input script.
|
||||
@@ -56,6 +58,16 @@ func (s *Script) SetImports(modules *ModuleMap) {
|
||||
s.modules = modules
|
||||
}
|
||||
|
||||
// SetImportDir sets the initial import directory for script files.
|
||||
func (s *Script) SetImportDir(dir string) error {
|
||||
dir, err := filepath.Abs(dir)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
s.importDir = dir
|
||||
return nil
|
||||
}
|
||||
|
||||
// SetMaxAllocs sets the maximum number of objects allocations during the run
|
||||
// time. Compiled script will return ErrObjectAllocLimit error if it
|
||||
// exceeds this limit.
|
||||
@@ -93,6 +105,7 @@ func (s *Script) Compile() (*Compiled, error) {
|
||||
|
||||
c := NewCompiler(srcFile, symbolTable, nil, s.modules, nil)
|
||||
c.EnableFileImport(s.enableFileImport)
|
||||
c.SetImportDir(s.importDir)
|
||||
if err := c.Compile(file); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
195
vendor/github.com/d5/tengo/v2/stdlib/json/encode.go
generated
vendored
195
vendor/github.com/d5/tengo/v2/stdlib/json/encode.go
generated
vendored
@@ -1,20 +1,129 @@
|
||||
// A modified version of Go's JSON implementation.
|
||||
|
||||
// Copyright 2010 The Go Authors. All rights reserved.
|
||||
// Copyright 2010, 2020 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package json
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/base64"
|
||||
"errors"
|
||||
"math"
|
||||
"strconv"
|
||||
"unicode/utf8"
|
||||
|
||||
"github.com/d5/tengo/v2"
|
||||
)
|
||||
|
||||
// safeSet holds the value true if the ASCII character with the given array
|
||||
// position can be represented inside a JSON string without any further
|
||||
// escaping.
|
||||
//
|
||||
// All values are true except for the ASCII control characters (0-31), the
|
||||
// double quote ("), and the backslash character ("\").
|
||||
var safeSet = [utf8.RuneSelf]bool{
|
||||
' ': true,
|
||||
'!': true,
|
||||
'"': false,
|
||||
'#': true,
|
||||
'$': true,
|
||||
'%': true,
|
||||
'&': true,
|
||||
'\'': true,
|
||||
'(': true,
|
||||
')': true,
|
||||
'*': true,
|
||||
'+': true,
|
||||
',': true,
|
||||
'-': true,
|
||||
'.': true,
|
||||
'/': true,
|
||||
'0': true,
|
||||
'1': true,
|
||||
'2': true,
|
||||
'3': true,
|
||||
'4': true,
|
||||
'5': true,
|
||||
'6': true,
|
||||
'7': true,
|
||||
'8': true,
|
||||
'9': true,
|
||||
':': true,
|
||||
';': true,
|
||||
'<': true,
|
||||
'=': true,
|
||||
'>': true,
|
||||
'?': true,
|
||||
'@': true,
|
||||
'A': true,
|
||||
'B': true,
|
||||
'C': true,
|
||||
'D': true,
|
||||
'E': true,
|
||||
'F': true,
|
||||
'G': true,
|
||||
'H': true,
|
||||
'I': true,
|
||||
'J': true,
|
||||
'K': true,
|
||||
'L': true,
|
||||
'M': true,
|
||||
'N': true,
|
||||
'O': true,
|
||||
'P': true,
|
||||
'Q': true,
|
||||
'R': true,
|
||||
'S': true,
|
||||
'T': true,
|
||||
'U': true,
|
||||
'V': true,
|
||||
'W': true,
|
||||
'X': true,
|
||||
'Y': true,
|
||||
'Z': true,
|
||||
'[': true,
|
||||
'\\': false,
|
||||
']': true,
|
||||
'^': true,
|
||||
'_': true,
|
||||
'`': true,
|
||||
'a': true,
|
||||
'b': true,
|
||||
'c': true,
|
||||
'd': true,
|
||||
'e': true,
|
||||
'f': true,
|
||||
'g': true,
|
||||
'h': true,
|
||||
'i': true,
|
||||
'j': true,
|
||||
'k': true,
|
||||
'l': true,
|
||||
'm': true,
|
||||
'n': true,
|
||||
'o': true,
|
||||
'p': true,
|
||||
'q': true,
|
||||
'r': true,
|
||||
's': true,
|
||||
't': true,
|
||||
'u': true,
|
||||
'v': true,
|
||||
'w': true,
|
||||
'x': true,
|
||||
'y': true,
|
||||
'z': true,
|
||||
'{': true,
|
||||
'|': true,
|
||||
'}': true,
|
||||
'~': true,
|
||||
'\u007f': true,
|
||||
}
|
||||
|
||||
var hex = "0123456789abcdef"
|
||||
|
||||
// Encode returns the JSON encoding of the object.
|
||||
func Encode(o tengo.Object) ([]byte, error) {
|
||||
var b []byte
|
||||
@@ -53,7 +162,7 @@ func Encode(o tengo.Object) ([]byte, error) {
|
||||
len1 := len(o.Value) - 1
|
||||
idx := 0
|
||||
for key, value := range o.Value {
|
||||
b = strconv.AppendQuote(b, key)
|
||||
b = encodeString(b, key)
|
||||
b = append(b, ':')
|
||||
eb, err := Encode(value)
|
||||
if err != nil {
|
||||
@@ -71,7 +180,7 @@ func Encode(o tengo.Object) ([]byte, error) {
|
||||
len1 := len(o.Value) - 1
|
||||
idx := 0
|
||||
for key, value := range o.Value {
|
||||
b = strconv.AppendQuote(b, key)
|
||||
b = encodeString(b, key)
|
||||
b = append(b, ':')
|
||||
eb, err := Encode(value)
|
||||
if err != nil {
|
||||
@@ -130,7 +239,9 @@ func Encode(o tengo.Object) ([]byte, error) {
|
||||
case *tengo.Int:
|
||||
b = strconv.AppendInt(b, o.Value, 10)
|
||||
case *tengo.String:
|
||||
b = strconv.AppendQuote(b, o.Value)
|
||||
// string encoding bug is fixed with newly introduced function
|
||||
// encodeString(). See: https://github.com/d5/tengo/issues/268
|
||||
b = encodeString(b, o.Value)
|
||||
case *tengo.Time:
|
||||
y, err := o.Value.MarshalJSON()
|
||||
if err != nil {
|
||||
@@ -144,3 +255,79 @@ func Encode(o tengo.Object) ([]byte, error) {
|
||||
}
|
||||
return b, nil
|
||||
}
|
||||
|
||||
// encodeString encodes given string as JSON string according to
|
||||
// https://www.json.org/img/string.png
|
||||
// Implementation is inspired by https://github.com/json-iterator/go
|
||||
// See encodeStringSlowPath() for more information.
|
||||
func encodeString(b []byte, val string) []byte {
|
||||
valLen := len(val)
|
||||
buf := bytes.NewBuffer(b)
|
||||
buf.WriteByte('"')
|
||||
|
||||
// write string, the fast path, without utf8 and escape support
|
||||
i := 0
|
||||
for ; i < valLen; i++ {
|
||||
c := val[i]
|
||||
if c > 31 && c != '"' && c != '\\' {
|
||||
buf.WriteByte(c)
|
||||
} else {
|
||||
break
|
||||
}
|
||||
}
|
||||
if i == valLen {
|
||||
buf.WriteByte('"')
|
||||
return buf.Bytes()
|
||||
}
|
||||
encodeStringSlowPath(buf, i, val, valLen)
|
||||
buf.WriteByte('"')
|
||||
return buf.Bytes()
|
||||
}
|
||||
|
||||
// encodeStringSlowPath is ported from Go 1.14.2 encoding/json package.
|
||||
// U+2028 U+2029 JSONP security holes can be fixed with addition call to
|
||||
// json.html_escape() thus it is removed from the implementation below.
|
||||
// Note: Invalid runes are not checked as they are checked in original
|
||||
// implementation.
|
||||
func encodeStringSlowPath(buf *bytes.Buffer, i int, val string, valLen int) {
|
||||
start := i
|
||||
for i < valLen {
|
||||
if b := val[i]; b < utf8.RuneSelf {
|
||||
if safeSet[b] {
|
||||
i++
|
||||
continue
|
||||
}
|
||||
if start < i {
|
||||
buf.WriteString(val[start:i])
|
||||
}
|
||||
buf.WriteByte('\\')
|
||||
switch b {
|
||||
case '\\', '"':
|
||||
buf.WriteByte(b)
|
||||
case '\n':
|
||||
buf.WriteByte('n')
|
||||
case '\r':
|
||||
buf.WriteByte('r')
|
||||
case '\t':
|
||||
buf.WriteByte('t')
|
||||
default:
|
||||
// This encodes bytes < 0x20 except for \t, \n and \r.
|
||||
// If escapeHTML is set, it also escapes <, >, and &
|
||||
// because they can lead to security holes when
|
||||
// user-controlled strings are rendered into JSON
|
||||
// and served to some browsers.
|
||||
buf.WriteString(`u00`)
|
||||
buf.WriteByte(hex[b>>4])
|
||||
buf.WriteByte(hex[b&0xF])
|
||||
}
|
||||
i++
|
||||
start = i
|
||||
continue
|
||||
}
|
||||
i++
|
||||
continue
|
||||
}
|
||||
if start < valLen {
|
||||
buf.WriteString(val[start:])
|
||||
}
|
||||
}
|
||||
|
32
vendor/github.com/d5/tengo/v2/vm.go
generated
vendored
32
vendor/github.com/d5/tengo/v2/vm.go
generated
vendored
@@ -80,14 +80,14 @@ func (v *VM) Run() (err error) {
|
||||
if err != nil {
|
||||
filePos := v.fileSet.Position(
|
||||
v.curFrame.fn.SourcePos(v.ip - 1))
|
||||
err = fmt.Errorf("Runtime Error: %s\n\tat %s",
|
||||
err.Error(), filePos)
|
||||
err = fmt.Errorf("Runtime Error: %w\n\tat %s",
|
||||
err, filePos)
|
||||
for v.framesIndex > 1 {
|
||||
v.framesIndex--
|
||||
v.curFrame = &v.frames[v.framesIndex-1]
|
||||
filePos = v.fileSet.Position(
|
||||
v.curFrame.fn.SourcePos(v.curFrame.ip - 1))
|
||||
err = fmt.Errorf("%s\n\tat %s", err.Error(), filePos)
|
||||
err = fmt.Errorf("%w\n\tat %s", err, filePos)
|
||||
}
|
||||
return err
|
||||
}
|
||||
@@ -537,12 +537,36 @@ func (v *VM) run() {
|
||||
}
|
||||
case parser.OpCall:
|
||||
numArgs := int(v.curInsts[v.ip+1])
|
||||
v.ip++
|
||||
spread := int(v.curInsts[v.ip+2])
|
||||
v.ip += 2
|
||||
|
||||
value := v.stack[v.sp-1-numArgs]
|
||||
if !value.CanCall() {
|
||||
v.err = fmt.Errorf("not callable: %s", value.TypeName())
|
||||
return
|
||||
}
|
||||
|
||||
if spread == 1 {
|
||||
v.sp--
|
||||
switch arr := v.stack[v.sp].(type) {
|
||||
case *Array:
|
||||
for _, item := range arr.Value {
|
||||
v.stack[v.sp] = item
|
||||
v.sp++
|
||||
}
|
||||
numArgs += len(arr.Value) - 1
|
||||
case *ImmutableArray:
|
||||
for _, item := range arr.Value {
|
||||
v.stack[v.sp] = item
|
||||
v.sp++
|
||||
}
|
||||
numArgs += len(arr.Value) - 1
|
||||
default:
|
||||
v.err = fmt.Errorf("not an array: %s", arr.TypeName())
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if callee, ok := value.(*CompiledFunction); ok {
|
||||
if callee.VarArgs {
|
||||
// if the closure is variadic,
|
||||
|
9
vendor/github.com/fsnotify/fsnotify/.editorconfig
generated
vendored
9
vendor/github.com/fsnotify/fsnotify/.editorconfig
generated
vendored
@@ -1,5 +1,12 @@
|
||||
root = true
|
||||
|
||||
[*]
|
||||
[*.go]
|
||||
indent_style = tab
|
||||
indent_size = 4
|
||||
insert_final_newline = true
|
||||
|
||||
[*.{yml,yaml}]
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
insert_final_newline = true
|
||||
trim_trailing_whitespace = true
|
||||
|
1
vendor/github.com/fsnotify/fsnotify/.gitattributes
generated
vendored
Normal file
1
vendor/github.com/fsnotify/fsnotify/.gitattributes
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
go.sum linguist-generated
|
20
vendor/github.com/fsnotify/fsnotify/.travis.yml
generated
vendored
20
vendor/github.com/fsnotify/fsnotify/.travis.yml
generated
vendored
@@ -2,29 +2,35 @@ sudo: false
|
||||
language: go
|
||||
|
||||
go:
|
||||
- 1.8.x
|
||||
- 1.9.x
|
||||
- tip
|
||||
- "stable"
|
||||
- "1.11.x"
|
||||
- "1.10.x"
|
||||
- "1.9.x"
|
||||
|
||||
matrix:
|
||||
include:
|
||||
- go: "stable"
|
||||
env: GOLINT=true
|
||||
allow_failures:
|
||||
- go: tip
|
||||
fast_finish: true
|
||||
|
||||
before_script:
|
||||
- go get -u github.com/golang/lint/golint
|
||||
|
||||
before_install:
|
||||
- if [ ! -z "${GOLINT}" ]; then go get -u golang.org/x/lint/golint; fi
|
||||
|
||||
script:
|
||||
- go test -v --race ./...
|
||||
- go test --race ./...
|
||||
|
||||
after_script:
|
||||
- test -z "$(gofmt -s -l -w . | tee /dev/stderr)"
|
||||
- test -z "$(golint ./... | tee /dev/stderr)"
|
||||
- if [ ! -z "${GOLINT}" ]; then echo running golint; golint --set_exit_status ./...; else echo skipping golint; fi
|
||||
- go vet ./...
|
||||
|
||||
os:
|
||||
- linux
|
||||
- osx
|
||||
- windows
|
||||
|
||||
notifications:
|
||||
email: false
|
||||
|
2
vendor/github.com/fsnotify/fsnotify/LICENSE
generated
vendored
2
vendor/github.com/fsnotify/fsnotify/LICENSE
generated
vendored
@@ -1,5 +1,5 @@
|
||||
Copyright (c) 2012 The Go Authors. All rights reserved.
|
||||
Copyright (c) 2012 fsnotify Authors. All rights reserved.
|
||||
Copyright (c) 2012-2019 fsnotify Authors. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
|
71
vendor/github.com/fsnotify/fsnotify/README.md
generated
vendored
71
vendor/github.com/fsnotify/fsnotify/README.md
generated
vendored
@@ -10,16 +10,16 @@ go get -u golang.org/x/sys/...
|
||||
|
||||
Cross platform: Windows, Linux, BSD and macOS.
|
||||
|
||||
|Adapter |OS |Status |
|
||||
|----------|----------|----------|
|
||||
|inotify |Linux 2.6.27 or later, Android\*|Supported [](https://travis-ci.org/fsnotify/fsnotify)|
|
||||
|kqueue |BSD, macOS, iOS\*|Supported [](https://travis-ci.org/fsnotify/fsnotify)|
|
||||
|ReadDirectoryChangesW|Windows|Supported [](https://ci.appveyor.com/project/NathanYoungman/fsnotify/branch/master)|
|
||||
|FSEvents |macOS |[Planned](https://github.com/fsnotify/fsnotify/issues/11)|
|
||||
|FEN |Solaris 11 |[In Progress](https://github.com/fsnotify/fsnotify/issues/12)|
|
||||
|fanotify |Linux 2.6.37+ | |
|
||||
|USN Journals |Windows |[Maybe](https://github.com/fsnotify/fsnotify/issues/53)|
|
||||
|Polling |*All* |[Maybe](https://github.com/fsnotify/fsnotify/issues/9)|
|
||||
| Adapter | OS | Status |
|
||||
| --------------------- | -------------------------------- | ------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| inotify | Linux 2.6.27 or later, Android\* | Supported [](https://travis-ci.org/fsnotify/fsnotify) |
|
||||
| kqueue | BSD, macOS, iOS\* | Supported [](https://travis-ci.org/fsnotify/fsnotify) |
|
||||
| ReadDirectoryChangesW | Windows | Supported [](https://travis-ci.org/fsnotify/fsnotify) |
|
||||
| FSEvents | macOS | [Planned](https://github.com/fsnotify/fsnotify/issues/11) |
|
||||
| FEN | Solaris 11 | [In Progress](https://github.com/fsnotify/fsnotify/issues/12) |
|
||||
| fanotify | Linux 2.6.37+ | [Planned](https://github.com/fsnotify/fsnotify/issues/114) |
|
||||
| USN Journals | Windows | [Maybe](https://github.com/fsnotify/fsnotify/issues/53) |
|
||||
| Polling | *All* | [Maybe](https://github.com/fsnotify/fsnotify/issues/9) |
|
||||
|
||||
\* Android and iOS are untested.
|
||||
|
||||
@@ -33,6 +33,53 @@ All [releases](https://github.com/fsnotify/fsnotify/releases) are tagged based o
|
||||
|
||||
Go 1.6 supports dependencies located in the `vendor/` folder. Unless you are creating a library, it is recommended that you copy fsnotify into `vendor/github.com/fsnotify/fsnotify` within your project, and likewise for `golang.org/x/sys`.
|
||||
|
||||
## Usage
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"log"
|
||||
|
||||
"github.com/fsnotify/fsnotify"
|
||||
)
|
||||
|
||||
func main() {
|
||||
watcher, err := fsnotify.NewWatcher()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
defer watcher.Close()
|
||||
|
||||
done := make(chan bool)
|
||||
go func() {
|
||||
for {
|
||||
select {
|
||||
case event, ok := <-watcher.Events:
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
log.Println("event:", event)
|
||||
if event.Op&fsnotify.Write == fsnotify.Write {
|
||||
log.Println("modified file:", event.Name)
|
||||
}
|
||||
case err, ok := <-watcher.Errors:
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
log.Println("error:", err)
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
err = watcher.Add("/tmp/foo")
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
<-done
|
||||
}
|
||||
```
|
||||
|
||||
## Contributing
|
||||
|
||||
Please refer to [CONTRIBUTING][] before opening an issue or pull request.
|
||||
@@ -65,6 +112,10 @@ There are OS-specific limits as to how many watches can be created:
|
||||
* Linux: /proc/sys/fs/inotify/max_user_watches contains the limit, reaching this limit results in a "no space left on device" error.
|
||||
* BSD / OSX: sysctl variables "kern.maxfiles" and "kern.maxfilesperproc", reaching these limits results in a "too many open files" error.
|
||||
|
||||
**Why don't notifications work with NFS filesystems or filesystem in userspace (FUSE)?**
|
||||
|
||||
fsnotify requires support from underlying OS to work. The current NFS protocol does not provide network level support for file notifications.
|
||||
|
||||
[#62]: https://github.com/howeyc/fsnotify/issues/62
|
||||
[#18]: https://github.com/fsnotify/fsnotify/issues/18
|
||||
[#11]: https://github.com/fsnotify/fsnotify/issues/11
|
||||
|
4
vendor/github.com/fsnotify/fsnotify/fsnotify.go
generated
vendored
4
vendor/github.com/fsnotify/fsnotify/fsnotify.go
generated
vendored
@@ -63,4 +63,6 @@ func (e Event) String() string {
|
||||
}
|
||||
|
||||
// Common errors that can be reported by a watcher
|
||||
var ErrEventOverflow = errors.New("fsnotify queue overflow")
|
||||
var (
|
||||
ErrEventOverflow = errors.New("fsnotify queue overflow")
|
||||
)
|
||||
|
5
vendor/github.com/fsnotify/fsnotify/go.mod
generated
vendored
Normal file
5
vendor/github.com/fsnotify/fsnotify/go.mod
generated
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
module github.com/fsnotify/fsnotify
|
||||
|
||||
go 1.13
|
||||
|
||||
require golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9
|
2
vendor/github.com/fsnotify/fsnotify/go.sum
generated
vendored
Normal file
2
vendor/github.com/fsnotify/fsnotify/go.sum
generated
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9 h1:L2auWcuQIvxz9xSEqzESnV/QN/gNRXNApHi3fYwl2w0=
|
||||
golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
4
vendor/github.com/fsnotify/fsnotify/inotify_poller.go
generated
vendored
4
vendor/github.com/fsnotify/fsnotify/inotify_poller.go
generated
vendored
@@ -40,12 +40,12 @@ func newFdPoller(fd int) (*fdPoller, error) {
|
||||
poller.fd = fd
|
||||
|
||||
// Create epoll fd
|
||||
poller.epfd, errno = unix.EpollCreate1(0)
|
||||
poller.epfd, errno = unix.EpollCreate1(unix.EPOLL_CLOEXEC)
|
||||
if poller.epfd == -1 {
|
||||
return nil, errno
|
||||
}
|
||||
// Create pipe; pipe[0] is the read end, pipe[1] the write end.
|
||||
errno = unix.Pipe2(poller.pipe[:], unix.O_NONBLOCK)
|
||||
errno = unix.Pipe2(poller.pipe[:], unix.O_NONBLOCK|unix.O_CLOEXEC)
|
||||
if errno != nil {
|
||||
return nil, errno
|
||||
}
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user