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

View File

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

View File

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

View File

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

View File

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

View File

@@ -10,7 +10,7 @@ import (
"github.com/42wim/matterbridge/bridge"
"github.com/42wim/matterbridge/bridge/config"
"github.com/42wim/matterbridge/bridge/helper"
"github.com/bwmarrin/discordgo"
"github.com/matterbridge/discordgo"
)
const MessageLength = 1950
@@ -21,6 +21,7 @@ type Bdiscord struct {
c *discordgo.Session
nick string
userID string
guildID string
webhookID string
webhookToken string
@@ -92,6 +93,7 @@ func (b *Bdiscord) Connect() error {
}
serverName := strings.Replace(b.GetString("Server"), "ID:", "", -1)
b.nick = userinfo.Username
b.userID = userinfo.ID
b.channelsMutex.Lock()
for _, guild := range guilds {
if guild.Name == serverName || guild.ID == serverName {
@@ -114,30 +116,37 @@ func (b *Bdiscord) Connect() error {
b.Log.Infof("Server=\"%s\" # Server ID", guild.ID)
}
}
if err != nil {
return err
}
b.channelsMutex.RLock()
if b.GetString("WebhookURL") == "" {
for _, channel := range b.channels {
b.Log.Debugf("found channel %#v", channel)
}
} else {
b.canEditWebhooks = true
for _, channel := range b.channels {
b.Log.Debugf("found channel %#v; verifying PermissionManageWebhooks", channel)
perms, permsErr := b.c.State.UserChannelPermissions(userinfo.ID, channel.ID)
manageWebhooks := discordgo.PermissionManageWebhooks
if permsErr != nil || perms&manageWebhooks != manageWebhooks {
b.Log.Warnf("Can't manage webhooks in channel \"%s\"", channel.Name)
b.canEditWebhooks = false
manageWebhooks := discordgo.PermissionManageWebhooks
var channelsDenied []string
for _, info := range b.Channels {
id := b.getChannelID(info.Name) // note(qaisjp): this readlocks channelsMutex
b.Log.Debugf("Verifying PermissionManageWebhooks for %s with ID %s", info.ID, id)
perms, permsErr := b.c.UserChannelPermissions(userinfo.ID, id)
if permsErr != nil {
b.Log.Warnf("Failed to check PermissionManageWebhooks in channel \"%s\": %s", info.Name, permsErr.Error())
} else if perms&manageWebhooks == manageWebhooks {
continue
}
channelsDenied = append(channelsDenied, fmt.Sprintf("%#v", info.Name))
}
b.canEditWebhooks = len(channelsDenied) == 0
if b.canEditWebhooks {
b.Log.Info("Can manage webhooks; will edit channel for global webhook on send")
} else {
b.Log.Warn("Can't manage webhooks; won't edit channel for global webhook on send")
b.Log.Warn("Can't manage webhooks in channels: ", strings.Join(channelsDenied, ", "))
}
}
b.channelsMutex.RUnlock()
@@ -380,6 +389,19 @@ func (b *Bdiscord) webhookSend(msg *config.Message, webhookID, token string) (*d
err error
)
// If avatar is unset, check if UseLocalAvatar contains the message's
// account or protocol, and if so, try to find a local avatar
if msg.Avatar == "" {
for _, val := range b.GetStringSlice("UseLocalAvatar") {
if msg.Protocol == val || msg.Account == val {
if avatar := b.findAvatar(msg); avatar != "" {
msg.Avatar = avatar
}
break
}
}
}
// WebhookParams can have either `Content` or `File`.
// We can't send empty messages.
@@ -429,3 +451,11 @@ func (b *Bdiscord) webhookSend(msg *config.Message, webhookID, token string) (*d
}
return res, err
}
func (b *Bdiscord) findAvatar(m *config.Message) string {
member, err := b.getGuildMemberByNick(m.Username)
if err != nil {
return ""
}
return member.User.AvatarURL("")
}

View File

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

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

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
func ParseMarkdown(input string) string {
extensions := parser.HardLineBreak
extensions := parser.HardLineBreak | parser.NoIntraEmphasis
markdownParser := parser.NewWithExtensions(extensions)
renderer := html.NewRenderer(html.RendererOptions{
Flags: 0,

View File

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

View File

@@ -4,7 +4,7 @@ import (
"strconv"
"github.com/42wim/matterbridge/bridge/config"
"github.com/keybase/go-keybase-chat-bot/kbchat"
"github.com/keybase/go-keybase-chat-bot/kbchat/types/chat1"
)
func (b *Bkeybase) handleKeybase() {
@@ -20,7 +20,7 @@ func (b *Bkeybase) handleKeybase() {
b.Log.Errorf("failed to read message: %s", err.Error())
}
if msg.Message.Content.Type != "text" {
if msg.Message.Content.TypeName != "text" {
continue
}
@@ -34,7 +34,7 @@ func (b *Bkeybase) handleKeybase() {
}()
}
func (b *Bkeybase) handleMessage(msg kbchat.Message) {
func (b *Bkeybase) handleMessage(msg chat1.MsgSummary) {
b.Log.Debugf("== Receiving event: %#v", msg)
if msg.Channel.TopicName != b.channel || msg.Channel.Name != b.team {
return
@@ -45,10 +45,10 @@ func (b *Bkeybase) handleMessage(msg kbchat.Message) {
// TODO download avatar
// Create our message
rmsg := config.Message{Username: msg.Sender.Username, Text: msg.Content.Text.Body, UserID: msg.Sender.Uid, Channel: msg.Channel.TopicName, ID: strconv.Itoa(msg.MsgID), Account: b.Account}
rmsg := config.Message{Username: msg.Sender.Username, Text: msg.Content.Text.Body, UserID: string(msg.Sender.Uid), Channel: msg.Channel.TopicName, ID: strconv.Itoa(int(msg.Id)), Account: b.Account}
// Text must be a string
if msg.Content.Type != "text" {
if msg.Content.TypeName != "text" {
b.Log.Errorf("message is not text")
return
}

View File

@@ -90,16 +90,17 @@ func (b *Bkeybase) Send(msg config.Message) (string, error) {
return "", err
}
_, _ = b.kbc.SendAttachmentByTeam(b.team, fpath, fcaption, &b.channel)
_, _ = b.kbc.SendAttachmentByTeam(b.team, &b.channel, fpath, fcaption)
}
return "", nil
}
// Send regular message
resp, err := b.kbc.SendMessageByTeamName(b.team, msg.Username+msg.Text, &b.channel)
text := msg.Username + msg.Text
resp, err := b.kbc.SendMessageByTeamName(b.team, &b.channel, text)
if err != nil {
return "", err
}
return strconv.Itoa(resp.Result.MsgID), err
return strconv.Itoa(int(*resp.Result.MessageID)), err
}

View File

@@ -172,10 +172,15 @@ func (b *Bmatrix) handleEvent(ev *matrix.Event) {
return
}
// TODO download avatar
// Create our message
rmsg := config.Message{Username: ev.Sender[1:], Channel: channel, Account: b.Account, UserID: ev.Sender, ID: ev.ID}
rmsg := config.Message{
Username: ev.Sender[1:],
Channel: channel,
Account: b.Account,
UserID: ev.Sender,
ID: ev.ID,
Avatar: b.getAvatarURL(ev.Sender),
}
// Text must be a string
if rmsg.Text, ok = ev.Content["body"].(string); !ok {
@@ -358,3 +363,15 @@ func (b *Bmatrix) containsAttachment(content map[string]interface{}) bool {
}
return true
}
// getAvatarURL returns the avatar URL of the specified sender
func (b *Bmatrix) getAvatarURL(sender string) string {
mxcURL, err := b.mc.GetSenderAvatarURL(sender)
if err != nil {
b.Log.Errorf("getAvatarURL failed: %s", err)
return ""
}
url := strings.ReplaceAll(mxcURL, "mxc://", b.GetString("Server")+"/_matrix/media/r0/thumbnail/")
url += "?width=37&height=37&method=crop"
return url
}

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
import (
"errors"
"fmt"
"html"
"time"
"github.com/42wim/matterbridge/bridge/config"
"github.com/42wim/matterbridge/bridge/helper"
"github.com/nlopes/slack"
"github.com/slack-go/slack"
)
// ErrEventIgnored is for events that should be ignored
var ErrEventIgnored = errors.New("this event message should ignored")
func (b *Bslack) handleSlack() {
messages := make(chan *config.Message)
if b.GetString(incomingWebhookConfig) != "" {
@@ -53,7 +57,9 @@ func (b *Bslack) handleSlackClient(messages chan *config.Message) {
continue
}
rmsg, err := b.handleTypingEvent(ev)
if err != nil {
if err == ErrEventIgnored {
continue
} else if err != nil {
b.Log.Errorf("%#v", err)
continue
}
@@ -87,7 +93,7 @@ func (b *Bslack) handleSlackClient(messages chan *config.Message) {
b.Log.Errorf("Connection failed %#v %#v", ev.Error(), ev.ErrorObj)
case *slack.MemberJoinedChannelEvent:
b.users.populateUser(ev.User)
case *slack.HelloEvent, *slack.LatencyReport:
case *slack.HelloEvent, *slack.LatencyReport, *slack.ConnectingEvent:
continue
default:
b.Log.Debugf("Unhandled incoming event: %T", ev)
@@ -124,10 +130,16 @@ func (b *Bslack) skipMessageEvent(ev *slack.MessageEvent) bool {
}
}
// Check for our callback ID
hasOurCallbackID := false
if len(ev.Blocks.BlockSet) == 1 {
block, ok := ev.Blocks.BlockSet[0].(*slack.SectionBlock)
hasOurCallbackID = ok && block.BlockID == "matterbridge_"+b.uuid
}
// Skip any messages that we made ourselves or from 'slackbot' (see #527).
if ev.Username == sSlackBotUser ||
(b.rtm != nil && ev.Username == b.si.User.Name) ||
(len(ev.Attachments) > 0 && ev.Attachments[0].CallbackID == "matterbridge_"+b.uuid) {
(b.rtm != nil && ev.Username == b.si.User.Name) || hasOurCallbackID {
return true
}
@@ -270,6 +282,9 @@ func (b *Bslack) handleAttachments(ev *slack.MessageEvent, rmsg *config.Message)
}
func (b *Bslack) handleTypingEvent(ev *slack.UserTypingEvent) (*config.Message, error) {
if ev.User == b.si.User.ID {
return nil, ErrEventIgnored
}
channelInfo, err := b.channels.getChannelByID(ev.Channel)
if err != nil {
return nil, err

View File

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

View File

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

View File

@@ -13,8 +13,8 @@ import (
"github.com/42wim/matterbridge/bridge/helper"
"github.com/42wim/matterbridge/matterhook"
lru "github.com/hashicorp/golang-lru"
"github.com/nlopes/slack"
"github.com/rs/xid"
"github.com/slack-go/slack"
)
type Bslack struct {
@@ -408,7 +408,6 @@ func (b *Bslack) editMessage(msg *config.Message, channelInfo *slack.Channel) (b
}
messageOptions := b.prepareMessageOptions(msg)
for {
messageOptions = append(messageOptions, slack.MsgOptionText(msg.Text, false))
_, _, _, err := b.rtm.UpdateMessage(channelInfo.ID, msg.ID, messageOptions...)
if err == nil {
return true, nil
@@ -427,11 +426,6 @@ func (b *Bslack) postMessage(msg *config.Message, channelInfo *slack.Channel) (s
return "", nil
}
messageOptions := b.prepareMessageOptions(msg)
messageOptions = append(
messageOptions,
slack.MsgOptionText(msg.Text, false),
slack.MsgOptionEnableLinkUnfurl(),
)
for {
_, id, err := b.rtm.PostMessage(channelInfo.ID, messageOptions...)
if err == nil {
@@ -497,8 +491,6 @@ func (b *Bslack) prepareMessageOptions(msg *config.Message) []slack.MsgOption {
}
var attachments []slack.Attachment
// add a callback ID so we can see we created it
attachments = append(attachments, slack.Attachment{CallbackID: "matterbridge_" + b.uuid})
// add file attachments
attachments = append(attachments, b.createAttach(msg.Extra)...)
// add slack attachments (from another slack bridge)
@@ -509,6 +501,19 @@ func (b *Bslack) prepareMessageOptions(msg *config.Message) []slack.MsgOption {
}
var opts []slack.MsgOption
opts = append(opts,
// provide regular text field (fallback used in Slack notifications, etc.)
slack.MsgOptionText(msg.Text, false),
// add a callback ID so we can see we created it
slack.MsgOptionBlocks(slack.NewSectionBlock(
slack.NewTextBlockObject(slack.MarkdownType, msg.Text, false, false),
nil, nil,
slack.SectionBlockOptionBlockID("matterbridge_"+b.uuid),
)),
slack.MsgOptionEnableLinkUnfurl(),
)
opts = append(opts, slack.MsgOptionAttachments(attachments...))
opts = append(opts, slack.MsgOptionPostMessageParameters(params))
return opts

View File

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

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)
if b.General.MediaServerUpload != "" {
if b.General.MediaServerUpload != "" || (b.General.MediaServerDownload != "" && b.General.MediaDownloadPath != "") {
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/helper"
"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") {
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

View File

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

View File

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

View File

@@ -1,7 +1,7 @@
#!/usr/bin/env bash
set -u -e -x -o pipefail
go version | grep go1.13 || exit
go version | grep go1.14 || exit
VERSION=$(git describe --tags)
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 (
"github.com/42wim/matterbridge/bridge"
"github.com/42wim/matterbridge/bridge/api"
bdiscord "github.com/42wim/matterbridge/bridge/discord"
bgitter "github.com/42wim/matterbridge/bridge/gitter"
birc "github.com/42wim/matterbridge/bridge/irc"
bkeybase "github.com/42wim/matterbridge/bridge/keybase"
bmatrix "github.com/42wim/matterbridge/bridge/matrix"
bmattermost "github.com/42wim/matterbridge/bridge/mattermost"
brocketchat "github.com/42wim/matterbridge/bridge/rocketchat"
bslack "github.com/42wim/matterbridge/bridge/slack"
bsshchat "github.com/42wim/matterbridge/bridge/sshchat"
bsteam "github.com/42wim/matterbridge/bridge/steam"
btelegram "github.com/42wim/matterbridge/bridge/telegram"
bwhatsapp "github.com/42wim/matterbridge/bridge/whatsapp"
bxmpp "github.com/42wim/matterbridge/bridge/xmpp"
bzulip "github.com/42wim/matterbridge/bridge/zulip"
)
var (
FullMap = map[string]bridge.Factory{
"api": api.New,
"discord": bdiscord.New,
"gitter": bgitter.New,
"irc": birc.New,
"mattermost": bmattermost.New,
"matrix": bmatrix.New,
"rocketchat": brocketchat.New,
"slack-legacy": bslack.NewLegacy,
"slack": bslack.New,
"sshchat": bsshchat.New,
"steam": bsteam.New,
"telegram": btelegram.New,
"whatsapp": bwhatsapp.New,
"xmpp": bxmpp.New,
"zulip": bzulip.New,
"keybase": bkeybase.New,
}
UserTypingSupport = map[string]struct{}{
"slack": {},
"discord": {},
}
FullMap = map[string]bridge.Factory{}
UserTypingSupport = map[string]struct{}{}
)

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

View File

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

24
go.mod
View File

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

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.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
github.com/42wim/go-gitter v0.0.0-20170828205020-017310c2d557 h1:IZtuWGfzQnKnCSu+vl8WGLhpVQ5Uvy3rlSwqXSg+sQg=
github.com/42wim/go-gitter v0.0.0-20170828205020-017310c2d557/go.mod h1:jL0YSXMs/txjtGJ4PWrmETOk6KUHMDPMshgQZlTeB3Y=
github.com/Baozisoftware/qrcode-terminal-go v0.0.0-20170407111555-c0650d8dff0f h1:2dk3eOnYllh+wUOuDhOoC2vUVoJF/5z478ryJ+wzEII=
@@ -11,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/go.mod h1:HuVM+sZFzumUdKPWiz+IlCMb4RdsKdT3T+nQBKL+sYg=
github.com/Rhymen/go-whatsapp v0.0.0/go.mod h1:rdQr95g2C1xcOfM7QGOhza58HeI3I+tZ/bbluv7VazA=
github.com/Rhymen/go-whatsapp v0.1.0 h1:XTXhFIQ/fx9jKObUnUX2Q+nh58EyeHNhX7DniE8xeuA=
github.com/Rhymen/go-whatsapp v0.1.0/go.mod h1:xJSy+okeRjKkQEH/lEYrnekXB3PG33fqL0I6ncAkV50=
github.com/Rhymen/go-whatsapp v0.1.1-0.20200408093540-2f227c53b44f h1:uclEol7RbpElhXXmwu38PDeGcgMXNU2vh5DWwzlg7xI=
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/restoreSession v0.0.0-20190325075644-cc2581bbf24d/go.mod h1:5sCUSpG616ZoSJhlt9iBNI/KXBqrVLcNUJqg7J9+8pU=
github.com/Rhymen/go-whatsapp/examples/sendImage v0.0.0-20190325075644-cc2581bbf24d/go.mod h1:RdiyhanVEGXTam+mZ3k6Y3VDCCvXYCwReOoxGozqhHw=
github.com/Rhymen/go-whatsapp/examples/sendTextMessages v0.0.0-20190325075644-cc2581bbf24d/go.mod h1:suwzklatySS3Q0+NCxCDh5hYfgXdQUWU1DNcxwAxStM=
github.com/StackExchange/wmi v0.0.0-20170410192909-ea383cf3ba6e h1:IHXQQIpxASe3m0Jtcd3XongL+lxHNd5nUmvHxJARUmg=
github.com/StackExchange/wmi v0.0.0-20170410192909-ea383cf3ba6e/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg=
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
@@ -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-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
github.com/d5/tengo/v2 v2.0.2 h1:3APkPZPc1FExaJoWrN5YzvDqc6GNkQH6ehmCRDmN83I=
github.com/d5/tengo/v2 v2.0.2/go.mod h1:XRGjEs5I9jYIKTxly6HCF8oiiilk5E/RYXOZ5b0DZC8=
github.com/d5/tengo/v2 v2.1.2 h1:JR5O6qJW2GW9lpv/MfEqK16a/Wpp2y8I0JZZ5fqNOL0=
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.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
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-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
github.com/go-ole/go-ole v1.2.1 h1:2lOsA72HgjxAuMlKpFiCbHTvu44PIVkZ5hqm3RSdI/E=
github.com/go-ole/go-ole v1.2.1/go.mod h1:7FAglXiTm7HKlQRDeOQ6ZNUHidzCWXuZWq/1dTyBNF8=
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
github.com/go-telegram-bot-api/telegram-bot-api v4.6.5-0.20181225215658-ec221ba9ea45+incompatible h1:i64CCJcSqkRIkm5OSdZQjZq84/gJsk2zNwHWIRYWlKE=
github.com/go-telegram-bot-api/telegram-bot-api v4.6.5-0.20181225215658-ec221ba9ea45+incompatible/go.mod h1:qf9acutJ8cwBUhm1bqgz6Bei9/C/c93FPDljKWwsOgM=
github.com/go-test/deep v1.0.4 h1:u2CU3YKy9I2pmu9pX0eq50wCgjfGIt539SqR7FbHiho=
github.com/go-test/deep v1.0.4/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA=
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.0 h1:kbxbvI4Un1LUWKxufD+BiE6AEExYYgkQLQmLFqA1LFk=
github.com/golang/protobuf v1.3.0/go.mod h1:Qd/q+1AKNOZr9uGQzbzCmRO6sUih6GTPZv6a1/R87v0=
github.com/golang/protobuf v1.3.1 h1:YF8+flBXS5eO826T4nzqPrxfhQThhXl0YzfuUPu4SBg=
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
@@ -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/gops v0.3.6 h1:6akvbMlpZrEYOuoebn2kR+ZJekbZqJ28fJXTs84+8to=
github.com/google/gops v0.3.6/go.mod h1:RZ1rH95wsAGX4vMWKmqBOIWynmWisBf4QFdgT/k/xOI=
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/gopackage/ddp v0.0.0-20170117053602-652027933df4 h1:4EZlYQIiyecYJlUbVkFXCXHz1QPhVXcHnQKAzBTPfQo=
github.com/gopackage/ddp v0.0.0-20170117053602-652027933df4/go.mod h1:lEO7XoHJ/xNRBCxrn4h/CEB67h0kW1B0t4ooP2yrjUA=
github.com/gopherjs/gopherjs v0.0.0-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/go.mod h1:kgLaKoK1FELgZqMAVxx/5cbj0kT+57qxUrAlIO2eleU=
github.com/gorilla/websocket v1.2.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
github.com/gorilla/websocket v1.4.0 h1:WDFjx/TMzVgy9VdMMQi2K2Emtwi2QcUQsztZ/zLaH/Q=
github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
github.com/gorilla/websocket v1.4.1 h1:q7AeDBpnBk8AogcD4DSag/Ukw/KV+YhzLj2bP5HvKCM=
github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
@@ -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/kardianos/osext v0.0.0-20170510131534-ae77be60afb1 h1:PJPDf8OUfOK1bb/NeTKd4f1QXZItOX389VN3B6qC8ro=
github.com/kardianos/osext v0.0.0-20170510131534-ae77be60afb1/go.mod h1:1NbS8ALrpOvjt0rHPNLyCIeMtbizbir8U//inJ+zuB8=
github.com/keybase/go-keybase-chat-bot v0.0.0-20190816161829-561f10822eb2 h1:zacJswvfPqUSGdcBXJzKvLN/dB1UjDGDvDesMBBzoA4=
github.com/keybase/go-keybase-chat-bot v0.0.0-20190816161829-561f10822eb2/go.mod h1:vNc28YFzigVJod0j5EbuTtRIe7swx8vodh2yA4jZ2s8=
github.com/keybase/go-keybase-chat-bot v0.0.0-20200226211841-4e48f3eaef3e h1:KbPTfR/PYuau1IzKoE4lnd8yby5I2pBj+VR6fSVbYU8=
github.com/keybase/go-keybase-chat-bot v0.0.0-20200226211841-4e48f3eaef3e/go.mod h1:vNc28YFzigVJod0j5EbuTtRIe7swx8vodh2yA4jZ2s8=
github.com/keybase/go-ps v0.0.0-20161005175911-668c8856d999 h1:2d+FLQbz4xRTi36DO1qYNUwfORax9XcQ0jhbO81Vago=
github.com/keybase/go-ps v0.0.0-20161005175911-668c8856d999/go.mod h1:hY+WOq6m2FpbvyrI93sMaypsttvaIL5nhVR92dTMUcQ=
github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
@@ -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/matterbridge/Rocket.Chat.Go.SDK v0.0.0-20190210153444-cc9d05784d5d h1:F+Sr+C0ojSlYQ37BLylQtSFmyQULe3jbAygcyXQ9mVs=
github.com/matterbridge/Rocket.Chat.Go.SDK v0.0.0-20190210153444-cc9d05784d5d/go.mod h1:c6MxwqHD+0HvtAJjsHMIdPCiAwGiQwPRPTp69ACMg8A=
github.com/matterbridge/discordgo v0.18.1-0.20200109173909-ed873362fa43 h1:xTcLiEPMp9jVh/lHEPpLc87RZ4sRWRZe0rM578/waOk=
github.com/matterbridge/discordgo v0.18.1-0.20200109173909-ed873362fa43/go.mod h1:O9S4p+ofTFwB02em7jkpkV8M3R0/PUVOwN61zSZ0r4Q=
github.com/matterbridge/discordgo v0.18.1-0.20200308151012-aa40f01cbcc3 h1:VP/DNRn2HtrVRN6+X3h4FDcQI2OOKT+88WUi21ZD1Kw=
github.com/matterbridge/discordgo v0.18.1-0.20200308151012-aa40f01cbcc3/go.mod h1:5a1bHtG/38ofcx9cgwM5eTW/Pl4SpbQksNDnTRcGA2Y=
github.com/matterbridge/emoji v2.1.1-0.20191117213217-af507f6b02db+incompatible h1:oaOqwbg5HxHRxvAbd84ks0Okwoc1ISyUZ87EiVJFhGI=
github.com/matterbridge/emoji v2.1.1-0.20191117213217-af507f6b02db+incompatible/go.mod h1:igE6rUAn3jai2wCdsjFHfhUoekjrFthoEjFObKKwSb4=
github.com/matterbridge/go-xmpp v0.0.0-20180529212104-cd19799fba91 h1:KzDEcy8eDbTx881giW8a6llsAck3e2bJvMyKvh1IK+k=
github.com/matterbridge/go-xmpp v0.0.0-20180529212104-cd19799fba91/go.mod h1:ECDRehsR9TYTKCAsRS8/wLeOk6UUqDydw47ln7wG41Q=
github.com/matterbridge/gomatrix v0.0.0-20191026211822-6fc7accd00ca h1:3ypqEpFpt6vg5Sv2xxA8/v4WiSOnWMXW7DqxTxpM4XI=
github.com/matterbridge/gomatrix v0.0.0-20191026211822-6fc7accd00ca/go.mod h1:+jWeaaUtXQbBRdKYWfjW6JDDYiI2XXE+3NnTjW5kg8g=
github.com/matterbridge/go-xmpp v0.0.0-20200329150250-5812999b292b h1:ZYI2HCj9zPzI4Si1ouSOi/ImA2xSQLUCJPQsLWr8FE0=
github.com/matterbridge/go-xmpp v0.0.0-20200329150250-5812999b292b/go.mod h1:ECDRehsR9TYTKCAsRS8/wLeOk6UUqDydw47ln7wG41Q=
github.com/matterbridge/gomatrix v0.0.0-20200209224845-c2104d7936a6 h1:Kl65VJv38HjYFnnwH+MP6Z8hcJT5UHuSpHVU5vW1HH0=
github.com/matterbridge/gomatrix v0.0.0-20200209224845-c2104d7936a6/go.mod h1:+jWeaaUtXQbBRdKYWfjW6JDDYiI2XXE+3NnTjW5kg8g=
github.com/matterbridge/gozulipbot v0.0.0-20190212232658-7aa251978a18 h1:fLhwXtWGtfTgZVxHG1lcKjv+re7dRwyyuYFNu69xdho=
github.com/matterbridge/gozulipbot v0.0.0-20190212232658-7aa251978a18/go.mod h1:yAjnZ34DuDyPHMPHHjOsTk/FefW4JJjoMMCGt/8uuQA=
github.com/matterbridge/logrus-prefixed-formatter v0.0.0-20180806162718-01618749af61 h1:R/MgM/eUyRBQx2FiH6JVmXck8PaAuKfe2M1tWIzW7nE=
github.com/matterbridge/logrus-prefixed-formatter v0.0.0-20180806162718-01618749af61/go.mod h1:iXGEotOvwI1R1SjLxRc+BF5rUORTMtE0iMZBT2lxqAU=
github.com/matterbridge/slack v0.1.1-0.20191208194820-95190f11bfb6 h1:UvXXR9tHYqJUXZVEtiK2qkEWBXfFneicate5kOshVFk=
github.com/matterbridge/slack v0.1.1-0.20191208194820-95190f11bfb6/go.mod h1:2uCJim0Ct2z1Uj+XQq47KCLLC1b/9UTYaZOvDtbZfK4=
github.com/mattermost/mattermost-server v5.5.0+incompatible h1:0wcLGgYtd+YImtLDPf2AOfpBHxbU4suATx+6XKw1XbU=
github.com/mattermost/mattermost-server v5.5.0+incompatible/go.mod h1:5L6MjAec+XXQwMIt791Ganu45GKsSiM+I0tLR9wUj8Y=
github.com/mattn/go-colorable v0.1.1 h1:G1f5SKeVxmagw/IyvzvtZE4Gybcc4Tr1tf7I8z0XgOg=
github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ=
github.com/mattn/go-colorable v0.1.2 h1:/bC9yWikZXAL9uJdulbSfyVNIR3n3trXl+v8+1sx8mU=
github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
github.com/mattn/go-colorable v0.1.4 h1:snbPLB8fVfU9iwbbo30TPtbLRzwWu6aJS6Xh4eaaviA=
github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
github.com/mattn/go-isatty v0.0.5 h1:tHXDdz1cpzGaovsTB+TVB8q90WEokoVmfMqoVcrLUgw=
github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
github.com/mattn/go-isatty v0.0.8 h1:HLtExJ+uU2HOZ+wI0Tt5DtUDrx8yhUqDcp7fYERX4CE=
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
github.com/mattn/go-isatty v0.0.9 h1:d5US/mDsogSGW37IV293h//ZFaeajb69h+EHFsv2xGg=
github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ=
github.com/mattn/go-isatty v0.0.11 h1:FxPOTFNqGkuDUGi3H/qkUbQO4ZiBa2brKq5r0l8TGeM=
github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE=
github.com/mattn/go-runewidth v0.0.7 h1:Ei8KR0497xHyKJPAv59M1dkC+rOZCMBJ+t3fZ+twI54=
github.com/mattn/go-runewidth v0.0.7/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
github.com/mattn/godown v0.0.0-20180312012330-2e9e17e0ea51 h1:MpI7hy3MiCnrggmZI/s8LaPbLVOOWpzDbjA4F+XaXaM=
github.com/mattn/godown v0.0.0-20180312012330-2e9e17e0ea51/go.mod h1:s3KUdOIXJ+jaGM++XHiXA6gikdleaWVATCcQGD4h734=
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b h1:j7+1HpAFS1zy5+Q4qx1fWh90gTKwiN4QCGoY9TWyyO4=
github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE=
@@ -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/nicksnyder/go-i18n v1.4.0 h1:AgLl+Yq7kg5OYlzCgu9cKTZOyI4tD/NgukKqLqC8E+I=
github.com/nicksnyder/go-i18n v1.4.0/go.mod h1:HrK7VCrbOvQoUAQ7Vpy7i87N7JZZZ7R2xBGjv0j365Q=
github.com/nlopes/slack v0.6.0 h1:jt0jxVQGhssx1Ib7naAOZEZcGdtIhTzkP0nopK0AsRA=
github.com/nlopes/slack v0.6.0/go.mod h1:JzQ9m3PMAqcpeCam7UaHSuBuupz7CmpjehYMayT6YOk=
github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
github.com/onsi/ginkgo v1.6.0 h1:Ix8l273rp3QzYgXSR+c8d1fTG7UPgYkOSELPhiY/YGw=
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
@@ -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-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU=
github.com/rickb777/date v1.12.4 h1:+6IzcCCS/1t17DrmnEvrznyq7nM8vPwir6/UhlyohKw=
github.com/rickb777/date v1.12.4/go.mod h1:xP0eo/I5qmUt97yRGClHZfyLZ3ikMw6v6SU5MOGZTE0=
github.com/rickb777/plural v1.2.0 h1:5tvEc7UBCZ7l8h/2UeybSkt/uu1DQsZFOFdNevmUhlE=
github.com/rickb777/plural v1.2.0/go.mod h1:UdpyWFCGbo3mvK3f/PfZOAOrkjzJlYN/sD46XNWJ+Es=
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
github.com/rs/xid v1.2.1 h1:mhH9Nq+C1fY2l1XIpgxIiUOfNpRBYH1kKcr+qfKgjRc=
github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ=
@@ -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/shazow/rateio v0.0.0-20150116013248-e8e00881e5c1 h1:Lx3BlDGFElJt4u/zKc9A3BuGYbQAGlEFyPuUA3jeMD0=
github.com/shazow/rateio v0.0.0-20150116013248-e8e00881e5c1/go.mod h1:vt2jWY/3Qw1bIzle5thrJWucsLuuX9iUNnp20CqCciI=
github.com/shazow/ssh-chat v1.8.2 h1:MMso9eWfCnPBelRsusYxKcRBUwHIPEQkR9WrO89II38=
github.com/shazow/ssh-chat v1.8.2/go.mod h1:cXTZK/D1zujEwB0y8DIT1GX8rIKjyLDYeWd+jitPX84=
github.com/shirou/gopsutil v0.0.0-20180427012116-c95755e4bcd7 h1:80VN+vGkqM773Br/uNNTSheo3KatTgV8IpjIKjvVLng=
github.com/shazow/ssh-chat v1.8.3-0.20200308224626-80ddf1f43a98 h1:sN07ff+PSRsUNhpSod4uGKAQ+Nc0FXsBPG9FmYMNg4w=
github.com/shazow/ssh-chat v1.8.3-0.20200308224626-80ddf1f43a98/go.mod h1:xkTgfD+WP+KR4HuG76oal25BBEeu5kJyi2EOsgiu/4Q=
github.com/shirou/gopsutil v0.0.0-20180427012116-c95755e4bcd7/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA=
github.com/shirou/w32 v0.0.0-20160930032740-bb4de0191aa4 h1:udFKJ0aHUL60LboW/A+DfgoHVedieIzIXE8uylPue0U=
github.com/shirou/w32 v0.0.0-20160930032740-bb4de0191aa4/go.mod h1:qsXQc7+bwAM3Q1u/4XEfrquwF8Lw7D7y5cD8CuHnfIc=
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4=
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
github.com/skip2/go-qrcode v0.0.0-20190110000554-dc11ecdae0a9 h1:lpEzuenPuO1XNTeikEmvqYFcU37GVLl8SRNblzyvGBE=
github.com/skip2/go-qrcode v0.0.0-20190110000554-dc11ecdae0a9/go.mod h1:PLPIyL7ikehBD1OAjmKKiOEhbvWyHGaNDjquXMcYABo=
github.com/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/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
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/go.mod h1:t3iDnF5Jlj76alVNuyFBk5oUMCvsrkbvZK0WQdfDi5k=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.1.1 h1:2vfRuCMp5sSVIDSqO8oNnWJq7mPa6KVP3iPIwFBuy8A=
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
@@ -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/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
github.com/valyala/fasttemplate v1.0.1 h1:tY9CJiPnMXf1ERmG2EyK7gNUd+c6RKGD0IfU8WdUSz8=
github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8=
github.com/valyala/fasttemplate v1.1.0 h1:RZqt0yGBsps8NGvLSGW804QQqCUYYLsaOjTVHy1Ocw4=
github.com/valyala/fasttemplate v1.1.0/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8=
github.com/x-cray/logrus-prefixed-formatter v0.5.2 h1:00txxvfBM9muc0jiLIEAkAcIMJzfthRT6usrui8uGmg=
github.com/x-cray/logrus-prefixed-formatter v0.5.2/go.mod h1:2duySbKsL6M18s5GU7VPsoEPHyzalCE06qoARUCeBBE=
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
github.com/xlab/treeprint v0.0.0-20180616005107-d6fb6747feb6 h1:YdYsPAZ2pC6Tow/nPZOPQ96O3hm/ToAkGsPLzedXERk=
github.com/xlab/treeprint v0.0.0-20180616005107-d6fb6747feb6/go.mod h1:ce1O1j6UtZfjr22oyGxGLbauSBp2YVXpARAosm7dHBg=
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
github.com/yaegashi/msgraph.go v0.1.2 h1:83uVRQaj8YBsVqOUGj0WRwzxdgGF69jRpg5IQYaTvoY=
github.com/yaegashi/msgraph.go v0.1.2/go.mod h1:Lp39e9oo596G5FcmMKI0cXR3mg/QikSdabgZdbMqbAM=
github.com/zfjagann/golang-ring v0.0.0-20190106091943-a88bb6aef447 h1:CHgPZh8bFkZmislPrr/0gd7MciDAX+JJB70A2/5Lvmo=
github.com/zfjagann/golang-ring v0.0.0-20190106091943-a88bb6aef447/go.mod h1:0MsIttMJIF/8Y7x0XjonJP7K99t3sR6bjj4m5S4JmqU=
go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
@@ -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-20181030102418-4d3f4d9ffa16/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190131182504-b8fe1690c613/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2 h1:VklqNMn3ovrHsnt90PveolxSbWFaJdECFbxSq0Mqo2M=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190320223903-b7391e95e576/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
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/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190522155817-f3200d17e092 h1:4QSRKanuywn15aTZvI/mIDEgPQpswuFndXpOj3rKEco=
golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553 h1:efeOvDhwQ29Dj3SdAV/MJf8oukgn+8D8WgaCaRMchF8=
golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/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-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4 h1:YUO/7uOKsKeq9UokNS62b8FYywz3ker1l1vDZRCRefw=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20171017063910-8dbc5d05d6ed/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@@ -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-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a h1:aYOabOQFp6Vj6W1F80affTUvO9UxmJRx8K0gsfABByQ=
golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8 h1:JA8d3MPx/IToSyXZG/RhwYEtfrKO1Fxrqe8KrkiLXKM=
golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
@@ -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-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
google.golang.org/appengine v1.4.0 h1:/wp5JvzpHIxhs/dumFmF7BXTf3Z+dd4uXta4kVyO508=
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
google.golang.org/genproto v0.0.0-20180831171423-11092d34479b/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
@@ -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/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74=
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.4 h1:/eiJrUcujPVeJ3xlSWaiNi3uSVmDGBK1pDHUHAnao1I=
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
rsc.io/goversion v1.0.0 h1:/IhXBiai89TyuerPquiZZ39IQkTfAUbZB2awsyYZ/2c=
rsc.io/goversion v1.0.0/go.mod h1:Eih9y/uIBS3ulggl7KNJ09xGSLcuNaLgmvvqa07sgfo=

View File

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

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/sendTextMessages v0.0.0-20190325075644-cc2581bbf24d // indirect
github.com/golang/protobuf v1.3.0
github.com/gorilla/websocket v1.4.0
github.com/gorilla/websocket v1.4.1
github.com/pkg/errors v0.8.1
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2
)

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.3.0 h1:kbxbvI4Un1LUWKxufD+BiE6AEExYYgkQLQmLFqA1LFk=
github.com/golang/protobuf v1.3.0/go.mod h1:Qd/q+1AKNOZr9uGQzbzCmRO6sUih6GTPZv6a1/R87v0=
github.com/gorilla/websocket v1.4.0 h1:WDFjx/TMzVgy9VdMMQi2K2Emtwi2QcUQsztZ/zLaH/Q=
github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
github.com/gorilla/websocket v1.4.1 h1:q7AeDBpnBk8AogcD4DSag/Ukw/KV+YhzLj2bP5HvKCM=
github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/mattn/go-colorable v0.1.1 h1:G1f5SKeVxmagw/IyvzvtZE4Gybcc4Tr1tf7I8z0XgOg=
github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ=
github.com/mattn/go-isatty v0.0.5 h1:tHXDdz1cpzGaovsTB+TVB8q90WEokoVmfMqoVcrLUgw=

View File

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

View File

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

View File

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

View File

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

View File

@@ -7,7 +7,6 @@
[![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)
[![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.**
@@ -75,6 +74,10 @@ _* See [here](https://github.com/d5/tengobench) for commands/codes used_
## Quick Start
```
go get github.com/d5/tengo/v2
```
A simple Go example code that compiles/runs Tengo script code with some input/output values:
```golang

View File

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

View File

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

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"
"fmt"
"io"
"io/ioutil"
"log"
"os"
"os/exec"
"strings"
"sync"
"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
type API struct {
sync.Mutex
apiInput io.Writer
apiOutput *bufio.Reader
apiCmd *exec.Cmd
username string
runOpts RunOptions
apiInput io.Writer
apiOutput *bufio.Reader
apiCmd *exec.Cmd
username string
runOpts RunOptions
subscriptions []*NewSubscription
}
func getUsername(runOpts RunOptions) (username string, err error) {
p := runOpts.Command("status")
p := runOpts.Command("whoami", "-json")
output, err := p.StdoutPipe()
if err != nil {
return "", err
}
p.ExtraFiles = []*os.File{output.(*os.File)}
if err = p.Start(); err != nil {
return "", err
}
doneCh := make(chan error)
go func() {
scanner := bufio.NewScanner(output)
if !scanner.Scan() {
doneCh <- errors.New("unable to find Keybase username")
defer func() { close(doneCh) }()
statusJSON, err := ioutil.ReadAll(output)
if err != nil {
doneCh <- fmt.Errorf("error reading whoami output: %v", err)
return
}
toks := strings.Fields(scanner.Text())
if len(toks) != 2 {
doneCh <- errors.New("invalid Keybase username output")
var status keybase1.CurrentStatus
if err := json.Unmarshal(statusJSON, &status); err != nil {
doneCh <- fmt.Errorf("invalid whoami JSON %q: %v", statusJSON, err)
return
}
username = toks[1]
doneCh <- nil
if status.LoggedIn && status.User != 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 {
@@ -71,6 +87,10 @@ type RunOptions struct {
HomeDir string
Oneshot *OneshotOptions
StartService bool
// Have the bot send/receive typing notifications
EnableTyping bool
// Disable bot lite mode
DisableBotLiteMode bool
}
func (r RunOptions) Location() string {
@@ -100,6 +120,10 @@ func Start(runOpts RunOptions) (*API, error) {
return api, nil
}
func (a *API) Command(args ...string) *exec.Cmd {
return a.runOpts.Command(args...)
}
func (a *API) auth() (string, error) {
username, err := getUsername(a.runOpts)
if err == nil {
@@ -132,17 +156,28 @@ func (a *API) startPipes() (err error) {
a.Lock()
defer a.Unlock()
if a.apiCmd != nil {
a.apiCmd.Process.Kill()
if err := a.apiCmd.Process.Kill(); err != nil {
return err
}
}
a.apiCmd = nil
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 {
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")
if a.apiInput, err = a.apiCmd.StdinPipe(); err != nil {
return err
@@ -151,6 +186,7 @@ func (a *API) startPipes() (err error) {
if err != nil {
return err
}
a.apiCmd.ExtraFiles = []*os.File{output.(*os.File)}
if err := a.apiCmd.Start(); err != nil {
return err
}
@@ -168,73 +204,11 @@ func (a *API) getAPIPipesLocked() (io.Writer, *bufio.Reader, error) {
return a.apiInput, a.apiOutput, nil
}
// GetConversations reads all conversations from the current user's inbox.
func (a *API) GetConversations(unreadOnly bool) ([]Conversation, 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
}
return inbox.Result.Convs, nil
func (a *API) GetUsername() string {
return a.username
}
// GetTextMessages fetches all text messages from a given channel. Optionally can filter
// 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) {
func (a *API) doSend(arg interface{}) (resp SendResponse, err error) {
a.Lock()
defer a.Unlock()
@@ -253,10 +227,12 @@ func (a *API) doSend(arg interface{}) (response SendResponse, err error) {
if err != nil {
return SendResponse{}, err
}
if err := json.Unmarshal(responseRaw, &response); err != nil {
return SendResponse{}, fmt.Errorf("failed to decode API response: %s", err)
if err := json.Unmarshal(responseRaw, &resp); err != nil {
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) {
@@ -278,237 +254,131 @@ func (a *API) doFetch(apiInput string) ([]byte, error) {
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
type SubscriptionMessage struct {
Message Message
Conversation Conversation
Message chat1.MsgSummary
Conversation chat1.ConvSummary
}
type SubscriptionConversation struct {
Conversation chat1.ConvSummary
}
type SubscriptionWalletEvent struct {
Payment Payment
Payment stellar1.PaymentDetailsLocal
}
// NewSubscription has methods to control the background message fetcher loop
type NewSubscription struct {
sync.Mutex
newMsgsCh <-chan SubscriptionMessage
newConvsCh <-chan SubscriptionConversation
newWalletCh <-chan SubscriptionWalletEvent
errorCh <-chan error
running bool
shutdownCh chan struct{}
}
// Read blocks until a new message arrives
func (m NewSubscription) Read() (SubscriptionMessage, error) {
func (m *NewSubscription) Read() (SubscriptionMessage, error) {
select {
case msg := <-m.newMsgsCh:
return msg, nil
case err := <-m.errorCh:
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
func (m NewSubscription) ReadWallet() (SubscriptionWalletEvent, error) {
func (m *NewSubscription) ReadWallet() (SubscriptionWalletEvent, error) {
select {
case msg := <-m.newWalletCh:
return msg, nil
case err := <-m.errorCh:
return SubscriptionWalletEvent{}, err
case <-m.shutdownCh:
return SubscriptionWalletEvent{}, errors.New("Subscription shutdown")
}
}
// Shutdown terminates the background process
func (m NewSubscription) Shutdown() {
m.shutdownCh <- struct{}{}
func (m *NewSubscription) Shutdown() {
m.Lock()
defer m.Unlock()
if m.running {
close(m.shutdownCh)
m.running = false
}
}
type ListenOptions struct {
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
func (a *API) ListenForNewTextMessages() (NewSubscription, error) {
func (a *API) ListenForNewTextMessages() (*NewSubscription, error) {
opts := ListenOptions{Wallet: false}
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
// events into channels
func (a *API) Listen(opts ListenOptions) (NewSubscription, error) {
newMsgCh := make(chan SubscriptionMessage, 100)
func (a *API) Listen(opts ListenOptions) (*NewSubscription, error) {
newMsgsCh := make(chan SubscriptionMessage, 100)
newConvsCh := make(chan SubscriptionConversation, 100)
newWalletCh := make(chan SubscriptionWalletEvent, 100)
errorCh := make(chan error, 100)
shutdownCh := make(chan struct{})
done := make(chan struct{})
sub := NewSubscription{
newMsgsCh: newMsgCh,
sub := &NewSubscription{
newMsgsCh: newMsgsCh,
newConvsCh: newConvsCh,
newWalletCh: newWalletCh,
shutdownCh: shutdownCh,
errorCh: errorCh,
running: true,
}
a.registerSubscription(sub)
pause := 2 * time.Second
readScanner := func(boutput *bufio.Scanner) {
defer func() { done <- struct{}{} }()
for {
select {
case <-shutdownCh:
log.Printf("readScanner: received shutdown")
return
default:
}
boutput.Scan()
t := boutput.Text()
var typeHolder TypeHolder
@@ -518,41 +388,72 @@ func (a *API) Listen(opts ListenOptions) (NewSubscription, error) {
}
switch typeHolder.Type {
case "chat":
var holder MessageHolder
if err := json.Unmarshal([]byte(t), &holder); err != nil {
var notification chat1.MsgNotification
if err := json.Unmarshal([]byte(t), &notification); err != nil {
errorCh <- err
break
}
subscriptionMessage := SubscriptionMessage{
Message: holder.Msg,
Conversation: Conversation{
ID: holder.Msg.ConversationID,
Channel: holder.Msg.Channel,
},
if notification.Error != nil {
log.Printf("error message received: %s", *notification.Error)
} else if notification.Msg != nil {
subscriptionMessage := SubscriptionMessage{
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":
var holder PaymentHolder
if err := json.Unmarshal([]byte(t), &holder); err != nil {
errorCh <- err
break
}
subscriptionPayment := SubscriptionWalletEvent{
Payment: holder.Payment,
}
subscriptionPayment := SubscriptionWalletEvent(holder)
newWalletCh <- subscriptionPayment
default:
continue
}
}
done <- struct{}{}
}
attempts := 0
maxAttempts := 1800
go func() {
defer func() {
close(newMsgsCh)
close(newConvsCh)
close(newWalletCh)
close(errorCh)
}()
for {
select {
case <-shutdownCh:
log.Printf("Listen: received shutdown")
return
default:
}
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")
}
attempts++
@@ -565,6 +466,9 @@ func (a *API) Listen(opts ListenOptions) (NewSubscription, error) {
if opts.Wallet {
cmdElements = append(cmdElements, "--wallet")
}
if opts.Convs {
cmdElements = append(cmdElements, "--convs")
}
p := a.runOpts.Command(cmdElements...)
output, err := p.StdoutPipe()
if err != nil {
@@ -572,8 +476,16 @@ func (a *API) Listen(opts ListenOptions) (NewSubscription, error) {
time.Sleep(pause)
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)
if err := p.Start(); err != nil {
log.Printf("Listen: failed to make listen scanner: %s", err)
time.Sleep(pause)
continue
@@ -581,78 +493,19 @@ func (a *API) Listen(opts ListenOptions) (NewSubscription, error) {
attempts = 0
go readScanner(boutput)
<-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)
}
}()
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 {
feedback = "go-keybase-chat-bot log send\n" +
"username: " + a.GetUsername() + "\n" +
@@ -675,6 +528,17 @@ func (a *API) LogSend(feedback string) 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 {
err := a.runOpts.Command("logout", "--force").Run()
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
import (
"bytes"
"encoding/json"
"fmt"
"log"
"strings"
"github.com/keybase/go-keybase-chat-bot/kbchat/types/keybase1"
)
type ListTeamMembers struct {
Result ListTeamMembersResult `json:"result"`
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"`
Result keybase1.TeamDetails `json:"result"`
Error Error `json:"error"`
}
type ListMembersOutputMembersCategory struct {
@@ -28,62 +21,56 @@ type ListMembersOutputMembersCategory struct {
}
type ListUserMemberships struct {
Result ListUserMembershipsResult `json:"result"`
Error Error `json:"error"`
Result keybase1.AnnotatedTeamList `json:"result"`
Error Error `json:"error"`
}
type ListUserMembershipsResult struct {
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{}
func (a *API) ListMembersOfTeam(teamName string) (res keybase1.TeamMembersDetails, err error) {
apiInput := fmt.Sprintf(`{"method": "list-team-memberships", "params": {"options": {"team": "%s"}}}`, teamName)
cmd := a.runOpts.Command("team", "api")
cmd.Stdin = strings.NewReader(apiInput)
bytes, err := cmd.CombinedOutput()
var stderr bytes.Buffer
cmd.Stderr = &stderr
output, err := cmd.Output()
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{}
err = json.Unmarshal(bytes, &members)
err = json.Unmarshal(output, &members)
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 != "" {
return empty, fmt.Errorf("received error from keybase team api: %s", members.Error.Message)
return res, members.Error
}
return members.Result.Members, nil
}
func (a *API) ListUserMemberships(username string) ([]ListUserMembershipsResultTeam, error) {
empty := []ListUserMembershipsResultTeam{}
func (a *API) ListUserMemberships(username string) ([]keybase1.AnnotatedMemberInfo, error) {
apiInput := fmt.Sprintf(`{"method": "list-user-memberships", "params": {"options": {"username": "%s"}}}`, username)
cmd := a.runOpts.Command("team", "api")
cmd.Stdin = strings.NewReader(apiInput)
bytes, err := cmd.CombinedOutput()
var stderr bytes.Buffer
cmd.Stderr = &stderr
output, err := cmd.Output()
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{}
err = json.Unmarshal(bytes, &members)
err = json.Unmarshal(output, &members)
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 != "" {
return empty, fmt.Errorf("received error from keybase team api: %s", members.Error.Message)
return nil, members.Error
}
return members.Result.Teams, nil
}

View File

@@ -1,16 +1,17 @@
# Rename this file to `test_config.yaml`
config:
bots:
alice:
username: "alice"
paperkey: "foo bar car..."
bob:
username: "bob"
paperkey: "one two three four..."
teams:
acme:
# A real team that you add your alice1 and bob1 into
name: "acme"
# The channel to use
topicname: "mysupercoolchannel"
keybase: "/path/to/keybase"
bots:
# Alice should have an active Stellar account with a little bit of XLM in it
alice:
username: "alice"
paperkey: "foo bar car..."
bob:
username: "bob"
paperkey: "one two three four..."
teams:
acme:
# A real team that you add your alice and bob into
name: "acme"
# 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.
// We do this to avoid any version mismatch issues.
func prepWorkingDir(t *testing.T, workingDir string) string {
kbLocation := whichKeybase(t)
func prepWorkingDir(t *testing.T, workingDir string, kbLocation string) string {
err := os.Mkdir(workingDir, 0777)
require.NoError(t, err)
kbDestination := path.Join(workingDir, "keybase")

View File

@@ -1,159 +1,14 @@
package kbchat
type Sender struct {
Uid string `json:"uid"`
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"`
}
import (
"github.com/keybase/go-keybase-chat-bot/kbchat/types/chat1"
)
type Result struct {
Convs []Conversation `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"`
Convs []chat1.ConvSummary `json:"conversations"`
}
type SendResponse struct {
Result SendResult `json:"result"`
}
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"`
Result chat1.SendRes `json:"result"`
Error *Error `json:"error,omitempty"`
}

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