forked from lug/matterbridge
Compare commits
85 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
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 | ||
![]() |
4be00bbe6b | ||
![]() |
9382dde098 | ||
![]() |
1bf46b7711 | ||
![]() |
b85bae31d9 | ||
![]() |
0898829313 | ||
![]() |
f8ad877601 | ||
![]() |
585d1556c1 | ||
![]() |
7486555875 | ||
![]() |
fc30b1bacc | ||
![]() |
0dd19af6e8 | ||
![]() |
4c44515f9d | ||
![]() |
9d84d6dd64 | ||
![]() |
0f708daf2d | ||
![]() |
b9354de8fd | ||
![]() |
c9d5f4c898 | ||
![]() |
810c150781 | ||
![]() |
31dd538c0b | ||
![]() |
62e38e7c45 | ||
![]() |
b9da28a29b | ||
![]() |
84bfa8a6b1 | ||
![]() |
1f830963f6 | ||
![]() |
12d2c6fe89 | ||
![]() |
f43faf15f8 | ||
![]() |
173a38a374 | ||
![]() |
1604ff15b5 | ||
![]() |
214fe502cd | ||
![]() |
aae45a8179 | ||
![]() |
075ca9ca47 | ||
![]() |
d4253d7a55 | ||
![]() |
0917dc8766 | ||
![]() |
aba86855b5 | ||
![]() |
ed5386c213 | ||
![]() |
455e75e92f | ||
![]() |
c394de0c88 |
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
|
||||
|
||||
---
|
||||
|
||||
|
3
.gitignore
vendored
3
.gitignore
vendored
@@ -1,5 +1,6 @@
|
||||
# Exclude matterbridge binary
|
||||
matterbridge
|
||||
/matterbridge
|
||||
/matterbridge.exe
|
||||
|
||||
# Exclude configuration file
|
||||
matterbridge.toml
|
||||
|
@@ -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
|
||||
@@ -174,6 +174,8 @@ linters:
|
||||
- lll
|
||||
- maligned
|
||||
- prealloc
|
||||
- wsl
|
||||
- gomnd
|
||||
|
||||
|
||||
# rules to deal with reported isues
|
||||
|
12
.travis.yml
12
.travis.yml
@@ -20,22 +20,22 @@ jobs:
|
||||
- stage: lint
|
||||
# Run linting in one Go environment only.
|
||||
script: ./ci/lint.sh
|
||||
go: 1.12.x
|
||||
go: 1.14.x
|
||||
env:
|
||||
- GO111MODULE=on
|
||||
- GOLANGCI_VERSION="v1.17.1"
|
||||
- GOLANGCI_VERSION="v1.23.7"
|
||||
- stage: test
|
||||
# Run tests in a combination of Go environments.
|
||||
script: ./ci/test.sh
|
||||
go: 1.11.x
|
||||
go: 1.13.x
|
||||
env:
|
||||
- GO111MODULE=off
|
||||
- GOFLAGS=-mod=vendor
|
||||
- script: ./ci/test.sh
|
||||
go: 1.11.x
|
||||
go: 1.13.x
|
||||
env:
|
||||
- GO111MODULE=on
|
||||
- script: ./ci/test.sh
|
||||
go: 1.12.x
|
||||
go: 1.14.x
|
||||
env:
|
||||
- GO111MODULE=on
|
||||
- REPORT_COVERAGE=1
|
||||
|
14
Dockerfile
14
Dockerfile
@@ -1,11 +1,13 @@
|
||||
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 \
|
||||
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
|
||||
ENTRYPOINT ["/bin/matterbridge"]
|
||||
|
75
README.md
75
README.md
@@ -22,6 +22,7 @@ Letting people be where they want to be.<br />
|
||||
[Zulip][mb-zulip] |
|
||||
[Telegram][mb-telegram] |
|
||||
[Keybase][mb-keybase] |
|
||||
[MSTeams][mb-msteams] |
|
||||
And more...
|
||||
</sup>
|
||||
|
||||
@@ -44,28 +45,34 @@ And more...
|
||||
</a>
|
||||
</p>
|
||||
|
||||
### Table of Contents
|
||||
# Table of Contents
|
||||
|
||||
- [Features](https://github.com/42wim/matterbridge/wiki/Features)
|
||||
- [Natively supported](#natively-supported)
|
||||
- [3rd party via matterbridge api](#3rd-party-via-matterbridge-api)
|
||||
- [API](#API)
|
||||
- [Chat with us](#chat-with-us)
|
||||
- [Screenshots](https://github.com/42wim/matterbridge/wiki/)
|
||||
- [Installing/upgrading](#installing--upgrading)
|
||||
- [Binaries](#binaries)
|
||||
- [Building](#building)
|
||||
- [Configuration](#configuration)
|
||||
- [Howto](https://github.com/42wim/matterbridge/wiki/How-to-create-your-config)
|
||||
- [Settings](#settings)
|
||||
- [Examples](#examples)
|
||||
- [Running](#running)
|
||||
- [Docker](#docker)
|
||||
- [Changelog](#changelog)
|
||||
- [FAQ](#faq)
|
||||
- [Related projects](#related-projects)
|
||||
- [Articles](#articles)
|
||||
- [Thanks](#thanks)
|
||||
- [matterbridge](#matterbridge)
|
||||
- [Table of Contents](#table-of-contents)
|
||||
- [Features](#features)
|
||||
- [Natively supported](#natively-supported)
|
||||
- [3rd party via matterbridge api](#3rd-party-via-matterbridge-api)
|
||||
- [API](#api)
|
||||
- [Chat with us](#chat-with-us)
|
||||
- [Screenshots](#screenshots)
|
||||
- [Installing / upgrading](#installing--upgrading)
|
||||
- [Binaries](#binaries)
|
||||
- [Packages](#packages)
|
||||
- [Building](#building)
|
||||
- [Configuration](#configuration)
|
||||
- [Basic configuration](#basic-configuration)
|
||||
- [Settings](#settings)
|
||||
- [Advanced configuration](#advanced-configuration)
|
||||
- [Examples](#examples)
|
||||
- [Bridge mattermost (off-topic) - irc (#testing)](#bridge-mattermost-off-topic---irc-testing)
|
||||
- [Bridge slack (#general) - discord (general)](#bridge-slack-general---discord-general)
|
||||
- [Running](#running)
|
||||
- [Docker](#docker)
|
||||
- [Changelog](#changelog)
|
||||
- [FAQ](#faq)
|
||||
- [Related projects](#related-projects)
|
||||
- [Articles](#articles)
|
||||
- [Thanks](#thanks)
|
||||
|
||||
## Features
|
||||
|
||||
@@ -89,6 +96,7 @@ And more...
|
||||
- [Telegram](https://telegram.org)
|
||||
- [Rocket.chat](https://rocket.chat)
|
||||
- [Matrix](https://matrix.org)
|
||||
- [Microsoft Teams](https://teams.microsoft.com)
|
||||
- [Steam](https://store.steampowered.com/)
|
||||
- [Twitch](https://twitch.tv)
|
||||
- [Ssh-chat](https://github.com/shazow/ssh-chat)
|
||||
@@ -102,6 +110,7 @@ And more...
|
||||
- [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)
|
||||
|
||||
### API
|
||||
|
||||
@@ -115,6 +124,7 @@ Used by the projects below. Feel free to make a PR to add your project to this l
|
||||
- [Mattereddit](https://github.com/bonehurtingjuice/mattereddit) (Reddit chat support)
|
||||
- [fbridge](https://github.com/VictorNine/fbridge) (Facebook messenger support)
|
||||
- [matterbabble](https://github.com/DeclanHoare/matterbabble) (Discourse support)
|
||||
- [MatterAMXX](https://forums.alliedmods.net/showthread.php?t=319430) (Counter-Strike, half-life and more via AMXX mod)
|
||||
|
||||
## Chat with us
|
||||
|
||||
@@ -131,6 +141,7 @@ Questions or want to test on your favorite platform? Join below:
|
||||
- [Twitch][mb-twitch]
|
||||
- [Zulip][mb-zulip]
|
||||
- [Telegram][mb-telegram]
|
||||
- [Keybase][mb-keybase]
|
||||
|
||||
## Screenshots
|
||||
|
||||
@@ -140,7 +151,7 @@ See https://github.com/42wim/matterbridge/wiki
|
||||
|
||||
### Binaries
|
||||
|
||||
- Latest stable release [v1.16.1](https://github.com/42wim/matterbridge/releases/latest)
|
||||
- Latest stable release [v1.17.1](https://github.com/42wim/matterbridge/releases/latest)
|
||||
- Development releases (follows master) can be downloaded [here](https://dl.bintray.com/42wim/nightly/)
|
||||
|
||||
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.
|
||||
@@ -154,19 +165,17 @@ To install or upgrade just download the latest [binary](https://github.com/42wim
|
||||
Most people just want to use binaries, you can find those [here](https://github.com/42wim/matterbridge/releases/latest)
|
||||
|
||||
If you really want to build from source, follow these instructions:
|
||||
Go 1.9+ is required. Make sure you have [Go](https://golang.org/doc/install) properly installed, including setting up your [GOPATH](https://golang.org/doc/code.html#GOPATH).
|
||||
Go 1.12+ is required. Make sure you have [Go](https://golang.org/doc/install) properly installed.
|
||||
|
||||
After Go is setup, download matterbridge to your \$GOPATH directory.
|
||||
|
||||
```
|
||||
cd $GOPATH
|
||||
go get github.com/42wim/matterbridge
|
||||
```
|
||||
|
||||
You should now have matterbridge binary in the bin directory:
|
||||
You should now have matterbridge binary in the ~/go/bin directory:
|
||||
|
||||
```
|
||||
$ ls bin/
|
||||
$ ls ~/go/bin/
|
||||
matterbridge
|
||||
```
|
||||
|
||||
@@ -262,11 +271,7 @@ Usage of ./matterbridge:
|
||||
|
||||
### Docker
|
||||
|
||||
Create your matterbridge.toml file locally eg in `/tmp/matterbridge.toml`
|
||||
|
||||
```
|
||||
docker run -ti -v /tmp/matterbridge.toml:/matterbridge.toml 42wim/matterbridge
|
||||
```
|
||||
Please take a look at the [Docker Wiki page](https://github.com/42wim/matterbridge/wiki/Deploy:-Docker) for more information.
|
||||
|
||||
## Changelog
|
||||
|
||||
@@ -278,7 +283,7 @@ See [FAQ](https://github.com/42wim/matterbridge/wiki/FAQ)
|
||||
|
||||
## Related projects
|
||||
|
||||
- [FOSSRIT/infrastructure - roles/matterbridge](https://github.com/FOSSRIT/infrastructure/tree/master/roles/matterbridge) (Ansible role used to automate deployments of Matterbridge)
|
||||
- [jwflory/ansible-role-matterbridge](https://galaxy.ansible.com/jwflory/matterbridge) (Ansible role to simplify deploying Matterbridge)
|
||||
- [matterbridge autoconfig](https://github.com/patcon/matterbridge-autoconfig)
|
||||
- [matterbridge config viewer](https://github.com/patcon/matterbridge-heroku-viewer)
|
||||
- [matterbridge-heroku](https://github.com/cadecairos/matterbridge-heroku)
|
||||
@@ -330,6 +335,7 @@ Matterbridge wouldn't exist without these libraries:
|
||||
- zulip - https://github.com/ifo/gozulipbot
|
||||
- tengo - https://github.com/d5/tengo
|
||||
- keybase - https://github.com/keybase/go-keybase-chat-bot
|
||||
- msgraph.go - https://github.com/yaegashi/msgraph.go
|
||||
|
||||
<!-- Links -->
|
||||
|
||||
@@ -343,6 +349,7 @@ Matterbridge wouldn't exist without these libraries:
|
||||
[mb-xmpp]: https://inverse.chat/
|
||||
[mb-twitch]: https://www.twitch.tv/matterbridge
|
||||
[mb-whatsapp]: https://www.whatsapp.com/
|
||||
[mb-keybase]: https://keybase.io
|
||||
[mb-keybase]: https://keybase.io/team/matterbridge
|
||||
[mb-zulip]: https://matterbridge.zulipchat.com/register/
|
||||
[mb-telegram]: https://t.me/Matterbridge
|
||||
[mb-msteams]: https://teams.microsoft.com/join/hj92x75gd3y7
|
||||
|
@@ -1,6 +1,7 @@
|
||||
package bridge
|
||||
|
||||
import (
|
||||
"log"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
@@ -41,6 +42,10 @@ type Factory func(*Config) Bridger
|
||||
|
||||
func New(bridge *config.Bridge) *Bridge {
|
||||
accInfo := strings.Split(bridge.Account, ".")
|
||||
if len(accInfo) != 2 {
|
||||
log.Fatalf("config failure, account incorrect: %s", bridge.Account)
|
||||
}
|
||||
|
||||
protocol := accInfo[0]
|
||||
name := accInfo[1]
|
||||
|
||||
|
@@ -3,6 +3,7 @@ package config
|
||||
import (
|
||||
"bytes"
|
||||
"io/ioutil"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
@@ -76,9 +77,11 @@ 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
|
||||
IconURL string // mattermost, slack
|
||||
@@ -116,12 +119,14 @@ type Protocol struct {
|
||||
Protocol string // all protocols
|
||||
QuoteDisable bool // telegram
|
||||
QuoteFormat string // telegram
|
||||
QuoteLengthLimit int // telegram
|
||||
RejoinDelay int // IRC
|
||||
ReplaceMessages [][]string // all protocols
|
||||
ReplaceNicks [][]string // all protocols
|
||||
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
|
||||
@@ -132,10 +137,13 @@ type Protocol struct {
|
||||
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
|
||||
@@ -233,7 +241,8 @@ 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.MediaDownloadSize == 0 {
|
||||
mycfg.cv.General.MediaDownloadSize = 1000000
|
||||
}
|
||||
@@ -244,14 +253,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()
|
||||
|
@@ -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,7 +21,7 @@ type Bdiscord struct {
|
||||
c *discordgo.Session
|
||||
|
||||
nick string
|
||||
useChannelID bool
|
||||
userID string
|
||||
guildID string
|
||||
webhookID string
|
||||
webhookToken string
|
||||
@@ -93,6 +93,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 {
|
||||
@@ -115,30 +116,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()
|
||||
@@ -174,10 +182,6 @@ func (b *Bdiscord) JoinChannel(channel config.ChannelInfo) error {
|
||||
defer b.channelsMutex.Unlock()
|
||||
|
||||
b.channelInfoMap[channel.ID] = &channel
|
||||
idcheck := strings.Split(channel.Name, "ID:")
|
||||
if len(idcheck) > 1 {
|
||||
b.useChannelID = true
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -385,6 +389,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.
|
||||
@@ -412,6 +429,10 @@ func (b *Bdiscord) webhookSend(msg *config.Message, webhookID, token string) (*d
|
||||
ContentType: "",
|
||||
Reader: bytes.NewReader(*fi.Data),
|
||||
}
|
||||
content := ""
|
||||
if msg.Text == "" {
|
||||
content = fi.Comment
|
||||
}
|
||||
_, e2 := b.c.WebhookExecute(
|
||||
webhookID,
|
||||
token,
|
||||
@@ -420,6 +441,7 @@ func (b *Bdiscord) webhookSend(msg *config.Message, webhookID, token string) (*d
|
||||
Username: msg.Username,
|
||||
AvatarURL: msg.Avatar,
|
||||
File: &file,
|
||||
Content: content,
|
||||
},
|
||||
)
|
||||
if e2 != nil {
|
||||
@@ -429,3 +451,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,15 +2,13 @@ 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
|
||||
rmsg := config.Message{Account: b.Account, ID: m.ID, Event: config.EventMsgDelete, Text: config.EventMsgDelete}
|
||||
rmsg.Channel = b.getChannelName(m.ChannelID)
|
||||
if b.useChannelID {
|
||||
rmsg.Channel = "ID:" + m.ChannelID
|
||||
}
|
||||
|
||||
b.Log.Debugf("<= Sending message from %s to gateway", b.Account)
|
||||
b.Log.Debugf("<= Message is %#v", rmsg)
|
||||
b.Remote <- rmsg
|
||||
@@ -24,11 +22,7 @@ func (b *Bdiscord) messageDeleteBulk(s *discordgo.Session, m *discordgo.MessageD
|
||||
ID: msgID,
|
||||
Event: config.EventMsgDelete,
|
||||
Text: config.EventMsgDelete,
|
||||
Channel: "ID:" + m.ChannelID,
|
||||
}
|
||||
|
||||
if !b.useChannelID {
|
||||
rmsg.Channel = b.getChannelName(m.ChannelID)
|
||||
Channel: b.getChannelName(m.ChannelID),
|
||||
}
|
||||
|
||||
b.Log.Debugf("<= Sending message from %s to gateway", b.Account)
|
||||
@@ -42,11 +36,13 @@ 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)
|
||||
if b.useChannelID {
|
||||
rmsg.Channel = "ID:" + m.ChannelID
|
||||
}
|
||||
b.Remote <- rmsg
|
||||
}
|
||||
|
||||
@@ -88,7 +84,6 @@ func (b *Bdiscord) messageCreate(s *discordgo.Session, m *discordgo.MessageCreat
|
||||
|
||||
if m.Content != "" {
|
||||
b.Log.Debugf("== Receiving event %#v", m.Message)
|
||||
m.Message.Content = b.stripCustomoji(m.Message.Content)
|
||||
m.Message.Content = b.replaceChannelMentions(m.Message.Content)
|
||||
rmsg.Text, err = m.ContentWithMoreMentionsReplaced(b.c)
|
||||
if err != nil {
|
||||
@@ -99,16 +94,13 @@ func (b *Bdiscord) messageCreate(s *discordgo.Session, m *discordgo.MessageCreat
|
||||
|
||||
// set channel name
|
||||
rmsg.Channel = b.getChannelName(m.ChannelID)
|
||||
if b.useChannelID {
|
||||
rmsg.Channel = "ID:" + 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
|
||||
}
|
||||
}
|
||||
@@ -116,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)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -132,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
|
||||
@@ -205,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 {
|
||||
@@ -96,6 +96,13 @@ func (b *Bdiscord) getChannelName(id string) string {
|
||||
b.channelsMutex.RLock()
|
||||
defer b.channelsMutex.RUnlock()
|
||||
|
||||
for _, c := range b.channelInfoMap {
|
||||
if c.Name == "ID:"+id {
|
||||
// if we have ID: specified in our gateway configuration return this
|
||||
return c.Name
|
||||
}
|
||||
}
|
||||
|
||||
for _, channel := range b.channels {
|
||||
if channel.ID == id {
|
||||
return b.getCategoryChannelName(channel.Name, channel.ParentID)
|
||||
@@ -129,8 +136,8 @@ func (b *Bdiscord) getCategoryChannelName(name, parentID string) string {
|
||||
var (
|
||||
// See https://discordapp.com/developers/docs/reference#message-formatting.
|
||||
channelMentionRE = regexp.MustCompile("<#[0-9]+>")
|
||||
emojiRE = regexp.MustCompile("<(:.*?:)[0-9]+>")
|
||||
userMentionRE = regexp.MustCompile("@[^@\n]{1,32}")
|
||||
emoteRE = regexp.MustCompile(`<a?(:\w+:)\d+>`)
|
||||
)
|
||||
|
||||
func (b *Bdiscord) replaceChannelMentions(text string) string {
|
||||
@@ -176,8 +183,8 @@ func (b *Bdiscord) replaceUserMentions(text string) string {
|
||||
return userMentionRE.ReplaceAllStringFunc(text, replaceUserMentionFunc)
|
||||
}
|
||||
|
||||
func (b *Bdiscord) stripCustomoji(text string) string {
|
||||
return emojiRE.ReplaceAllString(text, `$1`)
|
||||
func replaceEmotes(text string) string {
|
||||
return emoteRE.ReplaceAllString(text, "$1")
|
||||
}
|
||||
|
||||
func (b *Bdiscord) replaceAction(text string) (string, bool) {
|
||||
|
@@ -14,8 +14,10 @@ import (
|
||||
"golang.org/x/image/webp"
|
||||
|
||||
"github.com/42wim/matterbridge/bridge/config"
|
||||
"github.com/gomarkdown/markdown"
|
||||
"github.com/gomarkdown/markdown/html"
|
||||
"github.com/gomarkdown/markdown/parser"
|
||||
"github.com/sirupsen/logrus"
|
||||
"gitlab.com/golang-commonmark/markdown"
|
||||
)
|
||||
|
||||
// DownloadFile downloads the given non-authenticated URL.
|
||||
@@ -176,9 +178,15 @@ func ClipMessage(text string, length int) string {
|
||||
return text
|
||||
}
|
||||
|
||||
// ParseMarkdown takes in an input string as markdown and parses it to html
|
||||
func ParseMarkdown(input string) string {
|
||||
md := markdown.New(markdown.XHTMLOutput(true), markdown.Breaks(true))
|
||||
res := md.RenderToString([]byte(input))
|
||||
extensions := parser.HardLineBreak | parser.NoIntraEmphasis
|
||||
markdownParser := parser.NewWithExtensions(extensions)
|
||||
renderer := html.NewRenderer(html.RendererOptions{
|
||||
Flags: 0,
|
||||
})
|
||||
parsedMarkdown := markdown.ToHTML([]byte(input), markdownParser, renderer)
|
||||
res := string(parsedMarkdown)
|
||||
res = strings.TrimPrefix(res, "<p>")
|
||||
res = strings.TrimSuffix(res, "</p>\n")
|
||||
return res
|
||||
|
@@ -167,12 +167,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
|
||||
}
|
||||
|
@@ -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
|
||||
}
|
||||
|
@@ -1,6 +1,9 @@
|
||||
package bkeybase
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
|
||||
"github.com/42wim/matterbridge/bridge"
|
||||
@@ -66,17 +69,38 @@ func (b *Bkeybase) Send(msg config.Message) (string, error) {
|
||||
// Delete message if we have an ID
|
||||
// Delete message not supported by keybase go library yet
|
||||
|
||||
// Upload a file if it exists
|
||||
// kbchat lib does not support attachments yet
|
||||
|
||||
// Edit message if we have an ID
|
||||
// kbchat lib does not support message editing yet
|
||||
|
||||
if len(msg.Extra["file"]) > 0 {
|
||||
// Upload a file
|
||||
dir, err := ioutil.TempDir("", "matterbridge")
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
defer os.RemoveAll(dir)
|
||||
|
||||
for _, f := range msg.Extra["file"] {
|
||||
fname := f.(config.FileInfo).Name
|
||||
fdata := *f.(config.FileInfo).Data
|
||||
fcaption := f.(config.FileInfo).Comment
|
||||
fpath := filepath.Join(dir, fname)
|
||||
|
||||
if err = ioutil.WriteFile(fpath, fdata, 0600); err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
_, _ = 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
|
||||
}
|
||||
|
@@ -172,10 +172,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 +363,15 @@ 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/")
|
||||
url += "?width=37&height=37&method=crop"
|
||||
return url
|
||||
}
|
||||
|
@@ -67,9 +67,8 @@ func (b *Bmattermost) handleMatter() {
|
||||
b.Log.Debugf("Choosing login/password based receiving")
|
||||
}
|
||||
// if for some reason we only want to sent stuff to mattermost but not receive, return
|
||||
if b.GetString("WebhookBindAddress") == "" && b.GetString("WebhookURL") != "" {
|
||||
if b.GetString("WebhookBindAddress") == "" && b.GetString("WebhookURL") != "" && b.GetString("Token") == "" && b.GetString("Login") == "" {
|
||||
b.Log.Debugf("No WebhookBindAddress specified, only WebhookURL. You will not receive messages from mattermost, only sending is possible.")
|
||||
return
|
||||
}
|
||||
go b.handleMatterClient(messages)
|
||||
}
|
||||
|
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"
|
||||
}
|
205
bridge/msteams/msteams.go
Normal file
205
bridge/msteams/msteams.go
Normal file
@@ -0,0 +1,205 @@
|
||||
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/matterbridge/msgraph.go/msauth"
|
||||
"github.com/mattn/godown"
|
||||
msgraph "github.com/yaegashi/msgraph.go/beta"
|
||||
|
||||
"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 b.poll(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) {
|
||||
msgmap := make(map[string]time.Time)
|
||||
b.Log.Debug("getting initial messages")
|
||||
res, err := b.getMessages(channelName)
|
||||
if err != nil {
|
||||
panic(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 {
|
||||
panic(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 *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()
|
||||
}
|
@@ -1,15 +1,19 @@
|
||||
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) != "" {
|
||||
@@ -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,10 +130,16 @@ func (b *Bslack) skipMessageEvent(ev *slack.MessageEvent) bool {
|
||||
}
|
||||
}
|
||||
|
||||
// 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
|
||||
}
|
||||
|
||||
// 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) {
|
||||
(b.rtm != nil && ev.Username == b.si.User.Name) || hasOurCallbackID {
|
||||
return true
|
||||
}
|
||||
|
||||
@@ -270,6 +282,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 {
|
||||
@@ -408,7 +408,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 +426,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 +491,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 +501,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
|
||||
|
@@ -130,6 +130,10 @@ func (b *Bsshchat) handleSSHChat() error {
|
||||
if strings.Contains(b.r.Text(), "Rate limiting is in effect") {
|
||||
continue
|
||||
}
|
||||
// skip our own messages
|
||||
if !strings.HasPrefix(b.r.Text(), "["+b.GetString("Nick")+"] \x1b") {
|
||||
continue
|
||||
}
|
||||
res := strings.Split(stripPrompt(b.r.Text()), ":")
|
||||
if res[0] == "-> Set theme" {
|
||||
wait = false
|
||||
|
@@ -95,7 +95,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)
|
||||
}
|
||||
}
|
||||
@@ -357,6 +357,14 @@ func (b *Btelegram) handleQuote(message, quoteNick, quoteMessage string) string
|
||||
if format == "" {
|
||||
format = "{MESSAGE} (re @{QUOTENICK}: {QUOTEMESSAGE})"
|
||||
}
|
||||
quoteMessagelength := len(quoteMessage)
|
||||
if b.GetInt("QuoteLengthLimit") != 0 && quoteMessagelength >= b.GetInt("QuoteLengthLimit") {
|
||||
runes := []rune(quoteMessage)
|
||||
quoteMessage = string(runes[0:b.GetInt("QuoteLengthLimit")])
|
||||
if quoteMessagelength > b.GetInt("QuoteLengthLimit") {
|
||||
quoteMessage += "..."
|
||||
}
|
||||
}
|
||||
format = strings.Replace(format, "{MESSAGE}", message, -1)
|
||||
format = strings.Replace(format, "{QUOTENICK}", quoteNick, -1)
|
||||
format = strings.Replace(format, "{QUOTEMESSAGE}", quoteMessage, -1)
|
||||
|
@@ -8,7 +8,7 @@ import (
|
||||
"github.com/42wim/matterbridge/bridge"
|
||||
"github.com/42wim/matterbridge/bridge/config"
|
||||
"github.com/42wim/matterbridge/bridge/helper"
|
||||
"github.com/go-telegram-bot-api/telegram-bot-api"
|
||||
tgbotapi "github.com/go-telegram-bot-api/telegram-bot-api"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -81,8 +81,8 @@ func (b *Btelegram) Send(msg config.Message) (string, error) {
|
||||
// Upload a file if it exists
|
||||
if msg.Extra != nil {
|
||||
for _, rmsg := range helper.HandleExtra(&msg, b.General) {
|
||||
if _, err := b.sendMessage(chatid, rmsg.Username, rmsg.Text); err != nil {
|
||||
b.Log.Errorf("sendMessage failed: %s", err)
|
||||
if _, msgErr := b.sendMessage(chatid, rmsg.Username, rmsg.Text); msgErr != nil {
|
||||
b.Log.Errorf("sendMessage failed: %s", msgErr)
|
||||
}
|
||||
}
|
||||
// check if we have files to upload (from slack, telegram or mattermost)
|
||||
@@ -97,7 +97,14 @@ func (b *Btelegram) Send(msg config.Message) (string, error) {
|
||||
}
|
||||
|
||||
// Post normal message
|
||||
return b.sendMessage(chatid, msg.Username, msg.Text)
|
||||
// TODO: recheck it.
|
||||
// Ignore empty text field needs for prevent double messages from whatsapp to telegram
|
||||
// when sending media with text caption
|
||||
if msg.Text != "" {
|
||||
return b.sendMessage(chatid, msg.Username, msg.Text)
|
||||
}
|
||||
|
||||
return "", nil
|
||||
}
|
||||
|
||||
func (b *Btelegram) getFileDirectURL(id string) string {
|
||||
@@ -124,6 +131,9 @@ func (b *Btelegram) sendMessage(chatid int64, username, text string) (string, er
|
||||
m.Text = username + html.EscapeString(text)
|
||||
m.ParseMode = tgbotapi.ModeHTML
|
||||
}
|
||||
|
||||
m.DisableWebPagePreview = b.GetBool("DisableWebPagePreview")
|
||||
|
||||
res, err := b.c.Send(m)
|
||||
if err != nil {
|
||||
return "", err
|
||||
|
@@ -1,11 +1,15 @@
|
||||
package bwhatsapp
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"mime"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/42wim/matterbridge/bridge/config"
|
||||
"github.com/42wim/matterbridge/bridge/helper"
|
||||
"github.com/Rhymen/go-whatsapp"
|
||||
"github.com/jpillora/backoff"
|
||||
)
|
||||
|
||||
/*
|
||||
@@ -22,7 +26,38 @@ func (b *Bwhatsapp) HandleError(err error) {
|
||||
if strings.Contains(err.Error(), "error processing data: received invalid data") {
|
||||
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()
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// HandleTextMessage sent from WhatsApp, relay it to the brige
|
||||
@@ -36,16 +71,16 @@ func (b *Bwhatsapp) HandleTextMessage(message whatsapp.TextMessage) {
|
||||
}
|
||||
|
||||
messageTime := time.Unix(int64(message.Info.Timestamp), 0) // TODO check how behaves between timezones
|
||||
groupJid := message.Info.RemoteJid
|
||||
groupJID := message.Info.RemoteJid
|
||||
|
||||
senderJid := message.Info.SenderJid
|
||||
if len(senderJid) == 0 {
|
||||
senderJID := message.Info.SenderJid
|
||||
if len(senderJID) == 0 {
|
||||
// TODO workaround till https://github.com/Rhymen/go-whatsapp/issues/86 resolved
|
||||
senderJid = *message.Info.Source.Participant
|
||||
senderJID = *message.Info.Source.Participant
|
||||
}
|
||||
|
||||
// translate sender's Jid to the nicest username we can get
|
||||
senderName := b.getSenderName(senderJid)
|
||||
// translate sender's JID to the nicest username we can get
|
||||
senderName := b.getSenderName(senderJID)
|
||||
if senderName == "" {
|
||||
senderName = "Someone" // don't expose telephone number
|
||||
}
|
||||
@@ -53,8 +88,8 @@ func (b *Bwhatsapp) HandleTextMessage(message whatsapp.TextMessage) {
|
||||
extText := message.Info.Source.Message.ExtendedTextMessage
|
||||
if extText != nil && extText.ContextInfo != nil && extText.ContextInfo.MentionedJid != nil {
|
||||
// handle user mentions
|
||||
for _, mentionedJid := range extText.ContextInfo.MentionedJid {
|
||||
numberAndSuffix := strings.SplitN(mentionedJid, "@", 2)
|
||||
for _, mentionedJID := range extText.ContextInfo.MentionedJid {
|
||||
numberAndSuffix := strings.SplitN(mentionedJID, "@", 2)
|
||||
|
||||
// mentions comes as telephone numbers and we don't want to expose it to other bridges
|
||||
// replace it with something more meaninful to others
|
||||
@@ -66,22 +101,22 @@ func (b *Bwhatsapp) HandleTextMessage(message whatsapp.TextMessage) {
|
||||
}
|
||||
}
|
||||
|
||||
b.Log.Debugf("<= Sending message from %s on %s to gateway", senderJid, b.Account)
|
||||
b.Log.Debugf("<= Sending message from %s on %s to gateway", senderJID, b.Account)
|
||||
rmsg := config.Message{
|
||||
UserID: senderJid,
|
||||
UserID: senderJID,
|
||||
Username: senderName,
|
||||
Text: message.Text,
|
||||
Timestamp: messageTime,
|
||||
Channel: groupJid,
|
||||
Channel: groupJID,
|
||||
Account: b.Account,
|
||||
Protocol: b.Protocol,
|
||||
Extra: make(map[string][]interface{}),
|
||||
// ParentID: TODO, // TODO handle thread replies // map from Info.QuotedMessageID string
|
||||
// ParentID: TODO, // TODO handle thread replies // map from Info.QuotedMessageID string
|
||||
// Event string `json:"event"`
|
||||
// Gateway string // will be added during message processing
|
||||
ID: message.Info.Id}
|
||||
|
||||
if avatarURL, exists := b.userAvatars[senderJid]; exists {
|
||||
if avatarURL, exists := b.userAvatars[senderJID]; exists {
|
||||
rmsg.Avatar = avatarURL
|
||||
}
|
||||
|
||||
@@ -89,11 +124,75 @@ func (b *Bwhatsapp) HandleTextMessage(message whatsapp.TextMessage) {
|
||||
b.Remote <- rmsg
|
||||
}
|
||||
|
||||
//
|
||||
//func (b *Bwhatsapp) HandleImageMessage(message whatsapp.ImageMessage) {
|
||||
// fmt.Println(message) // TODO implement
|
||||
//}
|
||||
//
|
||||
// HandleImageMessage sent from WhatsApp, relay it to the brige
|
||||
func (b *Bwhatsapp) HandleImageMessage(message whatsapp.ImageMessage) {
|
||||
if message.Info.FromMe { // || !strings.Contains(strings.ToLower(message.Text), "@echo") {
|
||||
return
|
||||
}
|
||||
|
||||
// whatsapp sends last messages to show context , cut them
|
||||
if message.Info.Timestamp < b.startedAt {
|
||||
return
|
||||
}
|
||||
|
||||
messageTime := time.Unix(int64(message.Info.Timestamp), 0) // TODO check how behaves between timezones
|
||||
groupJID := message.Info.RemoteJid
|
||||
|
||||
senderJID := message.Info.SenderJid
|
||||
// if len(senderJid) == 0 {
|
||||
// // TODO workaround till https://github.com/Rhymen/go-whatsapp/issues/86 resolved
|
||||
// senderJid = *message.Info.Source.Participant
|
||||
// }
|
||||
|
||||
// translate sender's Jid to the nicest username we can get
|
||||
senderName := b.getSenderName(senderJID)
|
||||
if senderName == "" {
|
||||
senderName = "Someone" // don't expose telephone number
|
||||
}
|
||||
|
||||
b.Log.Debugf("<= Sending message from %s on %s to gateway", senderJID, b.Account)
|
||||
rmsg := config.Message{
|
||||
UserID: senderJID,
|
||||
Username: senderName,
|
||||
Timestamp: messageTime,
|
||||
Channel: groupJID,
|
||||
Account: b.Account,
|
||||
Protocol: b.Protocol,
|
||||
Extra: make(map[string][]interface{}),
|
||||
// ParentID: TODO, // TODO handle thread replies // map from Info.QuotedMessageID string
|
||||
// Event string `json:"event"`
|
||||
// Gateway string // will be added during message processing
|
||||
ID: message.Info.Id}
|
||||
|
||||
if avatarURL, exists := b.userAvatars[senderJID]; exists {
|
||||
rmsg.Avatar = avatarURL
|
||||
}
|
||||
|
||||
// Download and unencrypt content
|
||||
data, err := message.Download()
|
||||
if err != nil {
|
||||
b.Log.Errorf("%v", err)
|
||||
return
|
||||
}
|
||||
|
||||
// Get file extension by mimetype
|
||||
fileExt, err := mime.ExtensionsByType(message.Type)
|
||||
if err != nil {
|
||||
b.Log.Errorf("%v", err)
|
||||
return
|
||||
}
|
||||
|
||||
filename := fmt.Sprintf("%v%v", message.Info.Id, fileExt[0])
|
||||
|
||||
b.Log.Debugf("<= Image downloaded and unencrypted")
|
||||
|
||||
// Move file to bridge storage
|
||||
helper.HandleDownloadData(b.Log, &rmsg, filename, message.Caption, "", &data, b.General)
|
||||
|
||||
b.Log.Debugf("<= Image Message is %#v", rmsg)
|
||||
b.Remote <- rmsg
|
||||
}
|
||||
|
||||
//func (b *Bwhatsapp) HandleVideoMessage(message whatsapp.VideoMessage) {
|
||||
// fmt.Println(message) // TODO implement
|
||||
//}
|
||||
|
@@ -1,11 +1,14 @@
|
||||
package bwhatsapp
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/rand"
|
||||
"encoding/hex"
|
||||
"errors"
|
||||
"fmt"
|
||||
"mime"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
@@ -64,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, 1307)
|
||||
if err != nil {
|
||||
return errors.New("failed to connect to WhatsApp: " + err.Error())
|
||||
}
|
||||
@@ -230,6 +234,66 @@ func (b *Bwhatsapp) JoinChannel(channel config.ChannelInfo) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Post a document message from the bridge to WhatsApp
|
||||
func (b *Bwhatsapp) PostDocumentMessage(msg config.Message, filetype string) (string, error) {
|
||||
fi := msg.Extra["file"][0].(config.FileInfo)
|
||||
|
||||
// Post document message
|
||||
message := whatsapp.DocumentMessage{
|
||||
Info: whatsapp.MessageInfo{
|
||||
RemoteJid: msg.Channel,
|
||||
},
|
||||
Title: fi.Name,
|
||||
FileName: fi.Name,
|
||||
Type: filetype,
|
||||
Content: bytes.NewReader(*fi.Data),
|
||||
}
|
||||
|
||||
b.Log.Debugf("=> Sending %#v", msg)
|
||||
|
||||
// create message ID
|
||||
// TODO follow and act if https://github.com/Rhymen/go-whatsapp/issues/101 implemented
|
||||
idBytes := make([]byte, 10)
|
||||
if _, err := rand.Read(idBytes); err != nil {
|
||||
b.Log.Warn(err.Error())
|
||||
}
|
||||
|
||||
message.Info.Id = strings.ToUpper(hex.EncodeToString(idBytes))
|
||||
_, err := b.conn.Send(message)
|
||||
|
||||
return message.Info.Id, err
|
||||
}
|
||||
|
||||
// Post an image message from the bridge to WhatsApp
|
||||
// Handle, for sure image/jpeg, image/png and image/gif MIME types
|
||||
func (b *Bwhatsapp) PostImageMessage(msg config.Message, filetype string) (string, error) {
|
||||
fi := msg.Extra["file"][0].(config.FileInfo)
|
||||
|
||||
// Post image message
|
||||
message := whatsapp.ImageMessage{
|
||||
Info: whatsapp.MessageInfo{
|
||||
RemoteJid: msg.Channel,
|
||||
},
|
||||
Type: filetype,
|
||||
Caption: msg.Username + fi.Comment,
|
||||
Content: bytes.NewReader(*fi.Data),
|
||||
}
|
||||
|
||||
b.Log.Debugf("=> Sending %#v", msg)
|
||||
|
||||
// create message ID
|
||||
// TODO follow and act if https://github.com/Rhymen/go-whatsapp/issues/101 implemented
|
||||
idBytes := make([]byte, 10)
|
||||
if _, err := rand.Read(idBytes); err != nil {
|
||||
b.Log.Warn(err.Error())
|
||||
}
|
||||
|
||||
message.Info.Id = strings.ToUpper(hex.EncodeToString(idBytes))
|
||||
_, err := b.conn.Send(message)
|
||||
|
||||
return message.Info.Id, err
|
||||
}
|
||||
|
||||
// Send a message from the bridge to WhatsApp
|
||||
// Required implementation of the Bridger interface
|
||||
// https://github.com/42wim/matterbridge/blob/2cfd880cdb0df29771bf8f31df8d990ab897889d/bridge/bridge.go#L11-L16
|
||||
@@ -259,18 +323,25 @@ func (b *Bwhatsapp) Send(msg config.Message) (string, error) {
|
||||
// TODO handle edit as a message reply with updated text
|
||||
}
|
||||
|
||||
//// TODO Handle Upload a file
|
||||
//if msg.Extra != nil {
|
||||
// for _, rmsg := range helper.HandleExtra(&msg, b.General) {
|
||||
// b.c.SendMessage(roomID, rmsg.Username+rmsg.Text)
|
||||
// }
|
||||
// if len(msg.Extra["file"]) > 0 {
|
||||
// return b.handleUploadFile(&msg, roomID)
|
||||
// }
|
||||
//}
|
||||
// Handle Upload a file
|
||||
if msg.Extra["file"] != nil {
|
||||
fi := msg.Extra["file"][0].(config.FileInfo)
|
||||
filetype := mime.TypeByExtension(filepath.Ext(fi.Name))
|
||||
|
||||
b.Log.Debugf("Extra file is %#v", filetype)
|
||||
|
||||
// TODO: add different types
|
||||
// TODO: add webp conversion
|
||||
switch filetype {
|
||||
case "image/jpeg", "image/png", "image/gif":
|
||||
return b.PostImageMessage(msg, filetype)
|
||||
default:
|
||||
return b.PostDocumentMessage(msg, filetype)
|
||||
}
|
||||
}
|
||||
|
||||
// Post text message
|
||||
text := whatsapp.TextMessage{
|
||||
message := whatsapp.TextMessage{
|
||||
Info: whatsapp.MessageInfo{
|
||||
RemoteJid: msg.Channel, // which equals to group id
|
||||
},
|
||||
@@ -281,15 +352,14 @@ func (b *Bwhatsapp) Send(msg config.Message) (string, error) {
|
||||
|
||||
// create message ID
|
||||
// TODO follow and act if https://github.com/Rhymen/go-whatsapp/issues/101 implemented
|
||||
bytes := make([]byte, 10)
|
||||
if _, err := rand.Read(bytes); err != nil {
|
||||
idBytes := make([]byte, 10)
|
||||
if _, err := rand.Read(idBytes); err != nil {
|
||||
b.Log.Warn(err.Error())
|
||||
}
|
||||
text.Info.Id = strings.ToUpper(hex.EncodeToString(bytes))
|
||||
message.Info.Id = strings.ToUpper(hex.EncodeToString(idBytes))
|
||||
_, err := b.conn.Send(message)
|
||||
|
||||
_, err := b.conn.Send(text)
|
||||
|
||||
return text.Info.Id, err
|
||||
return message.Info.Id, err
|
||||
}
|
||||
|
||||
// TODO do we want that? to allow login with QR code from a bridged channel? https://github.com/tulir/mautrix-whatsapp/blob/513eb18e2d59bada0dd515ee1abaaf38a3bfe3d5/commands.go#L76
|
||||
|
108
changelog.md
108
changelog.md
@@ -1,4 +1,110 @@
|
||||
# dev
|
||||
# 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
|
||||
|
||||
# v1.16.4
|
||||
|
||||
## New features
|
||||
|
||||
- whatsapp: Add support for WhatsApp media (jpeg/png/gif) bridging (#974)
|
||||
- telegram: Add QuoteLengthLimit option (telegram) fixes #963 (#985)
|
||||
- telegram: Add DisableWebPagePreview option (telegram). Closes #980 (#994)
|
||||
|
||||
## Enhancements
|
||||
|
||||
- general: update dependencies
|
||||
- tengo: update to tengo v2
|
||||
- general: Add Docker Compose configuration (#990)
|
||||
|
||||
## Bugfix
|
||||
|
||||
- general: Fail with message instead of panic. #988 (#991)
|
||||
- telegram: Add extra mimetypes to docker image. Fixes #969
|
||||
- discord: Fix channel ID problem with multiple gateways (discord). Fixes #953 (#977)
|
||||
- discord: Show file comment in webhook if normal message is empty (discord). Fixes #962 (#995)
|
||||
- matrix: Fix parsing issues - Disable smartypants in markdown parser. Fixes #989, #983 (#993)
|
||||
- sshchat: Fix duplicated messages (sshchat). Fixes #950 (#996)
|
||||
|
||||
This release couldn't exist without the following contributors:
|
||||
@jwflory, @42wim, @pbek, @Humorhenker, @c0ncord2, @glazzara
|
||||
|
||||
# v1.16.3
|
||||
|
||||
## Bugfix
|
||||
|
||||
- slack: Fix issues with ratelimiting #959
|
||||
- mattermost: Fix bug when using webhookURL and login/token together #960
|
||||
|
||||
# v1.16.2
|
||||
|
||||
## New features
|
||||
|
||||
- keybase: Add support for receiving attachments (keybase) (#923)
|
||||
|
||||
## Enhancements
|
||||
|
||||
- general: Switch to new emoji library kyokomi/emoji (#948)
|
||||
- general: Update markdown parsing library to github.com/gomarkdown/markdown (#944)
|
||||
- ssh-chat: Update shazow/ssh-chat dependency (#947)
|
||||
|
||||
## Bugfix
|
||||
|
||||
- slack: Fix issues with the slack block kit API #937 (#943).
|
||||
|
||||
This release couldn't exist without the following contributors:
|
||||
@42wim, @bmpickford, @goncalor
|
||||
|
||||
# v1.16.1
|
||||
|
||||
|
@@ -1,7 +1,7 @@
|
||||
#!/usr/bin/env bash
|
||||
set -u -e -x -o pipefail
|
||||
|
||||
go version | grep go1.12 || exit
|
||||
go version | grep go1.14 || exit
|
||||
|
||||
VERSION=$(git describe --tags)
|
||||
mkdir ci/binaries
|
||||
|
10
contrib/outmessage-discordemoji.tengo
Normal file
10
contrib/outmessage-discordemoji.tengo
Normal file
@@ -0,0 +1,10 @@
|
||||
text := import("text")
|
||||
|
||||
// if we're not sending to a discord bridge,
|
||||
// then convert custom emoji tags into url's
|
||||
if (inProtocol == "discord" && outProtocol != "discord") {
|
||||
rePNG := text.re_compile(`<:.*?:([0-9]+)>`)
|
||||
msgText=rePNG.replace(msgText,"https://cdn.discordapp.com/emojis/$1.png")
|
||||
reGIF := text.re_compile(`<a:.*?:([0-9]+)>`)
|
||||
msgText=reGIF.replace(msgText,"https://cdn.discordapp.com/emojis/$1.gif")
|
||||
}
|
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
|
||||
}
|
@@ -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
|
||||
}
|
@@ -10,10 +10,10 @@ import (
|
||||
"github.com/42wim/matterbridge/bridge"
|
||||
"github.com/42wim/matterbridge/bridge/config"
|
||||
"github.com/42wim/matterbridge/internal"
|
||||
"github.com/d5/tengo/script"
|
||||
"github.com/d5/tengo/stdlib"
|
||||
"github.com/d5/tengo/v2"
|
||||
"github.com/d5/tengo/v2/stdlib"
|
||||
lru "github.com/hashicorp/golang-lru"
|
||||
"github.com/peterhellberg/emojilib"
|
||||
"github.com/matterbridge/emoji"
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
@@ -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]
|
||||
@@ -372,7 +371,7 @@ func (gw *Gateway) modifyMessage(msg *config.Message) {
|
||||
}
|
||||
|
||||
// replace :emoji: to unicode
|
||||
msg.Text = emojilib.Replace(msg.Text)
|
||||
msg.Text = emoji.Sprint(msg.Text)
|
||||
|
||||
br := gw.Bridges[msg.Account]
|
||||
// loop to replace messages
|
||||
@@ -514,7 +513,7 @@ func modifyMessageTengo(filename string, msg *config.Message) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
s := script.New(res)
|
||||
s := tengo.NewScript(res)
|
||||
s.SetImports(stdlib.GetModuleMap(stdlib.AllModuleNames()...))
|
||||
_ = s.Add("msgText", msg.Text)
|
||||
_ = s.Add("msgUsername", msg.Username)
|
||||
@@ -541,7 +540,7 @@ func (gw *Gateway) modifyUsernameTengo(msg *config.Message, br *bridge.Bridge) (
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
s := script.New(res)
|
||||
s := tengo.NewScript(res)
|
||||
s.SetImports(stdlib.GetModuleMap(stdlib.AllModuleNames()...))
|
||||
_ = s.Add("result", "")
|
||||
_ = s.Add("msgText", msg.Text)
|
||||
@@ -580,7 +579,7 @@ func (gw *Gateway) modifySendMessageTengo(origmsg *config.Message, msg *config.M
|
||||
return err
|
||||
}
|
||||
}
|
||||
s := script.New(res)
|
||||
s := tengo.NewScript(res)
|
||||
s.SetImports(stdlib.GetModuleMap(stdlib.AllModuleNames()...))
|
||||
_ = s.Add("inAccount", origmsg.Account)
|
||||
_ = s.Add("inProtocol", origmsg.Protocol)
|
||||
|
@@ -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
|
||||
|
50
go.mod
50
go.mod
@@ -5,71 +5,61 @@ 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.0.3-0.20191003184814-fc3f792c814c
|
||||
github.com/bwmarrin/discordgo v0.19.0
|
||||
// github.com/bwmarrin/discordgo v0.19.0
|
||||
github.com/d5/tengo v1.24.8
|
||||
github.com/Rhymen/go-whatsapp v0.1.0
|
||||
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/gopackage/ddp v0.0.0-20170117053602-652027933df4 // indirect
|
||||
github.com/gopherjs/gopherjs v0.0.0-20180628210949-0892b62f0d9f // 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/hpcloud/tail v1.0.0 // indirect
|
||||
github.com/jpillora/backoff v0.0.0-20180909062703-3050d21c67d7
|
||||
github.com/jtolds/gls v4.2.1+incompatible // indirect
|
||||
github.com/keybase/go-keybase-chat-bot v0.0.0-20190816161829-561f10822eb2
|
||||
github.com/labstack/echo/v4 v4.1.10
|
||||
github.com/jpillora/backoff v1.0.0
|
||||
github.com/keybase/go-keybase-chat-bot v0.0.0-20200226211841-4e48f3eaef3e
|
||||
github.com/labstack/echo/v4 v4.1.13
|
||||
github.com/lrstanley/girc v0.0.0-20190801035559-4fc93959e1a7
|
||||
github.com/matterbridge/Rocket.Chat.Go.SDK v0.0.0-20190210153444-cc9d05784d5d
|
||||
github.com/matterbridge/discordgo v0.18.1-0.20200308151012-aa40f01cbcc3
|
||||
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/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/msgraph.go v0.0.0-20200308150230-9e043fe9dbaa
|
||||
github.com/mattermost/mattermost-server v5.5.0+incompatible
|
||||
github.com/mattn/go-runewidth v0.0.7 // indirect
|
||||
github.com/mattn/godown v0.0.0-20180312012330-2e9e17e0ea51
|
||||
github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b // indirect
|
||||
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
|
||||
github.com/pborman/uuid v0.0.0-20160216163710-c55201b03606 // indirect
|
||||
github.com/peterhellberg/emojilib v0.0.0-20190124112554-c18758d55320
|
||||
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 v0.0.0-20190125184227-81d7e1686296
|
||||
github.com/shurcooL/sanitized_anchor_name v1.0.0 // indirect
|
||||
github.com/shazow/ssh-chat v1.8.3-0.20200308224626-80ddf1f43a98
|
||||
github.com/sirupsen/logrus v1.4.2
|
||||
github.com/smartystreets/assertions v0.0.0-20180803164922-886ec427f6b9 // indirect
|
||||
github.com/smartystreets/goconvey v0.0.0-20180222194500-ef6db91d284a // indirect
|
||||
github.com/spf13/viper v1.4.0
|
||||
github.com/slack-go/slack v0.6.3-0.20200228121756-f56d616d5901
|
||||
github.com/spf13/viper v1.6.1
|
||||
github.com/stretchr/testify v1.4.0
|
||||
github.com/technoweenie/multipartstreamer v1.0.1 // indirect
|
||||
github.com/x-cray/logrus-prefixed-formatter v0.5.2 // indirect
|
||||
github.com/zfjagann/golang-ring v0.0.0-20190304061218-d34796e0a6c2
|
||||
gitlab.com/golang-commonmark/html v0.0.0-20180917080848-cfaf75183c4a // indirect
|
||||
gitlab.com/golang-commonmark/linkify v0.0.0-20191026162114-a0c2df6c8f82 // indirect
|
||||
gitlab.com/golang-commonmark/markdown v0.0.0-20181102083822-772775880e1f
|
||||
gitlab.com/golang-commonmark/mdurl v0.0.0-20180912090424-e5bce34c34f2 // indirect
|
||||
gitlab.com/golang-commonmark/puny v0.0.0-20180912090636-2cd490539afe // indirect
|
||||
gitlab.com/opennota/wd v0.0.0-20180912061657-c5d65f63c638 // indirect
|
||||
golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586 // indirect
|
||||
golang.org/x/image v0.0.0-20190902063713-cb417be4ba39
|
||||
golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7 // indirect
|
||||
golang.org/x/text v0.3.2 // indirect
|
||||
github.com/yaegashi/msgraph.go v0.1.2
|
||||
github.com/zfjagann/golang-ring v0.0.0-20190106091943-a88bb6aef447
|
||||
golang.org/x/image v0.0.0-20191214001246-9130b4cfad52
|
||||
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d
|
||||
gopkg.in/fsnotify.v1 v1.4.7 // indirect
|
||||
gopkg.in/natefinch/lumberjack.v2 v2.0.0 // indirect
|
||||
gopkg.in/russross/blackfriday.v2 v2.0.0 // indirect
|
||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect
|
||||
)
|
||||
|
||||
replace github.com/bwmarrin/discordgo v0.19.0 => github.com/matterbridge/discordgo v0.0.0-20191026232317-01823f4ebba4
|
||||
//replace github.com/bwmarrin/discordgo v0.20.2 => github.com/matterbridge/discordgo v0.18.1-0.20200109173909-ed873362fa43
|
||||
|
||||
go 1.13
|
||||
|
166
go.sum
166
go.sum
@@ -1,4 +1,5 @@
|
||||
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=
|
||||
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=
|
||||
@@ -11,16 +12,16 @@ github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAE
|
||||
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.0.3-0.20191003184814-fc3f792c814c h1:+yAllLxP+WjpuVVE1WNm0/Oigbeob9+liYEyk/v4nj8=
|
||||
github.com/Rhymen/go-whatsapp v0.0.3-0.20191003184814-fc3f792c814c/go.mod h1:qf/2PQi82Okxw/igghu/oMGzTeUYuKBq1JNo3tdQyNg=
|
||||
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/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/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/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
|
||||
@@ -32,8 +33,8 @@ github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc
|
||||
github.com/coreos/go-semver v0.2.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 v1.24.8 h1:PRJ+NWt7ae/9sSbIfThOBTkPSvNV+dwYoBAvwfNgNJY=
|
||||
github.com/d5/tengo v1.24.8/go.mod h1:VhLq8Q2QFhCIJO3NhvM934qOThykMqJi9y9Siqd1ocQ=
|
||||
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/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=
|
||||
@@ -48,33 +49,35 @@ github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeME
|
||||
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-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-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/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/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/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
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-20180628210949-0892b62f0d9f h1:FDM3EtwZLyhW48YRiyqjivNlNZjAObv4xt4NnJaU+NQ=
|
||||
github.com/gopherjs/gopherjs v0.0.0-20180628210949-0892b62f0d9f/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
|
||||
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=
|
||||
@@ -88,17 +91,17 @@ github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T
|
||||
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=
|
||||
github.com/jessevdk/go-flags v1.3.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
|
||||
github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
|
||||
github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
|
||||
github.com/jpillora/backoff v0.0.0-20180909062703-3050d21c67d7 h1:K//n/AqR5HjG3qxbrBCL4vJPW0MVFSs9CPK1OOJdRME=
|
||||
github.com/jpillora/backoff v0.0.0-20180909062703-3050d21c67d7/go.mod h1:2iMrUgbbvHEiQClaW2NsSzMyGHqN+rDFqY705q49KG0=
|
||||
github.com/jtolds/gls v4.2.1+incompatible h1:fSuqC+Gmlu6l/ZYAoZzx2pyucC8Xza35fpRVWLVmUEE=
|
||||
github.com/jtolds/gls v4.2.1+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
|
||||
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/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-keybase-chat-bot v0.0.0-20200226211841-4e48f3eaef3e h1:KbPTfR/PYuau1IzKoE4lnd8yby5I2pBj+VR6fSVbYU8=
|
||||
github.com/keybase/go-keybase-chat-bot v0.0.0-20200226211841-4e48f3eaef3e/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/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
|
||||
@@ -111,38 +114,47 @@ github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORN
|
||||
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/v4 v4.1.10 h1:/yhIpO50CBInUbE/nHJtGIyhBv0dJe2cDAYxc3V3uMo=
|
||||
github.com/labstack/echo/v4 v4.1.10/go.mod h1:i541M3Fj6f76NZtHSj7TXnyM8n2gaodfvfxNnFqi74g=
|
||||
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/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.0 h1:LLgXmsheXeRoUOBOjtwPQCWIYqM/LU1ayDtDePerRcY=
|
||||
github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
|
||||
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.0.0-20191026232317-01823f4ebba4 h1:RvH3lC4bEp+bieca+Yh5xPU8tLJgnk7ridiSwMFHrrw=
|
||||
github.com/matterbridge/discordgo v0.0.0-20191026232317-01823f4ebba4/go.mod h1:O9S4p+ofTFwB02em7jkpkV8M3R0/PUVOwN61zSZ0r4Q=
|
||||
github.com/matterbridge/discordgo v0.18.1-0.20200308151012-aa40f01cbcc3 h1:VP/DNRn2HtrVRN6+X3h4FDcQI2OOKT+88WUi21ZD1Kw=
|
||||
github.com/matterbridge/discordgo v0.18.1-0.20200308151012-aa40f01cbcc3/go.mod h1:5a1bHtG/38ofcx9cgwM5eTW/Pl4SpbQksNDnTRcGA2Y=
|
||||
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/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/msgraph.go v0.0.0-20200308150230-9e043fe9dbaa h1:ZP87nK5Mhgvt6Rpgbztdmq9+6cb3aZ6MgW/JWKbnMrI=
|
||||
github.com/matterbridge/msgraph.go v0.0.0-20200308150230-9e043fe9dbaa/go.mod h1:l0kx9L8Z+NbBCGrQ/y+ldKZ/fiwBZjPoXwDS55LTumI=
|
||||
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.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-isatty v0.0.5 h1:tHXDdz1cpzGaovsTB+TVB8q90WEokoVmfMqoVcrLUgw=
|
||||
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/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-runewidth v0.0.7 h1:Ei8KR0497xHyKJPAv59M1dkC+rOZCMBJ+t3fZ+twI54=
|
||||
github.com/mattn/go-runewidth v0.0.7/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
|
||||
github.com/mattn/godown v0.0.0-20180312012330-2e9e17e0ea51 h1:MpI7hy3MiCnrggmZI/s8LaPbLVOOWpzDbjA4F+XaXaM=
|
||||
github.com/mattn/godown v0.0.0-20180312012330-2e9e17e0ea51/go.mod h1:s3KUdOIXJ+jaGM++XHiXA6gikdleaWVATCcQGD4h734=
|
||||
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=
|
||||
@@ -157,8 +169,6 @@ github.com/nelsonken/gomf v0.0.0-20180504123937-a9dd2f9deae9 h1:mp6tU1r0xLostUGL
|
||||
github.com/nelsonken/gomf v0.0.0-20180504123937-a9dd2f9deae9/go.mod h1:A5SRAcpTemjGgIuBq6Kic2yHcoeUFWUinOAlMP/i9xo=
|
||||
github.com/nicksnyder/go-i18n v1.4.0 h1:AgLl+Yq7kg5OYlzCgu9cKTZOyI4tD/NgukKqLqC8E+I=
|
||||
github.com/nicksnyder/go-i18n v1.4.0/go.mod h1:HrK7VCrbOvQoUAQ7Vpy7i87N7JZZZ7R2xBGjv0j365Q=
|
||||
github.com/nlopes/slack v0.6.0 h1:jt0jxVQGhssx1Ib7naAOZEZcGdtIhTzkP0nopK0AsRA=
|
||||
github.com/nlopes/slack v0.6.0/go.mod h1:JzQ9m3PMAqcpeCam7UaHSuBuupz7CmpjehYMayT6YOk=
|
||||
github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
|
||||
github.com/onsi/ginkgo v1.6.0 h1:Ix8l273rp3QzYgXSR+c8d1fTG7UPgYkOSELPhiY/YGw=
|
||||
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
@@ -170,8 +180,6 @@ github.com/pborman/uuid v0.0.0-20160216163710-c55201b03606 h1:/CPgDYrfeK2LMK6xcU
|
||||
github.com/pborman/uuid v0.0.0-20160216163710-c55201b03606/go.mod h1:VyrYX9gd7irzKovcSS6BIIEwPRkP2Wm2m9ufcdFSJ34=
|
||||
github.com/pelletier/go-toml v1.2.0 h1:T5zMGML61Wp+FlcbWjRDT7yAxhJNAiPPLOFECq181zc=
|
||||
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
|
||||
github.com/peterhellberg/emojilib v0.0.0-20190124112554-c18758d55320 h1:YxcQy/DV+48NGv1lxx1vsWBzs6W1f1ogubkuCozxpX0=
|
||||
github.com/peterhellberg/emojilib v0.0.0-20190124112554-c18758d55320/go.mod h1:G7LufuPajuIvdt9OitkNt2qh0mmvD4bfRgRM7bhDIOA=
|
||||
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
|
||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
@@ -186,6 +194,10 @@ 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/rs/xid v1.2.1 h1:mhH9Nq+C1fY2l1XIpgxIiUOfNpRBYH1kKcr+qfKgjRc=
|
||||
github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ=
|
||||
@@ -195,23 +207,21 @@ github.com/saintfish/chardet v0.0.0-20120816061221-3af4cd4741ca h1:NugYot0LIVPxT
|
||||
github.com/saintfish/chardet v0.0.0-20120816061221-3af4cd4741ca/go.mod h1:uugorj2VCxiV1x+LzaIdVa9b4S4qGAcH6cbhh4qVxOU=
|
||||
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 v0.0.0-20190125184227-81d7e1686296 h1:8RLq547MSVc6vhOuCl4Ca0TsAQknj6NX6ZLSZ3+xmio=
|
||||
github.com/shazow/ssh-chat v0.0.0-20190125184227-81d7e1686296/go.mod h1:1GLXsL4esywkpNId3v4QWuMf3THtWGitWvtQ/L3aSA4=
|
||||
github.com/shirou/gopsutil v0.0.0-20180427012116-c95755e4bcd7 h1:80VN+vGkqM773Br/uNNTSheo3KatTgV8IpjIKjvVLng=
|
||||
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 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/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5IYyJwS/kOiWx8mHo=
|
||||
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
|
||||
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/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/smartystreets/assertions v0.0.0-20180803164922-886ec427f6b9 h1:lXQ+j+KwZcbwrbgU0Rp4Eglg3EJLHbuZU3BbOqAGBmg=
|
||||
github.com/smartystreets/assertions v0.0.0-20180803164922-886ec427f6b9/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
|
||||
github.com/smartystreets/goconvey v0.0.0-20180222194500-ef6db91d284a h1:JSvGDIbmil4Ui/dDdFBExb7/cmkNjyX5F97oglmvCDo=
|
||||
github.com/smartystreets/goconvey v0.0.0-20180222194500-ef6db91d284a/go.mod h1:XDJAKZRPZ1CvBcN2aX5YOUTYGHki24fSF0Iv48Ibg0s=
|
||||
github.com/slack-go/slack v0.6.3-0.20200228121756-f56d616d5901 h1:sXIMY2YPYEm5NoGMCrJC50N+8t9W6vbY9qr61zcLEAE=
|
||||
github.com/slack-go/slack v0.6.3-0.20200228121756-f56d616d5901/go.mod h1:ZUNi+O1Pwr2ch2UOp2AfF+s7QYQgwht2Cd1UTeIYw9A=
|
||||
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=
|
||||
github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
|
||||
github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
|
||||
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
|
||||
github.com/spf13/afero v1.1.2 h1:m8/z1t7/fwjysjQRYbP0RD+bUIF/8tJwPdEZsI83ACI=
|
||||
@@ -222,41 +232,33 @@ 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.4.0 h1:yXHLWeravcrgGyFSyCgdYpXQ9dR9c/WED3pg1RhxqEU=
|
||||
github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE=
|
||||
github.com/spf13/viper v1.6.1 h1:VPZzIkznI1YhVMRi6vNFLHSwhnhReBfgTxIPccpfdZk=
|
||||
github.com/spf13/viper v1.6.1/go.mod h1:t3iDnF5Jlj76alVNuyFBk5oUMCvsrkbvZK0WQdfDi5k=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
|
||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||
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/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-20190304061218-d34796e0a6c2 h1:UQwvu7FjUEdVYofx0U6bsc5odNE7wa5TSA0fl559GcA=
|
||||
github.com/zfjagann/golang-ring v0.0.0-20190304061218-d34796e0a6c2/go.mod h1:0MsIttMJIF/8Y7x0XjonJP7K99t3sR6bjj4m5S4JmqU=
|
||||
gitlab.com/golang-commonmark/html v0.0.0-20180917080848-cfaf75183c4a h1:Ax7kdHNICZiIeFpmevmaEWb0Ae3BUj3zCTKhZHZ+zd0=
|
||||
gitlab.com/golang-commonmark/html v0.0.0-20180917080848-cfaf75183c4a/go.mod h1:JT4uoTz0tfPoyVH88GZoWDNm5NHJI2VbUW+eyPClueI=
|
||||
gitlab.com/golang-commonmark/linkify v0.0.0-20191026162114-a0c2df6c8f82 h1:oYrL81N608MLZhma3ruL8qTM4xcpYECGut8KSxRY59g=
|
||||
gitlab.com/golang-commonmark/linkify v0.0.0-20191026162114-a0c2df6c8f82/go.mod h1:Gn+LZmCrhPECMD3SOKlE+BOHwhOYD9j7WT9NUtkCrC8=
|
||||
gitlab.com/golang-commonmark/markdown v0.0.0-20181102083822-772775880e1f h1:jwXy/CsM4xS2aoiF2fHAlukmInWhd2TlWB+HDCyvzKc=
|
||||
gitlab.com/golang-commonmark/markdown v0.0.0-20181102083822-772775880e1f/go.mod h1:SIHlEr9462fpIfTrVWf3GqQDxnA65Vm3BMMsUtuA6W0=
|
||||
gitlab.com/golang-commonmark/mdurl v0.0.0-20180912090424-e5bce34c34f2 h1:wD/sPUgx2QJFPTyXZpJnLaROolfeKuruh06U4pRV0WY=
|
||||
gitlab.com/golang-commonmark/mdurl v0.0.0-20180912090424-e5bce34c34f2/go.mod h1:wQk4rLkWrdOPjUAtqJRJ10hIlseLSVYWP95PLrjDF9s=
|
||||
gitlab.com/golang-commonmark/puny v0.0.0-20180912090636-2cd490539afe h1:5kUPFAF52umOUPH12MuNUmyVTseJRNBftDl/KfsvX3I=
|
||||
gitlab.com/golang-commonmark/puny v0.0.0-20180912090636-2cd490539afe/go.mod h1:P9LSM1KVzrIstFgUaveuwiAm8PK5VTB3yJEU8kqlbrU=
|
||||
gitlab.com/opennota/wd v0.0.0-20180912061657-c5d65f63c638 h1:uPZaMiz6Sz0PZs3IZJWpU5qHKGNy///1pacZC9txiUI=
|
||||
gitlab.com/opennota/wd v0.0.0-20180912061657-c5d65f63c638/go.mod h1:EGRJaqe2eO9XGmFtQCvV3Lm9NLico3UhFwUpCG/+mVU=
|
||||
github.com/yaegashi/msgraph.go v0.1.2 h1:83uVRQaj8YBsVqOUGj0WRwzxdgGF69jRpg5IQYaTvoY=
|
||||
github.com/yaegashi/msgraph.go v0.1.2/go.mod h1:Lp39e9oo596G5FcmMKI0cXR3mg/QikSdabgZdbMqbAM=
|
||||
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=
|
||||
go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
|
||||
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=
|
||||
@@ -264,31 +266,36 @@ go.uber.org/multierr v1.1.0 h1:HoEmRHQPVSqub6w2z2d2EOVs2fjyFRGyofhKuyDq0QI=
|
||||
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
|
||||
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-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-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586 h1:7KByu05hhLed2MO29w7p1XfZvZ13m8mub3shuVftRs0=
|
||||
golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/image v0.0.0-20190902063713-cb417be4ba39 h1:4dQcAORh9oYBwVSBVIkP489LUPC+f1HBkTYXgmqfR+o=
|
||||
golang.org/x/image v0.0.0-20190902063713-cb417be4ba39/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
||||
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/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
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-20181114220301-adae6a3d119a/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-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/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
|
||||
golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7 h1:fHDIZ2oxGnUZRN6WgWFCbYBjH9uqVPRCUVUDhs0wnbA=
|
||||
golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
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/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45 h1:SVwTIAaPC2U/AvvLNZ2a7OVsmBpC8L5BlwK1whH3hm0=
|
||||
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/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
@@ -297,11 +304,13 @@ golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5h
|
||||
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-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-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
|
||||
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/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=
|
||||
@@ -310,7 +319,10 @@ golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGm
|
||||
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-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
||||
google.golang.org/appengine v1.4.0 h1:/wp5JvzpHIxhs/dumFmF7BXTf3Z+dd4uXta4kVyO508=
|
||||
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
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/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||
@@ -321,17 +333,17 @@ gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
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=
|
||||
gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
||||
gopkg.in/natefinch/lumberjack.v2 v2.0.0 h1:1Lc07Kr7qY4U2YPouBjpCLxpiyxIVoxqXgkXLknAOE8=
|
||||
gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k=
|
||||
gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=
|
||||
gopkg.in/russross/blackfriday.v2 v2.0.0 h1:+FlnIV8DSQnT7NZ43hcVKcdJdzZoeCmJj4Ql8gq5keA=
|
||||
gopkg.in/russross/blackfriday.v2 v2.0.0/go.mod h1:6sSBNz/GtOm/pJTuh5UmBK2ZHfmnxGbl2NZg1UliSOI=
|
||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
|
||||
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=
|
||||
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=
|
||||
|
@@ -12,8 +12,14 @@ text := import("text")
|
||||
|
||||
// start - strip irc colors
|
||||
// if we're not sending to an irc bridge we strip the IRC colors
|
||||
if inProtocol == "irc" {
|
||||
if inProtocol == "irc" && outProtocol != "irc" {
|
||||
re := text.re_compile(`\x03(?:\d{1,2}(?:,\d{1,2})?)?|[[:cntrl:]]`)
|
||||
msgText=re.replace(msgText,"")
|
||||
}
|
||||
// end - strip irc colors
|
||||
|
||||
// strip custom emoji
|
||||
if inProtocol == "discord" {
|
||||
re := text.re_compile(`<a?(:.*?:)[0-9]+>`)
|
||||
msgText=re.replace(msgText,"$1")
|
||||
}
|
||||
|
@@ -15,7 +15,7 @@ import (
|
||||
)
|
||||
|
||||
var (
|
||||
version = "1.16.1"
|
||||
version = "1.17.1"
|
||||
githash string
|
||||
|
||||
flagConfig = flag.String("conf", "matterbridge.toml", "config file")
|
||||
|
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)
|
||||
|
21
vendor/github.com/Rhymen/go-whatsapp/README.md
generated
vendored
21
vendor/github.com/Rhymen/go-whatsapp/README.md
generated
vendored
@@ -23,7 +23,7 @@ qrChan := make(chan string)
|
||||
go func() {
|
||||
fmt.Printf("qr code: %v\n", <-qrChan)
|
||||
//show qr code or save it somewhere to scan
|
||||
}
|
||||
}()
|
||||
sess, err := wac.Login(qrChan)
|
||||
```
|
||||
The authentication process requires you to scan the qr code, that is send through the channel, with the device you are using whatsapp on. The session struct that is returned can be saved and used to restore the login without scanning the qr code again. The qr code has a ttl of 20 seconds and the login function throws a timeout err if the time has passed or any other request fails.
|
||||
@@ -66,6 +66,10 @@ func (myHandler) HandleJsonMessage(message string) {
|
||||
fmt.Println(message)
|
||||
}
|
||||
|
||||
func (myHandler) HandleContactMessage(message whatsapp.ContactMessage) {
|
||||
fmt.Println(message)
|
||||
}
|
||||
|
||||
wac.AddHandler(myHandler{})
|
||||
```
|
||||
The message handlers are all optional, you don't need to implement anything but the error handler to implement the interface. The ImageMessage, VideoMessage, AudioMessage and DocumentMessage provide a Download function to get the media data.
|
||||
@@ -81,6 +85,21 @@ text := whatsapp.TextMessage{
|
||||
|
||||
err := wac.Send(text)
|
||||
```
|
||||
|
||||
### Sending Contact Messages
|
||||
```go
|
||||
contactMessage := whatsapp.ContactMessage{
|
||||
Info: whatsapp.MessageInfo{
|
||||
RemoteJid: "0123456789@s.whatsapp.net",
|
||||
},
|
||||
DisplayName: "Luke Skylwallker",
|
||||
Vcard: "BEGIN:VCARD\nVERSION:3.0\nN:Skyllwalker;Luke;;\nFN:Luke Skywallker\nitem1.TEL;waid=0123456789:+1 23 456789789\nitem1.X-ABLabel:Mobile\nEND:VCARD",
|
||||
}
|
||||
|
||||
id, error := client.WaConn.Send(contactMessage)
|
||||
```
|
||||
|
||||
|
||||
The message will be send over the websocket. The attributes seen above are the required ones. All other relevant attributes (id, timestamp, fromMe, status) are set if they are missing in the struct. For the time being we only support text messages, but other types are planned for the near future.
|
||||
|
||||
## Legal
|
||||
|
9
vendor/github.com/Rhymen/go-whatsapp/binary/node.go
generated
vendored
9
vendor/github.com/Rhymen/go-whatsapp/binary/node.go
generated
vendored
@@ -66,9 +66,12 @@ func Unmarshal(data []byte) (*Node, error) {
|
||||
}
|
||||
|
||||
if n != nil && n.Attributes != nil && n.Content != nil {
|
||||
n.Content, err = unmarshalMessageArray(n.Content.([]Node))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
nContent, ok := n.Content.([]Node)
|
||||
if ok {
|
||||
n.Content, err = unmarshalMessageArray(nContent)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
1401
vendor/github.com/Rhymen/go-whatsapp/binary/proto/def.pb.go
generated
vendored
1401
vendor/github.com/Rhymen/go-whatsapp/binary/proto/def.pb.go
generated
vendored
File diff suppressed because it is too large
Load Diff
67
vendor/github.com/Rhymen/go-whatsapp/binary/proto/def.proto
generated
vendored
67
vendor/github.com/Rhymen/go-whatsapp/binary/proto/def.proto
generated
vendored
@@ -3,7 +3,7 @@ package proto;
|
||||
|
||||
message HydratedQuickReplyButton {
|
||||
optional string displayText = 1;
|
||||
optional string buttonId = 2;
|
||||
optional string id = 2;
|
||||
}
|
||||
|
||||
message HydratedURLButton {
|
||||
@@ -17,6 +17,7 @@ message HydratedCallButton {
|
||||
}
|
||||
|
||||
message HydratedTemplateButton {
|
||||
optional uint32 index = 4;
|
||||
oneof hydratedButton {
|
||||
HydratedQuickReplyButton quickReplyButton = 1;
|
||||
HydratedURLButton urlButton = 2;
|
||||
@@ -26,7 +27,7 @@ message HydratedTemplateButton {
|
||||
|
||||
message QuickReplyButton {
|
||||
optional HighlyStructuredMessage displayText = 1;
|
||||
optional string buttonId = 2;
|
||||
optional string id = 2;
|
||||
}
|
||||
|
||||
message URLButton {
|
||||
@@ -40,6 +41,7 @@ message CallButton {
|
||||
}
|
||||
|
||||
message TemplateButton {
|
||||
optional uint32 index = 4;
|
||||
oneof button {
|
||||
QuickReplyButton quickReplyButton = 1;
|
||||
URLButton urlButton = 2;
|
||||
@@ -89,6 +91,8 @@ message ContextInfo {
|
||||
optional uint32 forwardingScore = 21;
|
||||
optional bool isForwarded = 22;
|
||||
optional AdReplyInfo quotedAd = 23;
|
||||
optional MessageKey placeholderKey = 24;
|
||||
optional uint32 expiration = 25;
|
||||
}
|
||||
|
||||
message SenderKeyDistributionMessage {
|
||||
@@ -114,6 +118,10 @@ message ImageMessage {
|
||||
optional bytes firstScanSidecar = 18;
|
||||
optional uint32 firstScanLength = 19;
|
||||
optional uint32 experimentGroupId = 20;
|
||||
optional bytes scansSidecar = 21;
|
||||
repeated uint32 scanLengths = 22;
|
||||
optional bytes midQualityFileSha256 = 23;
|
||||
optional bytes midQualityFileEncSha256 = 24;
|
||||
}
|
||||
|
||||
message ContactMessage {
|
||||
@@ -156,6 +164,7 @@ message ExtendedTextMessage {
|
||||
optional EXTENDED_TEXT_MESSAGE_PREVIEWTYPE previewType = 10;
|
||||
optional bytes jpegThumbnail = 16;
|
||||
optional ContextInfo contextInfo = 17;
|
||||
optional bool doNotPlayInline = 18;
|
||||
}
|
||||
|
||||
message DocumentMessage {
|
||||
@@ -228,8 +237,10 @@ message ProtocolMessage {
|
||||
optional MessageKey key = 1;
|
||||
enum PROTOCOL_MESSAGE_TYPE {
|
||||
REVOKE = 0;
|
||||
EPHEMERAL_SETTING = 3;
|
||||
}
|
||||
optional PROTOCOL_MESSAGE_TYPE type = 2;
|
||||
optional uint32 ephemeralExpiration = 4;
|
||||
}
|
||||
|
||||
message ContactsArrayMessage {
|
||||
@@ -294,6 +305,7 @@ message HighlyStructuredMessage {
|
||||
repeated HSMLocalizableParameter localizableParams = 6;
|
||||
optional string deterministicLg = 7;
|
||||
optional string deterministicLc = 8;
|
||||
optional TemplateMessage hydratedHsm = 9;
|
||||
}
|
||||
|
||||
message SendPaymentMessage {
|
||||
@@ -341,7 +353,8 @@ message StickerMessage {
|
||||
optional string directPath = 8;
|
||||
optional uint64 fileLength = 9;
|
||||
optional int64 mediaKeyTimestamp = 10;
|
||||
optional bytes pngThumbnail = 16;
|
||||
optional uint32 firstFrameLength = 11;
|
||||
optional bytes firstFrameSidecar = 12;
|
||||
optional ContextInfo contextInfo = 17;
|
||||
}
|
||||
|
||||
@@ -361,7 +374,8 @@ message FourRowTemplate {
|
||||
message HydratedFourRowTemplate {
|
||||
optional string hydratedContentText = 6;
|
||||
optional string hydratedFooterText = 7;
|
||||
repeated HydratedTemplateButton hydratedButtons = 9;
|
||||
repeated HydratedTemplateButton hydratedButtons = 8;
|
||||
optional string templateId = 9;
|
||||
oneof title {
|
||||
DocumentMessage documentMessage = 1;
|
||||
string hydratedTitleText = 2;
|
||||
@@ -372,6 +386,8 @@ message HydratedFourRowTemplate {
|
||||
}
|
||||
|
||||
message TemplateMessage {
|
||||
optional ContextInfo contextInfo = 3;
|
||||
optional HydratedFourRowTemplate hydratedTemplate = 4;
|
||||
oneof format {
|
||||
FourRowTemplate fourRowTemplate = 1;
|
||||
HydratedFourRowTemplate hydratedFourRowTemplate = 2;
|
||||
@@ -379,9 +395,10 @@ message TemplateMessage {
|
||||
}
|
||||
|
||||
message TemplateButtonReplyMessage {
|
||||
optional string selectedButtonId = 1;
|
||||
repeated string selectedButtonDisplayText = 2;
|
||||
optional string selectedId = 1;
|
||||
optional string selectedDisplayText = 2;
|
||||
optional ContextInfo contextInfo = 3;
|
||||
optional uint32 selectedIndex = 4;
|
||||
}
|
||||
|
||||
message ProductSnapshot {
|
||||
@@ -394,6 +411,7 @@ message ProductSnapshot {
|
||||
optional string retailerId = 7;
|
||||
optional string url = 8;
|
||||
optional uint32 productImageCount = 9;
|
||||
optional string firstImageId = 11;
|
||||
}
|
||||
|
||||
message ProductMessage {
|
||||
@@ -409,6 +427,16 @@ message GroupInviteMessage {
|
||||
optional string groupName = 4;
|
||||
optional bytes jpegThumbnail = 5;
|
||||
optional string caption = 6;
|
||||
optional ContextInfo contextInfo = 7;
|
||||
}
|
||||
|
||||
message DeviceSentMessage {
|
||||
optional string destinationJid = 1;
|
||||
optional Message message = 2;
|
||||
}
|
||||
|
||||
message DeviceSyncMessage {
|
||||
optional bytes serializedXmlBytes = 1;
|
||||
}
|
||||
|
||||
message Message {
|
||||
@@ -434,8 +462,11 @@ message Message {
|
||||
optional CancelPaymentRequestMessage cancelPaymentRequestMessage = 24;
|
||||
optional TemplateMessage templateMessage = 25;
|
||||
optional StickerMessage stickerMessage = 26;
|
||||
optional ProductMessage productMessage = 27;
|
||||
optional GroupInviteMessage groupInviteMessage = 28;
|
||||
optional TemplateButtonReplyMessage templateButtonReplyMessage = 29;
|
||||
optional ProductMessage productMessage = 30;
|
||||
optional DeviceSentMessage deviceSentMessage = 31;
|
||||
optional DeviceSyncMessage deviceSyncMessage = 32;
|
||||
}
|
||||
|
||||
message MessageKey {
|
||||
@@ -447,9 +478,10 @@ message MessageKey {
|
||||
|
||||
message WebFeatures {
|
||||
enum WEB_FEATURES_FLAG {
|
||||
NOT_IMPLEMENTED = 0;
|
||||
IMPLEMENTED = 1;
|
||||
OPTIONAL = 2;
|
||||
NOT_STARTED = 0;
|
||||
FORCE_UPGRADE = 1;
|
||||
DEVELOPMENT = 2;
|
||||
PRODUCTION = 3;
|
||||
}
|
||||
optional WEB_FEATURES_FLAG labelsDisplay = 1;
|
||||
optional WEB_FEATURES_FLAG voipIndividualOutgoing = 2;
|
||||
@@ -473,6 +505,14 @@ message WebFeatures {
|
||||
optional WEB_FEATURES_FLAG voipIndividualVideo = 22;
|
||||
optional WEB_FEATURES_FLAG thirdPartyStickers = 23;
|
||||
optional WEB_FEATURES_FLAG frequentlyForwardedSetting = 24;
|
||||
optional WEB_FEATURES_FLAG groupsV4JoinPermission = 25;
|
||||
optional WEB_FEATURES_FLAG recentStickers = 26;
|
||||
optional WEB_FEATURES_FLAG catalog = 27;
|
||||
optional WEB_FEATURES_FLAG starredStickers = 28;
|
||||
optional WEB_FEATURES_FLAG voipGroupCall = 29;
|
||||
optional WEB_FEATURES_FLAG templateMessage = 30;
|
||||
optional WEB_FEATURES_FLAG templateMessageInteractivity = 31;
|
||||
optional WEB_FEATURES_FLAG ephemeralMessages = 32;
|
||||
}
|
||||
|
||||
message TabletNotificationsInfo {
|
||||
@@ -614,6 +654,9 @@ message WebMessageInfo {
|
||||
BIZ_TWO_TIER_MIGRATION_BOTTOM = 67;
|
||||
OVERSIZED = 68;
|
||||
GROUP_CHANGE_NO_FREQUENTLY_FORWARDED = 69;
|
||||
GROUP_V4_ADD_INVITE_SENT = 70;
|
||||
GROUP_PARTICIPANT_ADD_REQUEST_JOIN = 71;
|
||||
CHANGE_EPHEMERAL_SETTING = 72;
|
||||
}
|
||||
optional WEB_MESSAGE_INFO_STUBTYPE messageStubType = 24;
|
||||
optional bool clearMedia = 25;
|
||||
@@ -623,4 +666,6 @@ message WebMessageInfo {
|
||||
optional PaymentInfo paymentInfo = 29;
|
||||
optional LiveLocationMessage finalLiveLocation = 30;
|
||||
optional PaymentInfo quotedPaymentInfo = 31;
|
||||
}
|
||||
optional uint64 ephemeralStartTimestamp = 32;
|
||||
optional uint32 ephemeralDuration = 33;
|
||||
}
|
2
vendor/github.com/Rhymen/go-whatsapp/conn.go
generated
vendored
2
vendor/github.com/Rhymen/go-whatsapp/conn.go
generated
vendored
@@ -93,6 +93,8 @@ type Conn struct {
|
||||
|
||||
loginSessionLock sync.RWMutex
|
||||
Proxy func(*http.Request) (*url.URL, error)
|
||||
|
||||
writerLock sync.RWMutex
|
||||
}
|
||||
|
||||
type websocketWrapper struct {
|
||||
|
10
vendor/github.com/Rhymen/go-whatsapp/contact.go
generated
vendored
10
vendor/github.com/Rhymen/go-whatsapp/contact.go
generated
vendored
@@ -10,11 +10,11 @@ import (
|
||||
type Presence string
|
||||
|
||||
const (
|
||||
PresenceAvailable = "available"
|
||||
PresenceUnavailable = "unavailable"
|
||||
PresenceComposing = "composing"
|
||||
PresenceRecording = "recording"
|
||||
PresencePaused = "paused"
|
||||
PresenceAvailable Presence = "available"
|
||||
PresenceUnavailable Presence = "unavailable"
|
||||
PresenceComposing Presence = "composing"
|
||||
PresenceRecording Presence = "recording"
|
||||
PresencePaused Presence = "paused"
|
||||
)
|
||||
|
||||
//TODO: filename? WhatsApp uses Store.Contacts for these functions
|
||||
|
2
vendor/github.com/Rhymen/go-whatsapp/go.mod
generated
vendored
2
vendor/github.com/Rhymen/go-whatsapp/go.mod
generated
vendored
@@ -10,3 +10,5 @@ require (
|
||||
github.com/pkg/errors v0.8.1
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2
|
||||
)
|
||||
|
||||
go 1.13
|
||||
|
21
vendor/github.com/Rhymen/go-whatsapp/handler.go
generated
vendored
21
vendor/github.com/Rhymen/go-whatsapp/handler.go
generated
vendored
@@ -82,13 +82,21 @@ type LocationMessageHandler interface {
|
||||
}
|
||||
|
||||
/*
|
||||
The StickerMessageHandler interface needs to be implemented to receive location messages dispatched by the dispatcher.
|
||||
The StickerMessageHandler interface needs to be implemented to receive sticker messages dispatched by the dispatcher.
|
||||
*/
|
||||
type StickerMessageHandler interface {
|
||||
Handler
|
||||
HandleStickerMessage(message StickerMessage)
|
||||
}
|
||||
|
||||
/*
|
||||
The ContactMessageHandler interface needs to be implemented to receive contact messages dispatched by the dispatcher.
|
||||
*/
|
||||
type ContactMessageHandler interface {
|
||||
Handler
|
||||
HandleContactMessage(message ContactMessage)
|
||||
}
|
||||
|
||||
/*
|
||||
The JsonMessageHandler interface needs to be implemented to receive json messages dispatched by the dispatcher.
|
||||
These json messages contain status updates of every kind sent by WhatsAppWeb servers. WhatsAppWeb uses these messages
|
||||
@@ -267,6 +275,17 @@ func (wac *Conn) handleWithCustomHandlers(message interface{}, handlers []Handle
|
||||
}
|
||||
}
|
||||
|
||||
case ContactMessage:
|
||||
for _, h := range handlers {
|
||||
if x, ok := h.(ContactMessageHandler); ok {
|
||||
if wac.shouldCallSynchronously(h) {
|
||||
x.HandleContactMessage(m)
|
||||
} else {
|
||||
go x.HandleContactMessage(m)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
case *proto.WebMessageInfo:
|
||||
for _, h := range handlers {
|
||||
if x, ok := h.(RawMessageHandler); ok {
|
||||
|
200
vendor/github.com/Rhymen/go-whatsapp/message.go
generated
vendored
200
vendor/github.com/Rhymen/go-whatsapp/message.go
generated
vendored
@@ -23,64 +23,53 @@ const (
|
||||
MediaDocument MediaType = "WhatsApp Document Keys"
|
||||
)
|
||||
|
||||
var msgInfo MessageInfo
|
||||
|
||||
func (wac *Conn) Send(msg interface{}) (string, error) {
|
||||
var err error
|
||||
var ch <-chan string
|
||||
var msgProto *proto.WebMessageInfo
|
||||
|
||||
switch m := msg.(type) {
|
||||
case *proto.WebMessageInfo:
|
||||
ch, err = wac.sendProto(m)
|
||||
msgProto = m
|
||||
case TextMessage:
|
||||
msgProto = getTextProto(m)
|
||||
msgInfo = getMessageInfo(msgProto)
|
||||
ch, err = wac.sendProto(msgProto)
|
||||
case ImageMessage:
|
||||
var err error
|
||||
m.url, m.mediaKey, m.fileEncSha256, m.fileSha256, m.fileLength, err = wac.Upload(m.Content, MediaImage)
|
||||
if err != nil {
|
||||
return "ERROR", fmt.Errorf("image upload failed: %v", err)
|
||||
}
|
||||
msgProto = getImageProto(m)
|
||||
msgInfo = getMessageInfo(msgProto)
|
||||
ch, err = wac.sendProto(msgProto)
|
||||
case VideoMessage:
|
||||
var err error
|
||||
m.url, m.mediaKey, m.fileEncSha256, m.fileSha256, m.fileLength, err = wac.Upload(m.Content, MediaVideo)
|
||||
if err != nil {
|
||||
return "ERROR", fmt.Errorf("video upload failed: %v", err)
|
||||
}
|
||||
msgProto = getVideoProto(m)
|
||||
msgInfo = getMessageInfo(msgProto)
|
||||
ch, err = wac.sendProto(msgProto)
|
||||
case DocumentMessage:
|
||||
var err error
|
||||
m.url, m.mediaKey, m.fileEncSha256, m.fileSha256, m.fileLength, err = wac.Upload(m.Content, MediaDocument)
|
||||
if err != nil {
|
||||
return "ERROR", fmt.Errorf("document upload failed: %v", err)
|
||||
}
|
||||
msgProto = getDocumentProto(m)
|
||||
msgInfo = getMessageInfo(msgProto)
|
||||
ch, err = wac.sendProto(msgProto)
|
||||
case AudioMessage:
|
||||
var err error
|
||||
m.url, m.mediaKey, m.fileEncSha256, m.fileSha256, m.fileLength, err = wac.Upload(m.Content, MediaAudio)
|
||||
if err != nil {
|
||||
return "ERROR", fmt.Errorf("audio upload failed: %v", err)
|
||||
}
|
||||
msgProto = getAudioProto(m)
|
||||
msgInfo = getMessageInfo(msgProto)
|
||||
ch, err = wac.sendProto(msgProto)
|
||||
case LocationMessage:
|
||||
msgProto = GetLocationProto(m)
|
||||
msgInfo = getMessageInfo(msgProto)
|
||||
ch, err = wac.sendProto(msgProto)
|
||||
case LiveLocationMessage:
|
||||
msgProto = GetLiveLocationProto(m)
|
||||
msgInfo = getMessageInfo(msgProto)
|
||||
ch, err = wac.sendProto(msgProto)
|
||||
case ContactMessage:
|
||||
msgProto = getContactMessageProto(m)
|
||||
default:
|
||||
return "ERROR", fmt.Errorf("cannot match type %T, use message types declared in the package", msg)
|
||||
}
|
||||
|
||||
ch, err := wac.sendProto(msgProto)
|
||||
if err != nil {
|
||||
return "ERROR", fmt.Errorf("could not send proto: %v", err)
|
||||
}
|
||||
@@ -95,7 +84,7 @@ func (wac *Conn) Send(msg interface{}) (string, error) {
|
||||
return "ERROR", fmt.Errorf("message sending responded with %d", resp["status"])
|
||||
}
|
||||
if int(resp["status"].(float64)) == 200 {
|
||||
return msgInfo.Id, nil
|
||||
return getMessageInfo(msgProto).Id, nil
|
||||
}
|
||||
case <-time.After(wac.msgTimeout):
|
||||
return "ERROR", fmt.Errorf("sending message timed out")
|
||||
@@ -124,15 +113,13 @@ func init() {
|
||||
MessageInfo contains general message information. It is part of every of every message type.
|
||||
*/
|
||||
type MessageInfo struct {
|
||||
Id string
|
||||
RemoteJid string
|
||||
SenderJid string
|
||||
FromMe bool
|
||||
Timestamp uint64
|
||||
PushName string
|
||||
Status MessageStatus
|
||||
QuotedMessageID string
|
||||
QuotedMessage proto.Message
|
||||
Id string
|
||||
RemoteJid string
|
||||
SenderJid string
|
||||
FromMe bool
|
||||
Timestamp uint64
|
||||
PushName string
|
||||
Status MessageStatus
|
||||
|
||||
Source *proto.WebMessageInfo
|
||||
}
|
||||
@@ -185,14 +172,35 @@ func getInfoProto(info *MessageInfo) *proto.WebMessageInfo {
|
||||
}
|
||||
}
|
||||
|
||||
func getContextInfoProto(info *MessageInfo) *proto.ContextInfo {
|
||||
if len(info.QuotedMessageID) > 0 {
|
||||
/*
|
||||
ContextInfo represents contextinfo of every message
|
||||
*/
|
||||
type ContextInfo struct {
|
||||
QuotedMessageID string //StanzaId
|
||||
QuotedMessage *proto.Message
|
||||
Participant string
|
||||
IsForwarded bool
|
||||
}
|
||||
|
||||
func getMessageContext(msg *proto.ContextInfo) ContextInfo {
|
||||
|
||||
return ContextInfo{
|
||||
QuotedMessageID: msg.GetStanzaId(), //StanzaId
|
||||
QuotedMessage: msg.GetQuotedMessage(),
|
||||
Participant: msg.GetParticipant(),
|
||||
IsForwarded: msg.GetIsForwarded(),
|
||||
}
|
||||
}
|
||||
|
||||
func getContextInfoProto(context *ContextInfo) *proto.ContextInfo {
|
||||
if len(context.QuotedMessageID) > 0 {
|
||||
contextInfo := &proto.ContextInfo{
|
||||
StanzaId: &info.QuotedMessageID,
|
||||
StanzaId: &context.QuotedMessageID,
|
||||
}
|
||||
|
||||
if &info.QuotedMessage != nil {
|
||||
contextInfo.QuotedMessage = &info.QuotedMessage
|
||||
if &context.QuotedMessage != nil {
|
||||
contextInfo.QuotedMessage = context.QuotedMessage
|
||||
contextInfo.Participant = &context.Participant
|
||||
}
|
||||
|
||||
return contextInfo
|
||||
@@ -205,24 +213,28 @@ func getContextInfoProto(info *MessageInfo) *proto.ContextInfo {
|
||||
TextMessage represents a text message.
|
||||
*/
|
||||
type TextMessage struct {
|
||||
Info MessageInfo
|
||||
Text string
|
||||
Info MessageInfo
|
||||
Text string
|
||||
ContextInfo ContextInfo
|
||||
}
|
||||
|
||||
func getTextMessage(msg *proto.WebMessageInfo) TextMessage {
|
||||
text := TextMessage{Info: getMessageInfo(msg)}
|
||||
if m := msg.GetMessage().GetExtendedTextMessage(); m != nil {
|
||||
text.Text = m.GetText()
|
||||
text.Info.QuotedMessageID = m.GetContextInfo().GetStanzaId()
|
||||
|
||||
text.ContextInfo = getMessageContext(m.GetContextInfo())
|
||||
} else {
|
||||
text.Text = msg.GetMessage().GetConversation()
|
||||
|
||||
}
|
||||
|
||||
return text
|
||||
}
|
||||
|
||||
func getTextProto(msg TextMessage) *proto.WebMessageInfo {
|
||||
p := getInfoProto(&msg.Info)
|
||||
contextInfo := getContextInfoProto(&msg.Info)
|
||||
contextInfo := getContextInfoProto(&msg.ContextInfo)
|
||||
|
||||
if contextInfo == nil {
|
||||
p.Message = &proto.Message{
|
||||
@@ -255,6 +267,7 @@ type ImageMessage struct {
|
||||
fileEncSha256 []byte
|
||||
fileSha256 []byte
|
||||
fileLength uint64
|
||||
ContextInfo ContextInfo
|
||||
}
|
||||
|
||||
func getImageMessage(msg *proto.WebMessageInfo) ImageMessage {
|
||||
@@ -270,10 +283,7 @@ func getImageMessage(msg *proto.WebMessageInfo) ImageMessage {
|
||||
fileEncSha256: image.GetFileEncSha256(),
|
||||
fileSha256: image.GetFileSha256(),
|
||||
fileLength: image.GetFileLength(),
|
||||
}
|
||||
|
||||
if contextInfo := image.GetContextInfo(); contextInfo != nil {
|
||||
imageMessage.Info.QuotedMessageID = contextInfo.GetStanzaId()
|
||||
ContextInfo: getMessageContext(image.GetContextInfo()),
|
||||
}
|
||||
|
||||
return imageMessage
|
||||
@@ -281,7 +291,7 @@ func getImageMessage(msg *proto.WebMessageInfo) ImageMessage {
|
||||
|
||||
func getImageProto(msg ImageMessage) *proto.WebMessageInfo {
|
||||
p := getInfoProto(&msg.Info)
|
||||
contextInfo := getContextInfoProto(&msg.Info)
|
||||
contextInfo := getContextInfoProto(&msg.ContextInfo)
|
||||
|
||||
p.Message = &proto.Message{
|
||||
ImageMessage: &proto.ImageMessage{
|
||||
@@ -323,6 +333,7 @@ type VideoMessage struct {
|
||||
fileEncSha256 []byte
|
||||
fileSha256 []byte
|
||||
fileLength uint64
|
||||
ContextInfo ContextInfo
|
||||
}
|
||||
|
||||
func getVideoMessage(msg *proto.WebMessageInfo) VideoMessage {
|
||||
@@ -340,10 +351,7 @@ func getVideoMessage(msg *proto.WebMessageInfo) VideoMessage {
|
||||
fileEncSha256: vid.GetFileEncSha256(),
|
||||
fileSha256: vid.GetFileSha256(),
|
||||
fileLength: vid.GetFileLength(),
|
||||
}
|
||||
|
||||
if contextInfo := vid.GetContextInfo(); contextInfo != nil {
|
||||
videoMessage.Info.QuotedMessageID = contextInfo.GetStanzaId()
|
||||
ContextInfo: getMessageContext(vid.GetContextInfo()),
|
||||
}
|
||||
|
||||
return videoMessage
|
||||
@@ -351,7 +359,7 @@ func getVideoMessage(msg *proto.WebMessageInfo) VideoMessage {
|
||||
|
||||
func getVideoProto(msg VideoMessage) *proto.WebMessageInfo {
|
||||
p := getInfoProto(&msg.Info)
|
||||
contextInfo := getContextInfoProto(&msg.Info)
|
||||
contextInfo := getContextInfoProto(&msg.ContextInfo)
|
||||
|
||||
p.Message = &proto.Message{
|
||||
VideoMessage: &proto.VideoMessage{
|
||||
@@ -393,6 +401,7 @@ type AudioMessage struct {
|
||||
fileEncSha256 []byte
|
||||
fileSha256 []byte
|
||||
fileLength uint64
|
||||
ContextInfo ContextInfo
|
||||
}
|
||||
|
||||
func getAudioMessage(msg *proto.WebMessageInfo) AudioMessage {
|
||||
@@ -407,10 +416,7 @@ func getAudioMessage(msg *proto.WebMessageInfo) AudioMessage {
|
||||
fileEncSha256: aud.GetFileEncSha256(),
|
||||
fileSha256: aud.GetFileSha256(),
|
||||
fileLength: aud.GetFileLength(),
|
||||
}
|
||||
|
||||
if contextInfo := aud.GetContextInfo(); contextInfo != nil {
|
||||
audioMessage.Info.QuotedMessageID = contextInfo.GetStanzaId()
|
||||
ContextInfo: getMessageContext(aud.GetContextInfo()),
|
||||
}
|
||||
|
||||
return audioMessage
|
||||
@@ -418,7 +424,7 @@ func getAudioMessage(msg *proto.WebMessageInfo) AudioMessage {
|
||||
|
||||
func getAudioProto(msg AudioMessage) *proto.WebMessageInfo {
|
||||
p := getInfoProto(&msg.Info)
|
||||
contextInfo := getContextInfoProto(&msg.Info)
|
||||
contextInfo := getContextInfoProto(&msg.ContextInfo)
|
||||
p.Message = &proto.Message{
|
||||
AudioMessage: &proto.AudioMessage{
|
||||
Url: &msg.url,
|
||||
@@ -459,6 +465,7 @@ type DocumentMessage struct {
|
||||
fileEncSha256 []byte
|
||||
fileSha256 []byte
|
||||
fileLength uint64
|
||||
ContextInfo ContextInfo
|
||||
}
|
||||
|
||||
func getDocumentMessage(msg *proto.WebMessageInfo) DocumentMessage {
|
||||
@@ -476,10 +483,7 @@ func getDocumentMessage(msg *proto.WebMessageInfo) DocumentMessage {
|
||||
fileEncSha256: doc.GetFileEncSha256(),
|
||||
fileSha256: doc.GetFileSha256(),
|
||||
fileLength: doc.GetFileLength(),
|
||||
}
|
||||
|
||||
if contextInfo := doc.GetContextInfo(); contextInfo != nil {
|
||||
documentMessage.Info.QuotedMessageID = contextInfo.GetStanzaId()
|
||||
ContextInfo: getMessageContext(doc.GetContextInfo()),
|
||||
}
|
||||
|
||||
return documentMessage
|
||||
@@ -487,7 +491,7 @@ func getDocumentMessage(msg *proto.WebMessageInfo) DocumentMessage {
|
||||
|
||||
func getDocumentProto(msg DocumentMessage) *proto.WebMessageInfo {
|
||||
p := getInfoProto(&msg.Info)
|
||||
contextInfo := getContextInfoProto(&msg.Info)
|
||||
contextInfo := getContextInfoProto(&msg.ContextInfo)
|
||||
p.Message = &proto.Message{
|
||||
DocumentMessage: &proto.DocumentMessage{
|
||||
JpegThumbnail: msg.Thumbnail,
|
||||
@@ -523,6 +527,7 @@ type LocationMessage struct {
|
||||
Address string
|
||||
Url string
|
||||
JpegThumbnail []byte
|
||||
ContextInfo ContextInfo
|
||||
}
|
||||
|
||||
func GetLocationMessage(msg *proto.WebMessageInfo) LocationMessage {
|
||||
@@ -536,10 +541,7 @@ func GetLocationMessage(msg *proto.WebMessageInfo) LocationMessage {
|
||||
Address: loc.GetAddress(),
|
||||
Url: loc.GetUrl(),
|
||||
JpegThumbnail: loc.GetJpegThumbnail(),
|
||||
}
|
||||
|
||||
if contextInfo := loc.GetContextInfo(); contextInfo != nil {
|
||||
locationMessage.Info.QuotedMessageID = contextInfo.GetStanzaId()
|
||||
ContextInfo: getMessageContext(loc.GetContextInfo()),
|
||||
}
|
||||
|
||||
return locationMessage
|
||||
@@ -547,7 +549,7 @@ func GetLocationMessage(msg *proto.WebMessageInfo) LocationMessage {
|
||||
|
||||
func GetLocationProto(msg LocationMessage) *proto.WebMessageInfo {
|
||||
p := getInfoProto(&msg.Info)
|
||||
contextInfo := getContextInfoProto(&msg.Info)
|
||||
contextInfo := getContextInfoProto(&msg.ContextInfo)
|
||||
|
||||
p.Message = &proto.Message{
|
||||
LocationMessage: &proto.LocationMessage{
|
||||
@@ -576,6 +578,7 @@ type LiveLocationMessage struct {
|
||||
Caption string
|
||||
SequenceNumber int64
|
||||
JpegThumbnail []byte
|
||||
ContextInfo ContextInfo
|
||||
}
|
||||
|
||||
func GetLiveLocationMessage(msg *proto.WebMessageInfo) LiveLocationMessage {
|
||||
@@ -591,10 +594,7 @@ func GetLiveLocationMessage(msg *proto.WebMessageInfo) LiveLocationMessage {
|
||||
Caption: loc.GetCaption(),
|
||||
SequenceNumber: loc.GetSequenceNumber(),
|
||||
JpegThumbnail: loc.GetJpegThumbnail(),
|
||||
}
|
||||
|
||||
if contextInfo := loc.GetContextInfo(); contextInfo != nil {
|
||||
liveLocationMessage.Info.QuotedMessageID = contextInfo.GetStanzaId()
|
||||
ContextInfo: getMessageContext(loc.GetContextInfo()),
|
||||
}
|
||||
|
||||
return liveLocationMessage
|
||||
@@ -602,7 +602,7 @@ func GetLiveLocationMessage(msg *proto.WebMessageInfo) LiveLocationMessage {
|
||||
|
||||
func GetLiveLocationProto(msg LiveLocationMessage) *proto.WebMessageInfo {
|
||||
p := getInfoProto(&msg.Info)
|
||||
contextInfo := getContextInfoProto(&msg.Info)
|
||||
contextInfo := getContextInfoProto(&msg.ContextInfo)
|
||||
p.Message = &proto.Message{
|
||||
LiveLocationMessage: &proto.LiveLocationMessage{
|
||||
DegreesLatitude: &msg.DegreesLatitude,
|
||||
@@ -625,7 +625,6 @@ StickerMessage represents a sticker message.
|
||||
type StickerMessage struct {
|
||||
Info MessageInfo
|
||||
|
||||
Thumbnail []byte
|
||||
Type string
|
||||
Content io.Reader
|
||||
url string
|
||||
@@ -633,30 +632,79 @@ type StickerMessage struct {
|
||||
fileEncSha256 []byte
|
||||
fileSha256 []byte
|
||||
fileLength uint64
|
||||
|
||||
ContextInfo ContextInfo
|
||||
}
|
||||
|
||||
func getStickerMessage(msg *proto.WebMessageInfo) StickerMessage {
|
||||
sticker := msg.GetMessage().GetStickerMessage()
|
||||
|
||||
StickerMessage := StickerMessage{
|
||||
stickerMessage := StickerMessage{
|
||||
Info: getMessageInfo(msg),
|
||||
Thumbnail: sticker.GetPngThumbnail(),
|
||||
url: sticker.GetUrl(),
|
||||
mediaKey: sticker.GetMediaKey(),
|
||||
Type: sticker.GetMimetype(),
|
||||
fileEncSha256: sticker.GetFileEncSha256(),
|
||||
fileSha256: sticker.GetFileSha256(),
|
||||
fileLength: sticker.GetFileLength(),
|
||||
ContextInfo: getMessageContext(sticker.GetContextInfo()),
|
||||
}
|
||||
|
||||
if contextInfo := sticker.GetContextInfo(); contextInfo != nil {
|
||||
StickerMessage.Info.QuotedMessageID = contextInfo.GetStanzaId()
|
||||
return stickerMessage
|
||||
}
|
||||
|
||||
/*
|
||||
Download is the function to retrieve Sticker media data. The media gets downloaded, validated and returned.
|
||||
*/
|
||||
|
||||
func (m *StickerMessage) Download() ([]byte, error) {
|
||||
return Download(m.url, m.mediaKey, MediaImage, int(m.fileLength))
|
||||
}
|
||||
|
||||
/*
|
||||
ContactMessage represents a contact message.
|
||||
*/
|
||||
type ContactMessage struct {
|
||||
Info MessageInfo
|
||||
|
||||
DisplayName string
|
||||
Vcard string
|
||||
|
||||
ContextInfo ContextInfo
|
||||
}
|
||||
|
||||
func getContactMessage(msg *proto.WebMessageInfo) ContactMessage {
|
||||
contact := msg.GetMessage().GetContactMessage()
|
||||
|
||||
contactMessage := ContactMessage{
|
||||
Info: getMessageInfo(msg),
|
||||
|
||||
DisplayName: contact.GetDisplayName(),
|
||||
Vcard: contact.GetVcard(),
|
||||
|
||||
ContextInfo: getMessageContext(contact.GetContextInfo()),
|
||||
}
|
||||
|
||||
return StickerMessage
|
||||
return contactMessage
|
||||
}
|
||||
|
||||
func getContactMessageProto(msg ContactMessage) *proto.WebMessageInfo {
|
||||
p := getInfoProto(&msg.Info)
|
||||
contextInfo := getContextInfoProto(&msg.ContextInfo)
|
||||
|
||||
p.Message = &proto.Message{
|
||||
ContactMessage: &proto.ContactMessage{
|
||||
DisplayName: &msg.DisplayName,
|
||||
Vcard: &msg.Vcard,
|
||||
ContextInfo: contextInfo,
|
||||
},
|
||||
}
|
||||
|
||||
return p
|
||||
}
|
||||
|
||||
func ParseProtoMessage(msg *proto.WebMessageInfo) interface{} {
|
||||
|
||||
switch {
|
||||
|
||||
case msg.GetMessage().GetAudioMessage() != nil:
|
||||
@@ -686,8 +734,12 @@ func ParseProtoMessage(msg *proto.WebMessageInfo) interface{} {
|
||||
case msg.GetMessage().GetStickerMessage() != nil:
|
||||
return getStickerMessage(msg)
|
||||
|
||||
case msg.GetMessage().GetContactMessage() != nil:
|
||||
return getContactMessage(msg)
|
||||
|
||||
default:
|
||||
//cannot match message
|
||||
|
||||
}
|
||||
|
||||
return nil
|
||||
|
43
vendor/github.com/Rhymen/go-whatsapp/profile.go
generated
vendored
Normal file
43
vendor/github.com/Rhymen/go-whatsapp/profile.go
generated
vendored
Normal file
@@ -0,0 +1,43 @@
|
||||
package whatsapp
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/Rhymen/go-whatsapp/binary"
|
||||
"strconv"
|
||||
"time"
|
||||
)
|
||||
|
||||
// Pictures must be JPG 640x640 and 96x96, respectively
|
||||
func (wac *Conn) UploadProfilePic(image, preview []byte) (<-chan string, error) {
|
||||
tag := fmt.Sprintf("%d.--%d", time.Now().Unix(), wac.msgCount*19)
|
||||
n := binary.Node{
|
||||
Description: "action",
|
||||
Attributes: map[string]string{
|
||||
"type": "set",
|
||||
"epoch": strconv.Itoa(wac.msgCount),
|
||||
},
|
||||
Content: []interface{}{
|
||||
binary.Node{
|
||||
Description: "picture",
|
||||
Attributes: map[string]string{
|
||||
"id": tag,
|
||||
"jid": wac.Info.Wid,
|
||||
"type": "set",
|
||||
},
|
||||
Content: []binary.Node{
|
||||
{
|
||||
Description: "image",
|
||||
Attributes: nil,
|
||||
Content: image,
|
||||
},
|
||||
{
|
||||
Description: "preview",
|
||||
Attributes: nil,
|
||||
Content: preview,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
return wac.writeBinary(n, profile, 136, tag)
|
||||
}
|
13
vendor/github.com/Rhymen/go-whatsapp/write.go
generated
vendored
13
vendor/github.com/Rhymen/go-whatsapp/write.go
generated
vendored
@@ -5,16 +5,22 @@ import (
|
||||
"crypto/sha256"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"strconv"
|
||||
|
||||
"time"
|
||||
|
||||
"github.com/Rhymen/go-whatsapp/binary"
|
||||
"github.com/Rhymen/go-whatsapp/crypto/cbc"
|
||||
"github.com/gorilla/websocket"
|
||||
"github.com/pkg/errors"
|
||||
"strconv"
|
||||
"time"
|
||||
)
|
||||
|
||||
//writeJson enqueues a json message into the writeChan
|
||||
func (wac *Conn) writeJson(data []interface{}) (<-chan string, error) {
|
||||
|
||||
wac.writerLock.Lock()
|
||||
defer wac.writerLock.Unlock()
|
||||
|
||||
d, err := json.Marshal(data)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -38,6 +44,9 @@ func (wac *Conn) writeBinary(node binary.Node, metric metric, flag flag, message
|
||||
return nil, ErrMissingMessageTag
|
||||
}
|
||||
|
||||
wac.writerLock.Lock()
|
||||
defer wac.writerLock.Unlock()
|
||||
|
||||
data, err := wac.encryptBinaryMessage(node)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "encryptBinaryMessage(node) failed")
|
||||
|
17
vendor/github.com/d5/tengo/.travis.yml
generated
vendored
17
vendor/github.com/d5/tengo/.travis.yml
generated
vendored
@@ -1,17 +0,0 @@
|
||||
language: go
|
||||
|
||||
go:
|
||||
- "1.12"
|
||||
|
||||
install:
|
||||
- env GO111MODULE=on go get -u golang.org/x/lint/golint
|
||||
|
||||
script:
|
||||
- env GO111MODULE=on make test
|
||||
|
||||
deploy:
|
||||
- provider: script
|
||||
skip_cleanup: true
|
||||
script: curl -sL https://git.io/goreleaser | bash
|
||||
on:
|
||||
tags: true
|
35
vendor/github.com/d5/tengo/compiler/ast/array_lit.go
generated
vendored
35
vendor/github.com/d5/tengo/compiler/ast/array_lit.go
generated
vendored
@@ -1,35 +0,0 @@
|
||||
package ast
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"github.com/d5/tengo/compiler/source"
|
||||
)
|
||||
|
||||
// ArrayLit represents an array literal.
|
||||
type ArrayLit struct {
|
||||
Elements []Expr
|
||||
LBrack source.Pos
|
||||
RBrack source.Pos
|
||||
}
|
||||
|
||||
func (e *ArrayLit) exprNode() {}
|
||||
|
||||
// Pos returns the position of first character belonging to the node.
|
||||
func (e *ArrayLit) Pos() source.Pos {
|
||||
return e.LBrack
|
||||
}
|
||||
|
||||
// End returns the position of first character immediately after the node.
|
||||
func (e *ArrayLit) End() source.Pos {
|
||||
return e.RBrack + 1
|
||||
}
|
||||
|
||||
func (e *ArrayLit) String() string {
|
||||
var elements []string
|
||||
for _, m := range e.Elements {
|
||||
elements = append(elements, m.String())
|
||||
}
|
||||
|
||||
return "[" + strings.Join(elements, ", ") + "]"
|
||||
}
|
40
vendor/github.com/d5/tengo/compiler/ast/assign_stmt.go
generated
vendored
40
vendor/github.com/d5/tengo/compiler/ast/assign_stmt.go
generated
vendored
@@ -1,40 +0,0 @@
|
||||
package ast
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"github.com/d5/tengo/compiler/source"
|
||||
"github.com/d5/tengo/compiler/token"
|
||||
)
|
||||
|
||||
// AssignStmt represents an assignment statement.
|
||||
type AssignStmt struct {
|
||||
LHS []Expr
|
||||
RHS []Expr
|
||||
Token token.Token
|
||||
TokenPos source.Pos
|
||||
}
|
||||
|
||||
func (s *AssignStmt) stmtNode() {}
|
||||
|
||||
// Pos returns the position of first character belonging to the node.
|
||||
func (s *AssignStmt) Pos() source.Pos {
|
||||
return s.LHS[0].Pos()
|
||||
}
|
||||
|
||||
// End returns the position of first character immediately after the node.
|
||||
func (s *AssignStmt) End() source.Pos {
|
||||
return s.RHS[len(s.RHS)-1].End()
|
||||
}
|
||||
|
||||
func (s *AssignStmt) String() string {
|
||||
var lhs, rhs []string
|
||||
for _, e := range s.LHS {
|
||||
lhs = append(lhs, e.String())
|
||||
}
|
||||
for _, e := range s.RHS {
|
||||
rhs = append(rhs, e.String())
|
||||
}
|
||||
|
||||
return strings.Join(lhs, ", ") + " " + s.Token.String() + " " + strings.Join(rhs, ", ")
|
||||
}
|
5
vendor/github.com/d5/tengo/compiler/ast/ast.go
generated
vendored
5
vendor/github.com/d5/tengo/compiler/ast/ast.go
generated
vendored
@@ -1,5 +0,0 @@
|
||||
package ast
|
||||
|
||||
const (
|
||||
nullRep = "<null>"
|
||||
)
|
25
vendor/github.com/d5/tengo/compiler/ast/bad_expr.go
generated
vendored
25
vendor/github.com/d5/tengo/compiler/ast/bad_expr.go
generated
vendored
@@ -1,25 +0,0 @@
|
||||
package ast
|
||||
|
||||
import "github.com/d5/tengo/compiler/source"
|
||||
|
||||
// BadExpr represents a bad expression.
|
||||
type BadExpr struct {
|
||||
From source.Pos
|
||||
To source.Pos
|
||||
}
|
||||
|
||||
func (e *BadExpr) exprNode() {}
|
||||
|
||||
// Pos returns the position of first character belonging to the node.
|
||||
func (e *BadExpr) Pos() source.Pos {
|
||||
return e.From
|
||||
}
|
||||
|
||||
// End returns the position of first character immediately after the node.
|
||||
func (e *BadExpr) End() source.Pos {
|
||||
return e.To
|
||||
}
|
||||
|
||||
func (e *BadExpr) String() string {
|
||||
return "<bad expression>"
|
||||
}
|
25
vendor/github.com/d5/tengo/compiler/ast/bad_stmt.go
generated
vendored
25
vendor/github.com/d5/tengo/compiler/ast/bad_stmt.go
generated
vendored
@@ -1,25 +0,0 @@
|
||||
package ast
|
||||
|
||||
import "github.com/d5/tengo/compiler/source"
|
||||
|
||||
// BadStmt represents a bad statement.
|
||||
type BadStmt struct {
|
||||
From source.Pos
|
||||
To source.Pos
|
||||
}
|
||||
|
||||
func (s *BadStmt) stmtNode() {}
|
||||
|
||||
// Pos returns the position of first character belonging to the node.
|
||||
func (s *BadStmt) Pos() source.Pos {
|
||||
return s.From
|
||||
}
|
||||
|
||||
// End returns the position of first character immediately after the node.
|
||||
func (s *BadStmt) End() source.Pos {
|
||||
return s.To
|
||||
}
|
||||
|
||||
func (s *BadStmt) String() string {
|
||||
return "<bad statement>"
|
||||
}
|
30
vendor/github.com/d5/tengo/compiler/ast/binary_expr.go
generated
vendored
30
vendor/github.com/d5/tengo/compiler/ast/binary_expr.go
generated
vendored
@@ -1,30 +0,0 @@
|
||||
package ast
|
||||
|
||||
import (
|
||||
"github.com/d5/tengo/compiler/source"
|
||||
"github.com/d5/tengo/compiler/token"
|
||||
)
|
||||
|
||||
// BinaryExpr represents a binary operator expression.
|
||||
type BinaryExpr struct {
|
||||
LHS Expr
|
||||
RHS Expr
|
||||
Token token.Token
|
||||
TokenPos source.Pos
|
||||
}
|
||||
|
||||
func (e *BinaryExpr) exprNode() {}
|
||||
|
||||
// Pos returns the position of first character belonging to the node.
|
||||
func (e *BinaryExpr) Pos() source.Pos {
|
||||
return e.LHS.Pos()
|
||||
}
|
||||
|
||||
// End returns the position of first character immediately after the node.
|
||||
func (e *BinaryExpr) End() source.Pos {
|
||||
return e.RHS.End()
|
||||
}
|
||||
|
||||
func (e *BinaryExpr) String() string {
|
||||
return "(" + e.LHS.String() + " " + e.Token.String() + " " + e.RHS.String() + ")"
|
||||
}
|
35
vendor/github.com/d5/tengo/compiler/ast/block_stmt.go
generated
vendored
35
vendor/github.com/d5/tengo/compiler/ast/block_stmt.go
generated
vendored
@@ -1,35 +0,0 @@
|
||||
package ast
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"github.com/d5/tengo/compiler/source"
|
||||
)
|
||||
|
||||
// BlockStmt represents a block statement.
|
||||
type BlockStmt struct {
|
||||
Stmts []Stmt
|
||||
LBrace source.Pos
|
||||
RBrace source.Pos
|
||||
}
|
||||
|
||||
func (s *BlockStmt) stmtNode() {}
|
||||
|
||||
// Pos returns the position of first character belonging to the node.
|
||||
func (s *BlockStmt) Pos() source.Pos {
|
||||
return s.LBrace
|
||||
}
|
||||
|
||||
// End returns the position of first character immediately after the node.
|
||||
func (s *BlockStmt) End() source.Pos {
|
||||
return s.RBrace + 1
|
||||
}
|
||||
|
||||
func (s *BlockStmt) String() string {
|
||||
var list []string
|
||||
for _, e := range s.Stmts {
|
||||
list = append(list, e.String())
|
||||
}
|
||||
|
||||
return "{" + strings.Join(list, "; ") + "}"
|
||||
}
|
26
vendor/github.com/d5/tengo/compiler/ast/bool_lit.go
generated
vendored
26
vendor/github.com/d5/tengo/compiler/ast/bool_lit.go
generated
vendored
@@ -1,26 +0,0 @@
|
||||
package ast
|
||||
|
||||
import "github.com/d5/tengo/compiler/source"
|
||||
|
||||
// BoolLit represents a boolean literal.
|
||||
type BoolLit struct {
|
||||
Value bool
|
||||
ValuePos source.Pos
|
||||
Literal string
|
||||
}
|
||||
|
||||
func (e *BoolLit) exprNode() {}
|
||||
|
||||
// Pos returns the position of first character belonging to the node.
|
||||
func (e *BoolLit) Pos() source.Pos {
|
||||
return e.ValuePos
|
||||
}
|
||||
|
||||
// End returns the position of first character immediately after the node.
|
||||
func (e *BoolLit) End() source.Pos {
|
||||
return source.Pos(int(e.ValuePos) + len(e.Literal))
|
||||
}
|
||||
|
||||
func (e *BoolLit) String() string {
|
||||
return e.Literal
|
||||
}
|
38
vendor/github.com/d5/tengo/compiler/ast/branch_stmt.go
generated
vendored
38
vendor/github.com/d5/tengo/compiler/ast/branch_stmt.go
generated
vendored
@@ -1,38 +0,0 @@
|
||||
package ast
|
||||
|
||||
import (
|
||||
"github.com/d5/tengo/compiler/source"
|
||||
"github.com/d5/tengo/compiler/token"
|
||||
)
|
||||
|
||||
// BranchStmt represents a branch statement.
|
||||
type BranchStmt struct {
|
||||
Token token.Token
|
||||
TokenPos source.Pos
|
||||
Label *Ident
|
||||
}
|
||||
|
||||
func (s *BranchStmt) stmtNode() {}
|
||||
|
||||
// Pos returns the position of first character belonging to the node.
|
||||
func (s *BranchStmt) Pos() source.Pos {
|
||||
return s.TokenPos
|
||||
}
|
||||
|
||||
// End returns the position of first character immediately after the node.
|
||||
func (s *BranchStmt) End() source.Pos {
|
||||
if s.Label != nil {
|
||||
return s.Label.End()
|
||||
}
|
||||
|
||||
return source.Pos(int(s.TokenPos) + len(s.Token.String()))
|
||||
}
|
||||
|
||||
func (s *BranchStmt) String() string {
|
||||
var label string
|
||||
if s.Label != nil {
|
||||
label = " " + s.Label.Name
|
||||
}
|
||||
|
||||
return s.Token.String() + label
|
||||
}
|
36
vendor/github.com/d5/tengo/compiler/ast/call_expr.go
generated
vendored
36
vendor/github.com/d5/tengo/compiler/ast/call_expr.go
generated
vendored
@@ -1,36 +0,0 @@
|
||||
package ast
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"github.com/d5/tengo/compiler/source"
|
||||
)
|
||||
|
||||
// CallExpr represents a function call expression.
|
||||
type CallExpr struct {
|
||||
Func Expr
|
||||
LParen source.Pos
|
||||
Args []Expr
|
||||
RParen source.Pos
|
||||
}
|
||||
|
||||
func (e *CallExpr) exprNode() {}
|
||||
|
||||
// Pos returns the position of first character belonging to the node.
|
||||
func (e *CallExpr) Pos() source.Pos {
|
||||
return e.Func.Pos()
|
||||
}
|
||||
|
||||
// End returns the position of first character immediately after the node.
|
||||
func (e *CallExpr) End() source.Pos {
|
||||
return e.RParen + 1
|
||||
}
|
||||
|
||||
func (e *CallExpr) String() string {
|
||||
var args []string
|
||||
for _, e := range e.Args {
|
||||
args = append(args, e.String())
|
||||
}
|
||||
|
||||
return e.Func.String() + "(" + strings.Join(args, ", ") + ")"
|
||||
}
|
26
vendor/github.com/d5/tengo/compiler/ast/char_lit.go
generated
vendored
26
vendor/github.com/d5/tengo/compiler/ast/char_lit.go
generated
vendored
@@ -1,26 +0,0 @@
|
||||
package ast
|
||||
|
||||
import "github.com/d5/tengo/compiler/source"
|
||||
|
||||
// CharLit represents a character literal.
|
||||
type CharLit struct {
|
||||
Value rune
|
||||
ValuePos source.Pos
|
||||
Literal string
|
||||
}
|
||||
|
||||
func (e *CharLit) exprNode() {}
|
||||
|
||||
// Pos returns the position of first character belonging to the node.
|
||||
func (e *CharLit) Pos() source.Pos {
|
||||
return e.ValuePos
|
||||
}
|
||||
|
||||
// End returns the position of first character immediately after the node.
|
||||
func (e *CharLit) End() source.Pos {
|
||||
return source.Pos(int(e.ValuePos) + len(e.Literal))
|
||||
}
|
||||
|
||||
func (e *CharLit) String() string {
|
||||
return e.Literal
|
||||
}
|
30
vendor/github.com/d5/tengo/compiler/ast/cond_expr.go
generated
vendored
30
vendor/github.com/d5/tengo/compiler/ast/cond_expr.go
generated
vendored
@@ -1,30 +0,0 @@
|
||||
package ast
|
||||
|
||||
import (
|
||||
"github.com/d5/tengo/compiler/source"
|
||||
)
|
||||
|
||||
// CondExpr represents a ternary conditional expression.
|
||||
type CondExpr struct {
|
||||
Cond Expr
|
||||
True Expr
|
||||
False Expr
|
||||
QuestionPos source.Pos
|
||||
ColonPos source.Pos
|
||||
}
|
||||
|
||||
func (e *CondExpr) exprNode() {}
|
||||
|
||||
// Pos returns the position of first character belonging to the node.
|
||||
func (e *CondExpr) Pos() source.Pos {
|
||||
return e.Cond.Pos()
|
||||
}
|
||||
|
||||
// End returns the position of first character immediately after the node.
|
||||
func (e *CondExpr) End() source.Pos {
|
||||
return e.False.End()
|
||||
}
|
||||
|
||||
func (e *CondExpr) String() string {
|
||||
return "(" + e.Cond.String() + " ? " + e.True.String() + " : " + e.False.String() + ")"
|
||||
}
|
29
vendor/github.com/d5/tengo/compiler/ast/empty_stmt.go
generated
vendored
29
vendor/github.com/d5/tengo/compiler/ast/empty_stmt.go
generated
vendored
@@ -1,29 +0,0 @@
|
||||
package ast
|
||||
|
||||
import "github.com/d5/tengo/compiler/source"
|
||||
|
||||
// EmptyStmt represents an empty statement.
|
||||
type EmptyStmt struct {
|
||||
Semicolon source.Pos
|
||||
Implicit bool
|
||||
}
|
||||
|
||||
func (s *EmptyStmt) stmtNode() {}
|
||||
|
||||
// Pos returns the position of first character belonging to the node.
|
||||
func (s *EmptyStmt) Pos() source.Pos {
|
||||
return s.Semicolon
|
||||
}
|
||||
|
||||
// End returns the position of first character immediately after the node.
|
||||
func (s *EmptyStmt) End() source.Pos {
|
||||
if s.Implicit {
|
||||
return s.Semicolon
|
||||
}
|
||||
|
||||
return s.Semicolon + 1
|
||||
}
|
||||
|
||||
func (s *EmptyStmt) String() string {
|
||||
return ";"
|
||||
}
|
29
vendor/github.com/d5/tengo/compiler/ast/error_expr.go
generated
vendored
29
vendor/github.com/d5/tengo/compiler/ast/error_expr.go
generated
vendored
@@ -1,29 +0,0 @@
|
||||
package ast
|
||||
|
||||
import (
|
||||
"github.com/d5/tengo/compiler/source"
|
||||
)
|
||||
|
||||
// ErrorExpr represents an error expression
|
||||
type ErrorExpr struct {
|
||||
Expr Expr
|
||||
ErrorPos source.Pos
|
||||
LParen source.Pos
|
||||
RParen source.Pos
|
||||
}
|
||||
|
||||
func (e *ErrorExpr) exprNode() {}
|
||||
|
||||
// Pos returns the position of first character belonging to the node.
|
||||
func (e *ErrorExpr) Pos() source.Pos {
|
||||
return e.ErrorPos
|
||||
}
|
||||
|
||||
// End returns the position of first character immediately after the node.
|
||||
func (e *ErrorExpr) End() source.Pos {
|
||||
return e.RParen
|
||||
}
|
||||
|
||||
func (e *ErrorExpr) String() string {
|
||||
return "error(" + e.Expr.String() + ")"
|
||||
}
|
27
vendor/github.com/d5/tengo/compiler/ast/export_stmt.go
generated
vendored
27
vendor/github.com/d5/tengo/compiler/ast/export_stmt.go
generated
vendored
@@ -1,27 +0,0 @@
|
||||
package ast
|
||||
|
||||
import (
|
||||
"github.com/d5/tengo/compiler/source"
|
||||
)
|
||||
|
||||
// ExportStmt represents an export statement.
|
||||
type ExportStmt struct {
|
||||
ExportPos source.Pos
|
||||
Result Expr
|
||||
}
|
||||
|
||||
func (s *ExportStmt) stmtNode() {}
|
||||
|
||||
// Pos returns the position of first character belonging to the node.
|
||||
func (s *ExportStmt) Pos() source.Pos {
|
||||
return s.ExportPos
|
||||
}
|
||||
|
||||
// End returns the position of first character immediately after the node.
|
||||
func (s *ExportStmt) End() source.Pos {
|
||||
return s.Result.End()
|
||||
}
|
||||
|
||||
func (s *ExportStmt) String() string {
|
||||
return "export " + s.Result.String()
|
||||
}
|
7
vendor/github.com/d5/tengo/compiler/ast/expr.go
generated
vendored
7
vendor/github.com/d5/tengo/compiler/ast/expr.go
generated
vendored
@@ -1,7 +0,0 @@
|
||||
package ast
|
||||
|
||||
// Expr represents an expression node in the AST.
|
||||
type Expr interface {
|
||||
Node
|
||||
exprNode()
|
||||
}
|
24
vendor/github.com/d5/tengo/compiler/ast/expr_stmt.go
generated
vendored
24
vendor/github.com/d5/tengo/compiler/ast/expr_stmt.go
generated
vendored
@@ -1,24 +0,0 @@
|
||||
package ast
|
||||
|
||||
import "github.com/d5/tengo/compiler/source"
|
||||
|
||||
// ExprStmt represents an expression statement.
|
||||
type ExprStmt struct {
|
||||
Expr Expr
|
||||
}
|
||||
|
||||
func (s *ExprStmt) stmtNode() {}
|
||||
|
||||
// Pos returns the position of first character belonging to the node.
|
||||
func (s *ExprStmt) Pos() source.Pos {
|
||||
return s.Expr.Pos()
|
||||
}
|
||||
|
||||
// End returns the position of first character immediately after the node.
|
||||
func (s *ExprStmt) End() source.Pos {
|
||||
return s.Expr.End()
|
||||
}
|
||||
|
||||
func (s *ExprStmt) String() string {
|
||||
return s.Expr.String()
|
||||
}
|
26
vendor/github.com/d5/tengo/compiler/ast/float_lit.go
generated
vendored
26
vendor/github.com/d5/tengo/compiler/ast/float_lit.go
generated
vendored
@@ -1,26 +0,0 @@
|
||||
package ast
|
||||
|
||||
import "github.com/d5/tengo/compiler/source"
|
||||
|
||||
// FloatLit represents a floating point literal.
|
||||
type FloatLit struct {
|
||||
Value float64
|
||||
ValuePos source.Pos
|
||||
Literal string
|
||||
}
|
||||
|
||||
func (e *FloatLit) exprNode() {}
|
||||
|
||||
// Pos returns the position of first character belonging to the node.
|
||||
func (e *FloatLit) Pos() source.Pos {
|
||||
return e.ValuePos
|
||||
}
|
||||
|
||||
// End returns the position of first character immediately after the node.
|
||||
func (e *FloatLit) End() source.Pos {
|
||||
return source.Pos(int(e.ValuePos) + len(e.Literal))
|
||||
}
|
||||
|
||||
func (e *FloatLit) String() string {
|
||||
return e.Literal
|
||||
}
|
32
vendor/github.com/d5/tengo/compiler/ast/for_in_stmt.go
generated
vendored
32
vendor/github.com/d5/tengo/compiler/ast/for_in_stmt.go
generated
vendored
@@ -1,32 +0,0 @@
|
||||
package ast
|
||||
|
||||
import "github.com/d5/tengo/compiler/source"
|
||||
|
||||
// ForInStmt represents a for-in statement.
|
||||
type ForInStmt struct {
|
||||
ForPos source.Pos
|
||||
Key *Ident
|
||||
Value *Ident
|
||||
Iterable Expr
|
||||
Body *BlockStmt
|
||||
}
|
||||
|
||||
func (s *ForInStmt) stmtNode() {}
|
||||
|
||||
// Pos returns the position of first character belonging to the node.
|
||||
func (s *ForInStmt) Pos() source.Pos {
|
||||
return s.ForPos
|
||||
}
|
||||
|
||||
// End returns the position of first character immediately after the node.
|
||||
func (s *ForInStmt) End() source.Pos {
|
||||
return s.Body.End()
|
||||
}
|
||||
|
||||
func (s *ForInStmt) String() string {
|
||||
if s.Value != nil {
|
||||
return "for " + s.Key.String() + ", " + s.Value.String() + " in " + s.Iterable.String() + " " + s.Body.String()
|
||||
}
|
||||
|
||||
return "for " + s.Key.String() + " in " + s.Iterable.String() + " " + s.Body.String()
|
||||
}
|
43
vendor/github.com/d5/tengo/compiler/ast/for_stmt.go
generated
vendored
43
vendor/github.com/d5/tengo/compiler/ast/for_stmt.go
generated
vendored
@@ -1,43 +0,0 @@
|
||||
package ast
|
||||
|
||||
import "github.com/d5/tengo/compiler/source"
|
||||
|
||||
// ForStmt represents a for statement.
|
||||
type ForStmt struct {
|
||||
ForPos source.Pos
|
||||
Init Stmt
|
||||
Cond Expr
|
||||
Post Stmt
|
||||
Body *BlockStmt
|
||||
}
|
||||
|
||||
func (s *ForStmt) stmtNode() {}
|
||||
|
||||
// Pos returns the position of first character belonging to the node.
|
||||
func (s *ForStmt) Pos() source.Pos {
|
||||
return s.ForPos
|
||||
}
|
||||
|
||||
// End returns the position of first character immediately after the node.
|
||||
func (s *ForStmt) End() source.Pos {
|
||||
return s.Body.End()
|
||||
}
|
||||
|
||||
func (s *ForStmt) String() string {
|
||||
var init, cond, post string
|
||||
if s.Init != nil {
|
||||
init = s.Init.String()
|
||||
}
|
||||
if s.Cond != nil {
|
||||
cond = s.Cond.String() + " "
|
||||
}
|
||||
if s.Post != nil {
|
||||
post = s.Post.String()
|
||||
}
|
||||
|
||||
if init != "" || post != "" {
|
||||
return "for " + init + " ; " + cond + " ; " + post + s.Body.String()
|
||||
}
|
||||
|
||||
return "for " + cond + s.Body.String()
|
||||
}
|
25
vendor/github.com/d5/tengo/compiler/ast/func_lit.go
generated
vendored
25
vendor/github.com/d5/tengo/compiler/ast/func_lit.go
generated
vendored
@@ -1,25 +0,0 @@
|
||||
package ast
|
||||
|
||||
import "github.com/d5/tengo/compiler/source"
|
||||
|
||||
// FuncLit represents a function literal.
|
||||
type FuncLit struct {
|
||||
Type *FuncType
|
||||
Body *BlockStmt
|
||||
}
|
||||
|
||||
func (e *FuncLit) exprNode() {}
|
||||
|
||||
// Pos returns the position of first character belonging to the node.
|
||||
func (e *FuncLit) Pos() source.Pos {
|
||||
return e.Type.Pos()
|
||||
}
|
||||
|
||||
// End returns the position of first character immediately after the node.
|
||||
func (e *FuncLit) End() source.Pos {
|
||||
return e.Body.End()
|
||||
}
|
||||
|
||||
func (e *FuncLit) String() string {
|
||||
return "func" + e.Type.Params.String() + " " + e.Body.String()
|
||||
}
|
25
vendor/github.com/d5/tengo/compiler/ast/func_type.go
generated
vendored
25
vendor/github.com/d5/tengo/compiler/ast/func_type.go
generated
vendored
@@ -1,25 +0,0 @@
|
||||
package ast
|
||||
|
||||
import "github.com/d5/tengo/compiler/source"
|
||||
|
||||
// FuncType represents a function type definition.
|
||||
type FuncType struct {
|
||||
FuncPos source.Pos
|
||||
Params *IdentList
|
||||
}
|
||||
|
||||
func (e *FuncType) exprNode() {}
|
||||
|
||||
// Pos returns the position of first character belonging to the node.
|
||||
func (e *FuncType) Pos() source.Pos {
|
||||
return e.FuncPos
|
||||
}
|
||||
|
||||
// End returns the position of first character immediately after the node.
|
||||
func (e *FuncType) End() source.Pos {
|
||||
return e.Params.End()
|
||||
}
|
||||
|
||||
func (e *FuncType) String() string {
|
||||
return "func" + e.Params.String()
|
||||
}
|
29
vendor/github.com/d5/tengo/compiler/ast/ident.go
generated
vendored
29
vendor/github.com/d5/tengo/compiler/ast/ident.go
generated
vendored
@@ -1,29 +0,0 @@
|
||||
package ast
|
||||
|
||||
import "github.com/d5/tengo/compiler/source"
|
||||
|
||||
// Ident represents an identifier.
|
||||
type Ident struct {
|
||||
Name string
|
||||
NamePos source.Pos
|
||||
}
|
||||
|
||||
func (e *Ident) exprNode() {}
|
||||
|
||||
// Pos returns the position of first character belonging to the node.
|
||||
func (e *Ident) Pos() source.Pos {
|
||||
return e.NamePos
|
||||
}
|
||||
|
||||
// End returns the position of first character immediately after the node.
|
||||
func (e *Ident) End() source.Pos {
|
||||
return source.Pos(int(e.NamePos) + len(e.Name))
|
||||
}
|
||||
|
||||
func (e *Ident) String() string {
|
||||
if e != nil {
|
||||
return e.Name
|
||||
}
|
||||
|
||||
return nullRep
|
||||
}
|
40
vendor/github.com/d5/tengo/compiler/ast/if_stmt.go
generated
vendored
40
vendor/github.com/d5/tengo/compiler/ast/if_stmt.go
generated
vendored
@@ -1,40 +0,0 @@
|
||||
package ast
|
||||
|
||||
import "github.com/d5/tengo/compiler/source"
|
||||
|
||||
// IfStmt represents an if statement.
|
||||
type IfStmt struct {
|
||||
IfPos source.Pos
|
||||
Init Stmt
|
||||
Cond Expr
|
||||
Body *BlockStmt
|
||||
Else Stmt // else branch; or nil
|
||||
}
|
||||
|
||||
func (s *IfStmt) stmtNode() {}
|
||||
|
||||
// Pos returns the position of first character belonging to the node.
|
||||
func (s *IfStmt) Pos() source.Pos {
|
||||
return s.IfPos
|
||||
}
|
||||
|
||||
// End returns the position of first character immediately after the node.
|
||||
func (s *IfStmt) End() source.Pos {
|
||||
if s.Else != nil {
|
||||
return s.Else.End()
|
||||
}
|
||||
|
||||
return s.Body.End()
|
||||
}
|
||||
|
||||
func (s *IfStmt) String() string {
|
||||
var initStmt, elseStmt string
|
||||
if s.Init != nil {
|
||||
initStmt = s.Init.String() + "; "
|
||||
}
|
||||
if s.Else != nil {
|
||||
elseStmt = " else " + s.Else.String()
|
||||
}
|
||||
|
||||
return "if " + initStmt + s.Cond.String() + " " + s.Body.String() + elseStmt
|
||||
}
|
29
vendor/github.com/d5/tengo/compiler/ast/immutable_expr.go
generated
vendored
29
vendor/github.com/d5/tengo/compiler/ast/immutable_expr.go
generated
vendored
@@ -1,29 +0,0 @@
|
||||
package ast
|
||||
|
||||
import (
|
||||
"github.com/d5/tengo/compiler/source"
|
||||
)
|
||||
|
||||
// ImmutableExpr represents an immutable expression
|
||||
type ImmutableExpr struct {
|
||||
Expr Expr
|
||||
ErrorPos source.Pos
|
||||
LParen source.Pos
|
||||
RParen source.Pos
|
||||
}
|
||||
|
||||
func (e *ImmutableExpr) exprNode() {}
|
||||
|
||||
// Pos returns the position of first character belonging to the node.
|
||||
func (e *ImmutableExpr) Pos() source.Pos {
|
||||
return e.ErrorPos
|
||||
}
|
||||
|
||||
// End returns the position of first character immediately after the node.
|
||||
func (e *ImmutableExpr) End() source.Pos {
|
||||
return e.RParen
|
||||
}
|
||||
|
||||
func (e *ImmutableExpr) String() string {
|
||||
return "immutable(" + e.Expr.String() + ")"
|
||||
}
|
29
vendor/github.com/d5/tengo/compiler/ast/import_expr.go
generated
vendored
29
vendor/github.com/d5/tengo/compiler/ast/import_expr.go
generated
vendored
@@ -1,29 +0,0 @@
|
||||
package ast
|
||||
|
||||
import (
|
||||
"github.com/d5/tengo/compiler/source"
|
||||
"github.com/d5/tengo/compiler/token"
|
||||
)
|
||||
|
||||
// ImportExpr represents an import expression
|
||||
type ImportExpr struct {
|
||||
ModuleName string
|
||||
Token token.Token
|
||||
TokenPos source.Pos
|
||||
}
|
||||
|
||||
func (e *ImportExpr) exprNode() {}
|
||||
|
||||
// Pos returns the position of first character belonging to the node.
|
||||
func (e *ImportExpr) Pos() source.Pos {
|
||||
return e.TokenPos
|
||||
}
|
||||
|
||||
// End returns the position of first character immediately after the node.
|
||||
func (e *ImportExpr) End() source.Pos {
|
||||
return source.Pos(int(e.TokenPos) + 10 + len(e.ModuleName)) // import("moduleName")
|
||||
}
|
||||
|
||||
func (e *ImportExpr) String() string {
|
||||
return `import("` + e.ModuleName + `")"`
|
||||
}
|
29
vendor/github.com/d5/tengo/compiler/ast/inc_dec_stmt.go
generated
vendored
29
vendor/github.com/d5/tengo/compiler/ast/inc_dec_stmt.go
generated
vendored
@@ -1,29 +0,0 @@
|
||||
package ast
|
||||
|
||||
import (
|
||||
"github.com/d5/tengo/compiler/source"
|
||||
"github.com/d5/tengo/compiler/token"
|
||||
)
|
||||
|
||||
// IncDecStmt represents increment or decrement statement.
|
||||
type IncDecStmt struct {
|
||||
Expr Expr
|
||||
Token token.Token
|
||||
TokenPos source.Pos
|
||||
}
|
||||
|
||||
func (s *IncDecStmt) stmtNode() {}
|
||||
|
||||
// Pos returns the position of first character belonging to the node.
|
||||
func (s *IncDecStmt) Pos() source.Pos {
|
||||
return s.Expr.Pos()
|
||||
}
|
||||
|
||||
// End returns the position of first character immediately after the node.
|
||||
func (s *IncDecStmt) End() source.Pos {
|
||||
return source.Pos(int(s.TokenPos) + 2)
|
||||
}
|
||||
|
||||
func (s *IncDecStmt) String() string {
|
||||
return s.Expr.String() + s.Token.String()
|
||||
}
|
32
vendor/github.com/d5/tengo/compiler/ast/index_expr.go
generated
vendored
32
vendor/github.com/d5/tengo/compiler/ast/index_expr.go
generated
vendored
@@ -1,32 +0,0 @@
|
||||
package ast
|
||||
|
||||
import "github.com/d5/tengo/compiler/source"
|
||||
|
||||
// IndexExpr represents an index expression.
|
||||
type IndexExpr struct {
|
||||
Expr Expr
|
||||
LBrack source.Pos
|
||||
Index Expr
|
||||
RBrack source.Pos
|
||||
}
|
||||
|
||||
func (e *IndexExpr) exprNode() {}
|
||||
|
||||
// Pos returns the position of first character belonging to the node.
|
||||
func (e *IndexExpr) Pos() source.Pos {
|
||||
return e.Expr.Pos()
|
||||
}
|
||||
|
||||
// End returns the position of first character immediately after the node.
|
||||
func (e *IndexExpr) End() source.Pos {
|
||||
return e.RBrack + 1
|
||||
}
|
||||
|
||||
func (e *IndexExpr) String() string {
|
||||
var index string
|
||||
if e.Index != nil {
|
||||
index = e.Index.String()
|
||||
}
|
||||
|
||||
return e.Expr.String() + "[" + index + "]"
|
||||
}
|
26
vendor/github.com/d5/tengo/compiler/ast/int_lit.go
generated
vendored
26
vendor/github.com/d5/tengo/compiler/ast/int_lit.go
generated
vendored
@@ -1,26 +0,0 @@
|
||||
package ast
|
||||
|
||||
import "github.com/d5/tengo/compiler/source"
|
||||
|
||||
// IntLit represents an integer literal.
|
||||
type IntLit struct {
|
||||
Value int64
|
||||
ValuePos source.Pos
|
||||
Literal string
|
||||
}
|
||||
|
||||
func (e *IntLit) exprNode() {}
|
||||
|
||||
// Pos returns the position of first character belonging to the node.
|
||||
func (e *IntLit) Pos() source.Pos {
|
||||
return e.ValuePos
|
||||
}
|
||||
|
||||
// End returns the position of first character immediately after the node.
|
||||
func (e *IntLit) End() source.Pos {
|
||||
return source.Pos(int(e.ValuePos) + len(e.Literal))
|
||||
}
|
||||
|
||||
func (e *IntLit) String() string {
|
||||
return e.Literal
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user