Compare commits

...

63 Commits

Author SHA1 Message Date
Wim
d97b077e85 Release v1.17.2 (#1080) 2020-04-09 22:54:51 +02:00
Wim
8950575bfb Update Rhymen/go-whatsapp vendor and whatsapp version (#1078) 2020-04-09 22:30:08 +02:00
Jerry Heiselman
11fc4c286f Clarify terminology used in mapping group chat IDs to channels in config (#1079)
* Clarify embedded docs for channel specification

Should help with #1072
2020-04-08 23:52:38 +02:00
Wim
8d08e348a9 Reset start timestamp on reconnect (whatsapp). Fixes #1059 (#1064) 2020-03-31 23:26:53 +02:00
Wim
a18807f19e Update matterbridge/go-xmpp to add xmpp avatar support (#1070) 2020-03-29 17:35:40 +02:00
Wim
29f658fd3c Use DebugWriter after upstream changes (xmpp) 2020-03-29 15:03:24 +02:00
Wim
a30bb8fed0 Sync matterbridge/go-xmpp with upstream 2020-03-29 15:03:24 +02:00
Wim
092ca1cd67 Update vendor slack-go/slack (#1068) 2020-03-28 23:50:47 +01:00
Wim
0df2539641 Use upstream yaegashi/msgraph.go/msauth (msteams) (#1067) 2020-03-28 23:44:49 +01:00
Wim
0f2d8a599c Update vendor d5/tengo (#1066) 2020-03-28 23:41:35 +01:00
Wim
54b3143a1d Bump version 2020-03-28 00:29:41 +01:00
Wim
148f7d2a91 Release v1.17.1 (#1063) 2020-03-28 00:18:29 +01:00
Wim
1aa662f763 Update client version whatsapp. Fixes #1061 (#1062)
See https://github.com/Rhymen/go-whatsapp/issues/305
2020-03-28 00:18:03 +01:00
Alex Wigen
0b86b88de7 Remove build dependencies from final docker image (multistage build) (#1057)
This multistage build takes the resulting image size down from 346MB to
90MB.
2020-03-22 22:55:29 +01:00
Qais Patankar
98033b1ba7 Don't transmit typing events from ourselves (slack/discord) (#1056) 2020-03-22 18:39:11 +01:00
Qais Patankar
2b7eab629d Add support for build tags (#1054)
By default all bridges are available.

You can turn off certain bridges by providing
e.g. "nodiscord" as a build tag.

    go build -tags nomsteams,noapi
2020-03-22 18:34:14 +01:00
Wim
0e4973e15c Exclude gateway/bridgemap from linting (#1055) 2020-03-22 14:35:48 +01:00
Qais Patankar
af0acf0dae Strip extra info from emotes (discord) (#1052) 2020-03-22 14:16:31 +01:00
Qais Patankar
76e5fe5a87 Update vendor yaegashi/msgraph.go to v0.1.2 (2) 2020-03-22 00:02:48 +01:00
Qais Patankar
802c80f40c Update vendor yaegashi/msgraph.go to v0.1.2 (1) 2020-03-22 00:02:48 +01:00
Wim
a51c5bd905 Add more msteams docs (#1051) 2020-03-21 23:30:22 +01:00
Wim
8c68556f52 Bump version 2020-03-21 22:51:22 +01:00
Wim
cca1ea2404 Release v1.17.0 (#1050) 2020-03-21 21:33:16 +01:00
Wim
281016a501 Fix duplicate separator on empty description/url (discord). Fixes #1008 (#1035)
Make this work for all possible cases.
Add tests
2020-03-21 21:27:17 +01:00
Qais Patankar
d4acdf2f89 Use blocks not attachments (slack) (#1048)
This removes the extra space below messages, as shown in
https://user-images.githubusercontent.com/923242/77235190-a3359980-6bab-11ea-8b7b-697d730ae5c1.png
2020-03-21 21:03:12 +01:00
Qais Patankar
0951e75c85 Fix #1039: messages sent to Slack being synced back (#1046)
This is a regression from https://github.com/42wim/matterbridge/pull/581#issuecomment-562937576

Behaves the same as 95190f11bf
2020-03-21 20:12:30 +01:00
Jakub
6b017b226a Support JSON and YAML config formats (#1045)
Signed-off-by: Jakub Sokołowski <jakub@status.im>
2020-03-18 23:20:29 +01:00
Qais Patankar
9e3bd7398c Fix #1027: warning when handling inbound webhooks (discord) (#1044) 2020-03-18 23:12:48 +01:00
Qais Patankar
79f764c7a8 Refactor webhook permission checks 2020-03-18 23:10:47 +01:00
Qais Patankar
b5dc4353fb Fix #1040: spotty webhook permission verification 2020-03-18 23:10:47 +01:00
Qais Patankar
2fbac73c29 Ignore ConnectingEvent (slack) (#1041) 2020-03-18 23:03:20 +01:00
burner1024
6616d105d1 Add markdownv2 mode for telegram documentation, see #1032 (#1037) 2020-03-18 22:43:11 +01:00
Wim
6b4b19194e Update vendor shazow/ssh-chat (#1029) 2020-03-08 23:55:09 +01:00
Wim
9785edd263 Remove replace directives and use own fork to make go get work again (#1028)
See https://github.com/golang/go/issues/30354
go get doesn't honor the go.mod replace options.
2020-03-08 17:08:18 +01:00
Qais Patankar
2a0bc11b68 Make some discord matterbridge.toml.sample lines less verbose 2020-03-08 14:30:54 +01:00
Qais Patankar
dd0325a88d Remove trailing newlines from matterbridge.toml.sample 2020-03-08 14:30:54 +01:00
Qais Patankar
20783c0978 Refactor matterbridge.toml.sample discord section 2020-03-08 14:30:54 +01:00
Wim
3f06a40bd5 Support code snippets from msteams 2020-03-01 22:19:33 +01:00
Wim
68f43985ad Add scopes again 2020-03-01 22:19:33 +01:00
Wim
915ca8f817 Make linter happy and cleanup (msteams) 2020-03-01 22:19:33 +01:00
Wim
a65a81610b Support threading from other bridges to msteams 2020-03-01 22:19:33 +01:00
Wim
8eb6ed5639 Support receiving attachments from msteams 2020-03-01 22:19:33 +01:00
Wim
795a8705c3 Add initial Microsoft Teams support
Documentation on https://github.com/42wim/matterbridge/wiki/MS-Teams-setup
2020-03-01 22:19:33 +01:00
Wim
3af0dc3b3a Vendor libraries needed for msteams support 2020-03-01 22:19:33 +01:00
Wim
9cf9b958a3 Do not lint gomnd (#1021) 2020-03-01 22:05:50 +01:00
Wim
3ac2ba8d5a Update to go1.14 and golangci-lint 1.23.7 (#1020) 2020-03-01 21:50:21 +01:00
Wim
d893421c7b Update vendor keybase/go-keybase-chat-bot (#1019) 2020-03-01 21:09:23 +01:00
Wim
250b3bb579 Use upstream slack-go/slack again (#1018) 2020-03-01 20:59:19 +01:00
Alexander Pushkov
e9edbfc051 Make Keybase link point to the team directly (#1013) 2020-02-19 21:02:44 +01:00
Wim
e343db6f72 Make avatars download work with mediaserverdownload (telegram). Fixes #920 (#1012) 2020-02-15 18:31:40 +01:00
Qais Patankar
4d57d66f85 Fix typo in feature_request.md (#1009) 2020-02-10 22:35:11 +01:00
Wim
54ed6320c2 Add support for avatars from matrix. #984 (#1007) 2020-02-10 00:06:54 +01:00
Wim
23083f3ae0 Rebase gomatrix vendor with upstream (#1006) 2020-02-09 23:49:17 +01:00
Wim
1985873494 Implement basic reconnect (whatsapp). Fixes #987 (#1003) 2020-02-09 22:11:46 +01:00
Qais Patankar
8ae5917659 Be less lossy when throttling IRC messages (#1004)
Note that msg.Text and chucking it through a chan is OK: https://play.golang.org/p/MTfT3YSsgPX
2020-02-09 22:10:18 +01:00
Qais Patankar
c91bfd08d8 Add ability to procure avatars from the destination bridge (#1000)
* remote_avatar: add UseLocalAvatar

* remote_avatar: make sure msg.Protocol is always set correctly

* remote_avatars: support msg.Account

* remote_avatar: add to matterbridge.toml.sample

* remote_avatar: clarify something
2020-02-09 22:07:26 +01:00
Qais Patankar
49110a5872 Assign automatically labels when creating issues (#1005)
* Update Bug_report.md

* Add 'label: enhancement' to feature_request.md
2020-02-09 22:03:53 +01:00
Wim
c01c8edeb8 Fix go-keybase-chat-bot api changes 2020-02-08 18:33:05 +01:00
Wim
ff8cf067b8 Update kekeybase/go-keybase-chat-bot vendor 2020-02-08 18:33:05 +01:00
Qais Patankar
1420f68050 Check only bridged channels for PermManageWebhooks (discord) (#1001)
* Check only bridged channels for PermManageWebhooks

* add note
2020-02-08 15:13:23 +01:00
Martijn Braam
c0be3e585a Enable intra-word emphasis supression in markdown (#999)
This fixes plain links sent to Matrix being broken if they contain
underscores. Fixes issue #997
2020-02-04 13:22:05 +01:00
Wim
3049ef9151 Bump version 2020-02-02 22:40:44 +01:00
Wim
4be00bbe6b Release v1.16.5 2020-02-02 22:36:07 +01:00
1692 changed files with 267624 additions and 1954 deletions

View File

@@ -1,6 +1,7 @@
--- ---
name: Bug report name: Bug report
about: Create a report to help us improve. (Check the FAQ on the wiki first) about: Create a report to help us improve. (Check the FAQ on the wiki first)
labels: bug
--- ---

View File

@@ -1,6 +1,7 @@
--- ---
name: Feature request name: Feature request
about: Suggest an idea for this project about: Suggest an idea for this project
labels: enhancement
--- ---

View File

@@ -23,7 +23,7 @@ run:
# default value is empty list, but next dirs are always skipped independently # default value is empty list, but next dirs are always skipped independently
# from this option's value: # from this option's value:
# vendor$, third_party$, testdata$, examples$, Godeps$, builtin$ # 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 # which files to skip: they will be analyzed, but issues from them
# won't be reported. Default value is empty list, but there is # won't be reported. Default value is empty list, but there is
@@ -175,6 +175,7 @@ linters:
- maligned - maligned
- prealloc - prealloc
- wsl - wsl
- gomnd
# rules to deal with reported isues # rules to deal with reported isues

View File

@@ -20,22 +20,22 @@ jobs:
- stage: lint - stage: lint
# Run linting in one Go environment only. # Run linting in one Go environment only.
script: ./ci/lint.sh script: ./ci/lint.sh
go: 1.13.x go: 1.14.x
env: env:
- GO111MODULE=on - GO111MODULE=on
- GOLANGCI_VERSION="v1.21.0" - GOLANGCI_VERSION="v1.23.7"
- stage: test - stage: test
# Run tests in a combination of Go environments. # Run tests in a combination of Go environments.
script: ./ci/test.sh script: ./ci/test.sh
go: 1.12.x go: 1.13.x
env: env:
- GO111MODULE=off - GOFLAGS=-mod=vendor
- script: ./ci/test.sh - script: ./ci/test.sh
go: 1.12.x go: 1.13.x
env: env:
- GO111MODULE=on - GO111MODULE=on
- script: ./ci/test.sh - script: ./ci/test.sh
go: 1.13.x go: 1.14.x
env: env:
- GO111MODULE=on - GO111MODULE=on
- REPORT_COVERAGE=1 - REPORT_COVERAGE=1

View File

@@ -1,11 +1,13 @@
FROM alpine:edge FROM alpine:edge AS builder
ENTRYPOINT ["/bin/matterbridge"]
COPY . /go/src/github.com/42wim/matterbridge COPY . /go/src/github.com/42wim/matterbridge
RUN apk update && apk add go git gcc musl-dev ca-certificates mailcap \ RUN apk update && apk add go git gcc musl-dev \
&& cd /go/src/github.com/42wim/matterbridge \ && cd /go/src/github.com/42wim/matterbridge \
&& export GOPATH=/go \ && export GOPATH=/go \
&& go get \ && go get \
&& go build -x -ldflags "-X main.githash=$(git log --pretty=format:'%h' -n 1)" -o /bin/matterbridge \ && 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 FROM alpine:edge
RUN apk --no-cache add ca-certificates mailcap
COPY --from=builder /bin/matterbridge /bin/matterbridge
ENTRYPOINT ["/bin/matterbridge"]

View File

@@ -22,6 +22,7 @@ Letting people be where they want to be.<br />
[Zulip][mb-zulip] | [Zulip][mb-zulip] |
[Telegram][mb-telegram] | [Telegram][mb-telegram] |
[Keybase][mb-keybase] | [Keybase][mb-keybase] |
[MSTeams][mb-msteams] |
And more... And more...
</sup> </sup>
@@ -44,28 +45,34 @@ And more...
</a> </a>
</p> </p>
### Table of Contents # Table of Contents
- [Features](https://github.com/42wim/matterbridge/wiki/Features) - [matterbridge](#matterbridge)
- [Natively supported](#natively-supported) - [Table of Contents](#table-of-contents)
- [3rd party via matterbridge api](#3rd-party-via-matterbridge-api) - [Features](#features)
- [API](#API) - [Natively supported](#natively-supported)
- [Chat with us](#chat-with-us) - [3rd party via matterbridge api](#3rd-party-via-matterbridge-api)
- [Screenshots](https://github.com/42wim/matterbridge/wiki/) - [API](#api)
- [Installing/upgrading](#installing--upgrading) - [Chat with us](#chat-with-us)
- [Binaries](#binaries) - [Screenshots](#screenshots)
- [Building](#building) - [Installing / upgrading](#installing--upgrading)
- [Configuration](#configuration) - [Binaries](#binaries)
- [Howto](https://github.com/42wim/matterbridge/wiki/How-to-create-your-config) - [Packages](#packages)
- [Settings](#settings) - [Building](#building)
- [Examples](#examples) - [Configuration](#configuration)
- [Running](#running) - [Basic configuration](#basic-configuration)
- [Docker](#docker) - [Settings](#settings)
- [Changelog](#changelog) - [Advanced configuration](#advanced-configuration)
- [FAQ](#faq) - [Examples](#examples)
- [Related projects](#related-projects) - [Bridge mattermost (off-topic) - irc (#testing)](#bridge-mattermost-off-topic---irc-testing)
- [Articles](#articles) - [Bridge slack (#general) - discord (general)](#bridge-slack-general---discord-general)
- [Thanks](#thanks) - [Running](#running)
- [Docker](#docker)
- [Changelog](#changelog)
- [FAQ](#faq)
- [Related projects](#related-projects)
- [Articles](#articles)
- [Thanks](#thanks)
## Features ## Features
@@ -89,6 +96,7 @@ And more...
- [Telegram](https://telegram.org) - [Telegram](https://telegram.org)
- [Rocket.chat](https://rocket.chat) - [Rocket.chat](https://rocket.chat)
- [Matrix](https://matrix.org) - [Matrix](https://matrix.org)
- [Microsoft Teams](https://teams.microsoft.com)
- [Steam](https://store.steampowered.com/) - [Steam](https://store.steampowered.com/)
- [Twitch](https://twitch.tv) - [Twitch](https://twitch.tv)
- [Ssh-chat](https://github.com/shazow/ssh-chat) - [Ssh-chat](https://github.com/shazow/ssh-chat)
@@ -133,6 +141,7 @@ Questions or want to test on your favorite platform? Join below:
- [Twitch][mb-twitch] - [Twitch][mb-twitch]
- [Zulip][mb-zulip] - [Zulip][mb-zulip]
- [Telegram][mb-telegram] - [Telegram][mb-telegram]
- [Keybase][mb-keybase]
## Screenshots ## Screenshots
@@ -142,7 +151,7 @@ See https://github.com/42wim/matterbridge/wiki
### Binaries ### Binaries
- Latest stable release [v1.16.4](https://github.com/42wim/matterbridge/releases/latest) - Latest stable release [v1.17.2](https://github.com/42wim/matterbridge/releases/latest)
- Development releases (follows master) can be downloaded [here](https://dl.bintray.com/42wim/nightly/) - 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. 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.
@@ -326,6 +335,7 @@ Matterbridge wouldn't exist without these libraries:
- zulip - https://github.com/ifo/gozulipbot - zulip - https://github.com/ifo/gozulipbot
- tengo - https://github.com/d5/tengo - tengo - https://github.com/d5/tengo
- keybase - https://github.com/keybase/go-keybase-chat-bot - keybase - https://github.com/keybase/go-keybase-chat-bot
- msgraph.go - https://github.com/yaegashi/msgraph.go
<!-- Links --> <!-- Links -->
@@ -339,6 +349,7 @@ Matterbridge wouldn't exist without these libraries:
[mb-xmpp]: https://inverse.chat/ [mb-xmpp]: https://inverse.chat/
[mb-twitch]: https://www.twitch.tv/matterbridge [mb-twitch]: https://www.twitch.tv/matterbridge
[mb-whatsapp]: https://www.whatsapp.com/ [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-zulip]: https://matterbridge.zulipchat.com/register/
[mb-telegram]: https://t.me/Matterbridge [mb-telegram]: https://t.me/Matterbridge
[mb-msteams]: https://teams.microsoft.com/join/hj92x75gd3y7

View File

@@ -3,6 +3,7 @@ package config
import ( import (
"bytes" "bytes"
"io/ioutil" "io/ioutil"
"path/filepath"
"strings" "strings"
"sync" "sync"
"time" "time"
@@ -76,6 +77,7 @@ type Protocol struct {
BindAddress string // mattermost, slack // DEPRECATED BindAddress string // mattermost, slack // DEPRECATED
Buffer int // api Buffer int // api
Charset string // irc Charset string // irc
ClientID string // msteams
ColorNicks bool // only irc for now ColorNicks bool // only irc for now
Debug bool // general Debug bool // general
DebugLevel int // only for irc now DebugLevel int // only for irc now
@@ -124,6 +126,7 @@ type Protocol struct {
RemoteNickFormat string // all protocols RemoteNickFormat string // all protocols
RunCommands []string // IRC RunCommands []string // IRC
Server string // IRC,mattermost,XMPP,discord Server string // IRC,mattermost,XMPP,discord
SessionFile string // msteams,whatsapp
ShowJoinPart bool // all protocols ShowJoinPart bool // all protocols
ShowTopicChange bool // slack ShowTopicChange bool // slack
ShowUserTyping bool // slack ShowUserTyping bool // slack
@@ -134,10 +137,13 @@ type Protocol struct {
SyncTopic bool // slack SyncTopic bool // slack
TengoModifyMessage string // general TengoModifyMessage string // general
Team string // mattermost, keybase Team string // mattermost, keybase
TeamID string // msteams
TenantID string // msteams
Token string // gitter, slack, discord, api Token string // gitter, slack, discord, api
Topic string // zulip Topic string // zulip
URL string // mattermost, slack // DEPRECATED URL string // mattermost, slack // DEPRECATED
UseAPI bool // mattermost, slack UseAPI bool // mattermost, slack
UseLocalAvatar []string // discord
UseSASL bool // IRC UseSASL bool // IRC
UseTLS bool // IRC UseTLS bool // IRC
UseDiscriminator bool // discord UseDiscriminator bool // discord
@@ -235,7 +241,8 @@ func NewConfig(rootLogger *logrus.Logger, cfgfile string) Config {
logger.Fatalf("Failed to read configuration file: %#v", err) 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 { if mycfg.cv.General.MediaDownloadSize == 0 {
mycfg.cv.General.MediaDownloadSize = 1000000 mycfg.cv.General.MediaDownloadSize = 1000000
} }
@@ -246,14 +253,26 @@ func NewConfig(rootLogger *logrus.Logger, cfgfile string) Config {
return mycfg 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. // NewConfigFromString instantiates a new configuration based on the specified string.
func NewConfigFromString(rootLogger *logrus.Logger, input []byte) Config { func NewConfigFromString(rootLogger *logrus.Logger, input []byte) Config {
logger := rootLogger.WithFields(logrus.Fields{"prefix": "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 { func newConfigFromString(logger *logrus.Entry, input []byte, cfgtype string) *config {
viper.SetConfigType("toml") viper.SetConfigType(cfgtype)
viper.SetEnvPrefix("matterbridge") viper.SetEnvPrefix("matterbridge")
viper.SetEnvKeyReplacer(strings.NewReplacer(".", "_", "-", "_")) viper.SetEnvKeyReplacer(strings.NewReplacer(".", "_", "-", "_"))
viper.AutomaticEnv() viper.AutomaticEnv()

View File

@@ -10,7 +10,7 @@ import (
"github.com/42wim/matterbridge/bridge" "github.com/42wim/matterbridge/bridge"
"github.com/42wim/matterbridge/bridge/config" "github.com/42wim/matterbridge/bridge/config"
"github.com/42wim/matterbridge/bridge/helper" "github.com/42wim/matterbridge/bridge/helper"
"github.com/bwmarrin/discordgo" "github.com/matterbridge/discordgo"
) )
const MessageLength = 1950 const MessageLength = 1950
@@ -21,6 +21,7 @@ type Bdiscord struct {
c *discordgo.Session c *discordgo.Session
nick string nick string
userID string
guildID string guildID string
webhookID string webhookID string
webhookToken string webhookToken string
@@ -92,6 +93,7 @@ func (b *Bdiscord) Connect() error {
} }
serverName := strings.Replace(b.GetString("Server"), "ID:", "", -1) serverName := strings.Replace(b.GetString("Server"), "ID:", "", -1)
b.nick = userinfo.Username b.nick = userinfo.Username
b.userID = userinfo.ID
b.channelsMutex.Lock() b.channelsMutex.Lock()
for _, guild := range guilds { for _, guild := range guilds {
if guild.Name == serverName || guild.ID == serverName { if guild.Name == serverName || guild.ID == serverName {
@@ -114,30 +116,37 @@ func (b *Bdiscord) Connect() error {
b.Log.Infof("Server=\"%s\" # Server ID", guild.ID) b.Log.Infof("Server=\"%s\" # Server ID", guild.ID)
} }
} }
if err != nil { if err != nil {
return err return err
} }
b.channelsMutex.RLock() b.channelsMutex.RLock()
if b.GetString("WebhookURL") == "" { if b.GetString("WebhookURL") == "" {
for _, channel := range b.channels { for _, channel := range b.channels {
b.Log.Debugf("found channel %#v", channel) b.Log.Debugf("found channel %#v", channel)
} }
} else { } else {
b.canEditWebhooks = true manageWebhooks := discordgo.PermissionManageWebhooks
for _, channel := range b.channels { var channelsDenied []string
b.Log.Debugf("found channel %#v; verifying PermissionManageWebhooks", channel) for _, info := range b.Channels {
perms, permsErr := b.c.State.UserChannelPermissions(userinfo.ID, channel.ID) id := b.getChannelID(info.Name) // note(qaisjp): this readlocks channelsMutex
manageWebhooks := discordgo.PermissionManageWebhooks b.Log.Debugf("Verifying PermissionManageWebhooks for %s with ID %s", info.ID, id)
if permsErr != nil || perms&manageWebhooks != manageWebhooks {
b.Log.Warnf("Can't manage webhooks in channel \"%s\"", channel.Name) perms, permsErr := b.c.UserChannelPermissions(userinfo.ID, id)
b.canEditWebhooks = false 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 { if b.canEditWebhooks {
b.Log.Info("Can manage webhooks; will edit channel for global webhook on send") b.Log.Info("Can manage webhooks; will edit channel for global webhook on send")
} else { } else {
b.Log.Warn("Can't manage webhooks; won't edit channel for global webhook on send") 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() b.channelsMutex.RUnlock()
@@ -380,6 +389,19 @@ func (b *Bdiscord) webhookSend(msg *config.Message, webhookID, token string) (*d
err error 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`. // WebhookParams can have either `Content` or `File`.
// We can't send empty messages. // We can't send empty messages.
@@ -429,3 +451,11 @@ func (b *Bdiscord) webhookSend(msg *config.Message, webhookID, token string) (*d
} }
return res, err 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("")
}

View File

@@ -2,7 +2,7 @@ package bdiscord
import ( import (
"github.com/42wim/matterbridge/bridge/config" "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 func (b *Bdiscord) messageDelete(s *discordgo.Session, m *discordgo.MessageDelete) { //nolint:unparam
@@ -36,6 +36,11 @@ func (b *Bdiscord) messageTyping(s *discordgo.Session, m *discordgo.TypingStart)
return return
} }
// Ignore our own typing messages
if m.UserID == b.userID {
return
}
rmsg := config.Message{Account: b.Account, Event: config.EventUserTyping} rmsg := config.Message{Account: b.Account, Event: config.EventUserTyping}
rmsg.Channel = b.getChannelName(m.ChannelID) rmsg.Channel = b.getChannelName(m.ChannelID)
b.Remote <- rmsg b.Remote <- rmsg
@@ -90,12 +95,12 @@ func (b *Bdiscord) messageCreate(s *discordgo.Session, m *discordgo.MessageCreat
// set channel name // set channel name
rmsg.Channel = b.getChannelName(m.ChannelID) rmsg.Channel = b.getChannelName(m.ChannelID)
// set username fromWebhook := m.WebhookID != ""
if !b.GetBool("UseUserName") { if !fromWebhook && !b.GetBool("UseUserName") {
rmsg.Username = b.getNick(m.Author, m.GuildID) rmsg.Username = b.getNick(m.Author, m.GuildID)
} else { } else {
rmsg.Username = m.Author.Username rmsg.Username = m.Author.Username
if b.GetBool("UseDiscriminator") { if !fromWebhook && b.GetBool("UseDiscriminator") {
rmsg.Username += "#" + m.Author.Discriminator rmsg.Username += "#" + m.Author.Discriminator
} }
} }
@@ -103,7 +108,7 @@ func (b *Bdiscord) messageCreate(s *discordgo.Session, m *discordgo.MessageCreat
// if we have embedded content add it to text // if we have embedded content add it to text
if b.GetBool("ShowEmbeds") && m.Message.Embeds != nil { if b.GetBool("ShowEmbeds") && m.Message.Embeds != nil {
for _, embed := range m.Message.Embeds { for _, embed := range m.Message.Embeds {
rmsg.Text = rmsg.Text + "embed: " + embed.Title + " - " + embed.Description + " - " + embed.URL + "\n" rmsg.Text += handleEmbed(embed)
} }
} }
@@ -119,6 +124,9 @@ func (b *Bdiscord) messageCreate(s *discordgo.Session, m *discordgo.MessageCreat
rmsg.Event = config.EventUserAction 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("<= Sending message from %s on %s to gateway", m.Author.Username, b.Account)
b.Log.Debugf("<= Message is %#v", rmsg) b.Log.Debugf("<= Message is %#v", rmsg)
b.Remote <- rmsg b.Remote <- rmsg
@@ -192,3 +200,33 @@ func (b *Bdiscord) memberRemove(s *discordgo.Session, m *discordgo.GuildMemberRe
b.Log.Debugf("<= Message is %#v", rmsg) b.Log.Debugf("<= Message is %#v", rmsg)
b.Remote <- 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
}

View 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)
}
}

View File

@@ -6,7 +6,7 @@ import (
"strings" "strings"
"unicode" "unicode"
"github.com/bwmarrin/discordgo" "github.com/matterbridge/discordgo"
) )
func (b *Bdiscord) getNick(user *discordgo.User, guildID string) string { func (b *Bdiscord) getNick(user *discordgo.User, guildID string) string {
@@ -137,6 +137,7 @@ var (
// See https://discordapp.com/developers/docs/reference#message-formatting. // See https://discordapp.com/developers/docs/reference#message-formatting.
channelMentionRE = regexp.MustCompile("<#[0-9]+>") channelMentionRE = regexp.MustCompile("<#[0-9]+>")
userMentionRE = regexp.MustCompile("@[^@\n]{1,32}") userMentionRE = regexp.MustCompile("@[^@\n]{1,32}")
emoteRE = regexp.MustCompile(`<a?(:\w+:)\d+>`)
) )
func (b *Bdiscord) replaceChannelMentions(text string) string { func (b *Bdiscord) replaceChannelMentions(text string) string {
@@ -182,6 +183,10 @@ func (b *Bdiscord) replaceUserMentions(text string) string {
return userMentionRE.ReplaceAllStringFunc(text, replaceUserMentionFunc) return userMentionRE.ReplaceAllStringFunc(text, replaceUserMentionFunc)
} }
func replaceEmotes(text string) string {
return emoteRE.ReplaceAllString(text, "$1")
}
func (b *Bdiscord) replaceAction(text string) (string, bool) { func (b *Bdiscord) replaceAction(text string) (string, bool) {
if strings.HasPrefix(text, "_") && strings.HasSuffix(text, "_") { if strings.HasPrefix(text, "_") && strings.HasSuffix(text, "_") {
return text[1 : len(text)-1], true return text[1 : len(text)-1], true

View File

@@ -180,7 +180,7 @@ func ClipMessage(text string, length int) string {
// ParseMarkdown takes in an input string as markdown and parses it to html // ParseMarkdown takes in an input string as markdown and parses it to html
func ParseMarkdown(input string) string { func ParseMarkdown(input string) string {
extensions := parser.HardLineBreak extensions := parser.HardLineBreak | parser.NoIntraEmphasis
markdownParser := parser.NewWithExtensions(extensions) markdownParser := parser.NewWithExtensions(extensions)
renderer := html.NewRenderer(html.RendererOptions{ renderer := html.NewRenderer(html.RendererOptions{
Flags: 0, Flags: 0,

View File

@@ -167,12 +167,8 @@ func (b *Birc) Send(msg config.Message) (string, error) {
return "", nil return "", nil
} }
b.Local <- config.Message{ msg.Text = msgLines[i]
Text: msgLines[i], b.Local <- msg
Username: msg.Username,
Channel: msg.Channel,
Event: msg.Event,
}
} }
return "", nil return "", nil
} }

View File

@@ -4,7 +4,7 @@ import (
"strconv" "strconv"
"github.com/42wim/matterbridge/bridge/config" "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() { func (b *Bkeybase) handleKeybase() {
@@ -20,7 +20,7 @@ func (b *Bkeybase) handleKeybase() {
b.Log.Errorf("failed to read message: %s", err.Error()) b.Log.Errorf("failed to read message: %s", err.Error())
} }
if msg.Message.Content.Type != "text" { if msg.Message.Content.TypeName != "text" {
continue 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) b.Log.Debugf("== Receiving event: %#v", msg)
if msg.Channel.TopicName != b.channel || msg.Channel.Name != b.team { if msg.Channel.TopicName != b.channel || msg.Channel.Name != b.team {
return return
@@ -45,10 +45,10 @@ func (b *Bkeybase) handleMessage(msg kbchat.Message) {
// TODO download avatar // TODO download avatar
// Create our message // 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 // Text must be a string
if msg.Content.Type != "text" { if msg.Content.TypeName != "text" {
b.Log.Errorf("message is not text") b.Log.Errorf("message is not text")
return return
} }

View File

@@ -90,16 +90,17 @@ func (b *Bkeybase) Send(msg config.Message) (string, error) {
return "", err return "", err
} }
_, _ = b.kbc.SendAttachmentByTeam(b.team, fpath, fcaption, &b.channel) _, _ = b.kbc.SendAttachmentByTeam(b.team, &b.channel, fpath, fcaption)
} }
return "", nil return "", nil
} }
// Send regular message // 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 { if err != nil {
return "", err return "", err
} }
return strconv.Itoa(resp.Result.MsgID), err return strconv.Itoa(int(*resp.Result.MessageID)), err
} }

View File

@@ -172,10 +172,15 @@ func (b *Bmatrix) handleEvent(ev *matrix.Event) {
return return
} }
// TODO download avatar
// Create our message // 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 // Text must be a string
if rmsg.Text, ok = ev.Content["body"].(string); !ok { if rmsg.Text, ok = ev.Content["body"].(string); !ok {
@@ -358,3 +363,15 @@ func (b *Bmatrix) containsAttachment(content map[string]interface{}) bool {
} }
return true 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
}

101
bridge/msteams/handler.go Normal file
View 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"
}

204
bridge/msteams/msteams.go Normal file
View File

@@ -0,0 +1,204 @@
package bmsteams
import (
"context"
"fmt"
"os"
"regexp"
"strings"
"time"
"github.com/42wim/matterbridge/bridge"
"github.com/42wim/matterbridge/bridge/config"
"github.com/mattn/godown"
msgraph "github.com/yaegashi/msgraph.go/beta"
"github.com/yaegashi/msgraph.go/msauth"
"golang.org/x/oauth2"
)
var defaultScopes = []string{"openid", "profile", "offline_access", "Group.Read.All", "Group.ReadWrite.All"}
var attachRE = regexp.MustCompile(`<attachment id=.*?attachment>`)
type Bmsteams struct {
gc *msgraph.GraphServiceRequestBuilder
ctx context.Context
botID string
*bridge.Config
}
func New(cfg *bridge.Config) bridge.Bridger {
return &Bmsteams{Config: cfg}
}
func (b *Bmsteams) Connect() error {
tokenCachePath := b.GetString("sessionFile")
if tokenCachePath == "" {
tokenCachePath = "msteams_session.json"
}
ctx := context.Background()
m := msauth.NewManager()
m.LoadFile(tokenCachePath) //nolint:errcheck
ts, err := m.DeviceAuthorizationGrant(ctx, b.GetString("TenantID"), b.GetString("ClientID"), defaultScopes, nil)
if err != nil {
return err
}
err = m.SaveFile(tokenCachePath)
if err != nil {
b.Log.Errorf("Couldn't save sessionfile in %s: %s", tokenCachePath, err)
}
// make file readable only for matterbridge user
err = os.Chmod(tokenCachePath, 0600)
if err != nil {
b.Log.Errorf("Couldn't change permissions for %s: %s", tokenCachePath, err)
}
httpClient := oauth2.NewClient(ctx, ts)
graphClient := msgraph.NewClient(httpClient)
b.gc = graphClient
b.ctx = ctx
err = b.setBotID()
if err != nil {
return err
}
b.Log.Info("Connection succeeded")
return nil
}
func (b *Bmsteams) Disconnect() error {
return nil
}
func (b *Bmsteams) JoinChannel(channel config.ChannelInfo) error {
go 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()
}

View File

@@ -1,15 +1,19 @@
package bslack package bslack
import ( import (
"errors"
"fmt" "fmt"
"html" "html"
"time" "time"
"github.com/42wim/matterbridge/bridge/config" "github.com/42wim/matterbridge/bridge/config"
"github.com/42wim/matterbridge/bridge/helper" "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() { func (b *Bslack) handleSlack() {
messages := make(chan *config.Message) messages := make(chan *config.Message)
if b.GetString(incomingWebhookConfig) != "" { if b.GetString(incomingWebhookConfig) != "" {
@@ -53,7 +57,9 @@ func (b *Bslack) handleSlackClient(messages chan *config.Message) {
continue continue
} }
rmsg, err := b.handleTypingEvent(ev) rmsg, err := b.handleTypingEvent(ev)
if err != nil { if err == ErrEventIgnored {
continue
} else if err != nil {
b.Log.Errorf("%#v", err) b.Log.Errorf("%#v", err)
continue continue
} }
@@ -87,7 +93,7 @@ func (b *Bslack) handleSlackClient(messages chan *config.Message) {
b.Log.Errorf("Connection failed %#v %#v", ev.Error(), ev.ErrorObj) b.Log.Errorf("Connection failed %#v %#v", ev.Error(), ev.ErrorObj)
case *slack.MemberJoinedChannelEvent: case *slack.MemberJoinedChannelEvent:
b.users.populateUser(ev.User) b.users.populateUser(ev.User)
case *slack.HelloEvent, *slack.LatencyReport: case *slack.HelloEvent, *slack.LatencyReport, *slack.ConnectingEvent:
continue continue
default: default:
b.Log.Debugf("Unhandled incoming event: %T", ev) 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). // Skip any messages that we made ourselves or from 'slackbot' (see #527).
if ev.Username == sSlackBotUser || if ev.Username == sSlackBotUser ||
(b.rtm != nil && ev.Username == b.si.User.Name) || (b.rtm != nil && ev.Username == b.si.User.Name) || hasOurCallbackID {
(len(ev.Attachments) > 0 && ev.Attachments[0].CallbackID == "matterbridge_"+b.uuid) {
return true 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) { 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) channelInfo, err := b.channels.getChannelByID(ev.Channel)
if err != nil { if err != nil {
return nil, err return nil, err

View File

@@ -7,8 +7,8 @@ import (
"time" "time"
"github.com/42wim/matterbridge/bridge/config" "github.com/42wim/matterbridge/bridge/config"
"github.com/nlopes/slack"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
"github.com/slack-go/slack"
) )
// populateReceivedMessage shapes the initial Matterbridge message that we will forward to the // populateReceivedMessage shapes the initial Matterbridge message that we will forward to the

View File

@@ -5,7 +5,7 @@ import (
"github.com/42wim/matterbridge/bridge" "github.com/42wim/matterbridge/bridge"
"github.com/42wim/matterbridge/matterhook" "github.com/42wim/matterbridge/matterhook"
"github.com/nlopes/slack" "github.com/slack-go/slack"
) )
type BLegacy struct { type BLegacy struct {

View File

@@ -13,8 +13,8 @@ import (
"github.com/42wim/matterbridge/bridge/helper" "github.com/42wim/matterbridge/bridge/helper"
"github.com/42wim/matterbridge/matterhook" "github.com/42wim/matterbridge/matterhook"
lru "github.com/hashicorp/golang-lru" lru "github.com/hashicorp/golang-lru"
"github.com/nlopes/slack"
"github.com/rs/xid" "github.com/rs/xid"
"github.com/slack-go/slack"
) )
type Bslack struct { type Bslack struct {
@@ -408,7 +408,6 @@ func (b *Bslack) editMessage(msg *config.Message, channelInfo *slack.Channel) (b
} }
messageOptions := b.prepareMessageOptions(msg) messageOptions := b.prepareMessageOptions(msg)
for { for {
messageOptions = append(messageOptions, slack.MsgOptionText(msg.Text, false))
_, _, _, err := b.rtm.UpdateMessage(channelInfo.ID, msg.ID, messageOptions...) _, _, _, err := b.rtm.UpdateMessage(channelInfo.ID, msg.ID, messageOptions...)
if err == nil { if err == nil {
return true, nil return true, nil
@@ -427,11 +426,6 @@ func (b *Bslack) postMessage(msg *config.Message, channelInfo *slack.Channel) (s
return "", nil return "", nil
} }
messageOptions := b.prepareMessageOptions(msg) messageOptions := b.prepareMessageOptions(msg)
messageOptions = append(
messageOptions,
slack.MsgOptionText(msg.Text, false),
slack.MsgOptionEnableLinkUnfurl(),
)
for { for {
_, id, err := b.rtm.PostMessage(channelInfo.ID, messageOptions...) _, id, err := b.rtm.PostMessage(channelInfo.ID, messageOptions...)
if err == nil { if err == nil {
@@ -497,8 +491,6 @@ func (b *Bslack) prepareMessageOptions(msg *config.Message) []slack.MsgOption {
} }
var attachments []slack.Attachment 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 // add file attachments
attachments = append(attachments, b.createAttach(msg.Extra)...) attachments = append(attachments, b.createAttach(msg.Extra)...)
// add slack attachments (from another slack bridge) // add slack attachments (from another slack bridge)
@@ -509,6 +501,19 @@ func (b *Bslack) prepareMessageOptions(msg *config.Message) []slack.MsgOption {
} }
var opts []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.MsgOptionAttachments(attachments...))
opts = append(opts, slack.MsgOptionPostMessageParameters(params)) opts = append(opts, slack.MsgOptionPostMessageParameters(params))
return opts return opts

View File

@@ -8,8 +8,8 @@ import (
"time" "time"
"github.com/42wim/matterbridge/bridge/config" "github.com/42wim/matterbridge/bridge/config"
"github.com/nlopes/slack"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
"github.com/slack-go/slack"
) )
const minimumRefreshInterval = 10 * time.Second const minimumRefreshInterval = 10 * time.Second

View File

@@ -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) // 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) b.handleDownloadAvatar(message.From.ID, rmsg.Channel)
} }
} }

View File

@@ -9,6 +9,7 @@ import (
"github.com/42wim/matterbridge/bridge/config" "github.com/42wim/matterbridge/bridge/config"
"github.com/42wim/matterbridge/bridge/helper" "github.com/42wim/matterbridge/bridge/helper"
"github.com/Rhymen/go-whatsapp" "github.com/Rhymen/go-whatsapp"
"github.com/jpillora/backoff"
) )
/* /*
@@ -25,7 +26,39 @@ func (b *Bwhatsapp) HandleError(err error) {
if strings.Contains(err.Error(), "error processing data: received invalid data") { if strings.Contains(err.Error(), "error processing data: received invalid data") {
return return
} }
b.Log.Errorf("%v", err) // TODO implement proper handling? at least respond to different error types
switch err.(type) {
case *whatsapp.ErrConnectionClosed, *whatsapp.ErrConnectionFailed:
b.reconnect(err)
default:
switch err {
case whatsapp.ErrConnectionTimeout:
b.reconnect(err)
default:
b.Log.Errorf("%v", err)
}
}
}
func (b *Bwhatsapp) reconnect(err error) {
bf := &backoff.Backoff{
Min: time.Second,
Max: 5 * time.Minute,
Jitter: true,
}
for {
d := bf.Duration()
b.Log.Errorf("Connection failed, underlying error: %v", err)
b.Log.Infof("Waiting %s...", d)
time.Sleep(d)
b.Log.Info("Reconnecting...")
err := b.conn.Restore()
if err == nil {
bf.Reset()
b.startedAt = uint64(time.Now().Unix())
return
}
}
} }
// HandleTextMessage sent from WhatsApp, relay it to the brige // HandleTextMessage sent from WhatsApp, relay it to the brige

View File

@@ -67,6 +67,7 @@ func (b *Bwhatsapp) Connect() error {
// https://github.com/Rhymen/go-whatsapp#creating-a-connection // https://github.com/Rhymen/go-whatsapp#creating-a-connection
b.Log.Debugln("Connecting to WhatsApp..") b.Log.Debugln("Connecting to WhatsApp..")
conn, err := whatsapp.NewConn(20 * time.Second) conn, err := whatsapp.NewConn(20 * time.Second)
conn.SetClientVersion(0, 4, 2080)
if err != nil { if err != nil {
return errors.New("failed to connect to WhatsApp: " + err.Error()) return errors.New("failed to connect to WhatsApp: " + err.Error())
} }

View File

@@ -114,6 +114,9 @@ func (b *Bxmpp) createXMPP() error {
ServerName: strings.Split(b.GetString("Jid"), "@")[1], ServerName: strings.Split(b.GetString("Jid"), "@")[1],
InsecureSkipVerify: b.GetBool("SkipTLSVerify"), // nolint: gosec InsecureSkipVerify: b.GetBool("SkipTLSVerify"), // nolint: gosec
} }
xmpp.DebugWriter = b.Log.Writer()
options := xmpp.Options{ options := xmpp.Options{
Host: b.GetString("Server"), Host: b.GetString("Server"),
User: b.GetString("Jid"), User: b.GetString("Jid"),
@@ -122,7 +125,6 @@ func (b *Bxmpp) createXMPP() error {
StartTLS: true, StartTLS: true,
TLSConfig: tc, TLSConfig: tc,
Debug: b.GetBool("debug"), Debug: b.GetBool("debug"),
Logger: b.Log.Writer(),
Session: true, Session: true,
Status: "", Status: "",
StatusMessage: "", StatusMessage: "",

View File

@@ -1,3 +1,75 @@
# v1.17.2
## Enhancements
- slack: Update vendor slack-go/slack (#1068)
- general: Update vendor d5/tengo (#1066)
- general: Clarify terminology used in mapping group chat IDs to channels in config (#1079)
## Bugfix
- whatsapp: Update Rhymen/go-whatsapp vendor and whatsapp version (#1078). Fixes Media upload #1074
- whatsapp: Reset start timestamp on reconnect (whatsapp). Fixes #1059 (#1064)
This release couldn't exist without the following contributors:
@42wim, @jheiselman
# v1.17.1
## Enhancements
- docker: Remove build dependencies from final image (multistage build) #1057
## Bugfix
- general: Don't transmit typing events from ourselves #1056
- general: Add support for build tags #1054
- discord: Strip extra info from emotes (discord) #1052
- msteams: fix macos build: Update vendor yaegashi/msgraph.go to v0.1.2 #1036
- whatsapp: Update client version whatsapp. Fixes #1061 #1062
This release couldn't exist without the following contributors:
@awigen, @qaisjp, @42wim
# v1.17.0
## New features
- msteams: new protocol added. Add initial Microsoft Teams support #967
See https://github.com/42wim/matterbridge/wiki/MS-Teams-setup for a complete walkthrough
- discord: Add ability to procure avatars from the destination bridge #1000
- matrix: Add support for avatars from matrix. #1007
- general: support JSON and YAML config formats #1045
## Enhancements
- discord: Check only bridged channels for PermManageWebhooks #1001
- irc: Be less lossy when throttling IRC messages #1004
- keybase: updated library #1002, #1019
- matrix: Rebase gomatrix vendor with upstream #1006
- slack: Use upstream slack-go/slack again #1018
- slack: Ignore ConnectingEvent #1041
- slack: use blocks not attachments #1048
- sshchat: Update vendor shazow/ssh-chat #1029
- telegram: added markdownv2 mode for telegram #1037
- whatsapp: Implement basic reconnect (whatsapp). Fixes #987 #1003
## Bugfix
- discord: Fix webhook permission checks sometimes failing #1043
- discord: Fix #1027: warning when handling inbound webhooks #1044
- discord: Fix duplicate separator on empty description/url (discord) #1035
- matrix: Fix issue with underscores in links #999
- slack: Fix #1039: messages sent to Slack being synced back #1046
- telegram: Make avatars download work with mediaserverdownload (telegram). Fixes #920
This release couldn't exist without the following contributors:
@qaisjp, @jakubgs, @burner1024, @notpushkin, @MartijnBraam, @42wim
# v1.16.5
- Fix version bump
# v1.16.4 # v1.16.4
## New features ## New features

View File

@@ -1,7 +1,7 @@
#!/usr/bin/env bash #!/usr/bin/env bash
set -u -e -x -o pipefail set -u -e -x -o pipefail
go version | grep go1.13 || exit go version | grep go1.14 || exit
VERSION=$(git describe --tags) VERSION=$(git describe --tags)
mkdir ci/binaries mkdir ci/binaries

11
gateway/bridgemap/api.go Normal file
View File

@@ -0,0 +1,11 @@
// +build !noapi
package bridgemap
import (
"github.com/42wim/matterbridge/bridge/api"
)
func init() {
FullMap["api"] = api.New
}

View 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{}{}
}

View 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
View File

@@ -0,0 +1,11 @@
// +build !noirc
package bridgemap
import (
birc "github.com/42wim/matterbridge/bridge/irc"
)
func init() {
FullMap["irc"] = birc.New
}

View File

@@ -0,0 +1,11 @@
// +build !nokeybase
package bridgemap
import (
bkeybase "github.com/42wim/matterbridge/bridge/keybase"
)
func init() {
FullMap["keybase"] = bkeybase.New
}

View File

@@ -0,0 +1,11 @@
// +build !nomatrix
package bridgemap
import (
bmatrix "github.com/42wim/matterbridge/bridge/matrix"
)
func init() {
FullMap["matrix"] = bmatrix.New
}

View File

@@ -0,0 +1,11 @@
// +build !nomattermost
package bridgemap
import (
bmattermost "github.com/42wim/matterbridge/bridge/mattermost"
)
func init() {
FullMap["mattermost"] = bmattermost.New
}

View File

@@ -0,0 +1,11 @@
// +build !nomsteams
package bridgemap
import (
bmsteams "github.com/42wim/matterbridge/bridge/msteams"
)
func init() {
FullMap["msteams"] = bmsteams.New
}

View File

@@ -2,45 +2,9 @@ package bridgemap
import ( import (
"github.com/42wim/matterbridge/bridge" "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 ( var (
FullMap = map[string]bridge.Factory{ FullMap = map[string]bridge.Factory{}
"api": api.New, UserTypingSupport = map[string]struct{}{}
"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": {},
}
) )

View File

@@ -0,0 +1,11 @@
// +build !norocketchat
package bridgemap
import (
brocketchat "github.com/42wim/matterbridge/bridge/rocketchat"
)
func init() {
FullMap["rocketchat"] = brocketchat.New
}

View 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{}{}
}

View File

@@ -0,0 +1,11 @@
// +build !nosshchat
package bridgemap
import (
bsshchat "github.com/42wim/matterbridge/bridge/sshchat"
)
func init() {
FullMap["sshchat"] = bsshchat.New
}

View File

@@ -0,0 +1,11 @@
// +build !nosteam
package bridgemap
import (
bsteam "github.com/42wim/matterbridge/bridge/steam"
)
func init() {
FullMap["steam"] = bsteam.New
}

View File

@@ -0,0 +1,11 @@
// +build !notelegram
package bridgemap
import (
btelegram "github.com/42wim/matterbridge/bridge/telegram"
)
func init() {
FullMap["telegram"] = btelegram.New
}

View File

@@ -0,0 +1,11 @@
// +build !nowhatsapp
package bridgemap
import (
bwhatsapp "github.com/42wim/matterbridge/bridge/whatsapp"
)
func init() {
FullMap["whatsapp"] = bwhatsapp.New
}

View File

@@ -0,0 +1,11 @@
// +build !noxmpp
package bridgemap
import (
bxmpp "github.com/42wim/matterbridge/bridge/xmpp"
)
func init() {
FullMap["xmpp"] = bxmpp.New
}

View File

@@ -0,0 +1,11 @@
// +build !nozulip
package bridgemap
import (
bzulip "github.com/42wim/matterbridge/bridge/zulip"
)
func init() {
FullMap["zulip"] = bzulip.New
}

View File

@@ -306,8 +306,6 @@ func (gw *Gateway) ignoreMessage(msg *config.Message) bool {
} }
func (gw *Gateway) modifyUsername(msg *config.Message, dest *bridge.Bridge) string { func (gw *Gateway) modifyUsername(msg *config.Message, dest *bridge.Bridge) string {
br := gw.Bridges[msg.Account]
msg.Protocol = br.Protocol
if dest.GetBool("StripNick") { if dest.GetBool("StripNick") {
re := regexp.MustCompile("[^a-zA-Z0-9]+") re := regexp.MustCompile("[^a-zA-Z0-9]+")
msg.Username = re.ReplaceAllString(msg.Username, "") 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") nick := dest.GetString("RemoteNickFormat")
// loop to replace nicks // loop to replace nicks
br := gw.Bridges[msg.Account]
for _, outer := range br.GetStringSlice2D("ReplaceNicks") { for _, outer := range br.GetStringSlice2D("ReplaceNicks") {
search := outer[0] search := outer[0]
replace := outer[1] replace := outer[1]

View File

@@ -132,6 +132,9 @@ func (r *Router) handleReceive() {
r.handleEventFailure(&msg) r.handleEventFailure(&msg)
r.handleEventRejoinChannels(&msg) r.handleEventRejoinChannels(&msg)
// Set message protocol based on the account it came from
msg.Protocol = r.getBridge(msg.Account).Protocol
filesHandled := false filesHandled := false
for _, gw := range r.Gateways { for _, gw := range r.Gateways {
// record all the message ID's of the different bridges // record all the message ID's of the different bridges

24
go.mod
View File

@@ -5,9 +5,8 @@ require (
github.com/Baozisoftware/qrcode-terminal-go v0.0.0-20170407111555-c0650d8dff0f github.com/Baozisoftware/qrcode-terminal-go v0.0.0-20170407111555-c0650d8dff0f
github.com/Jeffail/gabs v1.1.1 // indirect github.com/Jeffail/gabs v1.1.1 // indirect
github.com/Philipp15b/go-steam v1.0.1-0.20190816133340-b04c5a83c1c0 github.com/Philipp15b/go-steam v1.0.1-0.20190816133340-b04c5a83c1c0
github.com/Rhymen/go-whatsapp v0.1.0 github.com/Rhymen/go-whatsapp v0.1.1-0.20200408093540-2f227c53b44f
github.com/bwmarrin/discordgo v0.20.2 github.com/d5/tengo/v2 v2.1.2
github.com/d5/tengo/v2 v2.0.2
github.com/dfordsoft/golib v0.0.0-20180902042739-76ee6ab99bec github.com/dfordsoft/golib v0.0.0-20180902042739-76ee6ab99bec
github.com/fsnotify/fsnotify v1.4.7 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/go-telegram-bot-api/telegram-bot-api v4.6.5-0.20181225215658-ec221ba9ea45+incompatible
@@ -19,22 +18,24 @@ require (
github.com/hashicorp/golang-lru v0.5.3 github.com/hashicorp/golang-lru v0.5.3
github.com/hpcloud/tail v1.0.0 // indirect github.com/hpcloud/tail v1.0.0 // indirect
github.com/jpillora/backoff v1.0.0 github.com/jpillora/backoff v1.0.0
github.com/keybase/go-keybase-chat-bot v0.0.0-20190816161829-561f10822eb2 github.com/keybase/go-keybase-chat-bot v0.0.0-20200226211841-4e48f3eaef3e
github.com/labstack/echo/v4 v4.1.13 github.com/labstack/echo/v4 v4.1.13
github.com/lrstanley/girc v0.0.0-20190801035559-4fc93959e1a7 github.com/lrstanley/girc v0.0.0-20190801035559-4fc93959e1a7
github.com/matterbridge/Rocket.Chat.Go.SDK v0.0.0-20190210153444-cc9d05784d5d github.com/matterbridge/Rocket.Chat.Go.SDK v0.0.0-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/emoji v2.1.1-0.20191117213217-af507f6b02db+incompatible
github.com/matterbridge/go-xmpp v0.0.0-20180529212104-cd19799fba91 github.com/matterbridge/go-xmpp v0.0.0-20200329150250-5812999b292b
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/gozulipbot v0.0.0-20190212232658-7aa251978a18
github.com/matterbridge/logrus-prefixed-formatter v0.0.0-20180806162718-01618749af61 github.com/matterbridge/logrus-prefixed-formatter v0.0.0-20180806162718-01618749af61
github.com/mattermost/mattermost-server v5.5.0+incompatible 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/mgutz/ansi v0.0.0-20170206155736-9520e82c474b // indirect
github.com/mreiferson/go-httpclient v0.0.0-20160630210159-31f0106b4474 // indirect github.com/mreiferson/go-httpclient v0.0.0-20160630210159-31f0106b4474 // indirect
github.com/mrexodia/wray v0.0.0-20160318003008-78a2c1f284ff // indirect github.com/mrexodia/wray v0.0.0-20160318003008-78a2c1f284ff // indirect
github.com/nelsonken/gomf v0.0.0-20180504123937-a9dd2f9deae9 github.com/nelsonken/gomf v0.0.0-20180504123937-a9dd2f9deae9
github.com/nicksnyder/go-i18n v1.4.0 // indirect 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/ginkgo v1.6.0 // indirect
github.com/onsi/gomega v1.4.1 // indirect github.com/onsi/gomega v1.4.1 // indirect
github.com/paulrosania/go-charset v0.0.0-20190326053356-55c9d7a5834c github.com/paulrosania/go-charset v0.0.0-20190326053356-55c9d7a5834c
@@ -42,21 +43,22 @@ require (
github.com/rs/xid v1.2.1 github.com/rs/xid v1.2.1
github.com/russross/blackfriday v1.5.2 github.com/russross/blackfriday v1.5.2
github.com/saintfish/chardet v0.0.0-20120816061221-3af4cd4741ca github.com/saintfish/chardet v0.0.0-20120816061221-3af4cd4741ca
github.com/shazow/ssh-chat v1.8.2 github.com/shazow/ssh-chat v1.8.3-0.20200308224626-80ddf1f43a98
github.com/sirupsen/logrus v1.4.2 github.com/sirupsen/logrus v1.4.2
github.com/slack-go/slack v0.6.3
github.com/spf13/viper v1.6.1 github.com/spf13/viper v1.6.1
github.com/stretchr/testify v1.4.0 github.com/stretchr/testify v1.4.0
github.com/technoweenie/multipartstreamer v1.0.1 // indirect github.com/technoweenie/multipartstreamer v1.0.1 // indirect
github.com/x-cray/logrus-prefixed-formatter v0.5.2 // indirect github.com/x-cray/logrus-prefixed-formatter v0.5.2 // indirect
github.com/yaegashi/msgraph.go v0.1.2
github.com/zfjagann/golang-ring v0.0.0-20190106091943-a88bb6aef447 github.com/zfjagann/golang-ring v0.0.0-20190106091943-a88bb6aef447
golang.org/x/image v0.0.0-20191214001246-9130b4cfad52 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/fsnotify.v1 v1.4.7 // indirect
gopkg.in/natefinch/lumberjack.v2 v2.0.0 // indirect gopkg.in/natefinch/lumberjack.v2 v2.0.0 // indirect
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect
) )
replace github.com/nlopes/slack v0.6.0 => github.com/matterbridge/slack v0.1.1-0.20191208194820-95190f11bfb6 //replace github.com/bwmarrin/discordgo v0.20.2 => github.com/matterbridge/discordgo v0.18.1-0.20200109173909-ed873362fa43
replace github.com/bwmarrin/discordgo v0.20.2 => github.com/matterbridge/discordgo v0.18.1-0.20200109173909-ed873362fa43
go 1.13 go 1.13

75
go.sum
View File

@@ -1,4 +1,5 @@
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= 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 h1:IZtuWGfzQnKnCSu+vl8WGLhpVQ5Uvy3rlSwqXSg+sQg=
github.com/42wim/go-gitter v0.0.0-20170828205020-017310c2d557/go.mod h1:jL0YSXMs/txjtGJ4PWrmETOk6KUHMDPMshgQZlTeB3Y= github.com/42wim/go-gitter v0.0.0-20170828205020-017310c2d557/go.mod h1:jL0YSXMs/txjtGJ4PWrmETOk6KUHMDPMshgQZlTeB3Y=
github.com/Baozisoftware/qrcode-terminal-go v0.0.0-20170407111555-c0650d8dff0f h1:2dk3eOnYllh+wUOuDhOoC2vUVoJF/5z478ryJ+wzEII= github.com/Baozisoftware/qrcode-terminal-go v0.0.0-20170407111555-c0650d8dff0f h1:2dk3eOnYllh+wUOuDhOoC2vUVoJF/5z478ryJ+wzEII=
@@ -11,13 +12,12 @@ 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 h1:TO7d4rocnNFng6ZQrPe7U6WqHtK5eHEMrgrnnM/72IQ=
github.com/Philipp15b/go-steam v1.0.1-0.20190816133340-b04c5a83c1c0/go.mod h1:HuVM+sZFzumUdKPWiz+IlCMb4RdsKdT3T+nQBKL+sYg= 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.0/go.mod h1:rdQr95g2C1xcOfM7QGOhza58HeI3I+tZ/bbluv7VazA=
github.com/Rhymen/go-whatsapp v0.1.0 h1:XTXhFIQ/fx9jKObUnUX2Q+nh58EyeHNhX7DniE8xeuA= github.com/Rhymen/go-whatsapp v0.1.1-0.20200408093540-2f227c53b44f h1:uclEol7RbpElhXXmwu38PDeGcgMXNU2vh5DWwzlg7xI=
github.com/Rhymen/go-whatsapp v0.1.0/go.mod h1:xJSy+okeRjKkQEH/lEYrnekXB3PG33fqL0I6ncAkV50= github.com/Rhymen/go-whatsapp v0.1.1-0.20200408093540-2f227c53b44f/go.mod h1:o7jjkvKnigfu432dMbQ/w4PH0Yp5u4Y6ysCNjUlcYCk=
github.com/Rhymen/go-whatsapp/examples/echo v0.0.0-20190325075644-cc2581bbf24d/go.mod h1:zgCiQtBtZ4P4gFWvwl9aashsdwOcbb/EHOGRmSzM8ME= github.com/Rhymen/go-whatsapp/examples/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/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/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/Rhymen/go-whatsapp/examples/sendTextMessages v0.0.0-20190325075644-cc2581bbf24d/go.mod h1:suwzklatySS3Q0+NCxCDh5hYfgXdQUWU1DNcxwAxStM=
github.com/StackExchange/wmi v0.0.0-20170410192909-ea383cf3ba6e h1:IHXQQIpxASe3m0Jtcd3XongL+lxHNd5nUmvHxJARUmg=
github.com/StackExchange/wmi v0.0.0-20170410192909-ea383cf3ba6e/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg= github.com/StackExchange/wmi v0.0.0-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/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/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
@@ -33,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-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/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/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
github.com/d5/tengo/v2 v2.0.2 h1:3APkPZPc1FExaJoWrN5YzvDqc6GNkQH6ehmCRDmN83I= github.com/d5/tengo/v2 v2.1.2 h1:JR5O6qJW2GW9lpv/MfEqK16a/Wpp2y8I0JZZ5fqNOL0=
github.com/d5/tengo/v2 v2.0.2/go.mod h1:XRGjEs5I9jYIKTxly6HCF8oiiilk5E/RYXOZ5b0DZC8= github.com/d5/tengo/v2 v2.1.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.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 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
@@ -49,18 +49,18 @@ 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-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.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
github.com/go-ole/go-ole v1.2.1 h1:2lOsA72HgjxAuMlKpFiCbHTvu44PIVkZ5hqm3RSdI/E=
github.com/go-ole/go-ole v1.2.1/go.mod h1:7FAglXiTm7HKlQRDeOQ6ZNUHidzCWXuZWq/1dTyBNF8= github.com/go-ole/go-ole v1.2.1/go.mod h1:7FAglXiTm7HKlQRDeOQ6ZNUHidzCWXuZWq/1dTyBNF8=
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= 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 h1:i64CCJcSqkRIkm5OSdZQjZq84/gJsk2zNwHWIRYWlKE=
github.com/go-telegram-bot-api/telegram-bot-api v4.6.5-0.20181225215658-ec221ba9ea45+incompatible/go.mod h1:qf9acutJ8cwBUhm1bqgz6Bei9/C/c93FPDljKWwsOgM= github.com/go-telegram-bot-api/telegram-bot-api 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.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= 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/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/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.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.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.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 h1:YF8+flBXS5eO826T4nzqPrxfhQThhXl0YzfuUPu4SBg=
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
@@ -70,6 +70,7 @@ github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= 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 h1:6akvbMlpZrEYOuoebn2kR+ZJekbZqJ28fJXTs84+8to=
github.com/google/gops v0.3.6/go.mod h1:RZ1rH95wsAGX4vMWKmqBOIWynmWisBf4QFdgT/k/xOI= 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 h1:4EZlYQIiyecYJlUbVkFXCXHz1QPhVXcHnQKAzBTPfQo=
github.com/gopackage/ddp v0.0.0-20170117053602-652027933df4/go.mod h1:lEO7XoHJ/xNRBCxrn4h/CEB67h0kW1B0t4ooP2yrjUA= github.com/gopackage/ddp v0.0.0-20170117053602-652027933df4/go.mod h1:lEO7XoHJ/xNRBCxrn4h/CEB67h0kW1B0t4ooP2yrjUA=
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8=
@@ -77,7 +78,6 @@ github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORR
github.com/gorilla/schema v1.1.0 h1:CamqUDOFUBqzrvxuz2vEwo8+SUdwsluFh7IlzJh30LY= 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/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.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.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
github.com/gorilla/websocket v1.4.1 h1:q7AeDBpnBk8AogcD4DSag/Ukw/KV+YhzLj2bP5HvKCM= github.com/gorilla/websocket v1.4.1 h1:q7AeDBpnBk8AogcD4DSag/Ukw/KV+YhzLj2bP5HvKCM=
github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
@@ -100,8 +100,8 @@ github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfV
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= 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 h1:PJPDf8OUfOK1bb/NeTKd4f1QXZItOX389VN3B6qC8ro=
github.com/kardianos/osext v0.0.0-20170510131534-ae77be60afb1/go.mod h1:1NbS8ALrpOvjt0rHPNLyCIeMtbizbir8U//inJ+zuB8= 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-20200226211841-4e48f3eaef3e h1:KbPTfR/PYuau1IzKoE4lnd8yby5I2pBj+VR6fSVbYU8=
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/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 h1:2d+FLQbz4xRTi36DO1qYNUwfORax9XcQ0jhbO81Vago=
github.com/keybase/go-ps v0.0.0-20161005175911-668c8856d999/go.mod h1:hY+WOq6m2FpbvyrI93sMaypsttvaIL5nhVR92dTMUcQ= 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= github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
@@ -126,36 +126,33 @@ github.com/magiconair/properties v1.8.1 h1:ZC2Vc7/ZFkGmsVC9KvOjumD+G5lXy2RtTKyzR
github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= 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 h1:F+Sr+C0ojSlYQ37BLylQtSFmyQULe3jbAygcyXQ9mVs=
github.com/matterbridge/Rocket.Chat.Go.SDK v0.0.0-20190210153444-cc9d05784d5d/go.mod h1:c6MxwqHD+0HvtAJjsHMIdPCiAwGiQwPRPTp69ACMg8A= github.com/matterbridge/Rocket.Chat.Go.SDK v0.0.0-20190210153444-cc9d05784d5d/go.mod h1:c6MxwqHD+0HvtAJjsHMIdPCiAwGiQwPRPTp69ACMg8A=
github.com/matterbridge/discordgo v0.18.1-0.20200109173909-ed873362fa43 h1:xTcLiEPMp9jVh/lHEPpLc87RZ4sRWRZe0rM578/waOk= github.com/matterbridge/discordgo v0.18.1-0.20200308151012-aa40f01cbcc3 h1:VP/DNRn2HtrVRN6+X3h4FDcQI2OOKT+88WUi21ZD1Kw=
github.com/matterbridge/discordgo v0.18.1-0.20200109173909-ed873362fa43/go.mod h1:O9S4p+ofTFwB02em7jkpkV8M3R0/PUVOwN61zSZ0r4Q= 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 h1:oaOqwbg5HxHRxvAbd84ks0Okwoc1ISyUZ87EiVJFhGI=
github.com/matterbridge/emoji v2.1.1-0.20191117213217-af507f6b02db+incompatible/go.mod h1:igE6rUAn3jai2wCdsjFHfhUoekjrFthoEjFObKKwSb4= 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-20200329150250-5812999b292b h1:ZYI2HCj9zPzI4Si1ouSOi/ImA2xSQLUCJPQsLWr8FE0=
github.com/matterbridge/go-xmpp v0.0.0-20180529212104-cd19799fba91/go.mod h1:ECDRehsR9TYTKCAsRS8/wLeOk6UUqDydw47ln7wG41Q= github.com/matterbridge/go-xmpp v0.0.0-20200329150250-5812999b292b/go.mod h1:ECDRehsR9TYTKCAsRS8/wLeOk6UUqDydw47ln7wG41Q=
github.com/matterbridge/gomatrix v0.0.0-20191026211822-6fc7accd00ca h1:3ypqEpFpt6vg5Sv2xxA8/v4WiSOnWMXW7DqxTxpM4XI= github.com/matterbridge/gomatrix v0.0.0-20200209224845-c2104d7936a6 h1:Kl65VJv38HjYFnnwH+MP6Z8hcJT5UHuSpHVU5vW1HH0=
github.com/matterbridge/gomatrix v0.0.0-20191026211822-6fc7accd00ca/go.mod h1:+jWeaaUtXQbBRdKYWfjW6JDDYiI2XXE+3NnTjW5kg8g= 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 h1:fLhwXtWGtfTgZVxHG1lcKjv+re7dRwyyuYFNu69xdho=
github.com/matterbridge/gozulipbot v0.0.0-20190212232658-7aa251978a18/go.mod h1:yAjnZ34DuDyPHMPHHjOsTk/FefW4JJjoMMCGt/8uuQA= 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 h1:R/MgM/eUyRBQx2FiH6JVmXck8PaAuKfe2M1tWIzW7nE=
github.com/matterbridge/logrus-prefixed-formatter v0.0.0-20180806162718-01618749af61/go.mod h1:iXGEotOvwI1R1SjLxRc+BF5rUORTMtE0iMZBT2lxqAU= github.com/matterbridge/logrus-prefixed-formatter v0.0.0-20180806162718-01618749af61/go.mod h1:iXGEotOvwI1R1SjLxRc+BF5rUORTMtE0iMZBT2lxqAU=
github.com/matterbridge/slack v0.1.1-0.20191208194820-95190f11bfb6 h1:UvXXR9tHYqJUXZVEtiK2qkEWBXfFneicate5kOshVFk=
github.com/matterbridge/slack v0.1.1-0.20191208194820-95190f11bfb6/go.mod h1:2uCJim0Ct2z1Uj+XQq47KCLLC1b/9UTYaZOvDtbZfK4=
github.com/mattermost/mattermost-server v5.5.0+incompatible h1:0wcLGgYtd+YImtLDPf2AOfpBHxbU4suATx+6XKw1XbU= 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/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.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ=
github.com/mattn/go-colorable v0.1.2 h1:/bC9yWikZXAL9uJdulbSfyVNIR3n3trXl+v8+1sx8mU=
github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
github.com/mattn/go-colorable v0.1.4 h1:snbPLB8fVfU9iwbbo30TPtbLRzwWu6aJS6Xh4eaaviA= 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-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
github.com/mattn/go-isatty v0.0.5 h1:tHXDdz1cpzGaovsTB+TVB8q90WEokoVmfMqoVcrLUgw=
github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= 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.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.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 h1:FxPOTFNqGkuDUGi3H/qkUbQO4ZiBa2brKq5r0l8TGeM=
github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE= 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/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 h1:j7+1HpAFS1zy5+Q4qx1fWh90gTKwiN4QCGoY9TWyyO4=
github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE= github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE=
@@ -170,6 +167,8 @@ 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/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 h1:AgLl+Yq7kg5OYlzCgu9cKTZOyI4tD/NgukKqLqC8E+I=
github.com/nicksnyder/go-i18n v1.4.0/go.mod h1:HrK7VCrbOvQoUAQ7Vpy7i87N7JZZZ7R2xBGjv0j365Q= 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/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 h1:Ix8l273rp3QzYgXSR+c8d1fTG7UPgYkOSELPhiY/YGw=
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
@@ -195,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-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= 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/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU=
github.com/rickb777/date v1.12.4 h1:+6IzcCCS/1t17DrmnEvrznyq7nM8vPwir6/UhlyohKw=
github.com/rickb777/date v1.12.4/go.mod h1:xP0eo/I5qmUt97yRGClHZfyLZ3ikMw6v6SU5MOGZTE0=
github.com/rickb777/plural v1.2.0 h1:5tvEc7UBCZ7l8h/2UeybSkt/uu1DQsZFOFdNevmUhlE=
github.com/rickb777/plural v1.2.0/go.mod h1:UdpyWFCGbo3mvK3f/PfZOAOrkjzJlYN/sD46XNWJ+Es=
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= github.com/rogpeppe/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 h1:mhH9Nq+C1fY2l1XIpgxIiUOfNpRBYH1kKcr+qfKgjRc=
github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ= github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ=
@@ -204,17 +207,17 @@ 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/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 h1:Lx3BlDGFElJt4u/zKc9A3BuGYbQAGlEFyPuUA3jeMD0=
github.com/shazow/rateio v0.0.0-20150116013248-e8e00881e5c1/go.mod h1:vt2jWY/3Qw1bIzle5thrJWucsLuuX9iUNnp20CqCciI= github.com/shazow/rateio v0.0.0-20150116013248-e8e00881e5c1/go.mod h1:vt2jWY/3Qw1bIzle5thrJWucsLuuX9iUNnp20CqCciI=
github.com/shazow/ssh-chat v1.8.2 h1:MMso9eWfCnPBelRsusYxKcRBUwHIPEQkR9WrO89II38= github.com/shazow/ssh-chat v1.8.3-0.20200308224626-80ddf1f43a98 h1:sN07ff+PSRsUNhpSod4uGKAQ+Nc0FXsBPG9FmYMNg4w=
github.com/shazow/ssh-chat v1.8.2/go.mod h1:cXTZK/D1zujEwB0y8DIT1GX8rIKjyLDYeWd+jitPX84= 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 h1:80VN+vGkqM773Br/uNNTSheo3KatTgV8IpjIKjvVLng=
github.com/shirou/gopsutil v0.0.0-20180427012116-c95755e4bcd7/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= 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/shirou/w32 v0.0.0-20160930032740-bb4de0191aa4/go.mod h1:qsXQc7+bwAM3Q1u/4XEfrquwF8Lw7D7y5cD8CuHnfIc=
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= 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 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4=
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= 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 h1:lpEzuenPuO1XNTeikEmvqYFcU37GVLl8SRNblzyvGBE=
github.com/skip2/go-qrcode v0.0.0-20190110000554-dc11ecdae0a9/go.mod h1:PLPIyL7ikehBD1OAjmKKiOEhbvWyHGaNDjquXMcYABo= github.com/skip2/go-qrcode v0.0.0-20190110000554-dc11ecdae0a9/go.mod h1:PLPIyL7ikehBD1OAjmKKiOEhbvWyHGaNDjquXMcYABo=
github.com/slack-go/slack v0.6.3 h1:qU037g8gQ71EuH6S9zYKnvYrEUj0fLFH4HFekFqBoRU=
github.com/slack-go/slack v0.6.3/go.mod h1:HE4RwNe7YpOg/F0vqo5PwXH3Hki31TplTvKRW9dGGaw=
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM= 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/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 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s=
@@ -232,7 +235,6 @@ github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnIn
github.com/spf13/viper v1.6.1 h1:VPZzIkznI1YhVMRi6vNFLHSwhnhReBfgTxIPccpfdZk= github.com/spf13/viper v1.6.1 h1:VPZzIkznI1YhVMRi6vNFLHSwhnhReBfgTxIPccpfdZk=
github.com/spf13/viper v1.6.1/go.mod h1:t3iDnF5Jlj76alVNuyFBk5oUMCvsrkbvZK0WQdfDi5k= github.com/spf13/viper v1.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.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.1.1 h1:2vfRuCMp5sSVIDSqO8oNnWJq7mPa6KVP3iPIwFBuy8A=
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/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.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk= github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
@@ -245,16 +247,16 @@ github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1
github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= 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 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= 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.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8=
github.com/valyala/fasttemplate v1.1.0 h1:RZqt0yGBsps8NGvLSGW804QQqCUYYLsaOjTVHy1Ocw4= github.com/valyala/fasttemplate v1.1.0 h1:RZqt0yGBsps8NGvLSGW804QQqCUYYLsaOjTVHy1Ocw4=
github.com/valyala/fasttemplate v1.1.0/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8= 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 h1:00txxvfBM9muc0jiLIEAkAcIMJzfthRT6usrui8uGmg=
github.com/x-cray/logrus-prefixed-formatter v0.5.2/go.mod h1:2duySbKsL6M18s5GU7VPsoEPHyzalCE06qoARUCeBBE= 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/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/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/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
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 h1:CHgPZh8bFkZmislPrr/0gd7MciDAX+JJB70A2/5Lvmo=
github.com/zfjagann/golang-ring v0.0.0-20190106091943-a88bb6aef447/go.mod h1:0MsIttMJIF/8Y7x0XjonJP7K99t3sR6bjj4m5S4JmqU= 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.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
@@ -268,7 +270,6 @@ golang.org/dl v0.0.0-20190829154251-82a15e2f2ead/go.mod h1:IUMfjQLJQd4UTqG1Z90te
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= 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-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-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-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190320223903-b7391e95e576/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-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 h1:sKJQZMuxjOAR/Uo2LBfU90onWEf1dF4C+0hPJCc9Mpc=
@@ -277,20 +278,22 @@ golang.org/x/image v0.0.0-20191214001246-9130b4cfad52 h1:2fktqPPvDiVEEVT/vSTeoUP
golang.org/x/image v0.0.0-20191214001246-9130b4cfad52/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= 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-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/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-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-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-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-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-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-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190522155817-f3200d17e092 h1:4QSRKanuywn15aTZvI/mIDEgPQpswuFndXpOj3rKEco=
golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553 h1:efeOvDhwQ29Dj3SdAV/MJf8oukgn+8D8WgaCaRMchF8= golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553 h1:efeOvDhwQ29Dj3SdAV/MJf8oukgn+8D8WgaCaRMchF8=
golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-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-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
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-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-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/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-20171017063910-8dbc5d05d6ed/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@@ -302,12 +305,10 @@ golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5h
golang.org/x/sys v0.0.0-20190321052220-f7bb7a8bee54/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190321052220-f7bb7a8bee54/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-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-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/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-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 h1:JA8d3MPx/IToSyXZG/RhwYEtfrKO1Fxrqe8KrkiLXKM=
golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= 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 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
@@ -318,6 +319,8 @@ golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGm
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= 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= 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.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-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
google.golang.org/genproto v0.0.0-20180831171423-11092d34479b/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20180831171423-11092d34479b/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
@@ -337,10 +340,8 @@ gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkep
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= gopkg.in/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.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.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.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.4 h1:/eiJrUcujPVeJ3xlSWaiNi3uSVmDGBK1pDHUHAnao1I= gopkg.in/yaml.v2 v2.2.4 h1:/eiJrUcujPVeJ3xlSWaiNi3uSVmDGBK1pDHUHAnao1I=
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= 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= rsc.io/goversion v1.0.0/go.mod h1:Eih9y/uIBS3ulggl7KNJ09xGSLcuNaLgmvvqa07sgfo=

View File

@@ -15,7 +15,7 @@ import (
) )
var ( var (
version = "1.16.4-dev" version = "1.17.2"
githash string githash string
flagConfig = flag.String("conf", "matterbridge.toml", "config file") flagConfig = flag.String("conf", "matterbridge.toml", "config file")

File diff suppressed because it is too large Load Diff

View File

@@ -14,7 +14,7 @@ import (
"time" "time"
"github.com/gorilla/schema" "github.com/gorilla/schema"
"github.com/nlopes/slack" "github.com/slack-go/slack"
) )
// OMessage for mattermost incoming webhook. (send to mattermost) // OMessage for mattermost incoming webhook. (send to mattermost)

File diff suppressed because it is too large Load Diff

View File

@@ -56,6 +56,8 @@ message Location {
} }
message Point { message Point {
optional int32 xDeprecated = 1;
optional int32 yDeprecated = 2;
optional double x = 3; optional double x = 3;
optional double y = 4; optional double y = 4;
} }
@@ -93,6 +95,7 @@ message ContextInfo {
optional AdReplyInfo quotedAd = 23; optional AdReplyInfo quotedAd = 23;
optional MessageKey placeholderKey = 24; optional MessageKey placeholderKey = 24;
optional uint32 expiration = 25; optional uint32 expiration = 25;
optional int64 ephemeralSettingTimestamp = 26;
} }
message SenderKeyDistributionMessage { message SenderKeyDistributionMessage {
@@ -136,6 +139,11 @@ message LocationMessage {
optional string name = 3; optional string name = 3;
optional string address = 4; optional string address = 4;
optional string url = 5; optional string url = 5;
optional bool isLive = 6;
optional uint32 accuracyInMeters = 7;
optional float speedInMps = 8;
optional uint32 degreesClockwiseFromMagneticNorth = 9;
optional string comment = 11;
optional bytes jpegThumbnail = 16; optional bytes jpegThumbnail = 16;
optional ContextInfo contextInfo = 17; optional ContextInfo contextInfo = 17;
} }
@@ -238,9 +246,29 @@ message ProtocolMessage {
enum PROTOCOL_MESSAGE_TYPE { enum PROTOCOL_MESSAGE_TYPE {
REVOKE = 0; REVOKE = 0;
EPHEMERAL_SETTING = 3; EPHEMERAL_SETTING = 3;
EPHEMERAL_SYNC_RESPONSE = 4;
HISTORY_SYNC_NOTIFICATION = 5;
} }
optional PROTOCOL_MESSAGE_TYPE type = 2; optional PROTOCOL_MESSAGE_TYPE type = 2;
optional uint32 ephemeralExpiration = 4; optional uint32 ephemeralExpiration = 4;
optional int64 ephemeralSettingTimestamp = 5;
optional HistorySyncNotification historySyncNotification = 6;
}
message HistorySyncNotification {
optional bytes fileSha256 = 1;
optional uint64 fileLength = 2;
optional bytes mediaKey = 3;
optional bytes fileEncSha256 = 4;
optional string directPath = 5;
enum HISTORY_SYNC_NOTIFICATION_HISTORYSYNCTYPE {
INITIAL_BOOTSTRAP = 0;
INITIAL_STATUS_V3 = 1;
FULL = 2;
RECENT = 3;
}
optional HISTORY_SYNC_NOTIFICATION_HISTORYSYNCTYPE syncType = 6;
optional uint32 chunkOrder = 7;
} }
message ContactsArrayMessage { message ContactsArrayMessage {
@@ -355,6 +383,8 @@ message StickerMessage {
optional int64 mediaKeyTimestamp = 10; optional int64 mediaKeyTimestamp = 10;
optional uint32 firstFrameLength = 11; optional uint32 firstFrameLength = 11;
optional bytes firstFrameSidecar = 12; optional bytes firstFrameSidecar = 12;
optional bool isAnimated = 13;
optional bytes pngThumbnail = 16;
optional ContextInfo contextInfo = 17; optional ContextInfo contextInfo = 17;
} }
@@ -401,6 +431,12 @@ message TemplateButtonReplyMessage {
optional uint32 selectedIndex = 4; optional uint32 selectedIndex = 4;
} }
message CatalogSnapshot {
optional ImageMessage catalogImage = 1;
optional string title = 2;
optional string description = 3;
}
message ProductSnapshot { message ProductSnapshot {
optional ImageMessage productImage = 1; optional ImageMessage productImage = 1;
optional string productId = 2; optional string productId = 2;
@@ -417,6 +453,7 @@ message ProductSnapshot {
message ProductMessage { message ProductMessage {
optional ProductSnapshot product = 1; optional ProductSnapshot product = 1;
optional string businessOwnerJid = 2; optional string businessOwnerJid = 2;
optional CatalogSnapshot catalog = 4;
optional ContextInfo contextInfo = 17; optional ContextInfo contextInfo = 17;
} }
@@ -513,6 +550,8 @@ message WebFeatures {
optional WEB_FEATURES_FLAG templateMessage = 30; optional WEB_FEATURES_FLAG templateMessage = 30;
optional WEB_FEATURES_FLAG templateMessageInteractivity = 31; optional WEB_FEATURES_FLAG templateMessageInteractivity = 31;
optional WEB_FEATURES_FLAG ephemeralMessages = 32; optional WEB_FEATURES_FLAG ephemeralMessages = 32;
optional WEB_FEATURES_FLAG e2ENotificationSync = 33;
optional WEB_FEATURES_FLAG recentStickersV2 = 34;
} }
message TabletNotificationsInfo { message TabletNotificationsInfo {
@@ -537,6 +576,11 @@ message WebNotificationsInfo {
} }
message PaymentInfo { message PaymentInfo {
enum PAYMENT_INFO_CURRENCY {
UNKNOWN_CURRENCY = 0;
INR = 1;
}
optional PAYMENT_INFO_CURRENCY currencyDeprecated = 1;
optional uint64 amount1000 = 2; optional uint64 amount1000 = 2;
optional string receiverJid = 3; optional string receiverJid = 3;
enum PAYMENT_INFO_STATUS { enum PAYMENT_INFO_STATUS {
@@ -559,6 +603,37 @@ message PaymentInfo {
optional uint64 expiryTimestamp = 7; optional uint64 expiryTimestamp = 7;
optional bool futureproofed = 8; optional bool futureproofed = 8;
optional string currency = 9; optional string currency = 9;
enum PAYMENT_INFO_TXNSTATUS {
UNKNOWN = 0;
PENDING_SETUP = 1;
PENDING_RECEIVER_SETUP = 2;
INIT = 3;
SUCCESS = 4;
COMPLETED = 5;
FAILED = 6;
FAILED_RISK = 7;
FAILED_PROCESSING = 8;
FAILED_RECEIVER_PROCESSING = 9;
FAILED_DA = 10;
FAILED_DA_FINAL = 11;
REFUNDED_TXN = 12;
REFUND_FAILED = 13;
REFUND_FAILED_PROCESSING = 14;
REFUND_FAILED_DA = 15;
EXPIRED_TXN = 16;
AUTH_CANCELED = 17;
AUTH_CANCEL_FAILED_PROCESSING = 18;
AUTH_CANCEL_FAILED = 19;
COLLECT_INIT = 20;
COLLECT_SUCCESS = 21;
COLLECT_FAILED = 22;
COLLECT_FAILED_RISK = 23;
COLLECT_REJECTED = 24;
COLLECT_EXPIRED = 25;
COLLECT_CANCELED = 26;
COLLECT_CANCELLING = 27;
}
optional PAYMENT_INFO_TXNSTATUS txnStatus = 10;
} }
message WebMessageInfo { message WebMessageInfo {
@@ -668,4 +743,5 @@ message WebMessageInfo {
optional PaymentInfo quotedPaymentInfo = 31; optional PaymentInfo quotedPaymentInfo = 31;
optional uint64 ephemeralStartTimestamp = 32; optional uint64 ephemeralStartTimestamp = 32;
optional uint32 ephemeralDuration = 33; optional uint32 ephemeralDuration = 33;
} }

View File

@@ -6,7 +6,7 @@ require (
github.com/Rhymen/go-whatsapp/examples/sendImage v0.0.0-20190325075644-cc2581bbf24d // indirect github.com/Rhymen/go-whatsapp/examples/sendImage v0.0.0-20190325075644-cc2581bbf24d // indirect
github.com/Rhymen/go-whatsapp/examples/sendTextMessages v0.0.0-20190325075644-cc2581bbf24d // indirect github.com/Rhymen/go-whatsapp/examples/sendTextMessages v0.0.0-20190325075644-cc2581bbf24d // indirect
github.com/golang/protobuf v1.3.0 github.com/golang/protobuf v1.3.0
github.com/gorilla/websocket v1.4.0 github.com/gorilla/websocket v1.4.1
github.com/pkg/errors v0.8.1 github.com/pkg/errors v0.8.1
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2 golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2
) )

View File

@@ -12,8 +12,9 @@ github.com/Rhymen/go-whatsapp/examples/sendTextMessages v0.0.0-20190325075644-cc
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.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 h1:kbxbvI4Un1LUWKxufD+BiE6AEExYYgkQLQmLFqA1LFk=
github.com/golang/protobuf v1.3.0/go.mod h1:Qd/q+1AKNOZr9uGQzbzCmRO6sUih6GTPZv6a1/R87v0= github.com/golang/protobuf v1.3.0/go.mod h1:Qd/q+1AKNOZr9uGQzbzCmRO6sUih6GTPZv6a1/R87v0=
github.com/gorilla/websocket v1.4.0 h1:WDFjx/TMzVgy9VdMMQi2K2Emtwi2QcUQsztZ/zLaH/Q=
github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
github.com/gorilla/websocket v1.4.1 h1:q7AeDBpnBk8AogcD4DSag/Ukw/KV+YhzLj2bP5HvKCM=
github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/mattn/go-colorable v0.1.1 h1:G1f5SKeVxmagw/IyvzvtZE4Gybcc4Tr1tf7I8z0XgOg= github.com/mattn/go-colorable v0.1.1 h1:G1f5SKeVxmagw/IyvzvtZE4Gybcc4Tr1tf7I8z0XgOg=
github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ= github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ=
github.com/mattn/go-isatty v0.0.5 h1:tHXDdz1cpzGaovsTB+TVB8q90WEokoVmfMqoVcrLUgw= github.com/mattn/go-isatty v0.0.5 h1:tHXDdz1cpzGaovsTB+TVB8q90WEokoVmfMqoVcrLUgw=

View File

@@ -10,10 +10,8 @@ import (
"fmt" "fmt"
"io" "io"
"io/ioutil" "io/ioutil"
"mime/multipart"
"net/http" "net/http"
"os" "net/url"
"strings"
"time" "time"
"github.com/Rhymen/go-whatsapp/crypto/cbc" "github.com/Rhymen/go-whatsapp/crypto/cbc"
@@ -95,7 +93,50 @@ func downloadMedia(url string) (file []byte, mac []byte, err error) {
return data[:n-10], data[n-10 : n], nil return data[:n-10], data[n-10 : n], nil
} }
func (wac *Conn) Upload(reader io.Reader, appInfo MediaType) (url string, mediaKey []byte, fileEncSha256 []byte, fileSha256 []byte, fileLength uint64, err error) { type MediaConn struct {
Status int `json:"status"`
MediaConn struct {
Auth string `json:"auth"`
TTL int `json:"ttl"`
Hosts []struct {
Hostname string `json:"hostname"`
IPs []string `json:"ips"`
} `json:"hosts"`
} `json:"media_conn"`
}
func (wac *Conn) queryMediaConn() (hostname, auth string, ttl int, err error) {
queryReq := []interface{}{"query", "mediaConn"}
ch, err := wac.writeJson(queryReq)
if err != nil {
return "", "", 0, err
}
var resp MediaConn
select {
case r := <-ch:
if err = json.Unmarshal([]byte(r), &resp); err != nil {
return "", "", 0, fmt.Errorf("error decoding query media conn response: %v", err)
}
case <-time.After(wac.msgTimeout):
return "", "", 0, fmt.Errorf("query media conn timed out")
}
if resp.Status != 200 {
return "", "", 0, fmt.Errorf("query media conn responded with %d", resp.Status)
}
return resp.MediaConn.Hosts[0].Hostname, resp.MediaConn.Auth, resp.MediaConn.TTL, nil
}
var mediaTypeMap = map[MediaType]string{
MediaImage: "/mms/image",
MediaVideo: "/mms/video",
MediaDocument: "/mms/document",
MediaAudio: "/mms/audio",
}
func (wac *Conn) Upload(reader io.Reader, appInfo MediaType) (downloadURL string, mediaKey []byte, fileEncSha256 []byte, fileSha256 []byte, fileLength uint64, err error) {
data, err := ioutil.ReadAll(reader) data, err := ioutil.ReadAll(reader)
if err != nil { if err != nil {
return "", nil, nil, nil, 0, err return "", nil, nil, nil, 0, err
@@ -128,67 +169,30 @@ func (wac *Conn) Upload(reader io.Reader, appInfo MediaType) (url string, mediaK
sha.Write(append(enc, mac...)) sha.Write(append(enc, mac...))
fileEncSha256 = sha.Sum(nil) fileEncSha256 = sha.Sum(nil)
var filetype string hostname, auth, _, err := wac.queryMediaConn()
switch appInfo { token := base64.URLEncoding.EncodeToString(fileEncSha256)
case MediaImage: q := url.Values{
filetype = "image" "auth": []string{auth},
case MediaAudio: "token": []string{token},
filetype = "audio" }
case MediaDocument: path := mediaTypeMap[appInfo]
filetype = "document" uploadURL := url.URL{
case MediaVideo: Scheme: "https",
filetype = "video" Host: hostname,
Path: fmt.Sprintf("%s/%s", path, token),
RawQuery: q.Encode(),
} }
uploadReq := []interface{}{"action", "encr_upload", filetype, base64.StdEncoding.EncodeToString(fileEncSha256)} body := bytes.NewReader(append(enc, mac...))
ch, err := wac.writeJson(uploadReq)
req, err := http.NewRequest("POST", uploadURL.String(), body)
if err != nil { if err != nil {
return "", nil, nil, nil, 0, err return "", nil, nil, nil, 0, err
} }
var resp map[string]interface{}
select {
case r := <-ch:
if err = json.Unmarshal([]byte(r), &resp); err != nil {
return "", nil, nil, nil, 0, fmt.Errorf("error decoding upload response: %v", err)
}
case <-time.After(wac.msgTimeout):
return "", nil, nil, nil, 0, fmt.Errorf("restore session init timed out")
}
if int(resp["status"].(float64)) != 200 {
return "", nil, nil, nil, 0, fmt.Errorf("upload responsed with %d", resp["status"])
}
var b bytes.Buffer
w := multipart.NewWriter(&b)
hashWriter, err := w.CreateFormField("hash")
if err != nil {
fmt.Fprintf(os.Stderr, "%v\n", err)
}
io.Copy(hashWriter, strings.NewReader(base64.StdEncoding.EncodeToString(fileEncSha256)))
fileWriter, err := w.CreateFormFile("file", "blob")
if err != nil {
fmt.Fprintf(os.Stderr, "%v\n", err)
}
io.Copy(fileWriter, bytes.NewReader(append(enc, mac...)))
err = w.Close()
if err != nil {
fmt.Fprintf(os.Stderr, "%v\n", err)
}
req, err := http.NewRequest("POST", resp["url"].(string), &b)
if err != nil {
return "", nil, nil, nil, 0, err
}
req.Header.Set("Content-Type", w.FormDataContentType())
req.Header.Set("Origin", "https://web.whatsapp.com") req.Header.Set("Origin", "https://web.whatsapp.com")
req.Header.Set("Referer", "https://web.whatsapp.com/") req.Header.Set("Referer", "https://web.whatsapp.com/")
req.URL.Query().Set("f", "j")
client := &http.Client{} client := &http.Client{}
// Submit the request // Submit the request
res, err := client.Do(req) res, err := client.Do(req)

View File

@@ -15,7 +15,10 @@ import (
) )
func (wac *Conn) readPump() { func (wac *Conn) readPump() {
defer wac.wg.Done() defer func() {
wac.wg.Done()
_, _ = wac.Disconnect()
}()
var readErr error var readErr error
var msgType int var msgType int
@@ -31,7 +34,6 @@ func (wac *Conn) readPump() {
case <-readerFound: case <-readerFound:
if readErr != nil { if readErr != nil {
wac.handle(&ErrConnectionFailed{Err: readErr}) wac.handle(&ErrConnectionFailed{Err: readErr})
_, _ = wac.Disconnect()
return return
} }
msg, err := ioutil.ReadAll(reader) msg, err := ioutil.ReadAll(reader)

View File

@@ -18,7 +18,7 @@ import (
) )
//represents the WhatsAppWeb client version //represents the WhatsAppWeb client version
var waVersion = []int{0, 3, 3324} var waVersion = []int{0, 4, 2080}
/* /*
Session contains session individual information. To be able to resume the connection without scanning the qr code Session contains session individual information. To be able to resume the connection without scanning the qr code
@@ -110,7 +110,7 @@ func CheckCurrentServerVersion() ([]int, error) {
login := []interface{}{"admin", "init", waVersion, []string{wac.longClientName, wac.shortClientName}, b64ClientId, true} login := []interface{}{"admin", "init", waVersion, []string{wac.longClientName, wac.shortClientName}, b64ClientId, true}
loginChan, err := wac.writeJson(login) loginChan, err := wac.writeJson(login)
if err != nil { if err != nil {
return nil, fmt.Errorf("error writing login", err) return nil, fmt.Errorf("error writing login: %s", err.Error())
} }
// Retrieve an answer from the websocket // Retrieve an answer from the websocket
@@ -123,7 +123,7 @@ func CheckCurrentServerVersion() ([]int, error) {
var resp map[string]interface{} var resp map[string]interface{}
if err = json.Unmarshal([]byte(r), &resp); err != nil { if err = json.Unmarshal([]byte(r), &resp); err != nil {
return nil, fmt.Errorf("error decoding login", err) return nil, fmt.Errorf("error decoding login: %s", err.Error())
} }
// Take the curr property as X.Y.Z and split it into as int slice // Take the curr property as X.Y.Z and split it into as int slice
@@ -151,7 +151,7 @@ func (wac *Conn) SetClientName(long, short string) error {
/* /*
SetClientVersion sets WhatsApp client version SetClientVersion sets WhatsApp client version
Default value is 0.3.3324 Default value is 0.4.2080
*/ */
func (wac *Conn) SetClientVersion(major int, minor int, patch int) { func (wac *Conn) SetClientVersion(major int, minor int, patch int) {
waVersion = []int{major, minor, patch} waVersion = []int{major, minor, patch}

View File

@@ -11,9 +11,10 @@ builds:
- darwin - darwin
- linux - linux
- windows - windows
archive: archives:
files: -
- none* files:
- none*
checksum: checksum:
name_template: 'checksums.txt' name_template: 'checksums.txt'
changelog: changelog:

View File

@@ -7,7 +7,6 @@
[![GoDoc](https://godoc.org/github.com/d5/tengo?status.svg)](https://godoc.org/github.com/d5/tengo) [![GoDoc](https://godoc.org/github.com/d5/tengo?status.svg)](https://godoc.org/github.com/d5/tengo)
[![Go Report Card](https://goreportcard.com/badge/github.com/d5/tengo)](https://goreportcard.com/report/github.com/d5/tengo) [![Go Report Card](https://goreportcard.com/badge/github.com/d5/tengo)](https://goreportcard.com/report/github.com/d5/tengo)
[![CircleCI](https://circleci.com/gh/d5/tengo.svg?style=svg)](https://circleci.com/gh/d5/tengo) [![CircleCI](https://circleci.com/gh/d5/tengo.svg?style=svg)](https://circleci.com/gh/d5/tengo)
[![Sourcegraph](https://sourcegraph.com/github.com/d5/tengo/-/badge.svg)](https://sourcegraph.com/github.com/d5/tengo?badge)
**Tengo is a small, dynamic, fast, secure script language for Go.** **Tengo is a small, dynamic, fast, secure script language for Go.**
@@ -75,6 +74,10 @@ _* See [here](https://github.com/d5/tengobench) for commands/codes used_
## Quick Start ## Quick Start
```
go get github.com/d5/tengo/v2
```
A simple Go example code that compiles/runs Tengo script code with some input/output values: A simple Go example code that compiles/runs Tengo script code with some input/output values:
```golang ```golang

View File

@@ -13,6 +13,14 @@ var builtinFuncs = []*BuiltinFunction{
Name: "append", Name: "append",
Value: builtinAppend, Value: builtinAppend,
}, },
{
Name: "delete",
Value: builtinDelete,
},
{
Name: "splice",
Value: builtinSplice,
},
{ {
Name: "string", Name: "string",
Value: builtinString, Value: builtinString,
@@ -500,3 +508,104 @@ func builtinAppend(args ...Object) (Object, error) {
} }
} }
} }
// builtinDelete deletes Map keys
// usage: delete(map, "key")
// key must be a string
func builtinDelete(args ...Object) (Object, error) {
argsLen := len(args)
if argsLen != 2 {
return nil, ErrWrongNumArguments
}
switch arg := args[0].(type) {
case *Map:
if key, ok := args[1].(*String); ok {
delete(arg.Value, key.Value)
return UndefinedValue, nil
}
return nil, ErrInvalidArgumentType{
Name: "second",
Expected: "string",
Found: args[1].TypeName(),
}
default:
return nil, ErrInvalidArgumentType{
Name: "first",
Expected: "map",
Found: arg.TypeName(),
}
}
}
// builtinSplice deletes and changes given Array, returns deleted items.
// usage:
// deleted_items := splice(array[,start[,delete_count[,item1[,item2[,...]]]])
func builtinSplice(args ...Object) (Object, error) {
argsLen := len(args)
if argsLen == 0 {
return nil, ErrWrongNumArguments
}
array, ok := args[0].(*Array)
if !ok {
return nil, ErrInvalidArgumentType{
Name: "first",
Expected: "array",
Found: args[0].TypeName(),
}
}
arrayLen := len(array.Value)
var startIdx int
if argsLen > 1 {
arg1, ok := args[1].(*Int)
if !ok {
return nil, ErrInvalidArgumentType{
Name: "second",
Expected: "int",
Found: args[1].TypeName(),
}
}
startIdx = int(arg1.Value)
if startIdx < 0 || startIdx > arrayLen {
return nil, ErrIndexOutOfBounds
}
}
delCount := len(array.Value)
if argsLen > 2 {
arg2, ok := args[2].(*Int)
if !ok {
return nil, ErrInvalidArgumentType{
Name: "third",
Expected: "int",
Found: args[2].TypeName(),
}
}
delCount = int(arg2.Value)
if delCount < 0 {
return nil, ErrIndexOutOfBounds
}
}
// if count of to be deleted items is bigger than expected, truncate it
if startIdx+delCount > arrayLen {
delCount = arrayLen - startIdx
}
// delete items
endIdx := startIdx + delCount
deleted := append([]Object{}, array.Value[startIdx:endIdx]...)
head := array.Value[:startIdx]
var items []Object
if argsLen > 3 {
items = make([]Object, 0, argsLen-3)
for i := 3; i < argsLen; i++ {
items = append(items, args[i])
}
}
items = append(items, array.Value[endIdx:]...)
array.Value = append(head, items...)
// return deleted items
return &Array{Value: deleted}, nil
}

View File

@@ -80,14 +80,14 @@ func (v *VM) Run() (err error) {
if err != nil { if err != nil {
filePos := v.fileSet.Position( filePos := v.fileSet.Position(
v.curFrame.fn.SourcePos(v.ip - 1)) v.curFrame.fn.SourcePos(v.ip - 1))
err = fmt.Errorf("Runtime Error: %s\n\tat %s", err = fmt.Errorf("Runtime Error: %w\n\tat %s",
err.Error(), filePos) err, filePos)
for v.framesIndex > 1 { for v.framesIndex > 1 {
v.framesIndex-- v.framesIndex--
v.curFrame = &v.frames[v.framesIndex-1] v.curFrame = &v.frames[v.framesIndex-1]
filePos = v.fileSet.Position( filePos = v.fileSet.Position(
v.curFrame.fn.SourcePos(v.curFrame.ip - 1)) v.curFrame.fn.SourcePos(v.curFrame.ip - 1))
err = fmt.Errorf("%s\n\tat %s", err.Error(), filePos) err = fmt.Errorf("%w\n\tat %s", err, filePos)
} }
return err return err
} }

View File

@@ -0,0 +1,651 @@
package kbchat
import (
"encoding/json"
"errors"
"fmt"
"github.com/keybase/go-keybase-chat-bot/kbchat/types/chat1"
"github.com/keybase/go-keybase-chat-bot/kbchat/types/keybase1"
)
type Thread struct {
Result chat1.Thread `json:"result"`
Error *Error `json:"error,omitempty"`
}
type Inbox struct {
Result Result `json:"result"`
Error *Error `json:"error,omitempty"`
}
type sendMessageBody struct {
Body string
}
type sendMessageOptions struct {
Channel chat1.ChatChannel `json:"channel,omitempty"`
ConversationID chat1.ConvIDStr `json:"conversation_id,omitempty"`
Message sendMessageBody `json:",omitempty"`
Filename string `json:"filename,omitempty"`
Title string `json:"title,omitempty"`
MsgID chat1.MessageID `json:"message_id,omitempty"`
ConfirmLumenSend bool `json:"confirm_lumen_send"`
ReplyTo *chat1.MessageID `json:"reply_to,omitempty"`
}
type sendMessageParams struct {
Options sendMessageOptions
}
type sendMessageArg struct {
Method string
Params sendMessageParams
}
func newSendArg(options sendMessageOptions) sendMessageArg {
return sendMessageArg{
Method: "send",
Params: sendMessageParams{
Options: options,
},
}
}
// GetConversations reads all conversations from the current user's inbox.
func (a *API) GetConversations(unreadOnly bool) ([]chat1.ConvSummary, error) {
apiInput := fmt.Sprintf(`{"method":"list", "params": { "options": { "unread_only": %v}}}`, unreadOnly)
output, err := a.doFetch(apiInput)
if err != nil {
return nil, err
}
var inbox Inbox
if err := json.Unmarshal(output, &inbox); err != nil {
return nil, err
} else if inbox.Error != nil {
return nil, errors.New(inbox.Error.Message)
}
return inbox.Result.Convs, nil
}
func (a *API) GetConversation(convID chat1.ConvIDStr) (res chat1.ConvSummary, err error) {
apiInput := fmt.Sprintf(`{"method":"list", "params": { "options": { "conversation_id": "%s"}}}`, convID)
output, err := a.doFetch(apiInput)
if err != nil {
return res, err
}
var inbox Inbox
if err := json.Unmarshal(output, &inbox); err != nil {
return res, err
} else if inbox.Error != nil {
return res, errors.New(inbox.Error.Message)
} else if len(inbox.Result.Convs) == 0 {
return res, errors.New("conversation not found")
}
return inbox.Result.Convs[0], nil
}
// GetTextMessages fetches all text messages from a given channel. Optionally can filter
// ont unread status.
func (a *API) GetTextMessages(channel chat1.ChatChannel, unreadOnly bool) ([]chat1.MsgSummary, error) {
channelBytes, err := json.Marshal(channel)
if err != nil {
return nil, err
}
apiInput := fmt.Sprintf(`{"method": "read", "params": {"options": {"channel": %s}}}`, string(channelBytes))
output, err := a.doFetch(apiInput)
if err != nil {
return nil, err
}
var thread Thread
if err := json.Unmarshal(output, &thread); err != nil {
return nil, fmt.Errorf("unable to decode thread: %v", err)
} else if thread.Error != nil {
return nil, errors.New(thread.Error.Message)
}
var res []chat1.MsgSummary
for _, msg := range thread.Result.Messages {
if msg.Msg.Content.TypeName == "text" {
res = append(res, *msg.Msg)
}
}
return res, nil
}
func (a *API) SendMessage(channel chat1.ChatChannel, body string, args ...interface{}) (SendResponse, error) {
arg := newSendArg(sendMessageOptions{
Channel: channel,
Message: sendMessageBody{
Body: fmt.Sprintf(body, args...),
},
})
return a.doSend(arg)
}
func (a *API) Broadcast(body string, args ...interface{}) (SendResponse, error) {
return a.SendMessage(chat1.ChatChannel{
Name: a.GetUsername(),
Public: true,
}, fmt.Sprintf(body, args...))
}
func (a *API) SendMessageByConvID(convID chat1.ConvIDStr, body string, args ...interface{}) (SendResponse, error) {
arg := newSendArg(sendMessageOptions{
ConversationID: convID,
Message: sendMessageBody{
Body: fmt.Sprintf(body, args...),
},
})
return a.doSend(arg)
}
// SendMessageByTlfName sends a message on the given TLF name
func (a *API) SendMessageByTlfName(tlfName string, body string, args ...interface{}) (SendResponse, error) {
arg := newSendArg(sendMessageOptions{
Channel: chat1.ChatChannel{
Name: tlfName,
},
Message: sendMessageBody{
Body: fmt.Sprintf(body, args...),
},
})
return a.doSend(arg)
}
func (a *API) SendMessageByTeamName(teamName string, inChannel *string, body string, args ...interface{}) (SendResponse, error) {
channel := "general"
if inChannel != nil {
channel = *inChannel
}
arg := newSendArg(sendMessageOptions{
Channel: chat1.ChatChannel{
MembersType: "team",
Name: teamName,
TopicName: channel,
},
Message: sendMessageBody{
Body: fmt.Sprintf(body, args...),
},
})
return a.doSend(arg)
}
func (a *API) SendReply(channel chat1.ChatChannel, replyTo *chat1.MessageID, body string, args ...interface{}) (SendResponse, error) {
arg := newSendArg(sendMessageOptions{
Channel: channel,
Message: sendMessageBody{
Body: fmt.Sprintf(body, args...),
},
ReplyTo: replyTo,
})
return a.doSend(arg)
}
func (a *API) SendReplyByConvID(convID chat1.ConvIDStr, replyTo *chat1.MessageID, body string, args ...interface{}) (SendResponse, error) {
arg := newSendArg(sendMessageOptions{
ConversationID: convID,
Message: sendMessageBody{
Body: fmt.Sprintf(body, args...),
},
ReplyTo: replyTo,
})
return a.doSend(arg)
}
func (a *API) SendReplyByTlfName(tlfName string, replyTo *chat1.MessageID, body string, args ...interface{}) (SendResponse, error) {
arg := newSendArg(sendMessageOptions{
Channel: chat1.ChatChannel{
Name: tlfName,
},
Message: sendMessageBody{
Body: fmt.Sprintf(body, args...),
},
ReplyTo: replyTo,
})
return a.doSend(arg)
}
func (a *API) SendAttachmentByTeam(teamName string, inChannel *string, filename string, title string) (SendResponse, error) {
channel := "general"
if inChannel != nil {
channel = *inChannel
}
arg := sendMessageArg{
Method: "attach",
Params: sendMessageParams{
Options: sendMessageOptions{
Channel: chat1.ChatChannel{
MembersType: "team",
Name: teamName,
TopicName: channel,
},
Filename: filename,
Title: title,
},
},
}
return a.doSend(arg)
}
func (a *API) SendAttachmentByConvID(convID chat1.ConvIDStr, filename string, title string) (SendResponse, error) {
arg := sendMessageArg{
Method: "attach",
Params: sendMessageParams{
Options: sendMessageOptions{
ConversationID: convID,
Filename: filename,
Title: title,
},
},
}
return a.doSend(arg)
}
////////////////////////////////////////////////////////
// React to chat ///////////////////////////////////////
////////////////////////////////////////////////////////
type reactionOptions struct {
ConversationID chat1.ConvIDStr `json:"conversation_id"`
Message sendMessageBody
MsgID chat1.MessageID `json:"message_id"`
Channel chat1.ChatChannel `json:"channel"`
}
type reactionParams struct {
Options reactionOptions
}
type reactionArg struct {
Method string
Params reactionParams
}
func newReactionArg(options reactionOptions) reactionArg {
return reactionArg{
Method: "reaction",
Params: reactionParams{Options: options},
}
}
func (a *API) ReactByChannel(channel chat1.ChatChannel, msgID chat1.MessageID, reaction string) (SendResponse, error) {
arg := newReactionArg(reactionOptions{
Message: sendMessageBody{Body: reaction},
MsgID: msgID,
Channel: channel,
})
return a.doSend(arg)
}
func (a *API) ReactByConvID(convID chat1.ConvIDStr, msgID chat1.MessageID, reaction string) (SendResponse, error) {
arg := newReactionArg(reactionOptions{
Message: sendMessageBody{Body: reaction},
MsgID: msgID,
ConversationID: convID,
})
return a.doSend(arg)
}
func (a *API) EditByConvID(convID chat1.ConvIDStr, msgID chat1.MessageID, text string) (SendResponse, error) {
arg := reactionArg{
Method: "edit",
Params: reactionParams{Options: reactionOptions{
Message: sendMessageBody{Body: text},
MsgID: msgID,
ConversationID: convID,
}},
}
return a.doSend(arg)
}
////////////////////////////////////////////////////////
// Manage channels /////////////////////////////////////
////////////////////////////////////////////////////////
type ChannelsList struct {
Result Result `json:"result"`
Error *Error `json:"error,omitempty"`
}
type JoinChannel struct {
Error *Error `json:"error,omitempty"`
Result chat1.EmptyRes `json:"result"`
}
type LeaveChannel struct {
Error *Error `json:"error,omitempty"`
Result chat1.EmptyRes `json:"result"`
}
func (a *API) ListChannels(teamName string) ([]string, error) {
apiInput := fmt.Sprintf(`{"method": "listconvsonname", "params": {"options": {"topic_type": "CHAT", "members_type": "team", "name": "%s"}}}`, teamName)
output, err := a.doFetch(apiInput)
if err != nil {
return nil, err
}
var channelsList ChannelsList
if err := json.Unmarshal(output, &channelsList); err != nil {
return nil, err
} else if channelsList.Error != nil {
return nil, errors.New(channelsList.Error.Message)
}
var channels []string
for _, conv := range channelsList.Result.Convs {
channels = append(channels, conv.Channel.TopicName)
}
return channels, nil
}
func (a *API) JoinChannel(teamName string, channelName string) (chat1.EmptyRes, error) {
empty := chat1.EmptyRes{}
apiInput := fmt.Sprintf(`{"method": "join", "params": {"options": {"channel": {"name": "%s", "members_type": "team", "topic_name": "%s"}}}}`, teamName, channelName)
output, err := a.doFetch(apiInput)
if err != nil {
return empty, err
}
joinChannel := JoinChannel{}
err = json.Unmarshal(output, &joinChannel)
if err != nil {
return empty, fmt.Errorf("failed to parse output from keybase team api: %v", err)
} else if joinChannel.Error != nil {
return empty, errors.New(joinChannel.Error.Message)
}
return joinChannel.Result, nil
}
func (a *API) LeaveChannel(teamName string, channelName string) (chat1.EmptyRes, error) {
empty := chat1.EmptyRes{}
apiInput := fmt.Sprintf(`{"method": "leave", "params": {"options": {"channel": {"name": "%s", "members_type": "team", "topic_name": "%s"}}}}`, teamName, channelName)
output, err := a.doFetch(apiInput)
if err != nil {
return empty, err
}
leaveChannel := LeaveChannel{}
err = json.Unmarshal(output, &leaveChannel)
if err != nil {
return empty, fmt.Errorf("failed to parse output from keybase team api: %v", err)
} else if leaveChannel.Error != nil {
return empty, errors.New(leaveChannel.Error.Message)
}
return leaveChannel.Result, nil
}
////////////////////////////////////////////////////////
// Send lumens in chat /////////////////////////////////
////////////////////////////////////////////////////////
func (a *API) InChatSend(channel chat1.ChatChannel, body string, args ...interface{}) (SendResponse, error) {
arg := newSendArg(sendMessageOptions{
Channel: channel,
Message: sendMessageBody{
Body: fmt.Sprintf(body, args...),
},
ConfirmLumenSend: true,
})
return a.doSend(arg)
}
func (a *API) InChatSendByConvID(convID chat1.ConvIDStr, body string, args ...interface{}) (SendResponse, error) {
arg := newSendArg(sendMessageOptions{
ConversationID: convID,
Message: sendMessageBody{
Body: fmt.Sprintf(body, args...),
},
ConfirmLumenSend: true,
})
return a.doSend(arg)
}
func (a *API) InChatSendByTlfName(tlfName string, body string, args ...interface{}) (SendResponse, error) {
arg := newSendArg(sendMessageOptions{
Channel: chat1.ChatChannel{
Name: tlfName,
},
Message: sendMessageBody{
Body: fmt.Sprintf(body, args...),
},
ConfirmLumenSend: true,
})
return a.doSend(arg)
}
////////////////////////////////////////////////////////
// Misc commands ///////////////////////////////////////
////////////////////////////////////////////////////////
type Advertisement struct {
Alias string `json:"alias,omitempty"`
Advertisements []chat1.AdvertiseCommandAPIParam
}
type ListCommandsResponse struct {
Result struct {
Commands []chat1.UserBotCommandOutput `json:"commands"`
} `json:"result"`
Error *Error `json:"error,omitempty"`
}
type advertiseCmdsParams struct {
Options Advertisement
}
type advertiseCmdsMsgArg struct {
Method string
Params advertiseCmdsParams
}
func newAdvertiseCmdsMsgArg(ad Advertisement) advertiseCmdsMsgArg {
return advertiseCmdsMsgArg{
Method: "advertisecommands",
Params: advertiseCmdsParams{
Options: ad,
},
}
}
func (a *API) AdvertiseCommands(ad Advertisement) (SendResponse, error) {
return a.doSend(newAdvertiseCmdsMsgArg(ad))
}
func (a *API) ClearCommands() error {
arg := struct {
Method string
}{
Method: "clearcommands",
}
_, err := a.doSend(arg)
return err
}
type listCmdsOptions struct {
Channel chat1.ChatChannel `json:"channel,omitempty"`
ConversationID chat1.ConvIDStr `json:"conversation_id,omitempty"`
}
type listCmdsParams struct {
Options listCmdsOptions
}
type listCmdsArg struct {
Method string
Params listCmdsParams
}
func newListCmdsArg(options listCmdsOptions) listCmdsArg {
return listCmdsArg{
Method: "listcommands",
Params: listCmdsParams{
Options: options,
},
}
}
func (a *API) ListCommands(channel chat1.ChatChannel) ([]chat1.UserBotCommandOutput, error) {
arg := newListCmdsArg(listCmdsOptions{
Channel: channel,
})
return a.listCommands(arg)
}
func (a *API) ListCommandsByConvID(convID chat1.ConvIDStr) ([]chat1.UserBotCommandOutput, error) {
arg := newListCmdsArg(listCmdsOptions{
ConversationID: convID,
})
return a.listCommands(arg)
}
func (a *API) listCommands(arg listCmdsArg) ([]chat1.UserBotCommandOutput, error) {
bArg, err := json.Marshal(arg)
if err != nil {
return nil, err
}
output, err := a.doFetch(string(bArg))
if err != nil {
return nil, err
}
var res ListCommandsResponse
if err := json.Unmarshal(output, &res); err != nil {
return nil, err
} else if res.Error != nil {
return nil, errors.New(res.Error.Message)
}
return res.Result.Commands, nil
}
type listMembersOptions struct {
Channel chat1.ChatChannel `json:"channel,omitempty"`
ConversationID chat1.ConvIDStr `json:"conversation_id,omitempty"`
}
type listMembersParams struct {
Options listMembersOptions
}
type listMembersArg struct {
Method string
Params listMembersParams
}
func newListMembersArg(options listMembersOptions) listMembersArg {
return listMembersArg{
Method: "listmembers",
Params: listMembersParams{
Options: options,
},
}
}
func (a *API) ListMembers(channel chat1.ChatChannel) (keybase1.TeamMembersDetails, error) {
arg := newListMembersArg(listMembersOptions{
Channel: channel,
})
return a.listMembers(arg)
}
func (a *API) ListMembersByConvID(conversationID chat1.ConvIDStr) (keybase1.TeamMembersDetails, error) {
arg := newListMembersArg(listMembersOptions{
ConversationID: conversationID,
})
return a.listMembers(arg)
}
func (a *API) listMembers(arg listMembersArg) (res keybase1.TeamMembersDetails, err error) {
bArg, err := json.Marshal(arg)
if err != nil {
return res, err
}
output, err := a.doFetch(string(bArg))
if err != nil {
return res, err
}
members := ListTeamMembers{}
err = json.Unmarshal(output, &members)
if err != nil {
return res, UnmarshalError{err}
}
if members.Error.Message != "" {
return res, members.Error
}
return members.Result.Members, nil
}
type GetMessagesResult struct {
Result struct {
Messages []chat1.Message `json:"messages"`
} `json:"result"`
Error *Error `json:"error,omitempty"`
}
type getMessagesOptions struct {
Channel chat1.ChatChannel `json:"channel,omitempty"`
ConversationID chat1.ConvIDStr `json:"conversation_id,omitempty"`
MessageIDs []chat1.MessageID `json:"message_ids,omitempty"`
}
type getMessagesParams struct {
Options getMessagesOptions
}
type getMessagesArg struct {
Method string
Params getMessagesParams
}
func newGetMessagesArg(options getMessagesOptions) getMessagesArg {
return getMessagesArg{
Method: "get",
Params: getMessagesParams{
Options: options,
},
}
}
func (a *API) GetMessages(channel chat1.ChatChannel, msgIDs []chat1.MessageID) ([]chat1.Message, error) {
arg := newGetMessagesArg(getMessagesOptions{
Channel: channel,
MessageIDs: msgIDs,
})
return a.getMessages(arg)
}
func (a *API) GetMessagesByConvID(conversationID chat1.ConvIDStr, msgIDs []chat1.MessageID) ([]chat1.Message, error) {
arg := newGetMessagesArg(getMessagesOptions{
ConversationID: conversationID,
MessageIDs: msgIDs,
})
return a.getMessages(arg)
}
func (a *API) getMessages(arg getMessagesArg) ([]chat1.Message, error) {
bArg, err := json.Marshal(arg)
if err != nil {
return nil, err
}
output, err := a.doFetch(string(bArg))
if err != nil {
return nil, err
}
var res GetMessagesResult
err = json.Unmarshal(output, &res)
if err != nil {
return nil, UnmarshalError{err}
}
if res.Error != nil {
return nil, res.Error
}
return res.Result.Messages, nil
}

View File

@@ -0,0 +1,36 @@
package kbchat
import "fmt"
type ErrorCode int
const (
RevisionErrorCode ErrorCode = 2760
DeleteNonExistentErrorCode ErrorCode = 2762
)
// Error is for unmarshaling CLI json responses
type Error struct {
Code ErrorCode `json:"code"`
Message string `json:"message"`
}
func (e Error) Error() string {
return fmt.Sprintf("received error response from keybase api: %s", e.Message)
}
type APIError struct {
err error
}
func (e APIError) Error() string {
return fmt.Sprintf("failed to call keybase api: %v", e.err)
}
type UnmarshalError struct {
err error
}
func (e UnmarshalError) Error() string {
return fmt.Sprintf("failed to parse output from keybase api: %v", e.err)
}

View File

@@ -6,47 +6,63 @@ import (
"errors" "errors"
"fmt" "fmt"
"io" "io"
"io/ioutil"
"log" "log"
"os"
"os/exec" "os/exec"
"strings"
"sync" "sync"
"time" "time"
"github.com/keybase/go-keybase-chat-bot/kbchat/types/chat1"
"github.com/keybase/go-keybase-chat-bot/kbchat/types/keybase1"
"github.com/keybase/go-keybase-chat-bot/kbchat/types/stellar1"
) )
// API is the main object used for communicating with the Keybase JSON API // API is the main object used for communicating with the Keybase JSON API
type API struct { type API struct {
sync.Mutex sync.Mutex
apiInput io.Writer apiInput io.Writer
apiOutput *bufio.Reader apiOutput *bufio.Reader
apiCmd *exec.Cmd apiCmd *exec.Cmd
username string username string
runOpts RunOptions runOpts RunOptions
subscriptions []*NewSubscription
} }
func getUsername(runOpts RunOptions) (username string, err error) { func getUsername(runOpts RunOptions) (username string, err error) {
p := runOpts.Command("status") p := runOpts.Command("whoami", "-json")
output, err := p.StdoutPipe() output, err := p.StdoutPipe()
if err != nil { if err != nil {
return "", err return "", err
} }
p.ExtraFiles = []*os.File{output.(*os.File)}
if err = p.Start(); err != nil { if err = p.Start(); err != nil {
return "", err return "", err
} }
doneCh := make(chan error) doneCh := make(chan error)
go func() { go func() {
scanner := bufio.NewScanner(output) defer func() { close(doneCh) }()
if !scanner.Scan() { statusJSON, err := ioutil.ReadAll(output)
doneCh <- errors.New("unable to find Keybase username") if err != nil {
doneCh <- fmt.Errorf("error reading whoami output: %v", err)
return return
} }
toks := strings.Fields(scanner.Text()) var status keybase1.CurrentStatus
if len(toks) != 2 { if err := json.Unmarshal(statusJSON, &status); err != nil {
doneCh <- errors.New("invalid Keybase username output") doneCh <- fmt.Errorf("invalid whoami JSON %q: %v", statusJSON, err)
return return
} }
username = toks[1] if status.LoggedIn && status.User != nil {
doneCh <- nil username = status.User.Username
doneCh <- nil
} else {
doneCh <- fmt.Errorf("unable to authenticate to keybase service: logged in: %v user: %+v", status.LoggedIn, status.User)
}
// Cleanup the command
if err := p.Wait(); err != nil {
log.Printf("unable to wait for cmd: %v", err)
}
}() }()
select { select {
@@ -71,6 +87,10 @@ type RunOptions struct {
HomeDir string HomeDir string
Oneshot *OneshotOptions Oneshot *OneshotOptions
StartService bool StartService bool
// Have the bot send/receive typing notifications
EnableTyping bool
// Disable bot lite mode
DisableBotLiteMode bool
} }
func (r RunOptions) Location() string { func (r RunOptions) Location() string {
@@ -100,6 +120,10 @@ func Start(runOpts RunOptions) (*API, error) {
return api, nil return api, nil
} }
func (a *API) Command(args ...string) *exec.Cmd {
return a.runOpts.Command(args...)
}
func (a *API) auth() (string, error) { func (a *API) auth() (string, error) {
username, err := getUsername(a.runOpts) username, err := getUsername(a.runOpts)
if err == nil { if err == nil {
@@ -132,17 +156,28 @@ func (a *API) startPipes() (err error) {
a.Lock() a.Lock()
defer a.Unlock() defer a.Unlock()
if a.apiCmd != nil { if a.apiCmd != nil {
a.apiCmd.Process.Kill() if err := a.apiCmd.Process.Kill(); err != nil {
return err
}
} }
a.apiCmd = nil a.apiCmd = nil
if a.runOpts.StartService { if a.runOpts.StartService {
a.runOpts.Command("service").Start() args := []string{fmt.Sprintf("-enable-bot-lite-mode=%v", a.runOpts.DisableBotLiteMode), "service"}
if err := a.runOpts.Command(args...).Start(); err != nil {
return err
}
} }
if a.username, err = a.auth(); err != nil { if a.username, err = a.auth(); err != nil {
return err return err
} }
cmd := a.runOpts.Command("chat", "notification-settings", fmt.Sprintf("-disable-typing=%v", !a.runOpts.EnableTyping))
if err = cmd.Run(); err != nil {
return err
}
a.apiCmd = a.runOpts.Command("chat", "api") a.apiCmd = a.runOpts.Command("chat", "api")
if a.apiInput, err = a.apiCmd.StdinPipe(); err != nil { if a.apiInput, err = a.apiCmd.StdinPipe(); err != nil {
return err return err
@@ -151,6 +186,7 @@ func (a *API) startPipes() (err error) {
if err != nil { if err != nil {
return err return err
} }
a.apiCmd.ExtraFiles = []*os.File{output.(*os.File)}
if err := a.apiCmd.Start(); err != nil { if err := a.apiCmd.Start(); err != nil {
return err return err
} }
@@ -168,73 +204,11 @@ func (a *API) getAPIPipesLocked() (io.Writer, *bufio.Reader, error) {
return a.apiInput, a.apiOutput, nil return a.apiInput, a.apiOutput, nil
} }
// GetConversations reads all conversations from the current user's inbox. func (a *API) GetUsername() string {
func (a *API) GetConversations(unreadOnly bool) ([]Conversation, error) { return a.username
apiInput := fmt.Sprintf(`{"method":"list", "params": { "options": { "unread_only": %v}}}`, unreadOnly)
output, err := a.doFetch(apiInput)
if err != nil {
return nil, err
}
var inbox Inbox
if err := json.Unmarshal(output, &inbox); err != nil {
return nil, err
}
return inbox.Result.Convs, nil
} }
// GetTextMessages fetches all text messages from a given channel. Optionally can filter func (a *API) doSend(arg interface{}) (resp SendResponse, err error) {
// ont unread status.
func (a *API) GetTextMessages(channel Channel, unreadOnly bool) ([]Message, error) {
channelBytes, err := json.Marshal(channel)
if err != nil {
return nil, err
}
apiInput := fmt.Sprintf(`{"method": "read", "params": {"options": {"channel": %s}}}`, string(channelBytes))
output, err := a.doFetch(apiInput)
if err != nil {
return nil, err
}
var thread Thread
if err := json.Unmarshal(output, &thread); err != nil {
return nil, fmt.Errorf("unable to decode thread: %s", err.Error())
}
var res []Message
for _, msg := range thread.Result.Messages {
if msg.Msg.Content.Type == "text" {
res = append(res, msg.Msg)
}
}
return res, nil
}
type sendMessageBody struct {
Body string
}
type sendMessageOptions struct {
Channel Channel `json:"channel,omitempty"`
ConversationID string `json:"conversation_id,omitempty"`
Message sendMessageBody `json:",omitempty"`
Filename string `json:"filename,omitempty"`
Title string `json:"title,omitempty"`
MsgID int `json:"message_id,omitempty"`
}
type sendMessageParams struct {
Options sendMessageOptions
}
type sendMessageArg struct {
Method string
Params sendMessageParams
}
func (a *API) doSend(arg interface{}) (response SendResponse, err error) {
a.Lock() a.Lock()
defer a.Unlock() defer a.Unlock()
@@ -253,10 +227,12 @@ func (a *API) doSend(arg interface{}) (response SendResponse, err error) {
if err != nil { if err != nil {
return SendResponse{}, err return SendResponse{}, err
} }
if err := json.Unmarshal(responseRaw, &response); err != nil { if err := json.Unmarshal(responseRaw, &resp); err != nil {
return SendResponse{}, fmt.Errorf("failed to decode API response: %s", err) return resp, fmt.Errorf("failed to decode API response: %s", err)
} else if resp.Error != nil {
return resp, errors.New(resp.Error.Message)
} }
return response, nil return resp, nil
} }
func (a *API) doFetch(apiInput string) ([]byte, error) { func (a *API) doFetch(apiInput string) ([]byte, error) {
@@ -278,237 +254,131 @@ func (a *API) doFetch(apiInput string) ([]byte, error) {
return byteOutput, nil return byteOutput, nil
} }
func (a *API) SendMessage(channel Channel, body string) (SendResponse, error) {
arg := sendMessageArg{
Method: "send",
Params: sendMessageParams{
Options: sendMessageOptions{
Channel: channel,
Message: sendMessageBody{
Body: body,
},
},
},
}
return a.doSend(arg)
}
func (a *API) SendMessageByConvID(convID string, body string) (SendResponse, error) {
arg := sendMessageArg{
Method: "send",
Params: sendMessageParams{
Options: sendMessageOptions{
ConversationID: convID,
Message: sendMessageBody{
Body: body,
},
},
},
}
return a.doSend(arg)
}
// SendMessageByTlfName sends a message on the given TLF name
func (a *API) SendMessageByTlfName(tlfName string, body string) (SendResponse, error) {
arg := sendMessageArg{
Method: "send",
Params: sendMessageParams{
Options: sendMessageOptions{
Channel: Channel{
Name: tlfName,
},
Message: sendMessageBody{
Body: body,
},
},
},
}
return a.doSend(arg)
}
func (a *API) SendMessageByTeamName(teamName string, body string, inChannel *string) (SendResponse, error) {
channel := "general"
if inChannel != nil {
channel = *inChannel
}
arg := sendMessageArg{
Method: "send",
Params: sendMessageParams{
Options: sendMessageOptions{
Channel: Channel{
MembersType: "team",
Name: teamName,
TopicName: channel,
},
Message: sendMessageBody{
Body: body,
},
},
},
}
return a.doSend(arg)
}
func (a *API) SendAttachmentByTeam(teamName string, filename string, title string, inChannel *string) (SendResponse, error) {
channel := "general"
if inChannel != nil {
channel = *inChannel
}
arg := sendMessageArg{
Method: "attach",
Params: sendMessageParams{
Options: sendMessageOptions{
Channel: Channel{
MembersType: "team",
Name: teamName,
TopicName: channel,
},
Filename: filename,
Title: title,
},
},
}
return a.doSend(arg)
}
type reactionOptions struct {
ConversationID string `json:"conversation_id"`
Message sendMessageBody
MsgID int `json:"message_id"`
Channel Channel `json:"channel"`
}
type reactionParams struct {
Options reactionOptions
}
type reactionArg struct {
Method string
Params reactionParams
}
func newReactionArg(options reactionOptions) reactionArg {
return reactionArg{
Method: "reaction",
Params: reactionParams{Options: options},
}
}
func (a *API) ReactByChannel(channel Channel, msgID int, reaction string) (SendResponse, error) {
arg := newReactionArg(reactionOptions{
Message: sendMessageBody{Body: reaction},
MsgID: msgID,
Channel: channel,
})
return a.doSend(arg)
}
func (a *API) ReactByConvID(convID string, msgID int, reaction string) (SendResponse, error) {
arg := newReactionArg(reactionOptions{
Message: sendMessageBody{Body: reaction},
MsgID: msgID,
ConversationID: convID,
})
return a.doSend(arg)
}
type advertiseParams struct {
Options Advertisement
}
type advertiseMsgArg struct {
Method string
Params advertiseParams
}
func newAdvertiseMsgArg(ad Advertisement) advertiseMsgArg {
return advertiseMsgArg{
Method: "advertisecommands",
Params: advertiseParams{
Options: ad,
},
}
}
func (a *API) AdvertiseCommands(ad Advertisement) (SendResponse, error) {
return a.doSend(newAdvertiseMsgArg(ad))
}
func (a *API) Username() string {
return a.username
}
// SubscriptionMessage contains a message and conversation object // SubscriptionMessage contains a message and conversation object
type SubscriptionMessage struct { type SubscriptionMessage struct {
Message Message Message chat1.MsgSummary
Conversation Conversation Conversation chat1.ConvSummary
}
type SubscriptionConversation struct {
Conversation chat1.ConvSummary
} }
type SubscriptionWalletEvent struct { type SubscriptionWalletEvent struct {
Payment Payment Payment stellar1.PaymentDetailsLocal
} }
// NewSubscription has methods to control the background message fetcher loop // NewSubscription has methods to control the background message fetcher loop
type NewSubscription struct { type NewSubscription struct {
sync.Mutex
newMsgsCh <-chan SubscriptionMessage newMsgsCh <-chan SubscriptionMessage
newConvsCh <-chan SubscriptionConversation
newWalletCh <-chan SubscriptionWalletEvent newWalletCh <-chan SubscriptionWalletEvent
errorCh <-chan error errorCh <-chan error
running bool
shutdownCh chan struct{} shutdownCh chan struct{}
} }
// Read blocks until a new message arrives // Read blocks until a new message arrives
func (m NewSubscription) Read() (SubscriptionMessage, error) { func (m *NewSubscription) Read() (SubscriptionMessage, error) {
select { select {
case msg := <-m.newMsgsCh: case msg := <-m.newMsgsCh:
return msg, nil return msg, nil
case err := <-m.errorCh: case err := <-m.errorCh:
return SubscriptionMessage{}, err return SubscriptionMessage{}, err
case <-m.shutdownCh:
return SubscriptionMessage{}, errors.New("Subscription shutdown")
}
}
func (m *NewSubscription) ReadNewConvs() (SubscriptionConversation, error) {
select {
case conv := <-m.newConvsCh:
return conv, nil
case err := <-m.errorCh:
return SubscriptionConversation{}, err
case <-m.shutdownCh:
return SubscriptionConversation{}, errors.New("Subscription shutdown")
} }
} }
// Read blocks until a new message arrives // Read blocks until a new message arrives
func (m NewSubscription) ReadWallet() (SubscriptionWalletEvent, error) { func (m *NewSubscription) ReadWallet() (SubscriptionWalletEvent, error) {
select { select {
case msg := <-m.newWalletCh: case msg := <-m.newWalletCh:
return msg, nil return msg, nil
case err := <-m.errorCh: case err := <-m.errorCh:
return SubscriptionWalletEvent{}, err return SubscriptionWalletEvent{}, err
case <-m.shutdownCh:
return SubscriptionWalletEvent{}, errors.New("Subscription shutdown")
} }
} }
// Shutdown terminates the background process // Shutdown terminates the background process
func (m NewSubscription) Shutdown() { func (m *NewSubscription) Shutdown() {
m.shutdownCh <- struct{}{} m.Lock()
defer m.Unlock()
if m.running {
close(m.shutdownCh)
m.running = false
}
} }
type ListenOptions struct { type ListenOptions struct {
Wallet bool Wallet bool
Convs bool
}
type PaymentHolder struct {
Payment stellar1.PaymentDetailsLocal `json:"notification"`
}
type TypeHolder struct {
Type string `json:"type"`
} }
// ListenForNewTextMessages proxies to Listen without wallet events // ListenForNewTextMessages proxies to Listen without wallet events
func (a *API) ListenForNewTextMessages() (NewSubscription, error) { func (a *API) ListenForNewTextMessages() (*NewSubscription, error) {
opts := ListenOptions{Wallet: false} opts := ListenOptions{Wallet: false}
return a.Listen(opts) return a.Listen(opts)
} }
func (a *API) registerSubscription(sub *NewSubscription) {
a.Lock()
defer a.Unlock()
a.subscriptions = append(a.subscriptions, sub)
}
// Listen fires of a background loop and puts chat messages and wallet // Listen fires of a background loop and puts chat messages and wallet
// events into channels // events into channels
func (a *API) Listen(opts ListenOptions) (NewSubscription, error) { func (a *API) Listen(opts ListenOptions) (*NewSubscription, error) {
newMsgCh := make(chan SubscriptionMessage, 100) newMsgsCh := make(chan SubscriptionMessage, 100)
newConvsCh := make(chan SubscriptionConversation, 100)
newWalletCh := make(chan SubscriptionWalletEvent, 100) newWalletCh := make(chan SubscriptionWalletEvent, 100)
errorCh := make(chan error, 100) errorCh := make(chan error, 100)
shutdownCh := make(chan struct{}) shutdownCh := make(chan struct{})
done := make(chan struct{}) done := make(chan struct{})
sub := NewSubscription{ sub := &NewSubscription{
newMsgsCh: newMsgCh, newMsgsCh: newMsgsCh,
newConvsCh: newConvsCh,
newWalletCh: newWalletCh, newWalletCh: newWalletCh,
shutdownCh: shutdownCh, shutdownCh: shutdownCh,
errorCh: errorCh, errorCh: errorCh,
running: true,
} }
a.registerSubscription(sub)
pause := 2 * time.Second pause := 2 * time.Second
readScanner := func(boutput *bufio.Scanner) { readScanner := func(boutput *bufio.Scanner) {
defer func() { done <- struct{}{} }()
for { for {
select {
case <-shutdownCh:
log.Printf("readScanner: received shutdown")
return
default:
}
boutput.Scan() boutput.Scan()
t := boutput.Text() t := boutput.Text()
var typeHolder TypeHolder var typeHolder TypeHolder
@@ -518,41 +388,72 @@ func (a *API) Listen(opts ListenOptions) (NewSubscription, error) {
} }
switch typeHolder.Type { switch typeHolder.Type {
case "chat": case "chat":
var holder MessageHolder var notification chat1.MsgNotification
if err := json.Unmarshal([]byte(t), &holder); err != nil { if err := json.Unmarshal([]byte(t), &notification); err != nil {
errorCh <- err errorCh <- err
break break
} }
subscriptionMessage := SubscriptionMessage{ if notification.Error != nil {
Message: holder.Msg, log.Printf("error message received: %s", *notification.Error)
Conversation: Conversation{ } else if notification.Msg != nil {
ID: holder.Msg.ConversationID, subscriptionMessage := SubscriptionMessage{
Channel: holder.Msg.Channel, Message: *notification.Msg,
}, Conversation: chat1.ConvSummary{
Id: notification.Msg.ConvID,
Channel: notification.Msg.Channel,
},
}
newMsgsCh <- subscriptionMessage
}
case "chat_conv":
var notification chat1.ConvNotification
if err := json.Unmarshal([]byte(t), &notification); err != nil {
errorCh <- err
break
}
if notification.Error != nil {
log.Printf("error message received: %s", *notification.Error)
} else if notification.Conv != nil {
subscriptionConv := SubscriptionConversation{
Conversation: *notification.Conv,
}
newConvsCh <- subscriptionConv
} }
newMsgCh <- subscriptionMessage
case "wallet": case "wallet":
var holder PaymentHolder var holder PaymentHolder
if err := json.Unmarshal([]byte(t), &holder); err != nil { if err := json.Unmarshal([]byte(t), &holder); err != nil {
errorCh <- err errorCh <- err
break break
} }
subscriptionPayment := SubscriptionWalletEvent{ subscriptionPayment := SubscriptionWalletEvent(holder)
Payment: holder.Payment,
}
newWalletCh <- subscriptionPayment newWalletCh <- subscriptionPayment
default: default:
continue continue
} }
} }
done <- struct{}{}
} }
attempts := 0 attempts := 0
maxAttempts := 1800 maxAttempts := 1800
go func() { go func() {
defer func() {
close(newMsgsCh)
close(newConvsCh)
close(newWalletCh)
close(errorCh)
}()
for { for {
select {
case <-shutdownCh:
log.Printf("Listen: received shutdown")
return
default:
}
if attempts >= maxAttempts { if attempts >= maxAttempts {
if err := a.LogSend("Listen: failed to auth, giving up"); err != nil {
log.Printf("Listen: logsend failed to send: %v", err)
}
panic("Listen: failed to auth, giving up") panic("Listen: failed to auth, giving up")
} }
attempts++ attempts++
@@ -565,6 +466,9 @@ func (a *API) Listen(opts ListenOptions) (NewSubscription, error) {
if opts.Wallet { if opts.Wallet {
cmdElements = append(cmdElements, "--wallet") cmdElements = append(cmdElements, "--wallet")
} }
if opts.Convs {
cmdElements = append(cmdElements, "--convs")
}
p := a.runOpts.Command(cmdElements...) p := a.runOpts.Command(cmdElements...)
output, err := p.StdoutPipe() output, err := p.StdoutPipe()
if err != nil { if err != nil {
@@ -572,8 +476,16 @@ func (a *API) Listen(opts ListenOptions) (NewSubscription, error) {
time.Sleep(pause) time.Sleep(pause)
continue continue
} }
stderr, err := p.StderrPipe()
if err != nil {
log.Printf("Listen: failed to listen to stderr: %s", err)
time.Sleep(pause)
continue
}
p.ExtraFiles = []*os.File{stderr.(*os.File), output.(*os.File)}
boutput := bufio.NewScanner(output) boutput := bufio.NewScanner(output)
if err := p.Start(); err != nil { if err := p.Start(); err != nil {
log.Printf("Listen: failed to make listen scanner: %s", err) log.Printf("Listen: failed to make listen scanner: %s", err)
time.Sleep(pause) time.Sleep(pause)
continue continue
@@ -581,78 +493,19 @@ func (a *API) Listen(opts ListenOptions) (NewSubscription, error) {
attempts = 0 attempts = 0
go readScanner(boutput) go readScanner(boutput)
<-done <-done
p.Wait() if err := p.Wait(); err != nil {
stderrBytes, rerr := ioutil.ReadAll(stderr)
if rerr != nil {
stderrBytes = []byte("failed to get stderr")
}
log.Printf("Listen: failed to Wait for command: %s (```%s```)", err, stderrBytes)
}
time.Sleep(pause) time.Sleep(pause)
} }
}() }()
return sub, nil return sub, nil
} }
func (a *API) GetUsername() string {
return a.username
}
func (a *API) ListChannels(teamName string) ([]string, error) {
apiInput := fmt.Sprintf(`{"method": "listconvsonname", "params": {"options": {"topic_type": "CHAT", "members_type": "team", "name": "%s"}}}`, teamName)
output, err := a.doFetch(apiInput)
if err != nil {
return nil, err
}
var channelsList ChannelsList
if err := json.Unmarshal(output, &channelsList); err != nil {
return nil, err
}
var channels []string
for _, conv := range channelsList.Result.Convs {
channels = append(channels, conv.Channel.TopicName)
}
return channels, nil
}
func (a *API) JoinChannel(teamName string, channelName string) (JoinChannelResult, error) {
empty := JoinChannelResult{}
apiInput := fmt.Sprintf(`{"method": "join", "params": {"options": {"channel": {"name": "%s", "members_type": "team", "topic_name": "%s"}}}}`, teamName, channelName)
output, err := a.doFetch(apiInput)
if err != nil {
return empty, err
}
joinChannel := JoinChannel{}
err = json.Unmarshal(output, &joinChannel)
if err != nil {
return empty, fmt.Errorf("failed to parse output from keybase team api: %v", err)
}
if joinChannel.Error.Message != "" {
return empty, fmt.Errorf("received error from keybase team api: %s", joinChannel.Error.Message)
}
return joinChannel.Result, nil
}
func (a *API) LeaveChannel(teamName string, channelName string) (LeaveChannelResult, error) {
empty := LeaveChannelResult{}
apiInput := fmt.Sprintf(`{"method": "leave", "params": {"options": {"channel": {"name": "%s", "members_type": "team", "topic_name": "%s"}}}}`, teamName, channelName)
output, err := a.doFetch(apiInput)
if err != nil {
return empty, err
}
leaveChannel := LeaveChannel{}
err = json.Unmarshal(output, &leaveChannel)
if err != nil {
return empty, fmt.Errorf("failed to parse output from keybase team api: %v", err)
}
if leaveChannel.Error.Message != "" {
return empty, fmt.Errorf("received error from keybase team api: %s", leaveChannel.Error.Message)
}
return leaveChannel.Result, nil
}
func (a *API) LogSend(feedback string) error { func (a *API) LogSend(feedback string) error {
feedback = "go-keybase-chat-bot log send\n" + feedback = "go-keybase-chat-bot log send\n" +
"username: " + a.GetUsername() + "\n" + "username: " + a.GetUsername() + "\n" +
@@ -675,6 +528,17 @@ func (a *API) LogSend(feedback string) error {
} }
func (a *API) Shutdown() error { func (a *API) Shutdown() error {
a.Lock()
defer a.Unlock()
for _, sub := range a.subscriptions {
sub.Shutdown()
}
if a.apiCmd != nil {
if err := a.apiCmd.Wait(); err != nil {
return err
}
}
if a.runOpts.Oneshot != nil { if a.runOpts.Oneshot != nil {
err := a.runOpts.Command("logout", "--force").Run() err := a.runOpts.Command("logout", "--force").Run()
if err != nil { if err != nil {

View File

@@ -0,0 +1,228 @@
package kbchat
import (
"encoding/json"
"strings"
"github.com/keybase/go-keybase-chat-bot/kbchat/types/keybase1"
)
type kvstoreMethod string
type kvstoreOptions struct {
Team *string `json:"team"`
Namespace *string `json:"namespace,omitempty"`
EntryKey *string `json:"entryKey,omitempty"`
EntryValue *string `json:"entryValue,omitempty"`
Revision *int `json:"revision,omitempty"`
}
type kvstoreParams struct {
Options kvstoreOptions `json:"options"`
}
type kvstoreAPIReq struct {
Method kvstoreMethod `json:"method"`
Params kvstoreParams `json:"params"`
}
type GetEntryRes struct {
Result keybase1.KVGetResult `json:"result"`
Error Error `json:"error,omitempty"`
}
type PutEntryRes struct {
Result keybase1.KVPutResult `json:"result"`
Error Error `json:"error,omitempty"`
}
type DeleteEntryRes struct {
Result keybase1.KVDeleteEntryResult `json:"result"`
Error Error `json:"error,omitempty"`
}
type ListNamespacesRes struct {
Result keybase1.KVListNamespaceResult `json:"result"`
Error Error `json:"error,omitempty"`
}
type ListEntryKeysRes struct {
Result keybase1.KVListEntryResult `json:"result"`
Error Error `json:"error,omitempty"`
}
type KVStoreAPI interface {
PutEntry(teamName *string, namespace string, entryKey string, entryValue string) (keybase1.KVPutResult, error)
PutEntryWithRevision(teamName *string, namespace string, entryKey string, entryValue string, revision int) (keybase1.KVPutResult, error)
DeleteEntry(teamName *string, namespace string, entryKey string) (keybase1.KVDeleteEntryResult, error)
DeleteEntryWithRevision(teamName *string, namespace string, entryKey string, revision int) (keybase1.KVDeleteEntryResult, error)
GetEntry(teamName *string, namespace string, entryKey string) (keybase1.KVGetResult, error)
ListNamespaces(teamName *string) (keybase1.KVListNamespaceResult, error)
ListEntryKeys(teamName *string, namespace string) (keybase1.KVListEntryResult, error)
}
func (a *API) PutEntry(teamName *string, namespace string, entryKey string, entryValue string) (result keybase1.KVPutResult, err error) {
return a.PutEntryWithRevision(teamName, namespace, entryKey, entryValue, 0)
}
func (a *API) PutEntryWithRevision(teamName *string, namespace string, entryKey string, entryValue string, revision int) (result keybase1.KVPutResult, err error) {
opts := kvstoreOptions{
Team: teamName,
Namespace: &namespace,
EntryKey: &entryKey,
EntryValue: &entryValue,
}
if revision != 0 {
opts.Revision = &revision
}
args := kvstoreAPIReq{Method: "put", Params: kvstoreParams{Options: opts}}
apiInput, err := json.Marshal(args)
if err != nil {
return result, err
}
cmd := a.runOpts.Command("kvstore", "api")
cmd.Stdin = strings.NewReader(string(apiInput))
bytes, err := cmd.Output()
if err != nil {
return result, APIError{err}
}
entry := PutEntryRes{}
err = json.Unmarshal(bytes, &entry)
if err != nil {
return result, UnmarshalError{err}
}
if entry.Error.Message != "" {
return result, entry.Error
}
return entry.Result, nil
}
func (a *API) DeleteEntry(teamName *string, namespace string, entryKey string) (result keybase1.KVDeleteEntryResult, err error) {
return a.DeleteEntryWithRevision(teamName, namespace, entryKey, 0)
}
func (a *API) DeleteEntryWithRevision(teamName *string, namespace string, entryKey string, revision int) (result keybase1.KVDeleteEntryResult, err error) {
opts := kvstoreOptions{
Team: teamName,
Namespace: &namespace,
EntryKey: &entryKey,
}
if revision != 0 {
opts.Revision = &revision
}
args := kvstoreAPIReq{Method: "del", Params: kvstoreParams{Options: opts}}
apiInput, err := json.Marshal(args)
if err != nil {
return result, err
}
cmd := a.runOpts.Command("kvstore", "api")
cmd.Stdin = strings.NewReader(string(apiInput))
bytes, err := cmd.Output()
if err != nil {
return result, APIError{err}
}
entry := DeleteEntryRes{}
err = json.Unmarshal(bytes, &entry)
if err != nil {
return result, UnmarshalError{err}
}
if entry.Error.Message != "" {
return result, entry.Error
}
return entry.Result, nil
}
func (a *API) GetEntry(teamName *string, namespace string, entryKey string) (result keybase1.KVGetResult, err error) {
opts := kvstoreOptions{
Team: teamName,
Namespace: &namespace,
EntryKey: &entryKey,
}
args := kvstoreAPIReq{Method: "get", Params: kvstoreParams{Options: opts}}
apiInput, err := json.Marshal(args)
if err != nil {
return result, err
}
cmd := a.runOpts.Command("kvstore", "api")
cmd.Stdin = strings.NewReader(string(apiInput))
bytes, err := cmd.Output()
if err != nil {
return result, APIError{err}
}
entry := GetEntryRes{}
err = json.Unmarshal(bytes, &entry)
if err != nil {
return result, UnmarshalError{err}
}
if entry.Error.Message != "" {
return result, entry.Error
}
return entry.Result, nil
}
func (a *API) ListNamespaces(teamName *string) (result keybase1.KVListNamespaceResult, err error) {
opts := kvstoreOptions{
Team: teamName,
}
args := kvstoreAPIReq{Method: "list", Params: kvstoreParams{Options: opts}}
apiInput, err := json.Marshal(args)
if err != nil {
return result, err
}
cmd := a.runOpts.Command("kvstore", "api")
cmd.Stdin = strings.NewReader(string(apiInput))
bytes, err := cmd.Output()
if err != nil {
return result, APIError{err}
}
var namespaces ListNamespacesRes
err = json.Unmarshal(bytes, &namespaces)
if err != nil {
return result, UnmarshalError{err}
}
if namespaces.Error.Message != "" {
return result, namespaces.Error
}
return namespaces.Result, nil
}
func (a *API) ListEntryKeys(teamName *string, namespace string) (result keybase1.KVListEntryResult, err error) {
opts := kvstoreOptions{
Team: teamName,
Namespace: &namespace,
}
args := kvstoreAPIReq{Method: "list", Params: kvstoreParams{Options: opts}}
apiInput, err := json.Marshal(args)
if err != nil {
return result, err
}
cmd := a.runOpts.Command("kvstore", "api")
cmd.Stdin = strings.NewReader(string(apiInput))
bytes, err := cmd.Output()
if err != nil {
return result, APIError{err}
}
entryKeys := ListEntryKeysRes{}
err = json.Unmarshal(bytes, &entryKeys)
if err != nil {
return result, UnmarshalError{err}
}
if entryKeys.Error.Message != "" {
return result, entryKeys.Error
}
return entryKeys.Result, nil
}

View File

@@ -1,25 +1,18 @@
package kbchat package kbchat
import ( import (
"bytes"
"encoding/json" "encoding/json"
"fmt" "fmt"
"log"
"strings" "strings"
"github.com/keybase/go-keybase-chat-bot/kbchat/types/keybase1"
) )
type ListTeamMembers struct { type ListTeamMembers struct {
Result ListTeamMembersResult `json:"result"` Result keybase1.TeamDetails `json:"result"`
Error Error `json:"error"` Error Error `json:"error"`
}
type ListTeamMembersResult struct {
Members ListTeamMembersResultMembers `json:"members"`
}
type ListTeamMembersResultMembers struct {
Owners []ListMembersOutputMembersCategory `json:"owners"`
Admins []ListMembersOutputMembersCategory `json:"admins"`
Writers []ListMembersOutputMembersCategory `json:"writers"`
Readers []ListMembersOutputMembersCategory `json:"readers"`
} }
type ListMembersOutputMembersCategory struct { type ListMembersOutputMembersCategory struct {
@@ -28,62 +21,56 @@ type ListMembersOutputMembersCategory struct {
} }
type ListUserMemberships struct { type ListUserMemberships struct {
Result ListUserMembershipsResult `json:"result"` Result keybase1.AnnotatedTeamList `json:"result"`
Error Error `json:"error"` Error Error `json:"error"`
} }
type ListUserMembershipsResult struct { func (a *API) ListMembersOfTeam(teamName string) (res keybase1.TeamMembersDetails, err error) {
Teams []ListUserMembershipsResultTeam `json:"teams"`
}
type ListUserMembershipsResultTeam struct {
TeamName string `json:"fq_name"`
IsImplicitTeam bool `json:"is_implicit_team"`
IsOpenTeam bool `json:"is_open_team"`
Role int `json:"role"`
MemberCount int `json:"member_count"`
}
func (a *API) ListMembersOfTeam(teamName string) (ListTeamMembersResultMembers, error) {
empty := ListTeamMembersResultMembers{}
apiInput := fmt.Sprintf(`{"method": "list-team-memberships", "params": {"options": {"team": "%s"}}}`, teamName) apiInput := fmt.Sprintf(`{"method": "list-team-memberships", "params": {"options": {"team": "%s"}}}`, teamName)
cmd := a.runOpts.Command("team", "api") cmd := a.runOpts.Command("team", "api")
cmd.Stdin = strings.NewReader(apiInput) cmd.Stdin = strings.NewReader(apiInput)
bytes, err := cmd.CombinedOutput() var stderr bytes.Buffer
cmd.Stderr = &stderr
output, err := cmd.Output()
if err != nil { if err != nil {
return empty, fmt.Errorf("failed to call keybase team api: %v", err) return res, APIError{err}
}
if stderr.Len() != 0 {
log.Printf("ListMembersOfTeam error: %s", stderr.String())
} }
members := ListTeamMembers{} members := ListTeamMembers{}
err = json.Unmarshal(bytes, &members) err = json.Unmarshal(output, &members)
if err != nil { if err != nil {
return empty, fmt.Errorf("failed to parse output from keybase team api: %v", err) return res, UnmarshalError{err}
} }
if members.Error.Message != "" { if members.Error.Message != "" {
return empty, fmt.Errorf("received error from keybase team api: %s", members.Error.Message) return res, members.Error
} }
return members.Result.Members, nil return members.Result.Members, nil
} }
func (a *API) ListUserMemberships(username string) ([]ListUserMembershipsResultTeam, error) { func (a *API) ListUserMemberships(username string) ([]keybase1.AnnotatedMemberInfo, error) {
empty := []ListUserMembershipsResultTeam{}
apiInput := fmt.Sprintf(`{"method": "list-user-memberships", "params": {"options": {"username": "%s"}}}`, username) apiInput := fmt.Sprintf(`{"method": "list-user-memberships", "params": {"options": {"username": "%s"}}}`, username)
cmd := a.runOpts.Command("team", "api") cmd := a.runOpts.Command("team", "api")
cmd.Stdin = strings.NewReader(apiInput) cmd.Stdin = strings.NewReader(apiInput)
bytes, err := cmd.CombinedOutput() var stderr bytes.Buffer
cmd.Stderr = &stderr
output, err := cmd.Output()
if err != nil { if err != nil {
return empty, fmt.Errorf("failed to call keybase team api: %v", err) return nil, APIError{err}
}
if stderr.Len() != 0 {
log.Printf("ListUserMemberships error: %s", stderr.String())
} }
members := ListUserMemberships{} members := ListUserMemberships{}
err = json.Unmarshal(bytes, &members) err = json.Unmarshal(output, &members)
if err != nil { if err != nil {
return empty, fmt.Errorf("failed to parse output from keybase team api: %v", err) return nil, UnmarshalError{err}
} }
if members.Error.Message != "" { if members.Error.Message != "" {
return empty, fmt.Errorf("received error from keybase team api: %s", members.Error.Message) return nil, members.Error
} }
return members.Result.Teams, nil return members.Result.Teams, nil
} }

View File

@@ -1,16 +1,17 @@
# Rename this file to `test_config.yaml` # Rename this file to `test_config.yaml`
config: keybase: "/path/to/keybase"
bots: bots:
alice: # Alice should have an active Stellar account with a little bit of XLM in it
username: "alice" alice:
paperkey: "foo bar car..." username: "alice"
bob: paperkey: "foo bar car..."
username: "bob" bob:
paperkey: "one two three four..." username: "bob"
teams: paperkey: "one two three four..."
acme: teams:
# A real team that you add your alice1 and bob1 into acme:
name: "acme" # A real team that you add your alice and bob into
# The channel to use name: "acme"
topicname: "mysupercoolchannel" # The channel to use
topicname: "mysupercoolchannel"

View File

@@ -41,9 +41,7 @@ func copyFile(t *testing.T, source, dest string) {
// Creates the working directory and copies over the keybase binary in PATH. // Creates the working directory and copies over the keybase binary in PATH.
// We do this to avoid any version mismatch issues. // We do this to avoid any version mismatch issues.
func prepWorkingDir(t *testing.T, workingDir string) string { func prepWorkingDir(t *testing.T, workingDir string, kbLocation string) string {
kbLocation := whichKeybase(t)
err := os.Mkdir(workingDir, 0777) err := os.Mkdir(workingDir, 0777)
require.NoError(t, err) require.NoError(t, err)
kbDestination := path.Join(workingDir, "keybase") kbDestination := path.Join(workingDir, "keybase")

View File

@@ -1,159 +1,14 @@
package kbchat package kbchat
type Sender struct { import (
Uid string `json:"uid"` "github.com/keybase/go-keybase-chat-bot/kbchat/types/chat1"
Username string `json:"username"` )
DeviceID string `json:"device_id"`
DeviceName string `json:"device_name"`
}
type Channel struct {
Name string `json:"name"`
Public bool `json:"public"`
TopicType string `json:"topic_type"`
TopicName string `json:"topic_name"`
MembersType string `json:"members_type"`
}
type Conversation struct {
ID string `json:"id"`
Unread bool `json:"unread"`
Channel Channel `json:"channel"`
}
type PaymentHolder struct {
Payment Payment `json:"notification"`
}
type Payment struct {
TxID string `json:"txID"`
StatusDescription string `json:"statusDescription"`
FromAccountID string `json:"fromAccountID"`
FromUsername string `json:"fromUsername"`
ToAccountID string `json:"toAccountID"`
ToUsername string `json:"toUsername"`
AmountDescription string `json:"amountDescription"`
WorthAtSendTime string `json:"worthAtSendTime"`
ExternalTxURL string `json:"externalTxURL"`
}
type Result struct { type Result struct {
Convs []Conversation `json:"conversations"` Convs []chat1.ConvSummary `json:"conversations"`
}
type Inbox struct {
Result Result `json:"result"`
}
type ChannelsList struct {
Result Result `json:"result"`
}
type MsgPaymentDetails struct {
ResultType int `json:"resultTyp"` // 0 good. 1 error
PaymentID string `json:"sent"`
}
type MsgPayment struct {
Username string `json:"username"`
PaymentText string `json:"paymentText"`
Details MsgPaymentDetails `json:"result"`
}
type Text struct {
Body string `json:"body"`
Payments []MsgPayment `json:"payments"`
ReplyTo int `json:"replyTo"`
}
type Content struct {
Type string `json:"type"`
Text Text `json:"text"`
}
type Message struct {
Content Content `json:"content"`
Sender Sender `json:"sender"`
Channel Channel `json:"channel"`
ConversationID string `json:"conversation_id"`
MsgID int `json:"id"`
}
type SendResult struct {
MsgID int `json:"id"`
} }
type SendResponse struct { type SendResponse struct {
Result SendResult `json:"result"` Result chat1.SendRes `json:"result"`
} Error *Error `json:"error,omitempty"`
type TypeHolder struct {
Type string `json:"type"`
}
type MessageHolder struct {
Msg Message `json:"msg"`
Source string `json:"source"`
}
type ThreadResult struct {
Messages []MessageHolder `json:"messages"`
}
type Thread struct {
Result ThreadResult `json:"result"`
}
type CommandExtendedDescription struct {
Title string `json:"title"`
DesktopBody string `json:"desktop_body"`
MobileBody string `json:"mobile_body"`
}
type Command struct {
Name string `json:"name"`
Description string `json:"description"`
Usage string `json:"usage"`
ExtendedDescription *CommandExtendedDescription `json:"extended_description,omitempty"`
}
type CommandsAdvertisement struct {
Typ string `json:"type"`
Commands []Command
TeamName string `json:"team_name,omitempty"`
}
type Advertisement struct {
Alias string `json:"alias,omitempty"`
Advertisements []CommandsAdvertisement
}
type Error struct {
Code int `json:"code"`
Message string `json:"message"`
}
type JoinChannel struct {
Error Error `json:"error"`
Result JoinChannelResult `json:"result"`
}
type JoinChannelResult struct {
RateLimit []RateLimit `json:"ratelimits"`
}
type LeaveChannel struct {
Error Error `json:"error"`
Result LeaveChannelResult `json:"result"`
}
type LeaveChannelResult struct {
RateLimit []RateLimit `json:"ratelimits"`
}
type RateLimit struct {
Tank string `json:"tank"`
Capacity int `json:"capacity"`
Reset int `json:"reset"`
Gas int `json:"gas"`
} }

View File

@@ -0,0 +1,933 @@
// Auto-generated to Go types using avdl-compiler v1.4.6 (https://github.com/keybase/node-avdl-compiler)
// Input file: ../client/protocol/avdl/chat1/api.avdl
package chat1
import (
gregor1 "github.com/keybase/go-keybase-chat-bot/kbchat/types/gregor1"
keybase1 "github.com/keybase/go-keybase-chat-bot/kbchat/types/keybase1"
)
type ConvIDStr string
func (o ConvIDStr) DeepCopy() ConvIDStr {
return o
}
type TLFIDStr string
func (o TLFIDStr) DeepCopy() TLFIDStr {
return o
}
type FlipGameIDStr string
func (o FlipGameIDStr) DeepCopy() FlipGameIDStr {
return o
}
type RateLimitRes struct {
Tank string `codec:"tank" json:"tank"`
Capacity int `codec:"capacity" json:"capacity"`
Reset int `codec:"reset" json:"reset"`
Gas int `codec:"gas" json:"gas"`
}
func (o RateLimitRes) DeepCopy() RateLimitRes {
return RateLimitRes{
Tank: o.Tank,
Capacity: o.Capacity,
Reset: o.Reset,
Gas: o.Gas,
}
}
// A Keybase chat channel. This can be a channel in a team, or just an informal channel between two users.
// name: the name of the team or comma-separated list of participants
type ChatChannel struct {
Name string `codec:"name" json:"name"`
Public bool `codec:"public,omitempty" json:"public,omitempty"`
MembersType string `codec:"membersType,omitempty" json:"members_type,omitempty"`
TopicType string `codec:"topicType,omitempty" json:"topic_type,omitempty"`
TopicName string `codec:"topicName,omitempty" json:"topic_name,omitempty"`
}
func (o ChatChannel) DeepCopy() ChatChannel {
return ChatChannel{
Name: o.Name,
Public: o.Public,
MembersType: o.MembersType,
TopicType: o.TopicType,
TopicName: o.TopicName,
}
}
// A chat message. The content goes in the `body` property!
type ChatMessage struct {
Body string `codec:"body" json:"body"`
}
func (o ChatMessage) DeepCopy() ChatMessage {
return ChatMessage{
Body: o.Body,
}
}
type MsgSender struct {
Uid keybase1.UID `codec:"uid" json:"uid"`
Username string `codec:"username,omitempty" json:"username,omitempty"`
DeviceID keybase1.DeviceID `codec:"deviceID" json:"device_id"`
DeviceName string `codec:"deviceName,omitempty" json:"device_name,omitempty"`
}
func (o MsgSender) DeepCopy() MsgSender {
return MsgSender{
Uid: o.Uid.DeepCopy(),
Username: o.Username,
DeviceID: o.DeviceID.DeepCopy(),
DeviceName: o.DeviceName,
}
}
type MsgBotInfo struct {
BotUID keybase1.UID `codec:"botUID" json:"bot_uid"`
BotUsername string `codec:"botUsername,omitempty" json:"bot_username,omitempty"`
}
func (o MsgBotInfo) DeepCopy() MsgBotInfo {
return MsgBotInfo{
BotUID: o.BotUID.DeepCopy(),
BotUsername: o.BotUsername,
}
}
type MsgFlipContent struct {
Text string `codec:"text" json:"text"`
GameID FlipGameIDStr `codec:"gameID" json:"game_id"`
FlipConvID ConvIDStr `codec:"flipConvID" json:"flip_conv_id"`
UserMentions []KnownUserMention `codec:"userMentions" json:"user_mentions"`
TeamMentions []KnownTeamMention `codec:"teamMentions" json:"team_mentions"`
}
func (o MsgFlipContent) DeepCopy() MsgFlipContent {
return MsgFlipContent{
Text: o.Text,
GameID: o.GameID.DeepCopy(),
FlipConvID: o.FlipConvID.DeepCopy(),
UserMentions: (func(x []KnownUserMention) []KnownUserMention {
if x == nil {
return nil
}
ret := make([]KnownUserMention, len(x))
for i, v := range x {
vCopy := v.DeepCopy()
ret[i] = vCopy
}
return ret
})(o.UserMentions),
TeamMentions: (func(x []KnownTeamMention) []KnownTeamMention {
if x == nil {
return nil
}
ret := make([]KnownTeamMention, len(x))
for i, v := range x {
vCopy := v.DeepCopy()
ret[i] = vCopy
}
return ret
})(o.TeamMentions),
}
}
type MsgContent struct {
TypeName string `codec:"typeName" json:"type"`
Text *MessageText `codec:"text,omitempty" json:"text,omitempty"`
Attachment *MessageAttachment `codec:"attachment,omitempty" json:"attachment,omitempty"`
Edit *MessageEdit `codec:"edit,omitempty" json:"edit,omitempty"`
Reaction *MessageReaction `codec:"reaction,omitempty" json:"reaction,omitempty"`
Delete *MessageDelete `codec:"delete,omitempty" json:"delete,omitempty"`
Metadata *MessageConversationMetadata `codec:"metadata,omitempty" json:"metadata,omitempty"`
Headline *MessageHeadline `codec:"headline,omitempty" json:"headline,omitempty"`
AttachmentUploaded *MessageAttachmentUploaded `codec:"attachmentUploaded,omitempty" json:"attachment_uploaded,omitempty"`
System *MessageSystem `codec:"system,omitempty" json:"system,omitempty"`
SendPayment *MessageSendPayment `codec:"sendPayment,omitempty" json:"send_payment,omitempty"`
RequestPayment *MessageRequestPayment `codec:"requestPayment,omitempty" json:"request_payment,omitempty"`
Unfurl *MessageUnfurl `codec:"unfurl,omitempty" json:"unfurl,omitempty"`
Flip *MsgFlipContent `codec:"flip,omitempty" json:"flip,omitempty"`
}
func (o MsgContent) DeepCopy() MsgContent {
return MsgContent{
TypeName: o.TypeName,
Text: (func(x *MessageText) *MessageText {
if x == nil {
return nil
}
tmp := (*x).DeepCopy()
return &tmp
})(o.Text),
Attachment: (func(x *MessageAttachment) *MessageAttachment {
if x == nil {
return nil
}
tmp := (*x).DeepCopy()
return &tmp
})(o.Attachment),
Edit: (func(x *MessageEdit) *MessageEdit {
if x == nil {
return nil
}
tmp := (*x).DeepCopy()
return &tmp
})(o.Edit),
Reaction: (func(x *MessageReaction) *MessageReaction {
if x == nil {
return nil
}
tmp := (*x).DeepCopy()
return &tmp
})(o.Reaction),
Delete: (func(x *MessageDelete) *MessageDelete {
if x == nil {
return nil
}
tmp := (*x).DeepCopy()
return &tmp
})(o.Delete),
Metadata: (func(x *MessageConversationMetadata) *MessageConversationMetadata {
if x == nil {
return nil
}
tmp := (*x).DeepCopy()
return &tmp
})(o.Metadata),
Headline: (func(x *MessageHeadline) *MessageHeadline {
if x == nil {
return nil
}
tmp := (*x).DeepCopy()
return &tmp
})(o.Headline),
AttachmentUploaded: (func(x *MessageAttachmentUploaded) *MessageAttachmentUploaded {
if x == nil {
return nil
}
tmp := (*x).DeepCopy()
return &tmp
})(o.AttachmentUploaded),
System: (func(x *MessageSystem) *MessageSystem {
if x == nil {
return nil
}
tmp := (*x).DeepCopy()
return &tmp
})(o.System),
SendPayment: (func(x *MessageSendPayment) *MessageSendPayment {
if x == nil {
return nil
}
tmp := (*x).DeepCopy()
return &tmp
})(o.SendPayment),
RequestPayment: (func(x *MessageRequestPayment) *MessageRequestPayment {
if x == nil {
return nil
}
tmp := (*x).DeepCopy()
return &tmp
})(o.RequestPayment),
Unfurl: (func(x *MessageUnfurl) *MessageUnfurl {
if x == nil {
return nil
}
tmp := (*x).DeepCopy()
return &tmp
})(o.Unfurl),
Flip: (func(x *MsgFlipContent) *MsgFlipContent {
if x == nil {
return nil
}
tmp := (*x).DeepCopy()
return &tmp
})(o.Flip),
}
}
type MsgSummary struct {
Id MessageID `codec:"id" json:"id"`
ConvID ConvIDStr `codec:"convID" json:"conversation_id"`
Channel ChatChannel `codec:"channel" json:"channel"`
Sender MsgSender `codec:"sender" json:"sender"`
SentAt int64 `codec:"sentAt" json:"sent_at"`
SentAtMs int64 `codec:"sentAtMs" json:"sent_at_ms"`
Content MsgContent `codec:"content" json:"content"`
Prev []MessagePreviousPointer `codec:"prev" json:"prev"`
Unread bool `codec:"unread" json:"unread"`
RevokedDevice bool `codec:"revokedDevice,omitempty" json:"revoked_device,omitempty"`
Offline bool `codec:"offline,omitempty" json:"offline,omitempty"`
KbfsEncrypted bool `codec:"kbfsEncrypted,omitempty" json:"kbfs_encrypted,omitempty"`
IsEphemeral bool `codec:"isEphemeral,omitempty" json:"is_ephemeral,omitempty"`
IsEphemeralExpired bool `codec:"isEphemeralExpired,omitempty" json:"is_ephemeral_expired,omitempty"`
ETime gregor1.Time `codec:"eTime,omitempty" json:"e_time,omitempty"`
Reactions *ReactionMap `codec:"reactions,omitempty" json:"reactions,omitempty"`
HasPairwiseMacs bool `codec:"hasPairwiseMacs,omitempty" json:"has_pairwise_macs,omitempty"`
AtMentionUsernames []string `codec:"atMentionUsernames,omitempty" json:"at_mention_usernames,omitempty"`
ChannelMention string `codec:"channelMention,omitempty" json:"channel_mention,omitempty"`
ChannelNameMentions []UIChannelNameMention `codec:"channelNameMentions,omitempty" json:"channel_name_mentions,omitempty"`
BotInfo *MsgBotInfo `codec:"botInfo,omitempty" json:"bot_info,omitempty"`
}
func (o MsgSummary) DeepCopy() MsgSummary {
return MsgSummary{
Id: o.Id.DeepCopy(),
ConvID: o.ConvID.DeepCopy(),
Channel: o.Channel.DeepCopy(),
Sender: o.Sender.DeepCopy(),
SentAt: o.SentAt,
SentAtMs: o.SentAtMs,
Content: o.Content.DeepCopy(),
Prev: (func(x []MessagePreviousPointer) []MessagePreviousPointer {
if x == nil {
return nil
}
ret := make([]MessagePreviousPointer, len(x))
for i, v := range x {
vCopy := v.DeepCopy()
ret[i] = vCopy
}
return ret
})(o.Prev),
Unread: o.Unread,
RevokedDevice: o.RevokedDevice,
Offline: o.Offline,
KbfsEncrypted: o.KbfsEncrypted,
IsEphemeral: o.IsEphemeral,
IsEphemeralExpired: o.IsEphemeralExpired,
ETime: o.ETime.DeepCopy(),
Reactions: (func(x *ReactionMap) *ReactionMap {
if x == nil {
return nil
}
tmp := (*x).DeepCopy()
return &tmp
})(o.Reactions),
HasPairwiseMacs: o.HasPairwiseMacs,
AtMentionUsernames: (func(x []string) []string {
if x == nil {
return nil
}
ret := make([]string, len(x))
for i, v := range x {
vCopy := v
ret[i] = vCopy
}
return ret
})(o.AtMentionUsernames),
ChannelMention: o.ChannelMention,
ChannelNameMentions: (func(x []UIChannelNameMention) []UIChannelNameMention {
if x == nil {
return nil
}
ret := make([]UIChannelNameMention, len(x))
for i, v := range x {
vCopy := v.DeepCopy()
ret[i] = vCopy
}
return ret
})(o.ChannelNameMentions),
BotInfo: (func(x *MsgBotInfo) *MsgBotInfo {
if x == nil {
return nil
}
tmp := (*x).DeepCopy()
return &tmp
})(o.BotInfo),
}
}
type Message struct {
Msg *MsgSummary `codec:"msg,omitempty" json:"msg,omitempty"`
Error *string `codec:"error,omitempty" json:"error,omitempty"`
}
func (o Message) DeepCopy() Message {
return Message{
Msg: (func(x *MsgSummary) *MsgSummary {
if x == nil {
return nil
}
tmp := (*x).DeepCopy()
return &tmp
})(o.Msg),
Error: (func(x *string) *string {
if x == nil {
return nil
}
tmp := (*x)
return &tmp
})(o.Error),
}
}
type Thread struct {
Messages []Message `codec:"messages" json:"messages"`
Pagination *Pagination `codec:"pagination,omitempty" json:"pagination,omitempty"`
Offline bool `codec:"offline,omitempty" json:"offline,omitempty"`
IdentifyFailures []keybase1.TLFIdentifyFailure `codec:"identifyFailures,omitempty" json:"identify_failures,omitempty"`
RateLimits []RateLimitRes `codec:"rateLimits,omitempty" json:"ratelimits,omitempty"`
}
func (o Thread) DeepCopy() Thread {
return Thread{
Messages: (func(x []Message) []Message {
if x == nil {
return nil
}
ret := make([]Message, len(x))
for i, v := range x {
vCopy := v.DeepCopy()
ret[i] = vCopy
}
return ret
})(o.Messages),
Pagination: (func(x *Pagination) *Pagination {
if x == nil {
return nil
}
tmp := (*x).DeepCopy()
return &tmp
})(o.Pagination),
Offline: o.Offline,
IdentifyFailures: (func(x []keybase1.TLFIdentifyFailure) []keybase1.TLFIdentifyFailure {
if x == nil {
return nil
}
ret := make([]keybase1.TLFIdentifyFailure, len(x))
for i, v := range x {
vCopy := v.DeepCopy()
ret[i] = vCopy
}
return ret
})(o.IdentifyFailures),
RateLimits: (func(x []RateLimitRes) []RateLimitRes {
if x == nil {
return nil
}
ret := make([]RateLimitRes, len(x))
for i, v := range x {
vCopy := v.DeepCopy()
ret[i] = vCopy
}
return ret
})(o.RateLimits),
}
}
// A chat conversation. This is essentially a chat channel plus some additional metadata.
type ConvSummary struct {
Id ConvIDStr `codec:"id" json:"id"`
Channel ChatChannel `codec:"channel" json:"channel"`
IsDefaultConv bool `codec:"isDefaultConv" json:"is_default_conv"`
Unread bool `codec:"unread" json:"unread"`
ActiveAt int64 `codec:"activeAt" json:"active_at"`
ActiveAtMs int64 `codec:"activeAtMs" json:"active_at_ms"`
MemberStatus string `codec:"memberStatus" json:"member_status"`
ResetUsers []string `codec:"resetUsers,omitempty" json:"reset_users,omitempty"`
FinalizeInfo *ConversationFinalizeInfo `codec:"finalizeInfo,omitempty" json:"finalize_info,omitempty"`
Supersedes []string `codec:"supersedes,omitempty" json:"supersedes,omitempty"`
SupersededBy []string `codec:"supersededBy,omitempty" json:"superseded_by,omitempty"`
Error string `codec:"error,omitempty" json:"error,omitempty"`
CreatorInfo *ConversationCreatorInfoLocal `codec:"creatorInfo,omitempty" json:"creator_info,omitempty"`
}
func (o ConvSummary) DeepCopy() ConvSummary {
return ConvSummary{
Id: o.Id.DeepCopy(),
Channel: o.Channel.DeepCopy(),
IsDefaultConv: o.IsDefaultConv,
Unread: o.Unread,
ActiveAt: o.ActiveAt,
ActiveAtMs: o.ActiveAtMs,
MemberStatus: o.MemberStatus,
ResetUsers: (func(x []string) []string {
if x == nil {
return nil
}
ret := make([]string, len(x))
for i, v := range x {
vCopy := v
ret[i] = vCopy
}
return ret
})(o.ResetUsers),
FinalizeInfo: (func(x *ConversationFinalizeInfo) *ConversationFinalizeInfo {
if x == nil {
return nil
}
tmp := (*x).DeepCopy()
return &tmp
})(o.FinalizeInfo),
Supersedes: (func(x []string) []string {
if x == nil {
return nil
}
ret := make([]string, len(x))
for i, v := range x {
vCopy := v
ret[i] = vCopy
}
return ret
})(o.Supersedes),
SupersededBy: (func(x []string) []string {
if x == nil {
return nil
}
ret := make([]string, len(x))
for i, v := range x {
vCopy := v
ret[i] = vCopy
}
return ret
})(o.SupersededBy),
Error: o.Error,
CreatorInfo: (func(x *ConversationCreatorInfoLocal) *ConversationCreatorInfoLocal {
if x == nil {
return nil
}
tmp := (*x).DeepCopy()
return &tmp
})(o.CreatorInfo),
}
}
type ChatList struct {
Conversations []ConvSummary `codec:"conversations" json:"conversations"`
Offline bool `codec:"offline" json:"offline"`
IdentifyFailures []keybase1.TLFIdentifyFailure `codec:"identifyFailures,omitempty" json:"identify_failures,omitempty"`
RateLimits []RateLimitRes `codec:"rateLimits,omitempty" json:"ratelimits,omitempty"`
}
func (o ChatList) DeepCopy() ChatList {
return ChatList{
Conversations: (func(x []ConvSummary) []ConvSummary {
if x == nil {
return nil
}
ret := make([]ConvSummary, len(x))
for i, v := range x {
vCopy := v.DeepCopy()
ret[i] = vCopy
}
return ret
})(o.Conversations),
Offline: o.Offline,
IdentifyFailures: (func(x []keybase1.TLFIdentifyFailure) []keybase1.TLFIdentifyFailure {
if x == nil {
return nil
}
ret := make([]keybase1.TLFIdentifyFailure, len(x))
for i, v := range x {
vCopy := v.DeepCopy()
ret[i] = vCopy
}
return ret
})(o.IdentifyFailures),
RateLimits: (func(x []RateLimitRes) []RateLimitRes {
if x == nil {
return nil
}
ret := make([]RateLimitRes, len(x))
for i, v := range x {
vCopy := v.DeepCopy()
ret[i] = vCopy
}
return ret
})(o.RateLimits),
}
}
type SendRes struct {
Message string `codec:"message" json:"message"`
MessageID *MessageID `codec:"messageID,omitempty" json:"id,omitempty"`
OutboxID *OutboxID `codec:"outboxID,omitempty" json:"outbox_id,omitempty"`
IdentifyFailures []keybase1.TLFIdentifyFailure `codec:"identifyFailures,omitempty" json:"identify_failures,omitempty"`
RateLimits []RateLimitRes `codec:"rateLimits,omitempty" json:"ratelimits,omitempty"`
}
func (o SendRes) DeepCopy() SendRes {
return SendRes{
Message: o.Message,
MessageID: (func(x *MessageID) *MessageID {
if x == nil {
return nil
}
tmp := (*x).DeepCopy()
return &tmp
})(o.MessageID),
OutboxID: (func(x *OutboxID) *OutboxID {
if x == nil {
return nil
}
tmp := (*x).DeepCopy()
return &tmp
})(o.OutboxID),
IdentifyFailures: (func(x []keybase1.TLFIdentifyFailure) []keybase1.TLFIdentifyFailure {
if x == nil {
return nil
}
ret := make([]keybase1.TLFIdentifyFailure, len(x))
for i, v := range x {
vCopy := v.DeepCopy()
ret[i] = vCopy
}
return ret
})(o.IdentifyFailures),
RateLimits: (func(x []RateLimitRes) []RateLimitRes {
if x == nil {
return nil
}
ret := make([]RateLimitRes, len(x))
for i, v := range x {
vCopy := v.DeepCopy()
ret[i] = vCopy
}
return ret
})(o.RateLimits),
}
}
type SearchInboxResOutput struct {
Results *ChatSearchInboxResults `codec:"results,omitempty" json:"results,omitempty"`
IdentifyFailures []keybase1.TLFIdentifyFailure `codec:"identifyFailures,omitempty" json:"identify_failures,omitempty"`
RateLimits []RateLimitRes `codec:"rateLimits,omitempty" json:"ratelimits,omitempty"`
}
func (o SearchInboxResOutput) DeepCopy() SearchInboxResOutput {
return SearchInboxResOutput{
Results: (func(x *ChatSearchInboxResults) *ChatSearchInboxResults {
if x == nil {
return nil
}
tmp := (*x).DeepCopy()
return &tmp
})(o.Results),
IdentifyFailures: (func(x []keybase1.TLFIdentifyFailure) []keybase1.TLFIdentifyFailure {
if x == nil {
return nil
}
ret := make([]keybase1.TLFIdentifyFailure, len(x))
for i, v := range x {
vCopy := v.DeepCopy()
ret[i] = vCopy
}
return ret
})(o.IdentifyFailures),
RateLimits: (func(x []RateLimitRes) []RateLimitRes {
if x == nil {
return nil
}
ret := make([]RateLimitRes, len(x))
for i, v := range x {
vCopy := v.DeepCopy()
ret[i] = vCopy
}
return ret
})(o.RateLimits),
}
}
type RegexpRes struct {
Hits []ChatSearchHit `codec:"hits" json:"hits"`
IdentifyFailures []keybase1.TLFIdentifyFailure `codec:"identifyFailures,omitempty" json:"identify_failures,omitempty"`
RateLimits []RateLimitRes `codec:"rateLimits,omitempty" json:"ratelimits,omitempty"`
}
func (o RegexpRes) DeepCopy() RegexpRes {
return RegexpRes{
Hits: (func(x []ChatSearchHit) []ChatSearchHit {
if x == nil {
return nil
}
ret := make([]ChatSearchHit, len(x))
for i, v := range x {
vCopy := v.DeepCopy()
ret[i] = vCopy
}
return ret
})(o.Hits),
IdentifyFailures: (func(x []keybase1.TLFIdentifyFailure) []keybase1.TLFIdentifyFailure {
if x == nil {
return nil
}
ret := make([]keybase1.TLFIdentifyFailure, len(x))
for i, v := range x {
vCopy := v.DeepCopy()
ret[i] = vCopy
}
return ret
})(o.IdentifyFailures),
RateLimits: (func(x []RateLimitRes) []RateLimitRes {
if x == nil {
return nil
}
ret := make([]RateLimitRes, len(x))
for i, v := range x {
vCopy := v.DeepCopy()
ret[i] = vCopy
}
return ret
})(o.RateLimits),
}
}
type NewConvRes struct {
Id ConvIDStr `codec:"id" json:"id"`
IdentifyFailures []keybase1.TLFIdentifyFailure `codec:"identifyFailures,omitempty" json:"identify_failures,omitempty"`
RateLimits []RateLimitRes `codec:"rateLimits,omitempty" json:"ratelimits,omitempty"`
}
func (o NewConvRes) DeepCopy() NewConvRes {
return NewConvRes{
Id: o.Id.DeepCopy(),
IdentifyFailures: (func(x []keybase1.TLFIdentifyFailure) []keybase1.TLFIdentifyFailure {
if x == nil {
return nil
}
ret := make([]keybase1.TLFIdentifyFailure, len(x))
for i, v := range x {
vCopy := v.DeepCopy()
ret[i] = vCopy
}
return ret
})(o.IdentifyFailures),
RateLimits: (func(x []RateLimitRes) []RateLimitRes {
if x == nil {
return nil
}
ret := make([]RateLimitRes, len(x))
for i, v := range x {
vCopy := v.DeepCopy()
ret[i] = vCopy
}
return ret
})(o.RateLimits),
}
}
type ListCommandsRes struct {
Commands []UserBotCommandOutput `codec:"commands" json:"commands"`
RateLimits []RateLimitRes `codec:"rateLimits,omitempty" json:"ratelimits,omitempty"`
}
func (o ListCommandsRes) DeepCopy() ListCommandsRes {
return ListCommandsRes{
Commands: (func(x []UserBotCommandOutput) []UserBotCommandOutput {
if x == nil {
return nil
}
ret := make([]UserBotCommandOutput, len(x))
for i, v := range x {
vCopy := v.DeepCopy()
ret[i] = vCopy
}
return ret
})(o.Commands),
RateLimits: (func(x []RateLimitRes) []RateLimitRes {
if x == nil {
return nil
}
ret := make([]RateLimitRes, len(x))
for i, v := range x {
vCopy := v.DeepCopy()
ret[i] = vCopy
}
return ret
})(o.RateLimits),
}
}
type EmptyRes struct {
RateLimits []RateLimitRes `codec:"rateLimits,omitempty" json:"ratelimits,omitempty"`
}
func (o EmptyRes) DeepCopy() EmptyRes {
return EmptyRes{
RateLimits: (func(x []RateLimitRes) []RateLimitRes {
if x == nil {
return nil
}
ret := make([]RateLimitRes, len(x))
for i, v := range x {
vCopy := v.DeepCopy()
ret[i] = vCopy
}
return ret
})(o.RateLimits),
}
}
type MsgNotification struct {
Type string `codec:"type" json:"type"`
Source string `codec:"source" json:"source"`
Msg *MsgSummary `codec:"msg,omitempty" json:"msg,omitempty"`
Error *string `codec:"error,omitempty" json:"error,omitempty"`
Pagination *UIPagination `codec:"pagination,omitempty" json:"pagination,omitempty"`
}
func (o MsgNotification) DeepCopy() MsgNotification {
return MsgNotification{
Type: o.Type,
Source: o.Source,
Msg: (func(x *MsgSummary) *MsgSummary {
if x == nil {
return nil
}
tmp := (*x).DeepCopy()
return &tmp
})(o.Msg),
Error: (func(x *string) *string {
if x == nil {
return nil
}
tmp := (*x)
return &tmp
})(o.Error),
Pagination: (func(x *UIPagination) *UIPagination {
if x == nil {
return nil
}
tmp := (*x).DeepCopy()
return &tmp
})(o.Pagination),
}
}
type ConvNotification struct {
Type string `codec:"type" json:"type"`
Conv *ConvSummary `codec:"conv,omitempty" json:"conv,omitempty"`
Error *string `codec:"error,omitempty" json:"error,omitempty"`
}
func (o ConvNotification) DeepCopy() ConvNotification {
return ConvNotification{
Type: o.Type,
Conv: (func(x *ConvSummary) *ConvSummary {
if x == nil {
return nil
}
tmp := (*x).DeepCopy()
return &tmp
})(o.Conv),
Error: (func(x *string) *string {
if x == nil {
return nil
}
tmp := (*x)
return &tmp
})(o.Error),
}
}
type AdvertiseCommandAPIParam struct {
Typ string `codec:"typ" json:"type"`
Commands []UserBotCommandInput `codec:"commands" json:"commands"`
TeamName string `codec:"teamName,omitempty" json:"team_name,omitempty"`
}
func (o AdvertiseCommandAPIParam) DeepCopy() AdvertiseCommandAPIParam {
return AdvertiseCommandAPIParam{
Typ: o.Typ,
Commands: (func(x []UserBotCommandInput) []UserBotCommandInput {
if x == nil {
return nil
}
ret := make([]UserBotCommandInput, len(x))
for i, v := range x {
vCopy := v.DeepCopy()
ret[i] = vCopy
}
return ret
})(o.Commands),
TeamName: o.TeamName,
}
}
type ResetConvMemberAPI struct {
ConversationID ConvIDStr `codec:"conversationID" json:"conversationID"`
Username string `codec:"username" json:"username"`
}
func (o ResetConvMemberAPI) DeepCopy() ResetConvMemberAPI {
return ResetConvMemberAPI{
ConversationID: o.ConversationID.DeepCopy(),
Username: o.Username,
}
}
type GetResetConvMembersRes struct {
Members []ResetConvMemberAPI `codec:"members" json:"members"`
RateLimits []RateLimitRes `codec:"rateLimits" json:"rateLimits"`
}
func (o GetResetConvMembersRes) DeepCopy() GetResetConvMembersRes {
return GetResetConvMembersRes{
Members: (func(x []ResetConvMemberAPI) []ResetConvMemberAPI {
if x == nil {
return nil
}
ret := make([]ResetConvMemberAPI, len(x))
for i, v := range x {
vCopy := v.DeepCopy()
ret[i] = vCopy
}
return ret
})(o.Members),
RateLimits: (func(x []RateLimitRes) []RateLimitRes {
if x == nil {
return nil
}
ret := make([]RateLimitRes, len(x))
for i, v := range x {
vCopy := v.DeepCopy()
ret[i] = vCopy
}
return ret
})(o.RateLimits),
}
}
type DeviceInfo struct {
DeviceID keybase1.DeviceID `codec:"deviceID" json:"id"`
DeviceDescription string `codec:"deviceDescription" json:"description"`
DeviceType string `codec:"deviceType" json:"type"`
DeviceCtime int64 `codec:"deviceCtime" json:"ctime"`
}
func (o DeviceInfo) DeepCopy() DeviceInfo {
return DeviceInfo{
DeviceID: o.DeviceID.DeepCopy(),
DeviceDescription: o.DeviceDescription,
DeviceType: o.DeviceType,
DeviceCtime: o.DeviceCtime,
}
}
type GetDeviceInfoRes struct {
Devices []DeviceInfo `codec:"devices" json:"devices"`
}
func (o GetDeviceInfoRes) DeepCopy() GetDeviceInfoRes {
return GetDeviceInfoRes{
Devices: (func(x []DeviceInfo) []DeviceInfo {
if x == nil {
return nil
}
ret := make([]DeviceInfo, len(x))
for i, v := range x {
vCopy := v.DeepCopy()
ret[i] = vCopy
}
return ret
})(o.Devices),
}
}

View File

@@ -0,0 +1,4 @@
// Auto-generated to Go types using avdl-compiler v1.4.6 (https://github.com/keybase/node-avdl-compiler)
// Input file: ../client/protocol/avdl/chat1/blocking.avdl
package chat1

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,199 @@
// Auto-generated to Go types using avdl-compiler v1.4.6 (https://github.com/keybase/node-avdl-compiler)
// Input file: ../client/protocol/avdl/chat1/commands.avdl
package chat1
import (
"errors"
"fmt"
)
type ConversationCommand struct {
Description string `codec:"description" json:"description"`
Name string `codec:"name" json:"name"`
Usage string `codec:"usage" json:"usage"`
HasHelpText bool `codec:"hasHelpText" json:"hasHelpText"`
Username *string `codec:"username,omitempty" json:"username,omitempty"`
}
func (o ConversationCommand) DeepCopy() ConversationCommand {
return ConversationCommand{
Description: o.Description,
Name: o.Name,
Usage: o.Usage,
HasHelpText: o.HasHelpText,
Username: (func(x *string) *string {
if x == nil {
return nil
}
tmp := (*x)
return &tmp
})(o.Username),
}
}
type ConversationCommandGroupsTyp int
const (
ConversationCommandGroupsTyp_BUILTIN ConversationCommandGroupsTyp = 0
ConversationCommandGroupsTyp_CUSTOM ConversationCommandGroupsTyp = 1
ConversationCommandGroupsTyp_NONE ConversationCommandGroupsTyp = 2
)
func (o ConversationCommandGroupsTyp) DeepCopy() ConversationCommandGroupsTyp { return o }
var ConversationCommandGroupsTypMap = map[string]ConversationCommandGroupsTyp{
"BUILTIN": 0,
"CUSTOM": 1,
"NONE": 2,
}
var ConversationCommandGroupsTypRevMap = map[ConversationCommandGroupsTyp]string{
0: "BUILTIN",
1: "CUSTOM",
2: "NONE",
}
func (e ConversationCommandGroupsTyp) String() string {
if v, ok := ConversationCommandGroupsTypRevMap[e]; ok {
return v
}
return fmt.Sprintf("%v", int(e))
}
type ConversationBuiltinCommandTyp int
const (
ConversationBuiltinCommandTyp_NONE ConversationBuiltinCommandTyp = 0
ConversationBuiltinCommandTyp_ADHOC ConversationBuiltinCommandTyp = 1
ConversationBuiltinCommandTyp_SMALLTEAM ConversationBuiltinCommandTyp = 2
ConversationBuiltinCommandTyp_BIGTEAM ConversationBuiltinCommandTyp = 3
ConversationBuiltinCommandTyp_BIGTEAMGENERAL ConversationBuiltinCommandTyp = 4
)
func (o ConversationBuiltinCommandTyp) DeepCopy() ConversationBuiltinCommandTyp { return o }
var ConversationBuiltinCommandTypMap = map[string]ConversationBuiltinCommandTyp{
"NONE": 0,
"ADHOC": 1,
"SMALLTEAM": 2,
"BIGTEAM": 3,
"BIGTEAMGENERAL": 4,
}
var ConversationBuiltinCommandTypRevMap = map[ConversationBuiltinCommandTyp]string{
0: "NONE",
1: "ADHOC",
2: "SMALLTEAM",
3: "BIGTEAM",
4: "BIGTEAMGENERAL",
}
func (e ConversationBuiltinCommandTyp) String() string {
if v, ok := ConversationBuiltinCommandTypRevMap[e]; ok {
return v
}
return fmt.Sprintf("%v", int(e))
}
type ConversationCommandGroupsCustom struct {
Commands []ConversationCommand `codec:"commands" json:"commands"`
}
func (o ConversationCommandGroupsCustom) DeepCopy() ConversationCommandGroupsCustom {
return ConversationCommandGroupsCustom{
Commands: (func(x []ConversationCommand) []ConversationCommand {
if x == nil {
return nil
}
ret := make([]ConversationCommand, len(x))
for i, v := range x {
vCopy := v.DeepCopy()
ret[i] = vCopy
}
return ret
})(o.Commands),
}
}
type ConversationCommandGroups struct {
Typ__ ConversationCommandGroupsTyp `codec:"typ" json:"typ"`
Builtin__ *ConversationBuiltinCommandTyp `codec:"builtin,omitempty" json:"builtin,omitempty"`
Custom__ *ConversationCommandGroupsCustom `codec:"custom,omitempty" json:"custom,omitempty"`
}
func (o *ConversationCommandGroups) Typ() (ret ConversationCommandGroupsTyp, err error) {
switch o.Typ__ {
case ConversationCommandGroupsTyp_BUILTIN:
if o.Builtin__ == nil {
err = errors.New("unexpected nil value for Builtin__")
return ret, err
}
case ConversationCommandGroupsTyp_CUSTOM:
if o.Custom__ == nil {
err = errors.New("unexpected nil value for Custom__")
return ret, err
}
}
return o.Typ__, nil
}
func (o ConversationCommandGroups) Builtin() (res ConversationBuiltinCommandTyp) {
if o.Typ__ != ConversationCommandGroupsTyp_BUILTIN {
panic("wrong case accessed")
}
if o.Builtin__ == nil {
return
}
return *o.Builtin__
}
func (o ConversationCommandGroups) Custom() (res ConversationCommandGroupsCustom) {
if o.Typ__ != ConversationCommandGroupsTyp_CUSTOM {
panic("wrong case accessed")
}
if o.Custom__ == nil {
return
}
return *o.Custom__
}
func NewConversationCommandGroupsWithBuiltin(v ConversationBuiltinCommandTyp) ConversationCommandGroups {
return ConversationCommandGroups{
Typ__: ConversationCommandGroupsTyp_BUILTIN,
Builtin__: &v,
}
}
func NewConversationCommandGroupsWithCustom(v ConversationCommandGroupsCustom) ConversationCommandGroups {
return ConversationCommandGroups{
Typ__: ConversationCommandGroupsTyp_CUSTOM,
Custom__: &v,
}
}
func NewConversationCommandGroupsWithNone() ConversationCommandGroups {
return ConversationCommandGroups{
Typ__: ConversationCommandGroupsTyp_NONE,
}
}
func (o ConversationCommandGroups) DeepCopy() ConversationCommandGroups {
return ConversationCommandGroups{
Typ__: o.Typ__.DeepCopy(),
Builtin__: (func(x *ConversationBuiltinCommandTyp) *ConversationBuiltinCommandTyp {
if x == nil {
return nil
}
tmp := (*x).DeepCopy()
return &tmp
})(o.Builtin__),
Custom__: (func(x *ConversationCommandGroupsCustom) *ConversationCommandGroupsCustom {
if x == nil {
return nil
}
tmp := (*x).DeepCopy()
return &tmp
})(o.Custom__),
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,548 @@
// Auto-generated to Go types using avdl-compiler v1.4.6 (https://github.com/keybase/node-avdl-compiler)
// Input file: ../client/protocol/avdl/chat1/gregor.avdl
package chat1
import (
gregor1 "github.com/keybase/go-keybase-chat-bot/kbchat/types/gregor1"
keybase1 "github.com/keybase/go-keybase-chat-bot/kbchat/types/keybase1"
)
type GenericPayload struct {
Action string `codec:"Action" json:"Action"`
InboxVers InboxVers `codec:"inboxVers" json:"inboxVers"`
ConvID ConversationID `codec:"convID" json:"convID"`
TopicType TopicType `codec:"topicType" json:"topicType"`
UnreadUpdate *UnreadUpdate `codec:"unreadUpdate,omitempty" json:"unreadUpdate,omitempty"`
}
func (o GenericPayload) DeepCopy() GenericPayload {
return GenericPayload{
Action: o.Action,
InboxVers: o.InboxVers.DeepCopy(),
ConvID: o.ConvID.DeepCopy(),
TopicType: o.TopicType.DeepCopy(),
UnreadUpdate: (func(x *UnreadUpdate) *UnreadUpdate {
if x == nil {
return nil
}
tmp := (*x).DeepCopy()
return &tmp
})(o.UnreadUpdate),
}
}
type NewConversationPayload struct {
Action string `codec:"Action" json:"Action"`
ConvID ConversationID `codec:"convID" json:"convID"`
InboxVers InboxVers `codec:"inboxVers" json:"inboxVers"`
TopicType TopicType `codec:"topicType" json:"topicType"`
UnreadUpdate *UnreadUpdate `codec:"unreadUpdate,omitempty" json:"unreadUpdate,omitempty"`
}
func (o NewConversationPayload) DeepCopy() NewConversationPayload {
return NewConversationPayload{
Action: o.Action,
ConvID: o.ConvID.DeepCopy(),
InboxVers: o.InboxVers.DeepCopy(),
TopicType: o.TopicType.DeepCopy(),
UnreadUpdate: (func(x *UnreadUpdate) *UnreadUpdate {
if x == nil {
return nil
}
tmp := (*x).DeepCopy()
return &tmp
})(o.UnreadUpdate),
}
}
type NewMessagePayload struct {
Action string `codec:"Action" json:"Action"`
ConvID ConversationID `codec:"convID" json:"convID"`
Message MessageBoxed `codec:"message" json:"message"`
InboxVers InboxVers `codec:"inboxVers" json:"inboxVers"`
TopicType TopicType `codec:"topicType" json:"topicType"`
UnreadUpdate *UnreadUpdate `codec:"unreadUpdate,omitempty" json:"unreadUpdate,omitempty"`
UntrustedTeamRole keybase1.TeamRole `codec:"untrustedTeamRole" json:"untrustedTeamRole"`
MaxMsgs []MessageSummary `codec:"maxMsgs" json:"maxMsgs"`
}
func (o NewMessagePayload) DeepCopy() NewMessagePayload {
return NewMessagePayload{
Action: o.Action,
ConvID: o.ConvID.DeepCopy(),
Message: o.Message.DeepCopy(),
InboxVers: o.InboxVers.DeepCopy(),
TopicType: o.TopicType.DeepCopy(),
UnreadUpdate: (func(x *UnreadUpdate) *UnreadUpdate {
if x == nil {
return nil
}
tmp := (*x).DeepCopy()
return &tmp
})(o.UnreadUpdate),
UntrustedTeamRole: o.UntrustedTeamRole.DeepCopy(),
MaxMsgs: (func(x []MessageSummary) []MessageSummary {
if x == nil {
return nil
}
ret := make([]MessageSummary, len(x))
for i, v := range x {
vCopy := v.DeepCopy()
ret[i] = vCopy
}
return ret
})(o.MaxMsgs),
}
}
type ReadMessagePayload struct {
Action string `codec:"Action" json:"Action"`
ConvID ConversationID `codec:"convID" json:"convID"`
MsgID MessageID `codec:"msgID" json:"msgID"`
InboxVers InboxVers `codec:"inboxVers" json:"inboxVers"`
TopicType TopicType `codec:"topicType" json:"topicType"`
UnreadUpdate *UnreadUpdate `codec:"unreadUpdate,omitempty" json:"unreadUpdate,omitempty"`
}
func (o ReadMessagePayload) DeepCopy() ReadMessagePayload {
return ReadMessagePayload{
Action: o.Action,
ConvID: o.ConvID.DeepCopy(),
MsgID: o.MsgID.DeepCopy(),
InboxVers: o.InboxVers.DeepCopy(),
TopicType: o.TopicType.DeepCopy(),
UnreadUpdate: (func(x *UnreadUpdate) *UnreadUpdate {
if x == nil {
return nil
}
tmp := (*x).DeepCopy()
return &tmp
})(o.UnreadUpdate),
}
}
type SetStatusPayload struct {
Action string `codec:"Action" json:"Action"`
ConvID ConversationID `codec:"convID" json:"convID"`
Status ConversationStatus `codec:"status" json:"status"`
InboxVers InboxVers `codec:"inboxVers" json:"inboxVers"`
TopicType TopicType `codec:"topicType" json:"topicType"`
UnreadUpdate *UnreadUpdate `codec:"unreadUpdate,omitempty" json:"unreadUpdate,omitempty"`
}
func (o SetStatusPayload) DeepCopy() SetStatusPayload {
return SetStatusPayload{
Action: o.Action,
ConvID: o.ConvID.DeepCopy(),
Status: o.Status.DeepCopy(),
InboxVers: o.InboxVers.DeepCopy(),
TopicType: o.TopicType.DeepCopy(),
UnreadUpdate: (func(x *UnreadUpdate) *UnreadUpdate {
if x == nil {
return nil
}
tmp := (*x).DeepCopy()
return &tmp
})(o.UnreadUpdate),
}
}
type TeamTypePayload struct {
Action string `codec:"Action" json:"Action"`
ConvID ConversationID `codec:"convID" json:"convID"`
TeamType TeamType `codec:"teamType" json:"teamType"`
InboxVers InboxVers `codec:"inboxVers" json:"inboxVers"`
TopicType TopicType `codec:"topicType" json:"topicType"`
UnreadUpdate *UnreadUpdate `codec:"unreadUpdate,omitempty" json:"unreadUpdate,omitempty"`
}
func (o TeamTypePayload) DeepCopy() TeamTypePayload {
return TeamTypePayload{
Action: o.Action,
ConvID: o.ConvID.DeepCopy(),
TeamType: o.TeamType.DeepCopy(),
InboxVers: o.InboxVers.DeepCopy(),
TopicType: o.TopicType.DeepCopy(),
UnreadUpdate: (func(x *UnreadUpdate) *UnreadUpdate {
if x == nil {
return nil
}
tmp := (*x).DeepCopy()
return &tmp
})(o.UnreadUpdate),
}
}
type SetAppNotificationSettingsPayload struct {
Action string `codec:"Action" json:"Action"`
ConvID ConversationID `codec:"convID" json:"convID"`
InboxVers InboxVers `codec:"inboxVers" json:"inboxVers"`
Settings ConversationNotificationInfo `codec:"settings" json:"settings"`
TopicType TopicType `codec:"topicType" json:"topicType"`
UnreadUpdate *UnreadUpdate `codec:"unreadUpdate,omitempty" json:"unreadUpdate,omitempty"`
}
func (o SetAppNotificationSettingsPayload) DeepCopy() SetAppNotificationSettingsPayload {
return SetAppNotificationSettingsPayload{
Action: o.Action,
ConvID: o.ConvID.DeepCopy(),
InboxVers: o.InboxVers.DeepCopy(),
Settings: o.Settings.DeepCopy(),
TopicType: o.TopicType.DeepCopy(),
UnreadUpdate: (func(x *UnreadUpdate) *UnreadUpdate {
if x == nil {
return nil
}
tmp := (*x).DeepCopy()
return &tmp
})(o.UnreadUpdate),
}
}
type ExpungePayload struct {
Action string `codec:"Action" json:"Action"`
ConvID ConversationID `codec:"convID" json:"convID"`
InboxVers InboxVers `codec:"inboxVers" json:"inboxVers"`
Expunge Expunge `codec:"expunge" json:"expunge"`
MaxMsgs []MessageSummary `codec:"maxMsgs" json:"maxMsgs"`
TopicType TopicType `codec:"topicType" json:"topicType"`
UnreadUpdate *UnreadUpdate `codec:"unreadUpdate,omitempty" json:"unreadUpdate,omitempty"`
}
func (o ExpungePayload) DeepCopy() ExpungePayload {
return ExpungePayload{
Action: o.Action,
ConvID: o.ConvID.DeepCopy(),
InboxVers: o.InboxVers.DeepCopy(),
Expunge: o.Expunge.DeepCopy(),
MaxMsgs: (func(x []MessageSummary) []MessageSummary {
if x == nil {
return nil
}
ret := make([]MessageSummary, len(x))
for i, v := range x {
vCopy := v.DeepCopy()
ret[i] = vCopy
}
return ret
})(o.MaxMsgs),
TopicType: o.TopicType.DeepCopy(),
UnreadUpdate: (func(x *UnreadUpdate) *UnreadUpdate {
if x == nil {
return nil
}
tmp := (*x).DeepCopy()
return &tmp
})(o.UnreadUpdate),
}
}
type UnreadUpdate struct {
ConvID ConversationID `codec:"convID" json:"convID"`
UnreadMessages int `codec:"unreadMessages" json:"unreadMessages"`
UnreadNotifyingMessages map[keybase1.DeviceType]int `codec:"unreadNotifyingMessages" json:"unreadNotifyingMessages"`
CompatUnreadMessages int `codec:"UnreadMessages" json:"UnreadMessages"`
Diff bool `codec:"diff" json:"diff"`
}
func (o UnreadUpdate) DeepCopy() UnreadUpdate {
return UnreadUpdate{
ConvID: o.ConvID.DeepCopy(),
UnreadMessages: o.UnreadMessages,
UnreadNotifyingMessages: (func(x map[keybase1.DeviceType]int) map[keybase1.DeviceType]int {
if x == nil {
return nil
}
ret := make(map[keybase1.DeviceType]int, len(x))
for k, v := range x {
kCopy := k.DeepCopy()
vCopy := v
ret[kCopy] = vCopy
}
return ret
})(o.UnreadNotifyingMessages),
CompatUnreadMessages: o.CompatUnreadMessages,
Diff: o.Diff,
}
}
type TLFFinalizeUpdate struct {
FinalizeInfo ConversationFinalizeInfo `codec:"finalizeInfo" json:"finalizeInfo"`
ConvIDs []ConversationID `codec:"convIDs" json:"convIDs"`
InboxVers InboxVers `codec:"inboxVers" json:"inboxVers"`
}
func (o TLFFinalizeUpdate) DeepCopy() TLFFinalizeUpdate {
return TLFFinalizeUpdate{
FinalizeInfo: o.FinalizeInfo.DeepCopy(),
ConvIDs: (func(x []ConversationID) []ConversationID {
if x == nil {
return nil
}
ret := make([]ConversationID, len(x))
for i, v := range x {
vCopy := v.DeepCopy()
ret[i] = vCopy
}
return ret
})(o.ConvIDs),
InboxVers: o.InboxVers.DeepCopy(),
}
}
type TLFResolveUpdate struct {
ConvID ConversationID `codec:"convID" json:"convID"`
InboxVers InboxVers `codec:"inboxVers" json:"inboxVers"`
}
func (o TLFResolveUpdate) DeepCopy() TLFResolveUpdate {
return TLFResolveUpdate{
ConvID: o.ConvID.DeepCopy(),
InboxVers: o.InboxVers.DeepCopy(),
}
}
type RemoteUserTypingUpdate struct {
Uid gregor1.UID `codec:"uid" json:"uid"`
DeviceID gregor1.DeviceID `codec:"deviceID" json:"deviceID"`
ConvID ConversationID `codec:"convID" json:"convID"`
Typing bool `codec:"typing" json:"typing"`
TeamType TeamType `codec:"t" json:"teamType"`
}
func (o RemoteUserTypingUpdate) DeepCopy() RemoteUserTypingUpdate {
return RemoteUserTypingUpdate{
Uid: o.Uid.DeepCopy(),
DeviceID: o.DeviceID.DeepCopy(),
ConvID: o.ConvID.DeepCopy(),
Typing: o.Typing,
TeamType: o.TeamType.DeepCopy(),
}
}
type TeamMemberRoleUpdate struct {
TlfID TLFID `codec:"tlfID" json:"tlfID"`
Role keybase1.TeamRole `codec:"role" json:"role"`
}
func (o TeamMemberRoleUpdate) DeepCopy() TeamMemberRoleUpdate {
return TeamMemberRoleUpdate{
TlfID: o.TlfID.DeepCopy(),
Role: o.Role.DeepCopy(),
}
}
type UpdateConversationMembership struct {
InboxVers InboxVers `codec:"inboxVers" json:"inboxVers"`
TeamMemberRoleUpdate *TeamMemberRoleUpdate `codec:"teamMemberRoleUpdate,omitempty" json:"teamMemberRoleUpdate,omitempty"`
Joined []ConversationMember `codec:"joined" json:"joined"`
Removed []ConversationMember `codec:"removed" json:"removed"`
Reset []ConversationMember `codec:"reset" json:"reset"`
Previewed []ConversationID `codec:"previewed" json:"previewed"`
UnreadUpdate *UnreadUpdate `codec:"unreadUpdate,omitempty" json:"unreadUpdate,omitempty"`
UnreadUpdates []UnreadUpdate `codec:"unreadUpdates" json:"unreadUpdates"`
}
func (o UpdateConversationMembership) DeepCopy() UpdateConversationMembership {
return UpdateConversationMembership{
InboxVers: o.InboxVers.DeepCopy(),
TeamMemberRoleUpdate: (func(x *TeamMemberRoleUpdate) *TeamMemberRoleUpdate {
if x == nil {
return nil
}
tmp := (*x).DeepCopy()
return &tmp
})(o.TeamMemberRoleUpdate),
Joined: (func(x []ConversationMember) []ConversationMember {
if x == nil {
return nil
}
ret := make([]ConversationMember, len(x))
for i, v := range x {
vCopy := v.DeepCopy()
ret[i] = vCopy
}
return ret
})(o.Joined),
Removed: (func(x []ConversationMember) []ConversationMember {
if x == nil {
return nil
}
ret := make([]ConversationMember, len(x))
for i, v := range x {
vCopy := v.DeepCopy()
ret[i] = vCopy
}
return ret
})(o.Removed),
Reset: (func(x []ConversationMember) []ConversationMember {
if x == nil {
return nil
}
ret := make([]ConversationMember, len(x))
for i, v := range x {
vCopy := v.DeepCopy()
ret[i] = vCopy
}
return ret
})(o.Reset),
Previewed: (func(x []ConversationID) []ConversationID {
if x == nil {
return nil
}
ret := make([]ConversationID, len(x))
for i, v := range x {
vCopy := v.DeepCopy()
ret[i] = vCopy
}
return ret
})(o.Previewed),
UnreadUpdate: (func(x *UnreadUpdate) *UnreadUpdate {
if x == nil {
return nil
}
tmp := (*x).DeepCopy()
return &tmp
})(o.UnreadUpdate),
UnreadUpdates: (func(x []UnreadUpdate) []UnreadUpdate {
if x == nil {
return nil
}
ret := make([]UnreadUpdate, len(x))
for i, v := range x {
vCopy := v.DeepCopy()
ret[i] = vCopy
}
return ret
})(o.UnreadUpdates),
}
}
type ConversationUpdate struct {
ConvID ConversationID `codec:"convID" json:"convID"`
Existence ConversationExistence `codec:"existence" json:"existence"`
}
func (o ConversationUpdate) DeepCopy() ConversationUpdate {
return ConversationUpdate{
ConvID: o.ConvID.DeepCopy(),
Existence: o.Existence.DeepCopy(),
}
}
type UpdateConversations struct {
InboxVers InboxVers `codec:"inboxVers" json:"inboxVers"`
ConvUpdates []ConversationUpdate `codec:"convUpdates" json:"convUpdates"`
}
func (o UpdateConversations) DeepCopy() UpdateConversations {
return UpdateConversations{
InboxVers: o.InboxVers.DeepCopy(),
ConvUpdates: (func(x []ConversationUpdate) []ConversationUpdate {
if x == nil {
return nil
}
ret := make([]ConversationUpdate, len(x))
for i, v := range x {
vCopy := v.DeepCopy()
ret[i] = vCopy
}
return ret
})(o.ConvUpdates),
}
}
type TeamChannelUpdate struct {
TeamID TLFID `codec:"teamID" json:"teamID"`
}
func (o TeamChannelUpdate) DeepCopy() TeamChannelUpdate {
return TeamChannelUpdate{
TeamID: o.TeamID.DeepCopy(),
}
}
type SetConvRetentionUpdate struct {
InboxVers InboxVers `codec:"inboxVers" json:"inboxVers"`
ConvID ConversationID `codec:"convID" json:"convID"`
Policy RetentionPolicy `codec:"policy" json:"policy"`
}
func (o SetConvRetentionUpdate) DeepCopy() SetConvRetentionUpdate {
return SetConvRetentionUpdate{
InboxVers: o.InboxVers.DeepCopy(),
ConvID: o.ConvID.DeepCopy(),
Policy: o.Policy.DeepCopy(),
}
}
type SetTeamRetentionUpdate struct {
InboxVers InboxVers `codec:"inboxVers" json:"inboxVers"`
TeamID keybase1.TeamID `codec:"teamID" json:"teamID"`
Policy RetentionPolicy `codec:"policy" json:"policy"`
}
func (o SetTeamRetentionUpdate) DeepCopy() SetTeamRetentionUpdate {
return SetTeamRetentionUpdate{
InboxVers: o.InboxVers.DeepCopy(),
TeamID: o.TeamID.DeepCopy(),
Policy: o.Policy.DeepCopy(),
}
}
type SetConvSettingsUpdate struct {
InboxVers InboxVers `codec:"inboxVers" json:"inboxVers"`
ConvID ConversationID `codec:"convID" json:"convID"`
ConvSettings *ConversationSettings `codec:"convSettings,omitempty" json:"convSettings,omitempty"`
}
func (o SetConvSettingsUpdate) DeepCopy() SetConvSettingsUpdate {
return SetConvSettingsUpdate{
InboxVers: o.InboxVers.DeepCopy(),
ConvID: o.ConvID.DeepCopy(),
ConvSettings: (func(x *ConversationSettings) *ConversationSettings {
if x == nil {
return nil
}
tmp := (*x).DeepCopy()
return &tmp
})(o.ConvSettings),
}
}
type KBFSImpteamUpgradeUpdate struct {
ConvID ConversationID `codec:"convID" json:"convID"`
InboxVers InboxVers `codec:"inboxVers" json:"inboxVers"`
TopicType TopicType `codec:"topicType" json:"topicType"`
}
func (o KBFSImpteamUpgradeUpdate) DeepCopy() KBFSImpteamUpgradeUpdate {
return KBFSImpteamUpgradeUpdate{
ConvID: o.ConvID.DeepCopy(),
InboxVers: o.InboxVers.DeepCopy(),
TopicType: o.TopicType.DeepCopy(),
}
}
type SubteamRenameUpdate struct {
ConvIDs []ConversationID `codec:"convIDs" json:"convIDs"`
InboxVers InboxVers `codec:"inboxVers" json:"inboxVers"`
}
func (o SubteamRenameUpdate) DeepCopy() SubteamRenameUpdate {
return SubteamRenameUpdate{
ConvIDs: (func(x []ConversationID) []ConversationID {
if x == nil {
return nil
}
ret := make([]ConversationID, len(x))
for i, v := range x {
vCopy := v.DeepCopy()
ret[i] = vCopy
}
return ret
})(o.ConvIDs),
InboxVers: o.InboxVers.DeepCopy(),
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,938 @@
// Auto-generated to Go types using avdl-compiler v1.4.6 (https://github.com/keybase/node-avdl-compiler)
// Input file: ../client/protocol/avdl/chat1/notify.avdl
package chat1
import (
"errors"
"fmt"
keybase1 "github.com/keybase/go-keybase-chat-bot/kbchat/types/keybase1"
)
type ChatActivitySource int
const (
ChatActivitySource_LOCAL ChatActivitySource = 0
ChatActivitySource_REMOTE ChatActivitySource = 1
)
func (o ChatActivitySource) DeepCopy() ChatActivitySource { return o }
var ChatActivitySourceMap = map[string]ChatActivitySource{
"LOCAL": 0,
"REMOTE": 1,
}
var ChatActivitySourceRevMap = map[ChatActivitySource]string{
0: "LOCAL",
1: "REMOTE",
}
func (e ChatActivitySource) String() string {
if v, ok := ChatActivitySourceRevMap[e]; ok {
return v
}
return fmt.Sprintf("%v", int(e))
}
type ChatActivityType int
const (
ChatActivityType_RESERVED ChatActivityType = 0
ChatActivityType_INCOMING_MESSAGE ChatActivityType = 1
ChatActivityType_READ_MESSAGE ChatActivityType = 2
ChatActivityType_NEW_CONVERSATION ChatActivityType = 3
ChatActivityType_SET_STATUS ChatActivityType = 4
ChatActivityType_FAILED_MESSAGE ChatActivityType = 5
ChatActivityType_MEMBERS_UPDATE ChatActivityType = 6
ChatActivityType_SET_APP_NOTIFICATION_SETTINGS ChatActivityType = 7
ChatActivityType_TEAMTYPE ChatActivityType = 8
ChatActivityType_EXPUNGE ChatActivityType = 9
ChatActivityType_EPHEMERAL_PURGE ChatActivityType = 10
ChatActivityType_REACTION_UPDATE ChatActivityType = 11
ChatActivityType_MESSAGES_UPDATED ChatActivityType = 12
)
func (o ChatActivityType) DeepCopy() ChatActivityType { return o }
var ChatActivityTypeMap = map[string]ChatActivityType{
"RESERVED": 0,
"INCOMING_MESSAGE": 1,
"READ_MESSAGE": 2,
"NEW_CONVERSATION": 3,
"SET_STATUS": 4,
"FAILED_MESSAGE": 5,
"MEMBERS_UPDATE": 6,
"SET_APP_NOTIFICATION_SETTINGS": 7,
"TEAMTYPE": 8,
"EXPUNGE": 9,
"EPHEMERAL_PURGE": 10,
"REACTION_UPDATE": 11,
"MESSAGES_UPDATED": 12,
}
var ChatActivityTypeRevMap = map[ChatActivityType]string{
0: "RESERVED",
1: "INCOMING_MESSAGE",
2: "READ_MESSAGE",
3: "NEW_CONVERSATION",
4: "SET_STATUS",
5: "FAILED_MESSAGE",
6: "MEMBERS_UPDATE",
7: "SET_APP_NOTIFICATION_SETTINGS",
8: "TEAMTYPE",
9: "EXPUNGE",
10: "EPHEMERAL_PURGE",
11: "REACTION_UPDATE",
12: "MESSAGES_UPDATED",
}
func (e ChatActivityType) String() string {
if v, ok := ChatActivityTypeRevMap[e]; ok {
return v
}
return fmt.Sprintf("%v", int(e))
}
type IncomingMessage struct {
Message UIMessage `codec:"message" json:"message"`
ModifiedMessage *UIMessage `codec:"modifiedMessage,omitempty" json:"modifiedMessage,omitempty"`
ConvID ConversationID `codec:"convID" json:"convID"`
DisplayDesktopNotification bool `codec:"displayDesktopNotification" json:"displayDesktopNotification"`
DesktopNotificationSnippet string `codec:"desktopNotificationSnippet" json:"desktopNotificationSnippet"`
Conv *InboxUIItem `codec:"conv,omitempty" json:"conv,omitempty"`
Pagination *UIPagination `codec:"pagination,omitempty" json:"pagination,omitempty"`
}
func (o IncomingMessage) DeepCopy() IncomingMessage {
return IncomingMessage{
Message: o.Message.DeepCopy(),
ModifiedMessage: (func(x *UIMessage) *UIMessage {
if x == nil {
return nil
}
tmp := (*x).DeepCopy()
return &tmp
})(o.ModifiedMessage),
ConvID: o.ConvID.DeepCopy(),
DisplayDesktopNotification: o.DisplayDesktopNotification,
DesktopNotificationSnippet: o.DesktopNotificationSnippet,
Conv: (func(x *InboxUIItem) *InboxUIItem {
if x == nil {
return nil
}
tmp := (*x).DeepCopy()
return &tmp
})(o.Conv),
Pagination: (func(x *UIPagination) *UIPagination {
if x == nil {
return nil
}
tmp := (*x).DeepCopy()
return &tmp
})(o.Pagination),
}
}
type ReadMessageInfo struct {
ConvID ConversationID `codec:"convID" json:"convID"`
MsgID MessageID `codec:"msgID" json:"msgID"`
Conv *InboxUIItem `codec:"conv,omitempty" json:"conv,omitempty"`
}
func (o ReadMessageInfo) DeepCopy() ReadMessageInfo {
return ReadMessageInfo{
ConvID: o.ConvID.DeepCopy(),
MsgID: o.MsgID.DeepCopy(),
Conv: (func(x *InboxUIItem) *InboxUIItem {
if x == nil {
return nil
}
tmp := (*x).DeepCopy()
return &tmp
})(o.Conv),
}
}
type NewConversationInfo struct {
ConvID ConversationID `codec:"convID" json:"convID"`
Conv *InboxUIItem `codec:"conv,omitempty" json:"conv,omitempty"`
}
func (o NewConversationInfo) DeepCopy() NewConversationInfo {
return NewConversationInfo{
ConvID: o.ConvID.DeepCopy(),
Conv: (func(x *InboxUIItem) *InboxUIItem {
if x == nil {
return nil
}
tmp := (*x).DeepCopy()
return &tmp
})(o.Conv),
}
}
type SetStatusInfo struct {
ConvID ConversationID `codec:"convID" json:"convID"`
Status ConversationStatus `codec:"status" json:"status"`
Conv *InboxUIItem `codec:"conv,omitempty" json:"conv,omitempty"`
}
func (o SetStatusInfo) DeepCopy() SetStatusInfo {
return SetStatusInfo{
ConvID: o.ConvID.DeepCopy(),
Status: o.Status.DeepCopy(),
Conv: (func(x *InboxUIItem) *InboxUIItem {
if x == nil {
return nil
}
tmp := (*x).DeepCopy()
return &tmp
})(o.Conv),
}
}
type SetAppNotificationSettingsInfo struct {
ConvID ConversationID `codec:"convID" json:"convID"`
Settings ConversationNotificationInfo `codec:"settings" json:"settings"`
}
func (o SetAppNotificationSettingsInfo) DeepCopy() SetAppNotificationSettingsInfo {
return SetAppNotificationSettingsInfo{
ConvID: o.ConvID.DeepCopy(),
Settings: o.Settings.DeepCopy(),
}
}
type FailedMessageInfo struct {
OutboxRecords []OutboxRecord `codec:"outboxRecords" json:"outboxRecords"`
IsEphemeralPurge bool `codec:"isEphemeralPurge" json:"isEphemeralPurge"`
Conv *InboxUIItem `codec:"conv,omitempty" json:"conv,omitempty"`
}
func (o FailedMessageInfo) DeepCopy() FailedMessageInfo {
return FailedMessageInfo{
OutboxRecords: (func(x []OutboxRecord) []OutboxRecord {
if x == nil {
return nil
}
ret := make([]OutboxRecord, len(x))
for i, v := range x {
vCopy := v.DeepCopy()
ret[i] = vCopy
}
return ret
})(o.OutboxRecords),
IsEphemeralPurge: o.IsEphemeralPurge,
Conv: (func(x *InboxUIItem) *InboxUIItem {
if x == nil {
return nil
}
tmp := (*x).DeepCopy()
return &tmp
})(o.Conv),
}
}
type MemberInfo struct {
Member string `codec:"member" json:"member"`
Status ConversationMemberStatus `codec:"status" json:"status"`
}
func (o MemberInfo) DeepCopy() MemberInfo {
return MemberInfo{
Member: o.Member,
Status: o.Status.DeepCopy(),
}
}
type MembersUpdateInfo struct {
ConvID ConversationID `codec:"convID" json:"convID"`
Members []MemberInfo `codec:"members" json:"members"`
}
func (o MembersUpdateInfo) DeepCopy() MembersUpdateInfo {
return MembersUpdateInfo{
ConvID: o.ConvID.DeepCopy(),
Members: (func(x []MemberInfo) []MemberInfo {
if x == nil {
return nil
}
ret := make([]MemberInfo, len(x))
for i, v := range x {
vCopy := v.DeepCopy()
ret[i] = vCopy
}
return ret
})(o.Members),
}
}
type TeamTypeInfo struct {
ConvID ConversationID `codec:"convID" json:"convID"`
TeamType TeamType `codec:"teamType" json:"teamType"`
Conv *InboxUIItem `codec:"conv,omitempty" json:"conv,omitempty"`
}
func (o TeamTypeInfo) DeepCopy() TeamTypeInfo {
return TeamTypeInfo{
ConvID: o.ConvID.DeepCopy(),
TeamType: o.TeamType.DeepCopy(),
Conv: (func(x *InboxUIItem) *InboxUIItem {
if x == nil {
return nil
}
tmp := (*x).DeepCopy()
return &tmp
})(o.Conv),
}
}
type ExpungeInfo struct {
ConvID ConversationID `codec:"convID" json:"convID"`
Expunge Expunge `codec:"expunge" json:"expunge"`
}
func (o ExpungeInfo) DeepCopy() ExpungeInfo {
return ExpungeInfo{
ConvID: o.ConvID.DeepCopy(),
Expunge: o.Expunge.DeepCopy(),
}
}
type EphemeralPurgeNotifInfo struct {
ConvID ConversationID `codec:"convID" json:"convID"`
Msgs []UIMessage `codec:"msgs" json:"msgs"`
}
func (o EphemeralPurgeNotifInfo) DeepCopy() EphemeralPurgeNotifInfo {
return EphemeralPurgeNotifInfo{
ConvID: o.ConvID.DeepCopy(),
Msgs: (func(x []UIMessage) []UIMessage {
if x == nil {
return nil
}
ret := make([]UIMessage, len(x))
for i, v := range x {
vCopy := v.DeepCopy()
ret[i] = vCopy
}
return ret
})(o.Msgs),
}
}
type ReactionUpdate struct {
Reactions ReactionMap `codec:"reactions" json:"reactions"`
TargetMsgID MessageID `codec:"targetMsgID" json:"targetMsgID"`
}
func (o ReactionUpdate) DeepCopy() ReactionUpdate {
return ReactionUpdate{
Reactions: o.Reactions.DeepCopy(),
TargetMsgID: o.TargetMsgID.DeepCopy(),
}
}
type ReactionUpdateNotif struct {
ConvID ConversationID `codec:"convID" json:"convID"`
UserReacjis keybase1.UserReacjis `codec:"userReacjis" json:"userReacjis"`
ReactionUpdates []ReactionUpdate `codec:"reactionUpdates" json:"reactionUpdates"`
}
func (o ReactionUpdateNotif) DeepCopy() ReactionUpdateNotif {
return ReactionUpdateNotif{
ConvID: o.ConvID.DeepCopy(),
UserReacjis: o.UserReacjis.DeepCopy(),
ReactionUpdates: (func(x []ReactionUpdate) []ReactionUpdate {
if x == nil {
return nil
}
ret := make([]ReactionUpdate, len(x))
for i, v := range x {
vCopy := v.DeepCopy()
ret[i] = vCopy
}
return ret
})(o.ReactionUpdates),
}
}
type MessagesUpdated struct {
ConvID ConversationID `codec:"convID" json:"convID"`
Updates []UIMessage `codec:"updates" json:"updates"`
}
func (o MessagesUpdated) DeepCopy() MessagesUpdated {
return MessagesUpdated{
ConvID: o.ConvID.DeepCopy(),
Updates: (func(x []UIMessage) []UIMessage {
if x == nil {
return nil
}
ret := make([]UIMessage, len(x))
for i, v := range x {
vCopy := v.DeepCopy()
ret[i] = vCopy
}
return ret
})(o.Updates),
}
}
type ChatActivity struct {
ActivityType__ ChatActivityType `codec:"activityType" json:"activityType"`
IncomingMessage__ *IncomingMessage `codec:"incomingMessage,omitempty" json:"incomingMessage,omitempty"`
ReadMessage__ *ReadMessageInfo `codec:"readMessage,omitempty" json:"readMessage,omitempty"`
NewConversation__ *NewConversationInfo `codec:"newConversation,omitempty" json:"newConversation,omitempty"`
SetStatus__ *SetStatusInfo `codec:"setStatus,omitempty" json:"setStatus,omitempty"`
FailedMessage__ *FailedMessageInfo `codec:"failedMessage,omitempty" json:"failedMessage,omitempty"`
MembersUpdate__ *MembersUpdateInfo `codec:"membersUpdate,omitempty" json:"membersUpdate,omitempty"`
SetAppNotificationSettings__ *SetAppNotificationSettingsInfo `codec:"setAppNotificationSettings,omitempty" json:"setAppNotificationSettings,omitempty"`
Teamtype__ *TeamTypeInfo `codec:"teamtype,omitempty" json:"teamtype,omitempty"`
Expunge__ *ExpungeInfo `codec:"expunge,omitempty" json:"expunge,omitempty"`
EphemeralPurge__ *EphemeralPurgeNotifInfo `codec:"ephemeralPurge,omitempty" json:"ephemeralPurge,omitempty"`
ReactionUpdate__ *ReactionUpdateNotif `codec:"reactionUpdate,omitempty" json:"reactionUpdate,omitempty"`
MessagesUpdated__ *MessagesUpdated `codec:"messagesUpdated,omitempty" json:"messagesUpdated,omitempty"`
}
func (o *ChatActivity) ActivityType() (ret ChatActivityType, err error) {
switch o.ActivityType__ {
case ChatActivityType_INCOMING_MESSAGE:
if o.IncomingMessage__ == nil {
err = errors.New("unexpected nil value for IncomingMessage__")
return ret, err
}
case ChatActivityType_READ_MESSAGE:
if o.ReadMessage__ == nil {
err = errors.New("unexpected nil value for ReadMessage__")
return ret, err
}
case ChatActivityType_NEW_CONVERSATION:
if o.NewConversation__ == nil {
err = errors.New("unexpected nil value for NewConversation__")
return ret, err
}
case ChatActivityType_SET_STATUS:
if o.SetStatus__ == nil {
err = errors.New("unexpected nil value for SetStatus__")
return ret, err
}
case ChatActivityType_FAILED_MESSAGE:
if o.FailedMessage__ == nil {
err = errors.New("unexpected nil value for FailedMessage__")
return ret, err
}
case ChatActivityType_MEMBERS_UPDATE:
if o.MembersUpdate__ == nil {
err = errors.New("unexpected nil value for MembersUpdate__")
return ret, err
}
case ChatActivityType_SET_APP_NOTIFICATION_SETTINGS:
if o.SetAppNotificationSettings__ == nil {
err = errors.New("unexpected nil value for SetAppNotificationSettings__")
return ret, err
}
case ChatActivityType_TEAMTYPE:
if o.Teamtype__ == nil {
err = errors.New("unexpected nil value for Teamtype__")
return ret, err
}
case ChatActivityType_EXPUNGE:
if o.Expunge__ == nil {
err = errors.New("unexpected nil value for Expunge__")
return ret, err
}
case ChatActivityType_EPHEMERAL_PURGE:
if o.EphemeralPurge__ == nil {
err = errors.New("unexpected nil value for EphemeralPurge__")
return ret, err
}
case ChatActivityType_REACTION_UPDATE:
if o.ReactionUpdate__ == nil {
err = errors.New("unexpected nil value for ReactionUpdate__")
return ret, err
}
case ChatActivityType_MESSAGES_UPDATED:
if o.MessagesUpdated__ == nil {
err = errors.New("unexpected nil value for MessagesUpdated__")
return ret, err
}
}
return o.ActivityType__, nil
}
func (o ChatActivity) IncomingMessage() (res IncomingMessage) {
if o.ActivityType__ != ChatActivityType_INCOMING_MESSAGE {
panic("wrong case accessed")
}
if o.IncomingMessage__ == nil {
return
}
return *o.IncomingMessage__
}
func (o ChatActivity) ReadMessage() (res ReadMessageInfo) {
if o.ActivityType__ != ChatActivityType_READ_MESSAGE {
panic("wrong case accessed")
}
if o.ReadMessage__ == nil {
return
}
return *o.ReadMessage__
}
func (o ChatActivity) NewConversation() (res NewConversationInfo) {
if o.ActivityType__ != ChatActivityType_NEW_CONVERSATION {
panic("wrong case accessed")
}
if o.NewConversation__ == nil {
return
}
return *o.NewConversation__
}
func (o ChatActivity) SetStatus() (res SetStatusInfo) {
if o.ActivityType__ != ChatActivityType_SET_STATUS {
panic("wrong case accessed")
}
if o.SetStatus__ == nil {
return
}
return *o.SetStatus__
}
func (o ChatActivity) FailedMessage() (res FailedMessageInfo) {
if o.ActivityType__ != ChatActivityType_FAILED_MESSAGE {
panic("wrong case accessed")
}
if o.FailedMessage__ == nil {
return
}
return *o.FailedMessage__
}
func (o ChatActivity) MembersUpdate() (res MembersUpdateInfo) {
if o.ActivityType__ != ChatActivityType_MEMBERS_UPDATE {
panic("wrong case accessed")
}
if o.MembersUpdate__ == nil {
return
}
return *o.MembersUpdate__
}
func (o ChatActivity) SetAppNotificationSettings() (res SetAppNotificationSettingsInfo) {
if o.ActivityType__ != ChatActivityType_SET_APP_NOTIFICATION_SETTINGS {
panic("wrong case accessed")
}
if o.SetAppNotificationSettings__ == nil {
return
}
return *o.SetAppNotificationSettings__
}
func (o ChatActivity) Teamtype() (res TeamTypeInfo) {
if o.ActivityType__ != ChatActivityType_TEAMTYPE {
panic("wrong case accessed")
}
if o.Teamtype__ == nil {
return
}
return *o.Teamtype__
}
func (o ChatActivity) Expunge() (res ExpungeInfo) {
if o.ActivityType__ != ChatActivityType_EXPUNGE {
panic("wrong case accessed")
}
if o.Expunge__ == nil {
return
}
return *o.Expunge__
}
func (o ChatActivity) EphemeralPurge() (res EphemeralPurgeNotifInfo) {
if o.ActivityType__ != ChatActivityType_EPHEMERAL_PURGE {
panic("wrong case accessed")
}
if o.EphemeralPurge__ == nil {
return
}
return *o.EphemeralPurge__
}
func (o ChatActivity) ReactionUpdate() (res ReactionUpdateNotif) {
if o.ActivityType__ != ChatActivityType_REACTION_UPDATE {
panic("wrong case accessed")
}
if o.ReactionUpdate__ == nil {
return
}
return *o.ReactionUpdate__
}
func (o ChatActivity) MessagesUpdated() (res MessagesUpdated) {
if o.ActivityType__ != ChatActivityType_MESSAGES_UPDATED {
panic("wrong case accessed")
}
if o.MessagesUpdated__ == nil {
return
}
return *o.MessagesUpdated__
}
func NewChatActivityWithIncomingMessage(v IncomingMessage) ChatActivity {
return ChatActivity{
ActivityType__: ChatActivityType_INCOMING_MESSAGE,
IncomingMessage__: &v,
}
}
func NewChatActivityWithReadMessage(v ReadMessageInfo) ChatActivity {
return ChatActivity{
ActivityType__: ChatActivityType_READ_MESSAGE,
ReadMessage__: &v,
}
}
func NewChatActivityWithNewConversation(v NewConversationInfo) ChatActivity {
return ChatActivity{
ActivityType__: ChatActivityType_NEW_CONVERSATION,
NewConversation__: &v,
}
}
func NewChatActivityWithSetStatus(v SetStatusInfo) ChatActivity {
return ChatActivity{
ActivityType__: ChatActivityType_SET_STATUS,
SetStatus__: &v,
}
}
func NewChatActivityWithFailedMessage(v FailedMessageInfo) ChatActivity {
return ChatActivity{
ActivityType__: ChatActivityType_FAILED_MESSAGE,
FailedMessage__: &v,
}
}
func NewChatActivityWithMembersUpdate(v MembersUpdateInfo) ChatActivity {
return ChatActivity{
ActivityType__: ChatActivityType_MEMBERS_UPDATE,
MembersUpdate__: &v,
}
}
func NewChatActivityWithSetAppNotificationSettings(v SetAppNotificationSettingsInfo) ChatActivity {
return ChatActivity{
ActivityType__: ChatActivityType_SET_APP_NOTIFICATION_SETTINGS,
SetAppNotificationSettings__: &v,
}
}
func NewChatActivityWithTeamtype(v TeamTypeInfo) ChatActivity {
return ChatActivity{
ActivityType__: ChatActivityType_TEAMTYPE,
Teamtype__: &v,
}
}
func NewChatActivityWithExpunge(v ExpungeInfo) ChatActivity {
return ChatActivity{
ActivityType__: ChatActivityType_EXPUNGE,
Expunge__: &v,
}
}
func NewChatActivityWithEphemeralPurge(v EphemeralPurgeNotifInfo) ChatActivity {
return ChatActivity{
ActivityType__: ChatActivityType_EPHEMERAL_PURGE,
EphemeralPurge__: &v,
}
}
func NewChatActivityWithReactionUpdate(v ReactionUpdateNotif) ChatActivity {
return ChatActivity{
ActivityType__: ChatActivityType_REACTION_UPDATE,
ReactionUpdate__: &v,
}
}
func NewChatActivityWithMessagesUpdated(v MessagesUpdated) ChatActivity {
return ChatActivity{
ActivityType__: ChatActivityType_MESSAGES_UPDATED,
MessagesUpdated__: &v,
}
}
func (o ChatActivity) DeepCopy() ChatActivity {
return ChatActivity{
ActivityType__: o.ActivityType__.DeepCopy(),
IncomingMessage__: (func(x *IncomingMessage) *IncomingMessage {
if x == nil {
return nil
}
tmp := (*x).DeepCopy()
return &tmp
})(o.IncomingMessage__),
ReadMessage__: (func(x *ReadMessageInfo) *ReadMessageInfo {
if x == nil {
return nil
}
tmp := (*x).DeepCopy()
return &tmp
})(o.ReadMessage__),
NewConversation__: (func(x *NewConversationInfo) *NewConversationInfo {
if x == nil {
return nil
}
tmp := (*x).DeepCopy()
return &tmp
})(o.NewConversation__),
SetStatus__: (func(x *SetStatusInfo) *SetStatusInfo {
if x == nil {
return nil
}
tmp := (*x).DeepCopy()
return &tmp
})(o.SetStatus__),
FailedMessage__: (func(x *FailedMessageInfo) *FailedMessageInfo {
if x == nil {
return nil
}
tmp := (*x).DeepCopy()
return &tmp
})(o.FailedMessage__),
MembersUpdate__: (func(x *MembersUpdateInfo) *MembersUpdateInfo {
if x == nil {
return nil
}
tmp := (*x).DeepCopy()
return &tmp
})(o.MembersUpdate__),
SetAppNotificationSettings__: (func(x *SetAppNotificationSettingsInfo) *SetAppNotificationSettingsInfo {
if x == nil {
return nil
}
tmp := (*x).DeepCopy()
return &tmp
})(o.SetAppNotificationSettings__),
Teamtype__: (func(x *TeamTypeInfo) *TeamTypeInfo {
if x == nil {
return nil
}
tmp := (*x).DeepCopy()
return &tmp
})(o.Teamtype__),
Expunge__: (func(x *ExpungeInfo) *ExpungeInfo {
if x == nil {
return nil
}
tmp := (*x).DeepCopy()
return &tmp
})(o.Expunge__),
EphemeralPurge__: (func(x *EphemeralPurgeNotifInfo) *EphemeralPurgeNotifInfo {
if x == nil {
return nil
}
tmp := (*x).DeepCopy()
return &tmp
})(o.EphemeralPurge__),
ReactionUpdate__: (func(x *ReactionUpdateNotif) *ReactionUpdateNotif {
if x == nil {
return nil
}
tmp := (*x).DeepCopy()
return &tmp
})(o.ReactionUpdate__),
MessagesUpdated__: (func(x *MessagesUpdated) *MessagesUpdated {
if x == nil {
return nil
}
tmp := (*x).DeepCopy()
return &tmp
})(o.MessagesUpdated__),
}
}
type TyperInfo struct {
Uid keybase1.UID `codec:"uid" json:"uid"`
Username string `codec:"username" json:"username"`
DeviceID keybase1.DeviceID `codec:"deviceID" json:"deviceID"`
DeviceName string `codec:"deviceName" json:"deviceName"`
DeviceType string `codec:"deviceType" json:"deviceType"`
}
func (o TyperInfo) DeepCopy() TyperInfo {
return TyperInfo{
Uid: o.Uid.DeepCopy(),
Username: o.Username,
DeviceID: o.DeviceID.DeepCopy(),
DeviceName: o.DeviceName,
DeviceType: o.DeviceType,
}
}
type ConvTypingUpdate struct {
ConvID ConversationID `codec:"convID" json:"convID"`
Typers []TyperInfo `codec:"typers" json:"typers"`
}
func (o ConvTypingUpdate) DeepCopy() ConvTypingUpdate {
return ConvTypingUpdate{
ConvID: o.ConvID.DeepCopy(),
Typers: (func(x []TyperInfo) []TyperInfo {
if x == nil {
return nil
}
ret := make([]TyperInfo, len(x))
for i, v := range x {
vCopy := v.DeepCopy()
ret[i] = vCopy
}
return ret
})(o.Typers),
}
}
type StaleUpdateType int
const (
StaleUpdateType_CLEAR StaleUpdateType = 0
StaleUpdateType_NEWACTIVITY StaleUpdateType = 1
)
func (o StaleUpdateType) DeepCopy() StaleUpdateType { return o }
var StaleUpdateTypeMap = map[string]StaleUpdateType{
"CLEAR": 0,
"NEWACTIVITY": 1,
}
var StaleUpdateTypeRevMap = map[StaleUpdateType]string{
0: "CLEAR",
1: "NEWACTIVITY",
}
func (e StaleUpdateType) String() string {
if v, ok := StaleUpdateTypeRevMap[e]; ok {
return v
}
return fmt.Sprintf("%v", int(e))
}
type ConversationStaleUpdate struct {
ConvID ConversationID `codec:"convID" json:"convID"`
UpdateType StaleUpdateType `codec:"updateType" json:"updateType"`
}
func (o ConversationStaleUpdate) DeepCopy() ConversationStaleUpdate {
return ConversationStaleUpdate{
ConvID: o.ConvID.DeepCopy(),
UpdateType: o.UpdateType.DeepCopy(),
}
}
type ChatSyncIncrementalConv struct {
Conv UnverifiedInboxUIItem `codec:"conv" json:"conv"`
ShouldUnbox bool `codec:"shouldUnbox" json:"shouldUnbox"`
}
func (o ChatSyncIncrementalConv) DeepCopy() ChatSyncIncrementalConv {
return ChatSyncIncrementalConv{
Conv: o.Conv.DeepCopy(),
ShouldUnbox: o.ShouldUnbox,
}
}
type ChatSyncIncrementalInfo struct {
Items []ChatSyncIncrementalConv `codec:"items" json:"items"`
Removals []string `codec:"removals" json:"removals"`
}
func (o ChatSyncIncrementalInfo) DeepCopy() ChatSyncIncrementalInfo {
return ChatSyncIncrementalInfo{
Items: (func(x []ChatSyncIncrementalConv) []ChatSyncIncrementalConv {
if x == nil {
return nil
}
ret := make([]ChatSyncIncrementalConv, len(x))
for i, v := range x {
vCopy := v.DeepCopy()
ret[i] = vCopy
}
return ret
})(o.Items),
Removals: (func(x []string) []string {
if x == nil {
return nil
}
ret := make([]string, len(x))
for i, v := range x {
vCopy := v
ret[i] = vCopy
}
return ret
})(o.Removals),
}
}
type ChatSyncResult struct {
SyncType__ SyncInboxResType `codec:"syncType" json:"syncType"`
Incremental__ *ChatSyncIncrementalInfo `codec:"incremental,omitempty" json:"incremental,omitempty"`
}
func (o *ChatSyncResult) SyncType() (ret SyncInboxResType, err error) {
switch o.SyncType__ {
case SyncInboxResType_INCREMENTAL:
if o.Incremental__ == nil {
err = errors.New("unexpected nil value for Incremental__")
return ret, err
}
}
return o.SyncType__, nil
}
func (o ChatSyncResult) Incremental() (res ChatSyncIncrementalInfo) {
if o.SyncType__ != SyncInboxResType_INCREMENTAL {
panic("wrong case accessed")
}
if o.Incremental__ == nil {
return
}
return *o.Incremental__
}
func NewChatSyncResultWithCurrent() ChatSyncResult {
return ChatSyncResult{
SyncType__: SyncInboxResType_CURRENT,
}
}
func NewChatSyncResultWithClear() ChatSyncResult {
return ChatSyncResult{
SyncType__: SyncInboxResType_CLEAR,
}
}
func NewChatSyncResultWithIncremental(v ChatSyncIncrementalInfo) ChatSyncResult {
return ChatSyncResult{
SyncType__: SyncInboxResType_INCREMENTAL,
Incremental__: &v,
}
}
func (o ChatSyncResult) DeepCopy() ChatSyncResult {
return ChatSyncResult{
SyncType__: o.SyncType__.DeepCopy(),
Incremental__: (func(x *ChatSyncIncrementalInfo) *ChatSyncIncrementalInfo {
if x == nil {
return nil
}
tmp := (*x).DeepCopy()
return &tmp
})(o.Incremental__),
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,850 @@
// Auto-generated to Go types using avdl-compiler v1.4.6 (https://github.com/keybase/node-avdl-compiler)
// Input file: ../client/protocol/avdl/chat1/unfurl.avdl
package chat1
import (
"errors"
"fmt"
gregor1 "github.com/keybase/go-keybase-chat-bot/kbchat/types/gregor1"
)
type UnfurlType int
const (
UnfurlType_GENERIC UnfurlType = 0
UnfurlType_YOUTUBE UnfurlType = 1
UnfurlType_GIPHY UnfurlType = 2
UnfurlType_MAPS UnfurlType = 3
)
func (o UnfurlType) DeepCopy() UnfurlType { return o }
var UnfurlTypeMap = map[string]UnfurlType{
"GENERIC": 0,
"YOUTUBE": 1,
"GIPHY": 2,
"MAPS": 3,
}
var UnfurlTypeRevMap = map[UnfurlType]string{
0: "GENERIC",
1: "YOUTUBE",
2: "GIPHY",
3: "MAPS",
}
func (e UnfurlType) String() string {
if v, ok := UnfurlTypeRevMap[e]; ok {
return v
}
return fmt.Sprintf("%v", int(e))
}
type UnfurlVideo struct {
Url string `codec:"url" json:"url"`
MimeType string `codec:"mimeType" json:"mimeType"`
Height int `codec:"height" json:"height"`
Width int `codec:"width" json:"width"`
}
func (o UnfurlVideo) DeepCopy() UnfurlVideo {
return UnfurlVideo{
Url: o.Url,
MimeType: o.MimeType,
Height: o.Height,
Width: o.Width,
}
}
type UnfurlGenericRaw struct {
Title string `codec:"title" json:"title"`
Url string `codec:"url" json:"url"`
SiteName string `codec:"siteName" json:"siteName"`
FaviconUrl *string `codec:"faviconUrl,omitempty" json:"faviconUrl,omitempty"`
ImageUrl *string `codec:"imageUrl,omitempty" json:"imageUrl,omitempty"`
Video *UnfurlVideo `codec:"video,omitempty" json:"video,omitempty"`
PublishTime *int `codec:"publishTime,omitempty" json:"publishTime,omitempty"`
Description *string `codec:"description,omitempty" json:"description,omitempty"`
}
func (o UnfurlGenericRaw) DeepCopy() UnfurlGenericRaw {
return UnfurlGenericRaw{
Title: o.Title,
Url: o.Url,
SiteName: o.SiteName,
FaviconUrl: (func(x *string) *string {
if x == nil {
return nil
}
tmp := (*x)
return &tmp
})(o.FaviconUrl),
ImageUrl: (func(x *string) *string {
if x == nil {
return nil
}
tmp := (*x)
return &tmp
})(o.ImageUrl),
Video: (func(x *UnfurlVideo) *UnfurlVideo {
if x == nil {
return nil
}
tmp := (*x).DeepCopy()
return &tmp
})(o.Video),
PublishTime: (func(x *int) *int {
if x == nil {
return nil
}
tmp := (*x)
return &tmp
})(o.PublishTime),
Description: (func(x *string) *string {
if x == nil {
return nil
}
tmp := (*x)
return &tmp
})(o.Description),
}
}
type UnfurlYoutubeRaw struct {
}
func (o UnfurlYoutubeRaw) DeepCopy() UnfurlYoutubeRaw {
return UnfurlYoutubeRaw{}
}
type UnfurlGiphyRaw struct {
ImageUrl *string `codec:"imageUrl,omitempty" json:"imageUrl,omitempty"`
Video *UnfurlVideo `codec:"video,omitempty" json:"video,omitempty"`
FaviconUrl *string `codec:"faviconUrl,omitempty" json:"faviconUrl,omitempty"`
}
func (o UnfurlGiphyRaw) DeepCopy() UnfurlGiphyRaw {
return UnfurlGiphyRaw{
ImageUrl: (func(x *string) *string {
if x == nil {
return nil
}
tmp := (*x)
return &tmp
})(o.ImageUrl),
Video: (func(x *UnfurlVideo) *UnfurlVideo {
if x == nil {
return nil
}
tmp := (*x).DeepCopy()
return &tmp
})(o.Video),
FaviconUrl: (func(x *string) *string {
if x == nil {
return nil
}
tmp := (*x)
return &tmp
})(o.FaviconUrl),
}
}
type UnfurlMapsRaw struct {
Title string `codec:"title" json:"title"`
Url string `codec:"url" json:"url"`
SiteName string `codec:"siteName" json:"siteName"`
ImageUrl string `codec:"imageUrl" json:"imageUrl"`
HistoryImageUrl *string `codec:"historyImageUrl,omitempty" json:"historyImageUrl,omitempty"`
Description string `codec:"description" json:"description"`
Coord Coordinate `codec:"coord" json:"coord"`
Time gregor1.Time `codec:"time" json:"time"`
LiveLocationEndTime *gregor1.Time `codec:"liveLocationEndTime,omitempty" json:"liveLocationEndTime,omitempty"`
LiveLocationDone bool `codec:"liveLocationDone" json:"liveLocationDone"`
}
func (o UnfurlMapsRaw) DeepCopy() UnfurlMapsRaw {
return UnfurlMapsRaw{
Title: o.Title,
Url: o.Url,
SiteName: o.SiteName,
ImageUrl: o.ImageUrl,
HistoryImageUrl: (func(x *string) *string {
if x == nil {
return nil
}
tmp := (*x)
return &tmp
})(o.HistoryImageUrl),
Description: o.Description,
Coord: o.Coord.DeepCopy(),
Time: o.Time.DeepCopy(),
LiveLocationEndTime: (func(x *gregor1.Time) *gregor1.Time {
if x == nil {
return nil
}
tmp := (*x).DeepCopy()
return &tmp
})(o.LiveLocationEndTime),
LiveLocationDone: o.LiveLocationDone,
}
}
type UnfurlRaw struct {
UnfurlType__ UnfurlType `codec:"unfurlType" json:"unfurlType"`
Generic__ *UnfurlGenericRaw `codec:"generic,omitempty" json:"generic,omitempty"`
Youtube__ *UnfurlYoutubeRaw `codec:"youtube,omitempty" json:"youtube,omitempty"`
Giphy__ *UnfurlGiphyRaw `codec:"giphy,omitempty" json:"giphy,omitempty"`
Maps__ *UnfurlMapsRaw `codec:"maps,omitempty" json:"maps,omitempty"`
}
func (o *UnfurlRaw) UnfurlType() (ret UnfurlType, err error) {
switch o.UnfurlType__ {
case UnfurlType_GENERIC:
if o.Generic__ == nil {
err = errors.New("unexpected nil value for Generic__")
return ret, err
}
case UnfurlType_YOUTUBE:
if o.Youtube__ == nil {
err = errors.New("unexpected nil value for Youtube__")
return ret, err
}
case UnfurlType_GIPHY:
if o.Giphy__ == nil {
err = errors.New("unexpected nil value for Giphy__")
return ret, err
}
case UnfurlType_MAPS:
if o.Maps__ == nil {
err = errors.New("unexpected nil value for Maps__")
return ret, err
}
}
return o.UnfurlType__, nil
}
func (o UnfurlRaw) Generic() (res UnfurlGenericRaw) {
if o.UnfurlType__ != UnfurlType_GENERIC {
panic("wrong case accessed")
}
if o.Generic__ == nil {
return
}
return *o.Generic__
}
func (o UnfurlRaw) Youtube() (res UnfurlYoutubeRaw) {
if o.UnfurlType__ != UnfurlType_YOUTUBE {
panic("wrong case accessed")
}
if o.Youtube__ == nil {
return
}
return *o.Youtube__
}
func (o UnfurlRaw) Giphy() (res UnfurlGiphyRaw) {
if o.UnfurlType__ != UnfurlType_GIPHY {
panic("wrong case accessed")
}
if o.Giphy__ == nil {
return
}
return *o.Giphy__
}
func (o UnfurlRaw) Maps() (res UnfurlMapsRaw) {
if o.UnfurlType__ != UnfurlType_MAPS {
panic("wrong case accessed")
}
if o.Maps__ == nil {
return
}
return *o.Maps__
}
func NewUnfurlRawWithGeneric(v UnfurlGenericRaw) UnfurlRaw {
return UnfurlRaw{
UnfurlType__: UnfurlType_GENERIC,
Generic__: &v,
}
}
func NewUnfurlRawWithYoutube(v UnfurlYoutubeRaw) UnfurlRaw {
return UnfurlRaw{
UnfurlType__: UnfurlType_YOUTUBE,
Youtube__: &v,
}
}
func NewUnfurlRawWithGiphy(v UnfurlGiphyRaw) UnfurlRaw {
return UnfurlRaw{
UnfurlType__: UnfurlType_GIPHY,
Giphy__: &v,
}
}
func NewUnfurlRawWithMaps(v UnfurlMapsRaw) UnfurlRaw {
return UnfurlRaw{
UnfurlType__: UnfurlType_MAPS,
Maps__: &v,
}
}
func (o UnfurlRaw) DeepCopy() UnfurlRaw {
return UnfurlRaw{
UnfurlType__: o.UnfurlType__.DeepCopy(),
Generic__: (func(x *UnfurlGenericRaw) *UnfurlGenericRaw {
if x == nil {
return nil
}
tmp := (*x).DeepCopy()
return &tmp
})(o.Generic__),
Youtube__: (func(x *UnfurlYoutubeRaw) *UnfurlYoutubeRaw {
if x == nil {
return nil
}
tmp := (*x).DeepCopy()
return &tmp
})(o.Youtube__),
Giphy__: (func(x *UnfurlGiphyRaw) *UnfurlGiphyRaw {
if x == nil {
return nil
}
tmp := (*x).DeepCopy()
return &tmp
})(o.Giphy__),
Maps__: (func(x *UnfurlMapsRaw) *UnfurlMapsRaw {
if x == nil {
return nil
}
tmp := (*x).DeepCopy()
return &tmp
})(o.Maps__),
}
}
type UnfurlGenericMapInfo struct {
Coord Coordinate `codec:"coord" json:"coord"`
Time gregor1.Time `codec:"time" json:"time"`
LiveLocationEndTime *gregor1.Time `codec:"liveLocationEndTime,omitempty" json:"liveLocationEndTime,omitempty"`
IsLiveLocationDone bool `codec:"isLiveLocationDone" json:"isLiveLocationDone"`
}
func (o UnfurlGenericMapInfo) DeepCopy() UnfurlGenericMapInfo {
return UnfurlGenericMapInfo{
Coord: o.Coord.DeepCopy(),
Time: o.Time.DeepCopy(),
LiveLocationEndTime: (func(x *gregor1.Time) *gregor1.Time {
if x == nil {
return nil
}
tmp := (*x).DeepCopy()
return &tmp
})(o.LiveLocationEndTime),
IsLiveLocationDone: o.IsLiveLocationDone,
}
}
type UnfurlGeneric struct {
Title string `codec:"title" json:"title"`
Url string `codec:"url" json:"url"`
SiteName string `codec:"siteName" json:"siteName"`
Favicon *Asset `codec:"favicon,omitempty" json:"favicon,omitempty"`
Image *Asset `codec:"image,omitempty" json:"image,omitempty"`
PublishTime *int `codec:"publishTime,omitempty" json:"publishTime,omitempty"`
Description *string `codec:"description,omitempty" json:"description,omitempty"`
MapInfo *UnfurlGenericMapInfo `codec:"mapInfo,omitempty" json:"mapInfo,omitempty"`
}
func (o UnfurlGeneric) DeepCopy() UnfurlGeneric {
return UnfurlGeneric{
Title: o.Title,
Url: o.Url,
SiteName: o.SiteName,
Favicon: (func(x *Asset) *Asset {
if x == nil {
return nil
}
tmp := (*x).DeepCopy()
return &tmp
})(o.Favicon),
Image: (func(x *Asset) *Asset {
if x == nil {
return nil
}
tmp := (*x).DeepCopy()
return &tmp
})(o.Image),
PublishTime: (func(x *int) *int {
if x == nil {
return nil
}
tmp := (*x)
return &tmp
})(o.PublishTime),
Description: (func(x *string) *string {
if x == nil {
return nil
}
tmp := (*x)
return &tmp
})(o.Description),
MapInfo: (func(x *UnfurlGenericMapInfo) *UnfurlGenericMapInfo {
if x == nil {
return nil
}
tmp := (*x).DeepCopy()
return &tmp
})(o.MapInfo),
}
}
type UnfurlYoutube struct {
}
func (o UnfurlYoutube) DeepCopy() UnfurlYoutube {
return UnfurlYoutube{}
}
type UnfurlGiphy struct {
Favicon *Asset `codec:"favicon,omitempty" json:"favicon,omitempty"`
Image *Asset `codec:"image,omitempty" json:"image,omitempty"`
Video *Asset `codec:"video,omitempty" json:"video,omitempty"`
}
func (o UnfurlGiphy) DeepCopy() UnfurlGiphy {
return UnfurlGiphy{
Favicon: (func(x *Asset) *Asset {
if x == nil {
return nil
}
tmp := (*x).DeepCopy()
return &tmp
})(o.Favicon),
Image: (func(x *Asset) *Asset {
if x == nil {
return nil
}
tmp := (*x).DeepCopy()
return &tmp
})(o.Image),
Video: (func(x *Asset) *Asset {
if x == nil {
return nil
}
tmp := (*x).DeepCopy()
return &tmp
})(o.Video),
}
}
type Unfurl struct {
UnfurlType__ UnfurlType `codec:"unfurlType" json:"unfurlType"`
Generic__ *UnfurlGeneric `codec:"generic,omitempty" json:"generic,omitempty"`
Youtube__ *UnfurlYoutube `codec:"youtube,omitempty" json:"youtube,omitempty"`
Giphy__ *UnfurlGiphy `codec:"giphy,omitempty" json:"giphy,omitempty"`
}
func (o *Unfurl) UnfurlType() (ret UnfurlType, err error) {
switch o.UnfurlType__ {
case UnfurlType_GENERIC:
if o.Generic__ == nil {
err = errors.New("unexpected nil value for Generic__")
return ret, err
}
case UnfurlType_YOUTUBE:
if o.Youtube__ == nil {
err = errors.New("unexpected nil value for Youtube__")
return ret, err
}
case UnfurlType_GIPHY:
if o.Giphy__ == nil {
err = errors.New("unexpected nil value for Giphy__")
return ret, err
}
}
return o.UnfurlType__, nil
}
func (o Unfurl) Generic() (res UnfurlGeneric) {
if o.UnfurlType__ != UnfurlType_GENERIC {
panic("wrong case accessed")
}
if o.Generic__ == nil {
return
}
return *o.Generic__
}
func (o Unfurl) Youtube() (res UnfurlYoutube) {
if o.UnfurlType__ != UnfurlType_YOUTUBE {
panic("wrong case accessed")
}
if o.Youtube__ == nil {
return
}
return *o.Youtube__
}
func (o Unfurl) Giphy() (res UnfurlGiphy) {
if o.UnfurlType__ != UnfurlType_GIPHY {
panic("wrong case accessed")
}
if o.Giphy__ == nil {
return
}
return *o.Giphy__
}
func NewUnfurlWithGeneric(v UnfurlGeneric) Unfurl {
return Unfurl{
UnfurlType__: UnfurlType_GENERIC,
Generic__: &v,
}
}
func NewUnfurlWithYoutube(v UnfurlYoutube) Unfurl {
return Unfurl{
UnfurlType__: UnfurlType_YOUTUBE,
Youtube__: &v,
}
}
func NewUnfurlWithGiphy(v UnfurlGiphy) Unfurl {
return Unfurl{
UnfurlType__: UnfurlType_GIPHY,
Giphy__: &v,
}
}
func (o Unfurl) DeepCopy() Unfurl {
return Unfurl{
UnfurlType__: o.UnfurlType__.DeepCopy(),
Generic__: (func(x *UnfurlGeneric) *UnfurlGeneric {
if x == nil {
return nil
}
tmp := (*x).DeepCopy()
return &tmp
})(o.Generic__),
Youtube__: (func(x *UnfurlYoutube) *UnfurlYoutube {
if x == nil {
return nil
}
tmp := (*x).DeepCopy()
return &tmp
})(o.Youtube__),
Giphy__: (func(x *UnfurlGiphy) *UnfurlGiphy {
if x == nil {
return nil
}
tmp := (*x).DeepCopy()
return &tmp
})(o.Giphy__),
}
}
type UnfurlResult struct {
Unfurl Unfurl `codec:"unfurl" json:"unfurl"`
Url string `codec:"url" json:"url"`
}
func (o UnfurlResult) DeepCopy() UnfurlResult {
return UnfurlResult{
Unfurl: o.Unfurl.DeepCopy(),
Url: o.Url,
}
}
type UnfurlImageDisplay struct {
Url string `codec:"url" json:"url"`
Height int `codec:"height" json:"height"`
Width int `codec:"width" json:"width"`
IsVideo bool `codec:"isVideo" json:"isVideo"`
}
func (o UnfurlImageDisplay) DeepCopy() UnfurlImageDisplay {
return UnfurlImageDisplay{
Url: o.Url,
Height: o.Height,
Width: o.Width,
IsVideo: o.IsVideo,
}
}
type UnfurlGenericDisplay struct {
Title string `codec:"title" json:"title"`
Url string `codec:"url" json:"url"`
SiteName string `codec:"siteName" json:"siteName"`
Favicon *UnfurlImageDisplay `codec:"favicon,omitempty" json:"favicon,omitempty"`
Media *UnfurlImageDisplay `codec:"media,omitempty" json:"media,omitempty"`
PublishTime *int `codec:"publishTime,omitempty" json:"publishTime,omitempty"`
Description *string `codec:"description,omitempty" json:"description,omitempty"`
MapInfo *UnfurlGenericMapInfo `codec:"mapInfo,omitempty" json:"mapInfo,omitempty"`
}
func (o UnfurlGenericDisplay) DeepCopy() UnfurlGenericDisplay {
return UnfurlGenericDisplay{
Title: o.Title,
Url: o.Url,
SiteName: o.SiteName,
Favicon: (func(x *UnfurlImageDisplay) *UnfurlImageDisplay {
if x == nil {
return nil
}
tmp := (*x).DeepCopy()
return &tmp
})(o.Favicon),
Media: (func(x *UnfurlImageDisplay) *UnfurlImageDisplay {
if x == nil {
return nil
}
tmp := (*x).DeepCopy()
return &tmp
})(o.Media),
PublishTime: (func(x *int) *int {
if x == nil {
return nil
}
tmp := (*x)
return &tmp
})(o.PublishTime),
Description: (func(x *string) *string {
if x == nil {
return nil
}
tmp := (*x)
return &tmp
})(o.Description),
MapInfo: (func(x *UnfurlGenericMapInfo) *UnfurlGenericMapInfo {
if x == nil {
return nil
}
tmp := (*x).DeepCopy()
return &tmp
})(o.MapInfo),
}
}
type UnfurlYoutubeDisplay struct {
}
func (o UnfurlYoutubeDisplay) DeepCopy() UnfurlYoutubeDisplay {
return UnfurlYoutubeDisplay{}
}
type UnfurlGiphyDisplay struct {
Favicon *UnfurlImageDisplay `codec:"favicon,omitempty" json:"favicon,omitempty"`
Image *UnfurlImageDisplay `codec:"image,omitempty" json:"image,omitempty"`
Video *UnfurlImageDisplay `codec:"video,omitempty" json:"video,omitempty"`
}
func (o UnfurlGiphyDisplay) DeepCopy() UnfurlGiphyDisplay {
return UnfurlGiphyDisplay{
Favicon: (func(x *UnfurlImageDisplay) *UnfurlImageDisplay {
if x == nil {
return nil
}
tmp := (*x).DeepCopy()
return &tmp
})(o.Favicon),
Image: (func(x *UnfurlImageDisplay) *UnfurlImageDisplay {
if x == nil {
return nil
}
tmp := (*x).DeepCopy()
return &tmp
})(o.Image),
Video: (func(x *UnfurlImageDisplay) *UnfurlImageDisplay {
if x == nil {
return nil
}
tmp := (*x).DeepCopy()
return &tmp
})(o.Video),
}
}
type UnfurlDisplay struct {
UnfurlType__ UnfurlType `codec:"unfurlType" json:"unfurlType"`
Generic__ *UnfurlGenericDisplay `codec:"generic,omitempty" json:"generic,omitempty"`
Youtube__ *UnfurlYoutubeDisplay `codec:"youtube,omitempty" json:"youtube,omitempty"`
Giphy__ *UnfurlGiphyDisplay `codec:"giphy,omitempty" json:"giphy,omitempty"`
}
func (o *UnfurlDisplay) UnfurlType() (ret UnfurlType, err error) {
switch o.UnfurlType__ {
case UnfurlType_GENERIC:
if o.Generic__ == nil {
err = errors.New("unexpected nil value for Generic__")
return ret, err
}
case UnfurlType_YOUTUBE:
if o.Youtube__ == nil {
err = errors.New("unexpected nil value for Youtube__")
return ret, err
}
case UnfurlType_GIPHY:
if o.Giphy__ == nil {
err = errors.New("unexpected nil value for Giphy__")
return ret, err
}
}
return o.UnfurlType__, nil
}
func (o UnfurlDisplay) Generic() (res UnfurlGenericDisplay) {
if o.UnfurlType__ != UnfurlType_GENERIC {
panic("wrong case accessed")
}
if o.Generic__ == nil {
return
}
return *o.Generic__
}
func (o UnfurlDisplay) Youtube() (res UnfurlYoutubeDisplay) {
if o.UnfurlType__ != UnfurlType_YOUTUBE {
panic("wrong case accessed")
}
if o.Youtube__ == nil {
return
}
return *o.Youtube__
}
func (o UnfurlDisplay) Giphy() (res UnfurlGiphyDisplay) {
if o.UnfurlType__ != UnfurlType_GIPHY {
panic("wrong case accessed")
}
if o.Giphy__ == nil {
return
}
return *o.Giphy__
}
func NewUnfurlDisplayWithGeneric(v UnfurlGenericDisplay) UnfurlDisplay {
return UnfurlDisplay{
UnfurlType__: UnfurlType_GENERIC,
Generic__: &v,
}
}
func NewUnfurlDisplayWithYoutube(v UnfurlYoutubeDisplay) UnfurlDisplay {
return UnfurlDisplay{
UnfurlType__: UnfurlType_YOUTUBE,
Youtube__: &v,
}
}
func NewUnfurlDisplayWithGiphy(v UnfurlGiphyDisplay) UnfurlDisplay {
return UnfurlDisplay{
UnfurlType__: UnfurlType_GIPHY,
Giphy__: &v,
}
}
func (o UnfurlDisplay) DeepCopy() UnfurlDisplay {
return UnfurlDisplay{
UnfurlType__: o.UnfurlType__.DeepCopy(),
Generic__: (func(x *UnfurlGenericDisplay) *UnfurlGenericDisplay {
if x == nil {
return nil
}
tmp := (*x).DeepCopy()
return &tmp
})(o.Generic__),
Youtube__: (func(x *UnfurlYoutubeDisplay) *UnfurlYoutubeDisplay {
if x == nil {
return nil
}
tmp := (*x).DeepCopy()
return &tmp
})(o.Youtube__),
Giphy__: (func(x *UnfurlGiphyDisplay) *UnfurlGiphyDisplay {
if x == nil {
return nil
}
tmp := (*x).DeepCopy()
return &tmp
})(o.Giphy__),
}
}
type UnfurlMode int
const (
UnfurlMode_ALWAYS UnfurlMode = 0
UnfurlMode_NEVER UnfurlMode = 1
UnfurlMode_WHITELISTED UnfurlMode = 2
)
func (o UnfurlMode) DeepCopy() UnfurlMode { return o }
var UnfurlModeMap = map[string]UnfurlMode{
"ALWAYS": 0,
"NEVER": 1,
"WHITELISTED": 2,
}
var UnfurlModeRevMap = map[UnfurlMode]string{
0: "ALWAYS",
1: "NEVER",
2: "WHITELISTED",
}
func (e UnfurlMode) String() string {
if v, ok := UnfurlModeRevMap[e]; ok {
return v
}
return fmt.Sprintf("%v", int(e))
}
type UnfurlSettings struct {
Mode UnfurlMode `codec:"mode" json:"mode"`
Whitelist map[string]bool `codec:"whitelist" json:"whitelist"`
}
func (o UnfurlSettings) DeepCopy() UnfurlSettings {
return UnfurlSettings{
Mode: o.Mode.DeepCopy(),
Whitelist: (func(x map[string]bool) map[string]bool {
if x == nil {
return nil
}
ret := make(map[string]bool, len(x))
for k, v := range x {
kCopy := k
vCopy := v
ret[kCopy] = vCopy
}
return ret
})(o.Whitelist),
}
}
type UnfurlSettingsDisplay struct {
Mode UnfurlMode `codec:"mode" json:"mode"`
Whitelist []string `codec:"whitelist" json:"whitelist"`
}
func (o UnfurlSettingsDisplay) DeepCopy() UnfurlSettingsDisplay {
return UnfurlSettingsDisplay{
Mode: o.Mode.DeepCopy(),
Whitelist: (func(x []string) []string {
if x == nil {
return nil
}
ret := make([]string, len(x))
for i, v := range x {
vCopy := v
ret[i] = vCopy
}
return ret
})(o.Whitelist),
}
}

View File

@@ -0,0 +1,20 @@
// Auto-generated to Go types using avdl-compiler v1.4.6 (https://github.com/keybase/node-avdl-compiler)
// Input file: ../client/protocol/avdl/gregor1/auth.avdl
package gregor1
type AuthResult struct {
Uid UID `codec:"uid" json:"uid"`
Username string `codec:"username" json:"username"`
Sid SessionID `codec:"sid" json:"sid"`
IsAdmin bool `codec:"isAdmin" json:"isAdmin"`
}
func (o AuthResult) DeepCopy() AuthResult {
return AuthResult{
Uid: o.Uid.DeepCopy(),
Username: o.Username,
Sid: o.Sid.DeepCopy(),
IsAdmin: o.IsAdmin,
}
}

View File

@@ -0,0 +1,4 @@
// Auto-generated to Go types using avdl-compiler v1.4.6 (https://github.com/keybase/node-avdl-compiler)
// Input file: ../client/protocol/avdl/gregor1/auth_internal.avdl
package gregor1

View File

@@ -0,0 +1,4 @@
// Auto-generated to Go types using avdl-compiler v1.4.6 (https://github.com/keybase/node-avdl-compiler)
// Input file: ../client/protocol/avdl/gregor1/auth_update.avdl
package gregor1

View File

@@ -0,0 +1,394 @@
// Auto-generated to Go types using avdl-compiler v1.4.6 (https://github.com/keybase/node-avdl-compiler)
// Input file: ../client/protocol/avdl/gregor1/common.avdl
package gregor1
type TimeOrOffset struct {
Time_ Time `codec:"time" json:"time"`
Offset_ DurationMsec `codec:"offset" json:"offset"`
}
func (o TimeOrOffset) DeepCopy() TimeOrOffset {
return TimeOrOffset{
Time_: o.Time_.DeepCopy(),
Offset_: o.Offset_.DeepCopy(),
}
}
type Metadata struct {
Uid_ UID `codec:"uid" json:"uid"`
MsgID_ MsgID `codec:"msgID" json:"msgID"`
Ctime_ Time `codec:"ctime" json:"ctime"`
DeviceID_ DeviceID `codec:"deviceID" json:"deviceID"`
InBandMsgType_ int `codec:"inBandMsgType" json:"inBandMsgType"`
}
func (o Metadata) DeepCopy() Metadata {
return Metadata{
Uid_: o.Uid_.DeepCopy(),
MsgID_: o.MsgID_.DeepCopy(),
Ctime_: o.Ctime_.DeepCopy(),
DeviceID_: o.DeviceID_.DeepCopy(),
InBandMsgType_: o.InBandMsgType_,
}
}
type InBandMessage struct {
StateUpdate_ *StateUpdateMessage `codec:"stateUpdate,omitempty" json:"stateUpdate,omitempty"`
StateSync_ *StateSyncMessage `codec:"stateSync,omitempty" json:"stateSync,omitempty"`
}
func (o InBandMessage) DeepCopy() InBandMessage {
return InBandMessage{
StateUpdate_: (func(x *StateUpdateMessage) *StateUpdateMessage {
if x == nil {
return nil
}
tmp := (*x).DeepCopy()
return &tmp
})(o.StateUpdate_),
StateSync_: (func(x *StateSyncMessage) *StateSyncMessage {
if x == nil {
return nil
}
tmp := (*x).DeepCopy()
return &tmp
})(o.StateSync_),
}
}
type State struct {
Items_ []ItemAndMetadata `codec:"items" json:"items"`
}
func (o State) DeepCopy() State {
return State{
Items_: (func(x []ItemAndMetadata) []ItemAndMetadata {
if x == nil {
return nil
}
ret := make([]ItemAndMetadata, len(x))
for i, v := range x {
vCopy := v.DeepCopy()
ret[i] = vCopy
}
return ret
})(o.Items_),
}
}
type StateUpdateMessage struct {
Md_ Metadata `codec:"md" json:"md"`
Creation_ *Item `codec:"creation,omitempty" json:"creation,omitempty"`
Dismissal_ *Dismissal `codec:"dismissal,omitempty" json:"dismissal,omitempty"`
}
func (o StateUpdateMessage) DeepCopy() StateUpdateMessage {
return StateUpdateMessage{
Md_: o.Md_.DeepCopy(),
Creation_: (func(x *Item) *Item {
if x == nil {
return nil
}
tmp := (*x).DeepCopy()
return &tmp
})(o.Creation_),
Dismissal_: (func(x *Dismissal) *Dismissal {
if x == nil {
return nil
}
tmp := (*x).DeepCopy()
return &tmp
})(o.Dismissal_),
}
}
type StateSyncMessage struct {
Md_ Metadata `codec:"md" json:"md"`
}
func (o StateSyncMessage) DeepCopy() StateSyncMessage {
return StateSyncMessage{
Md_: o.Md_.DeepCopy(),
}
}
type MsgRange struct {
EndTime_ TimeOrOffset `codec:"endTime" json:"endTime"`
Category_ Category `codec:"category" json:"category"`
SkipMsgIDs_ []MsgID `codec:"skipMsgIDs" json:"skipMsgIDs"`
}
func (o MsgRange) DeepCopy() MsgRange {
return MsgRange{
EndTime_: o.EndTime_.DeepCopy(),
Category_: o.Category_.DeepCopy(),
SkipMsgIDs_: (func(x []MsgID) []MsgID {
if x == nil {
return nil
}
ret := make([]MsgID, len(x))
for i, v := range x {
vCopy := v.DeepCopy()
ret[i] = vCopy
}
return ret
})(o.SkipMsgIDs_),
}
}
type Dismissal struct {
MsgIDs_ []MsgID `codec:"msgIDs" json:"msgIDs"`
Ranges_ []MsgRange `codec:"ranges" json:"ranges"`
}
func (o Dismissal) DeepCopy() Dismissal {
return Dismissal{
MsgIDs_: (func(x []MsgID) []MsgID {
if x == nil {
return nil
}
ret := make([]MsgID, len(x))
for i, v := range x {
vCopy := v.DeepCopy()
ret[i] = vCopy
}
return ret
})(o.MsgIDs_),
Ranges_: (func(x []MsgRange) []MsgRange {
if x == nil {
return nil
}
ret := make([]MsgRange, len(x))
for i, v := range x {
vCopy := v.DeepCopy()
ret[i] = vCopy
}
return ret
})(o.Ranges_),
}
}
type Item struct {
Category_ Category `codec:"category" json:"category"`
Dtime_ TimeOrOffset `codec:"dtime" json:"dtime"`
RemindTimes_ []TimeOrOffset `codec:"remindTimes" json:"remindTimes"`
Body_ Body `codec:"body" json:"body"`
}
func (o Item) DeepCopy() Item {
return Item{
Category_: o.Category_.DeepCopy(),
Dtime_: o.Dtime_.DeepCopy(),
RemindTimes_: (func(x []TimeOrOffset) []TimeOrOffset {
if x == nil {
return nil
}
ret := make([]TimeOrOffset, len(x))
for i, v := range x {
vCopy := v.DeepCopy()
ret[i] = vCopy
}
return ret
})(o.RemindTimes_),
Body_: o.Body_.DeepCopy(),
}
}
type ItemAndMetadata struct {
Md_ *Metadata `codec:"md,omitempty" json:"md,omitempty"`
Item_ *Item `codec:"item,omitempty" json:"item,omitempty"`
}
func (o ItemAndMetadata) DeepCopy() ItemAndMetadata {
return ItemAndMetadata{
Md_: (func(x *Metadata) *Metadata {
if x == nil {
return nil
}
tmp := (*x).DeepCopy()
return &tmp
})(o.Md_),
Item_: (func(x *Item) *Item {
if x == nil {
return nil
}
tmp := (*x).DeepCopy()
return &tmp
})(o.Item_),
}
}
type Reminder struct {
Item_ ItemAndMetadata `codec:"item" json:"item"`
Seqno_ int `codec:"seqno" json:"seqno"`
RemindTime_ Time `codec:"remindTime" json:"remindTime"`
}
func (o Reminder) DeepCopy() Reminder {
return Reminder{
Item_: o.Item_.DeepCopy(),
Seqno_: o.Seqno_,
RemindTime_: o.RemindTime_.DeepCopy(),
}
}
type ReminderID struct {
Uid_ UID `codec:"uid" json:"uid"`
MsgID_ MsgID `codec:"msgID" json:"msgID"`
Seqno_ int `codec:"seqno" json:"seqno"`
}
func (o ReminderID) DeepCopy() ReminderID {
return ReminderID{
Uid_: o.Uid_.DeepCopy(),
MsgID_: o.MsgID_.DeepCopy(),
Seqno_: o.Seqno_,
}
}
type OutOfBandMessage struct {
Uid_ UID `codec:"uid" json:"uid"`
System_ System `codec:"system" json:"system"`
Body_ Body `codec:"body" json:"body"`
}
func (o OutOfBandMessage) DeepCopy() OutOfBandMessage {
return OutOfBandMessage{
Uid_: o.Uid_.DeepCopy(),
System_: o.System_.DeepCopy(),
Body_: o.Body_.DeepCopy(),
}
}
type ReminderSet struct {
Reminders_ []Reminder `codec:"reminders" json:"reminders"`
MoreRemindersReady_ bool `codec:"moreRemindersReady" json:"moreRemindersReady"`
}
func (o ReminderSet) DeepCopy() ReminderSet {
return ReminderSet{
Reminders_: (func(x []Reminder) []Reminder {
if x == nil {
return nil
}
ret := make([]Reminder, len(x))
for i, v := range x {
vCopy := v.DeepCopy()
ret[i] = vCopy
}
return ret
})(o.Reminders_),
MoreRemindersReady_: o.MoreRemindersReady_,
}
}
type Message struct {
Oobm_ *OutOfBandMessage `codec:"oobm,omitempty" json:"oobm,omitempty"`
Ibm_ *InBandMessage `codec:"ibm,omitempty" json:"ibm,omitempty"`
}
func (o Message) DeepCopy() Message {
return Message{
Oobm_: (func(x *OutOfBandMessage) *OutOfBandMessage {
if x == nil {
return nil
}
tmp := (*x).DeepCopy()
return &tmp
})(o.Oobm_),
Ibm_: (func(x *InBandMessage) *InBandMessage {
if x == nil {
return nil
}
tmp := (*x).DeepCopy()
return &tmp
})(o.Ibm_),
}
}
type DurationMsec int64
func (o DurationMsec) DeepCopy() DurationMsec {
return o
}
type DurationSec int64
func (o DurationSec) DeepCopy() DurationSec {
return o
}
type Category string
func (o Category) DeepCopy() Category {
return o
}
type System string
func (o System) DeepCopy() System {
return o
}
type UID []byte
func (o UID) DeepCopy() UID {
return (func(x []byte) []byte {
if x == nil {
return nil
}
return append([]byte{}, x...)
})(o)
}
type MsgID []byte
func (o MsgID) DeepCopy() MsgID {
return (func(x []byte) []byte {
if x == nil {
return nil
}
return append([]byte{}, x...)
})(o)
}
type DeviceID []byte
func (o DeviceID) DeepCopy() DeviceID {
return (func(x []byte) []byte {
if x == nil {
return nil
}
return append([]byte{}, x...)
})(o)
}
type Body []byte
func (o Body) DeepCopy() Body {
return (func(x []byte) []byte {
if x == nil {
return nil
}
return append([]byte{}, x...)
})(o)
}
type Time int64
func (o Time) DeepCopy() Time {
return o
}
type SessionID string
func (o SessionID) DeepCopy() SessionID {
return o
}
type SessionToken string
func (o SessionToken) DeepCopy() SessionToken {
return o
}

View File

@@ -0,0 +1,72 @@
// Auto-generated to Go types using avdl-compiler v1.4.6 (https://github.com/keybase/node-avdl-compiler)
// Input file: ../client/protocol/avdl/gregor1/incoming.avdl
package gregor1
type SyncResult struct {
Msgs []InBandMessage `codec:"msgs" json:"msgs"`
Hash []byte `codec:"hash" json:"hash"`
}
func (o SyncResult) DeepCopy() SyncResult {
return SyncResult{
Msgs: (func(x []InBandMessage) []InBandMessage {
if x == nil {
return nil
}
ret := make([]InBandMessage, len(x))
for i, v := range x {
vCopy := v.DeepCopy()
ret[i] = vCopy
}
return ret
})(o.Msgs),
Hash: (func(x []byte) []byte {
if x == nil {
return nil
}
return append([]byte{}, x...)
})(o.Hash),
}
}
// DescribeConnectedUsers will take a list of users, and return the list of users
// which are connected to any Gregor in the cluster, and what devices (and device type)
// those users are connected with.
type ConnectedDevice struct {
DeviceID DeviceID `codec:"deviceID" json:"deviceID"`
DeviceType string `codec:"deviceType" json:"deviceType"`
DevicePlatform string `codec:"devicePlatform" json:"devicePlatform"`
UserAgent string `codec:"userAgent" json:"userAgent"`
}
func (o ConnectedDevice) DeepCopy() ConnectedDevice {
return ConnectedDevice{
DeviceID: o.DeviceID.DeepCopy(),
DeviceType: o.DeviceType,
DevicePlatform: o.DevicePlatform,
UserAgent: o.UserAgent,
}
}
type ConnectedUser struct {
Uid UID `codec:"uid" json:"uid"`
Devices []ConnectedDevice `codec:"devices" json:"devices"`
}
func (o ConnectedUser) DeepCopy() ConnectedUser {
return ConnectedUser{
Uid: o.Uid.DeepCopy(),
Devices: (func(x []ConnectedDevice) []ConnectedDevice {
if x == nil {
return nil
}
ret := make([]ConnectedDevice, len(x))
for i, v := range x {
vCopy := v.DeepCopy()
ret[i] = vCopy
}
return ret
})(o.Devices),
}
}

View File

@@ -0,0 +1,4 @@
// Auto-generated to Go types using avdl-compiler v1.4.6 (https://github.com/keybase/node-avdl-compiler)
// Input file: ../client/protocol/avdl/gregor1/outgoing.avdl
package gregor1

View File

@@ -0,0 +1,4 @@
// Auto-generated to Go types using avdl-compiler v1.4.6 (https://github.com/keybase/node-avdl-compiler)
// Input file: ../client/protocol/avdl/gregor1/remind.avdl
package gregor1

View File

@@ -0,0 +1,98 @@
// Auto-generated to Go types using avdl-compiler v1.4.6 (https://github.com/keybase/node-avdl-compiler)
// Input file: ../client/protocol/avdl/keybase1/account.avdl
package keybase1
type HasServerKeysRes struct {
HasServerKeys bool `codec:"hasServerKeys" json:"hasServerKeys"`
}
func (o HasServerKeysRes) DeepCopy() HasServerKeysRes {
return HasServerKeysRes{
HasServerKeys: o.HasServerKeys,
}
}
type LockdownHistory struct {
Status bool `codec:"status" json:"status"`
CreationTime Time `codec:"creationTime" json:"ctime"`
DeviceID DeviceID `codec:"deviceID" json:"device_id"`
DeviceName string `codec:"deviceName" json:"deviceName"`
}
func (o LockdownHistory) DeepCopy() LockdownHistory {
return LockdownHistory{
Status: o.Status,
CreationTime: o.CreationTime.DeepCopy(),
DeviceID: o.DeviceID.DeepCopy(),
DeviceName: o.DeviceName,
}
}
type GetLockdownResponse struct {
History []LockdownHistory `codec:"history" json:"history"`
Status bool `codec:"status" json:"status"`
}
func (o GetLockdownResponse) DeepCopy() GetLockdownResponse {
return GetLockdownResponse{
History: (func(x []LockdownHistory) []LockdownHistory {
if x == nil {
return nil
}
ret := make([]LockdownHistory, len(x))
for i, v := range x {
vCopy := v.DeepCopy()
ret[i] = vCopy
}
return ret
})(o.History),
Status: o.Status,
}
}
type TeamContactSettings struct {
TeamID TeamID `codec:"teamID" json:"team_id"`
Enabled bool `codec:"enabled" json:"enabled"`
}
func (o TeamContactSettings) DeepCopy() TeamContactSettings {
return TeamContactSettings{
TeamID: o.TeamID.DeepCopy(),
Enabled: o.Enabled,
}
}
type ContactSettings struct {
Version *int `codec:"version,omitempty" json:"version,omitempty"`
AllowFolloweeDegrees int `codec:"allowFolloweeDegrees" json:"allow_followee_degrees"`
AllowGoodTeams bool `codec:"allowGoodTeams" json:"allow_good_teams"`
Enabled bool `codec:"enabled" json:"enabled"`
Teams []TeamContactSettings `codec:"teams" json:"teams"`
}
func (o ContactSettings) DeepCopy() ContactSettings {
return ContactSettings{
Version: (func(x *int) *int {
if x == nil {
return nil
}
tmp := (*x)
return &tmp
})(o.Version),
AllowFolloweeDegrees: o.AllowFolloweeDegrees,
AllowGoodTeams: o.AllowGoodTeams,
Enabled: o.Enabled,
Teams: (func(x []TeamContactSettings) []TeamContactSettings {
if x == nil {
return nil
}
ret := make([]TeamContactSettings, len(x))
for i, v := range x {
vCopy := v.DeepCopy()
ret[i] = vCopy
}
return ret
})(o.Teams),
}
}

View File

@@ -0,0 +1,22 @@
// Auto-generated to Go types using avdl-compiler v1.4.6 (https://github.com/keybase/node-avdl-compiler)
// Input file: ../client/protocol/avdl/keybase1/airdrop.avdl
package keybase1
type AirdropDetails struct {
Uid UID `codec:"uid" json:"uid"`
Kid BinaryKID `codec:"kid" json:"kid"`
Vid VID `codec:"vid" json:"vid"`
Vers string `codec:"vers" json:"vers"`
Time Time `codec:"time" json:"time"`
}
func (o AirdropDetails) DeepCopy() AirdropDetails {
return AirdropDetails{
Uid: o.Uid.DeepCopy(),
Kid: o.Kid.DeepCopy(),
Vid: o.Vid.DeepCopy(),
Vers: o.Vers,
Time: o.Time.DeepCopy(),
}
}

View File

@@ -0,0 +1,20 @@
// Auto-generated to Go types using avdl-compiler v1.4.6 (https://github.com/keybase/node-avdl-compiler)
// Input file: ../client/protocol/avdl/keybase1/apiserver.avdl
package keybase1
type APIRes struct {
Status string `codec:"status" json:"status"`
Body string `codec:"body" json:"body"`
HttpStatus int `codec:"httpStatus" json:"httpStatus"`
AppStatus string `codec:"appStatus" json:"appStatus"`
}
func (o APIRes) DeepCopy() APIRes {
return APIRes{
Status: o.Status,
Body: o.Body,
HttpStatus: o.HttpStatus,
AppStatus: o.AppStatus,
}
}

View File

@@ -0,0 +1,75 @@
// Auto-generated to Go types using avdl-compiler v1.4.6 (https://github.com/keybase/node-avdl-compiler)
// Input file: ../client/protocol/avdl/keybase1/appstate.avdl
package keybase1
import (
"fmt"
)
type MobileAppState int
const (
MobileAppState_FOREGROUND MobileAppState = 0
MobileAppState_BACKGROUND MobileAppState = 1
MobileAppState_INACTIVE MobileAppState = 2
MobileAppState_BACKGROUNDACTIVE MobileAppState = 3
)
func (o MobileAppState) DeepCopy() MobileAppState { return o }
var MobileAppStateMap = map[string]MobileAppState{
"FOREGROUND": 0,
"BACKGROUND": 1,
"INACTIVE": 2,
"BACKGROUNDACTIVE": 3,
}
var MobileAppStateRevMap = map[MobileAppState]string{
0: "FOREGROUND",
1: "BACKGROUND",
2: "INACTIVE",
3: "BACKGROUNDACTIVE",
}
func (e MobileAppState) String() string {
if v, ok := MobileAppStateRevMap[e]; ok {
return v
}
return fmt.Sprintf("%v", int(e))
}
type MobileNetworkState int
const (
MobileNetworkState_NONE MobileNetworkState = 0
MobileNetworkState_WIFI MobileNetworkState = 1
MobileNetworkState_CELLULAR MobileNetworkState = 2
MobileNetworkState_UNKNOWN MobileNetworkState = 3
MobileNetworkState_NOTAVAILABLE MobileNetworkState = 4
)
func (o MobileNetworkState) DeepCopy() MobileNetworkState { return o }
var MobileNetworkStateMap = map[string]MobileNetworkState{
"NONE": 0,
"WIFI": 1,
"CELLULAR": 2,
"UNKNOWN": 3,
"NOTAVAILABLE": 4,
}
var MobileNetworkStateRevMap = map[MobileNetworkState]string{
0: "NONE",
1: "WIFI",
2: "CELLULAR",
3: "UNKNOWN",
4: "NOTAVAILABLE",
}
func (e MobileNetworkState) String() string {
if v, ok := MobileNetworkStateRevMap[e]; ok {
return v
}
return fmt.Sprintf("%v", int(e))
}

View File

@@ -0,0 +1,76 @@
// Auto-generated to Go types using avdl-compiler v1.4.6 (https://github.com/keybase/node-avdl-compiler)
// Input file: ../client/protocol/avdl/keybase1/audit.avdl
package keybase1
import (
"fmt"
)
type BoxAuditAttemptResult int
const (
BoxAuditAttemptResult_FAILURE_RETRYABLE BoxAuditAttemptResult = 0
BoxAuditAttemptResult_FAILURE_MALICIOUS_SERVER BoxAuditAttemptResult = 1
BoxAuditAttemptResult_OK_VERIFIED BoxAuditAttemptResult = 2
BoxAuditAttemptResult_OK_NOT_ATTEMPTED_ROLE BoxAuditAttemptResult = 3
BoxAuditAttemptResult_OK_NOT_ATTEMPTED_OPENTEAM BoxAuditAttemptResult = 4
BoxAuditAttemptResult_OK_NOT_ATTEMPTED_SUBTEAM BoxAuditAttemptResult = 5
)
func (o BoxAuditAttemptResult) DeepCopy() BoxAuditAttemptResult { return o }
var BoxAuditAttemptResultMap = map[string]BoxAuditAttemptResult{
"FAILURE_RETRYABLE": 0,
"FAILURE_MALICIOUS_SERVER": 1,
"OK_VERIFIED": 2,
"OK_NOT_ATTEMPTED_ROLE": 3,
"OK_NOT_ATTEMPTED_OPENTEAM": 4,
"OK_NOT_ATTEMPTED_SUBTEAM": 5,
}
var BoxAuditAttemptResultRevMap = map[BoxAuditAttemptResult]string{
0: "FAILURE_RETRYABLE",
1: "FAILURE_MALICIOUS_SERVER",
2: "OK_VERIFIED",
3: "OK_NOT_ATTEMPTED_ROLE",
4: "OK_NOT_ATTEMPTED_OPENTEAM",
5: "OK_NOT_ATTEMPTED_SUBTEAM",
}
func (e BoxAuditAttemptResult) String() string {
if v, ok := BoxAuditAttemptResultRevMap[e]; ok {
return v
}
return fmt.Sprintf("%v", int(e))
}
type BoxAuditAttempt struct {
Ctime UnixTime `codec:"ctime" json:"ctime"`
Error *string `codec:"error,omitempty" json:"error,omitempty"`
Result BoxAuditAttemptResult `codec:"result" json:"result"`
Generation *PerTeamKeyGeneration `codec:"generation,omitempty" json:"generation,omitempty"`
Rotated bool `codec:"rotated" json:"rotated"`
}
func (o BoxAuditAttempt) DeepCopy() BoxAuditAttempt {
return BoxAuditAttempt{
Ctime: o.Ctime.DeepCopy(),
Error: (func(x *string) *string {
if x == nil {
return nil
}
tmp := (*x)
return &tmp
})(o.Error),
Result: o.Result.DeepCopy(),
Generation: (func(x *PerTeamKeyGeneration) *PerTeamKeyGeneration {
if x == nil {
return nil
}
tmp := (*x).DeepCopy()
return &tmp
})(o.Generation),
Rotated: o.Rotated,
}
}

View File

@@ -0,0 +1,72 @@
// Auto-generated to Go types using avdl-compiler v1.4.6 (https://github.com/keybase/node-avdl-compiler)
// Input file: ../client/protocol/avdl/keybase1/avatars.avdl
package keybase1
type AvatarUrl string
func (o AvatarUrl) DeepCopy() AvatarUrl {
return o
}
type AvatarFormat string
func (o AvatarFormat) DeepCopy() AvatarFormat {
return o
}
type LoadAvatarsRes struct {
Picmap map[string]map[AvatarFormat]AvatarUrl `codec:"picmap" json:"picmap"`
}
func (o LoadAvatarsRes) DeepCopy() LoadAvatarsRes {
return LoadAvatarsRes{
Picmap: (func(x map[string]map[AvatarFormat]AvatarUrl) map[string]map[AvatarFormat]AvatarUrl {
if x == nil {
return nil
}
ret := make(map[string]map[AvatarFormat]AvatarUrl, len(x))
for k, v := range x {
kCopy := k
vCopy := (func(x map[AvatarFormat]AvatarUrl) map[AvatarFormat]AvatarUrl {
if x == nil {
return nil
}
ret := make(map[AvatarFormat]AvatarUrl, len(x))
for k, v := range x {
kCopy := k.DeepCopy()
vCopy := v.DeepCopy()
ret[kCopy] = vCopy
}
return ret
})(v)
ret[kCopy] = vCopy
}
return ret
})(o.Picmap),
}
}
type AvatarClearCacheMsg struct {
Name string `codec:"name" json:"name"`
Formats []AvatarFormat `codec:"formats" json:"formats"`
Typ AvatarUpdateType `codec:"typ" json:"typ"`
}
func (o AvatarClearCacheMsg) DeepCopy() AvatarClearCacheMsg {
return AvatarClearCacheMsg{
Name: o.Name,
Formats: (func(x []AvatarFormat) []AvatarFormat {
if x == nil {
return nil
}
ret := make([]AvatarFormat, len(x))
for i, v := range x {
vCopy := v.DeepCopy()
ret[i] = vCopy
}
return ret
})(o.Formats),
Typ: o.Typ.DeepCopy(),
}
}

View File

@@ -0,0 +1,63 @@
// Auto-generated to Go types using avdl-compiler v1.4.6 (https://github.com/keybase/node-avdl-compiler)
// Input file: ../client/protocol/avdl/keybase1/backend_common.avdl
package keybase1
import (
"fmt"
)
type BlockType int
const (
BlockType_DATA BlockType = 0
BlockType_MD BlockType = 1
BlockType_GIT BlockType = 2
)
func (o BlockType) DeepCopy() BlockType { return o }
var BlockTypeMap = map[string]BlockType{
"DATA": 0,
"MD": 1,
"GIT": 2,
}
var BlockTypeRevMap = map[BlockType]string{
0: "DATA",
1: "MD",
2: "GIT",
}
func (e BlockType) String() string {
if v, ok := BlockTypeRevMap[e]; ok {
return v
}
return fmt.Sprintf("%v", int(e))
}
type BlockIdCombo struct {
BlockHash string `codec:"blockHash" json:"blockHash"`
ChargedTo UserOrTeamID `codec:"chargedTo" json:"chargedTo"`
BlockType BlockType `codec:"blockType" json:"blockType"`
}
func (o BlockIdCombo) DeepCopy() BlockIdCombo {
return BlockIdCombo{
BlockHash: o.BlockHash,
ChargedTo: o.ChargedTo.DeepCopy(),
BlockType: o.BlockType.DeepCopy(),
}
}
type ChallengeInfo struct {
Now int64 `codec:"now" json:"now"`
Challenge string `codec:"challenge" json:"challenge"`
}
func (o ChallengeInfo) DeepCopy() ChallengeInfo {
return ChallengeInfo{
Now: o.Now,
Challenge: o.Challenge,
}
}

View File

@@ -0,0 +1,4 @@
// Auto-generated to Go types using avdl-compiler v1.4.6 (https://github.com/keybase/node-avdl-compiler)
// Input file: ../client/protocol/avdl/keybase1/badger.avdl
package keybase1

View File

@@ -0,0 +1,153 @@
// Auto-generated to Go types using avdl-compiler v1.4.6 (https://github.com/keybase/node-avdl-compiler)
// Input file: ../client/protocol/avdl/keybase1/block.avdl
package keybase1
import (
"fmt"
)
type BlockStatus int
const (
BlockStatus_UNKNOWN BlockStatus = 0
BlockStatus_LIVE BlockStatus = 1
BlockStatus_ARCHIVED BlockStatus = 2
)
func (o BlockStatus) DeepCopy() BlockStatus { return o }
var BlockStatusMap = map[string]BlockStatus{
"UNKNOWN": 0,
"LIVE": 1,
"ARCHIVED": 2,
}
var BlockStatusRevMap = map[BlockStatus]string{
0: "UNKNOWN",
1: "LIVE",
2: "ARCHIVED",
}
func (e BlockStatus) String() string {
if v, ok := BlockStatusRevMap[e]; ok {
return v
}
return fmt.Sprintf("%v", int(e))
}
type GetBlockRes struct {
BlockKey string `codec:"blockKey" json:"blockKey"`
Buf []byte `codec:"buf" json:"buf"`
Size int `codec:"size" json:"size"`
Status BlockStatus `codec:"status" json:"status"`
}
func (o GetBlockRes) DeepCopy() GetBlockRes {
return GetBlockRes{
BlockKey: o.BlockKey,
Buf: (func(x []byte) []byte {
if x == nil {
return nil
}
return append([]byte{}, x...)
})(o.Buf),
Size: o.Size,
Status: o.Status.DeepCopy(),
}
}
type BlockRefNonce [8]byte
func (o BlockRefNonce) DeepCopy() BlockRefNonce {
var ret BlockRefNonce
copy(ret[:], o[:])
return ret
}
type BlockReference struct {
Bid BlockIdCombo `codec:"bid" json:"bid"`
Nonce BlockRefNonce `codec:"nonce" json:"nonce"`
ChargedTo UserOrTeamID `codec:"chargedTo" json:"chargedTo"`
}
func (o BlockReference) DeepCopy() BlockReference {
return BlockReference{
Bid: o.Bid.DeepCopy(),
Nonce: o.Nonce.DeepCopy(),
ChargedTo: o.ChargedTo.DeepCopy(),
}
}
type BlockReferenceCount struct {
Ref BlockReference `codec:"ref" json:"ref"`
LiveCount int `codec:"liveCount" json:"liveCount"`
}
func (o BlockReferenceCount) DeepCopy() BlockReferenceCount {
return BlockReferenceCount{
Ref: o.Ref.DeepCopy(),
LiveCount: o.LiveCount,
}
}
type DowngradeReferenceRes struct {
Completed []BlockReferenceCount `codec:"completed" json:"completed"`
Failed BlockReference `codec:"failed" json:"failed"`
}
func (o DowngradeReferenceRes) DeepCopy() DowngradeReferenceRes {
return DowngradeReferenceRes{
Completed: (func(x []BlockReferenceCount) []BlockReferenceCount {
if x == nil {
return nil
}
ret := make([]BlockReferenceCount, len(x))
for i, v := range x {
vCopy := v.DeepCopy()
ret[i] = vCopy
}
return ret
})(o.Completed),
Failed: o.Failed.DeepCopy(),
}
}
type BlockIdCount struct {
Id BlockIdCombo `codec:"id" json:"id"`
LiveCount int `codec:"liveCount" json:"liveCount"`
}
func (o BlockIdCount) DeepCopy() BlockIdCount {
return BlockIdCount{
Id: o.Id.DeepCopy(),
LiveCount: o.LiveCount,
}
}
type ReferenceCountRes struct {
Counts []BlockIdCount `codec:"counts" json:"counts"`
}
func (o ReferenceCountRes) DeepCopy() ReferenceCountRes {
return ReferenceCountRes{
Counts: (func(x []BlockIdCount) []BlockIdCount {
if x == nil {
return nil
}
ret := make([]BlockIdCount, len(x))
for i, v := range x {
vCopy := v.DeepCopy()
ret[i] = vCopy
}
return ret
})(o.Counts),
}
}
type BlockPingResponse struct {
}
func (o BlockPingResponse) DeepCopy() BlockPingResponse {
return BlockPingResponse{}
}

View File

@@ -0,0 +1,22 @@
// Auto-generated to Go types using avdl-compiler v1.4.6 (https://github.com/keybase/node-avdl-compiler)
// Input file: ../client/protocol/avdl/keybase1/bot.avdl
package keybase1
type BotToken string
func (o BotToken) DeepCopy() BotToken {
return o
}
type BotTokenInfo struct {
Token BotToken `codec:"token" json:"bot_token"`
Ctime Time `codec:"ctime" json:"ctime"`
}
func (o BotTokenInfo) DeepCopy() BotTokenInfo {
return BotTokenInfo{
Token: o.Token.DeepCopy(),
Ctime: o.Ctime.DeepCopy(),
}
}

View File

@@ -0,0 +1,4 @@
// Auto-generated to Go types using avdl-compiler v1.4.6 (https://github.com/keybase/node-avdl-compiler)
// Input file: ../client/protocol/avdl/keybase1/btc.avdl
package keybase1

Some files were not shown because too many files have changed in this diff Show More