forked from lug/matterbridge
		
	Compare commits
	
		
			70 Commits
		
	
	
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|   | 24bc0f127b | ||
|   | f0f801402d | ||
|   | 663850a2b8 | ||
|   | c51753cab1 | ||
|   | b3be2e208c | ||
|   | c30e90ff3f | ||
|   | e4c0ca0f48 | ||
|   | 9c203327c0 | ||
|   | ccb5b1d075 | ||
|   | 0dbbd0414c | ||
|   | e7b3ebf98a | ||
|   | 5bc18fb780 | ||
|   | df30366072 | ||
|   | 65c7ac80b5 | ||
| ![dependabot[bot]](/assets/img/avatar_default.png)  | dd3fb32ec7 | ||
|   | 2a3f475ff5 | ||
|   | 7288f71201 | ||
|   | 9c43eff753 | ||
|   | c8d7fdeedc | ||
|   | c211152e23 | ||
|   | ab75d5097e | ||
|   | c3644c8d3b | ||
|   | 6438a3dba3 | ||
|   | 4b226a6a63 | ||
|   | 4801850013 | ||
|   | 6a7412bf2b | ||
| ![dependabot[bot]](/assets/img/avatar_default.png)  | 5a1fd7dadd | ||
| ![dependabot[bot]](/assets/img/avatar_default.png)  | ac06a26809 | ||
| ![dependabot[bot]](/assets/img/avatar_default.png)  | 61d56f26f8 | ||
| ![dependabot[bot]](/assets/img/avatar_default.png)  | 6aa05b3981 | ||
| ![dependabot[bot]](/assets/img/avatar_default.png)  | aad60c882e | ||
| ![dependabot[bot]](/assets/img/avatar_default.png)  | fecca57507 | ||
|   | 2bcad846c0 | ||
|   | 15ad0165fc | ||
|   | 2e8ab11978 | ||
|   | 9a8ce9b17e | ||
|   | 16ab4c6fed | ||
|   | e3ee0df7ba | ||
|   | 8f7ab280e2 | ||
|   | dbedc99421 | ||
|   | 6cb359cb80 | ||
|   | ae2ad824a9 | ||
|   | 02e3d7852b | ||
|   | 3893a035be | ||
|   | 658bdd9faa | ||
|   | e1eebcd4e0 | ||
|   | 062b831e88 | ||
|   | b275efaeff | ||
|   | 80d3033456 | ||
|   | bd0516f09a | ||
|   | df4d76e466 | ||
|   | dcbd7f8cad | ||
|   | 73ec02ab9d | ||
|   | d1f8347071 | ||
|   | 8601eedada | ||
|   | 9afd33cdfc | ||
|   | 5e1be8e558 | ||
|   | 835dd2635a | ||
|   | f65b18c2f6 | ||
|   | b0e7b84f40 | ||
|   | 1635db93c7 | ||
|   | c4fe462d11 | ||
|   | b1f403165d | ||
|   | 46e4317b77 | ||
|   | e3ffbcadd8 | ||
|   | b7d73077e5 | ||
|   | 77f61ee20a | ||
|   | 8967f02fc9 | ||
|   | 831ff6d0a9 | ||
|   | 2199174def | 
							
								
								
									
										6
									
								
								.github/workflows/development.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										6
									
								
								.github/workflows/development.yml
									
									
									
									
										vendored
									
									
								
							| @@ -35,9 +35,9 @@ jobs: | ||||
|       run: | | ||||
|         mkdir -p output/{win,lin,arm,mac} | ||||
|         VERSION=$(git describe --tags) | ||||
|         CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -ldflags "-s -X main.githash=$(git log --pretty=format:'%h' -n 1)" -o output/lin/matterbridge-$VERSION-linux-amd64 | ||||
|         CGO_ENABLED=0 GOOS=windows GOARCH=amd64 go build -ldflags "-s -X main.githash=$(git log --pretty=format:'%h' -n 1)" -o output/win/matterbridge-$VERSION-windows-amd64.exe | ||||
|         CGO_ENABLED=0 GOOS=darwin GOARCH=amd64 go build -ldflags "-s -X main.githash=$(git log --pretty=format:'%h' -n 1)" -o output/mac/matterbridge-$VERSION-darwin-amd64 | ||||
|         CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -ldflags "-s -X github.com/42wim/matterbridge/version.GitHash=$(git log --pretty=format:'%h' -n 1)" -o output/lin/matterbridge-$VERSION-linux-amd64 | ||||
|         CGO_ENABLED=0 GOOS=windows GOARCH=amd64 go build -ldflags "-s -X github.com/42wim/matterbridge/version.GitHash=$(git log --pretty=format:'%h' -n 1)" -o output/win/matterbridge-$VERSION-windows-amd64.exe | ||||
|         CGO_ENABLED=0 GOOS=darwin GOARCH=amd64 go build -ldflags "-s -X github.com/42wim/matterbridge/version.GitHash=$(git log --pretty=format:'%h' -n 1)" -o output/mac/matterbridge-$VERSION-darwin-amd64 | ||||
|     - name: Upload linux 64-bit | ||||
|       if: startsWith(matrix.go-version,'1.17') | ||||
|       uses: actions/upload-artifact@v2 | ||||
|   | ||||
							
								
								
									
										3
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										3
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							| @@ -4,3 +4,6 @@ | ||||
|  | ||||
| # Exclude configuration file | ||||
| matterbridge.toml | ||||
|  | ||||
| # Exclude IDE Files | ||||
| .vscode | ||||
|   | ||||
| @@ -186,7 +186,24 @@ linters: | ||||
|     - errorlint | ||||
|     - nlreturn | ||||
|     - exhaustivestruct | ||||
|  | ||||
|     - forbidigo | ||||
|     - wrapcheck | ||||
|     - varnamelen | ||||
|     - ireturn | ||||
|     - errorlint | ||||
|     - tparallel | ||||
|     - wrapcheck | ||||
|     - paralleltest | ||||
|     - makezero | ||||
|     - thelper | ||||
|     - cyclop | ||||
|     - revive | ||||
|     - importas | ||||
|     - gomoddirectives | ||||
|     - promlinter | ||||
|     - tagliatelle | ||||
|     - errname | ||||
|     - typecheck | ||||
| # rules to deal with reported isues | ||||
| issues: | ||||
|   # List of regexps of issue texts to exclude, empty list by default. | ||||
|   | ||||
| @@ -22,7 +22,7 @@ builds: | ||||
|     - 6 | ||||
|     - 7 | ||||
|   ldflags: | ||||
|     - -s -w -X main.githash={{.ShortCommit}} | ||||
|     - -s -w -X github.com/42wim/matterbridge/version.GitHash={{.ShortCommit}} | ||||
|  | ||||
| archives: | ||||
|   - | ||||
|   | ||||
| @@ -1,9 +1,9 @@ | ||||
| FROM alpine:edge AS builder | ||||
| FROM alpine AS builder | ||||
|  | ||||
| COPY . /go/src/matterbridge | ||||
| RUN apk --no-cache add go git \ | ||||
|         && cd /go/src/matterbridge \ | ||||
|         && CGO_ENABLED=0 go build -mod vendor -ldflags "-X main.githash=$(git log --pretty=format:'%h' -n 1)" -o /bin/matterbridge | ||||
|         && CGO_ENABLED=0 go build -mod vendor -ldflags "-X github.com/42wim/matterbridge/version.GitHash=$(git log --pretty=format:'%h' -n 1)" -o /bin/matterbridge | ||||
|  | ||||
| FROM alpine | ||||
| RUN apk --no-cache add ca-certificates mailcap | ||||
|   | ||||
| @@ -164,7 +164,7 @@ See <https://github.com/42wim/matterbridge/wiki> | ||||
|  | ||||
| ### Binaries | ||||
|  | ||||
| - Latest stable release [v1.23.0](https://github.com/42wim/matterbridge/releases/latest) | ||||
| - Latest stable release [v1.24.1](https://github.com/42wim/matterbridge/releases/latest) | ||||
| - Development releases (follows master) can be downloaded [here](https://github.com/42wim/matterbridge/actions) selecting the latest green build and then artifacts. | ||||
|  | ||||
| To install or upgrade just download the latest [binary](https://github.com/42wim/matterbridge/releases/latest). On \*nix platforms you may need to make the binary executable - you can do this by running `chmod a+x` on the binary (example: `chmod a+x matterbridge-1.20.0-linux-64bit`). After downloading (and making the binary executable, if necessary), 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. | ||||
| @@ -185,13 +185,13 @@ Go 1.17+ is required. Make sure you have [Go](https://golang.org/doc/install) pr | ||||
| To install the latest stable run: | ||||
|  | ||||
| ```bash | ||||
| go install github.com/42wim/matterbridge | ||||
| go install github.com/42wim/matterbridge@v1.24.1 | ||||
| ``` | ||||
|  | ||||
| To install the latest dev run: | ||||
|  | ||||
| ```bash | ||||
| go install github.com/42wim/matterbridge@master | ||||
| go install github.com/42wim/matterbridge@latest | ||||
| ``` | ||||
|  | ||||
| You should now have matterbridge binary in the ~/go/bin directory: | ||||
| @@ -336,6 +336,7 @@ See [FAQ](https://github.com/42wim/matterbridge/wiki/FAQ) | ||||
| - <https://daniele.tech/2019/02/how-to-use-matterbridge-to-connect-2-different-slack-workspaces/> | ||||
| - <https://userlinux.net/mattermost-and-matterbridge.html> | ||||
| - <https://nextcloud.com/blog/bridging-chat-services-in-talk/> | ||||
| - <https://minecraftchest1.wordpress.com/2021/06/05/how-to-install-and-setup-matterbridge/> | ||||
| - Youtube: [whatsapp - telegram bridging](https://www.youtube.com/watch?v=W-VXISoKtNc) | ||||
|  | ||||
| ## Thanks | ||||
|   | ||||
| @@ -23,6 +23,7 @@ const ( | ||||
| 	EventRejoinChannels    = "rejoin_channels" | ||||
| 	EventUserAction        = "user_action" | ||||
| 	EventMsgDelete         = "msg_delete" | ||||
| 	EventFileDelete        = "file_delete" | ||||
| 	EventAPIConnected      = "api_connected" | ||||
| 	EventUserTyping        = "user_typing" | ||||
| 	EventGetChannelMembers = "get_channel_members" | ||||
| @@ -56,13 +57,14 @@ func (m Message) ParentValid() bool { | ||||
| } | ||||
|  | ||||
| type FileInfo struct { | ||||
| 	Name    string | ||||
| 	Data    *[]byte | ||||
| 	Comment string | ||||
| 	URL     string | ||||
| 	Size    int64 | ||||
| 	Avatar  bool | ||||
| 	SHA     string | ||||
| 	Name     string | ||||
| 	Data     *[]byte | ||||
| 	Comment  string | ||||
| 	URL      string | ||||
| 	Size     int64 | ||||
| 	Avatar   bool | ||||
| 	SHA      string | ||||
| 	NativeID string | ||||
| } | ||||
|  | ||||
| type ChannelInfo struct { | ||||
| @@ -168,7 +170,7 @@ type Protocol struct { | ||||
| 	UseTLS                 bool       // IRC | ||||
| 	UseDiscriminator       bool       // discord | ||||
| 	UseFirstName           bool       // telegram | ||||
| 	UseUserName            bool       // discord, matrix | ||||
| 	UseUserName            bool       // discord, matrix, mattermost | ||||
| 	UseInsecureURL         bool       // telegram | ||||
| 	UserName               string     // IRC | ||||
| 	VerboseJoinPart        bool       // IRC | ||||
|   | ||||
| @@ -10,10 +10,14 @@ import ( | ||||
| 	"github.com/42wim/matterbridge/bridge/config" | ||||
| 	"github.com/42wim/matterbridge/bridge/discord/transmitter" | ||||
| 	"github.com/42wim/matterbridge/bridge/helper" | ||||
| 	"github.com/matterbridge/discordgo" | ||||
| 	"github.com/bwmarrin/discordgo" | ||||
| 	lru "github.com/hashicorp/golang-lru" | ||||
| ) | ||||
|  | ||||
| const MessageLength = 1950 | ||||
| const ( | ||||
| 	MessageLength = 1950 | ||||
| 	cFileUpload   = "file_upload" | ||||
| ) | ||||
|  | ||||
| type Bdiscord struct { | ||||
| 	*bridge.Config | ||||
| @@ -35,10 +39,20 @@ type Bdiscord struct { | ||||
| 	// Webhook specific logic | ||||
| 	useAutoWebhooks bool | ||||
| 	transmitter     *transmitter.Transmitter | ||||
| 	cache           *lru.Cache | ||||
| } | ||||
|  | ||||
| func New(cfg *bridge.Config) bridge.Bridger { | ||||
| 	b := &Bdiscord{Config: cfg} | ||||
| 	newCache, err := lru.New(5000) | ||||
| 	if err != nil { | ||||
| 		cfg.Log.Fatalf("Could not create LRU cache: %v", err) | ||||
| 	} | ||||
|  | ||||
| 	b := &Bdiscord{ | ||||
| 		Config: cfg, | ||||
| 		cache:  newCache, | ||||
| 	} | ||||
|  | ||||
| 	b.userMemberMap = make(map[string]*discordgo.Member) | ||||
| 	b.nickMemberMap = make(map[string]*discordgo.Member) | ||||
| 	b.channelInfoMap = make(map[string]*config.ChannelInfo) | ||||
| @@ -75,6 +89,9 @@ func (b *Bdiscord) Connect() error { | ||||
| 	b.c.AddHandler(b.messageDeleteBulk) | ||||
| 	b.c.AddHandler(b.memberAdd) | ||||
| 	b.c.AddHandler(b.memberRemove) | ||||
| 	if b.GetInt("debuglevel") == 1 { | ||||
| 		b.c.AddHandler(b.messageEvent) | ||||
| 	} | ||||
| 	// Add privileged intent for guild member tracking. This is needed to track nicks | ||||
| 	// for display names and @mention translation | ||||
| 	b.c.Identify.Intents = discordgo.MakeIntent(discordgo.IntentsAllWithoutPrivileged | | ||||
| @@ -153,7 +170,7 @@ func (b *Bdiscord) Connect() error { | ||||
| 		return fmt.Errorf("use of removed WebhookURL setting") | ||||
| 	} | ||||
|  | ||||
| 	if b.GetInt("debuglevel") > 0 { | ||||
| 	if b.GetInt("debuglevel") == 2 { | ||||
| 		b.Log.Debug("enabling even more discord debug") | ||||
| 		b.c.Debug = true | ||||
| 	} | ||||
| @@ -280,6 +297,21 @@ func (b *Bdiscord) handleEventBotUser(msg *config.Message, channelID string) (st | ||||
| 		return "", err | ||||
| 	} | ||||
|  | ||||
| 	// Delete a file | ||||
| 	if msg.Event == config.EventFileDelete { | ||||
| 		if msg.ID == "" { | ||||
| 			return "", nil | ||||
| 		} | ||||
|  | ||||
| 		if fi, ok := b.cache.Get(cFileUpload + msg.ID); ok { | ||||
| 			err := b.c.ChannelMessageDelete(channelID, fi.(string)) // nolint:forcetypeassert | ||||
| 			b.cache.Remove(cFileUpload + msg.ID) | ||||
| 			return "", err | ||||
| 		} | ||||
|  | ||||
| 		return "", fmt.Errorf("file %s not found", msg.ID) | ||||
| 	} | ||||
|  | ||||
| 	// Upload a file if it exists | ||||
| 	if msg.Extra != nil { | ||||
| 		for _, rmsg := range helper.HandleExtra(msg, b.General) { | ||||
| @@ -327,7 +359,6 @@ func (b *Bdiscord) handleEventBotUser(msg *config.Message, channelID string) (st | ||||
|  | ||||
| // handleUploadFile handles native upload of files | ||||
| func (b *Bdiscord) handleUploadFile(msg *config.Message, channelID string) (string, error) { | ||||
| 	var err error | ||||
| 	for _, f := range msg.Extra["file"] { | ||||
| 		fi := f.(config.FileInfo) | ||||
| 		file := discordgo.File{ | ||||
| @@ -340,10 +371,15 @@ func (b *Bdiscord) handleUploadFile(msg *config.Message, channelID string) (stri | ||||
| 			Files:           []*discordgo.File{&file}, | ||||
| 			AllowedMentions: b.getAllowedMentions(), | ||||
| 		} | ||||
| 		_, err = b.c.ChannelMessageSendComplex(channelID, &m) | ||||
| 		res, err := b.c.ChannelMessageSendComplex(channelID, &m) | ||||
| 		if err != nil { | ||||
| 			return "", fmt.Errorf("file upload failed: %s", err) | ||||
| 		} | ||||
|  | ||||
| 		// link file_upload_nativeID (file ID from the original bridge) to our upload id | ||||
| 		// so that we can remove this later when it eg needs to be deleted | ||||
| 		b.cache.Add(cFileUpload+fi.NativeID, res.ID) | ||||
| 	} | ||||
|  | ||||
| 	return "", nil | ||||
| } | ||||
|   | ||||
| @@ -2,7 +2,8 @@ package bdiscord | ||||
|  | ||||
| import ( | ||||
| 	"github.com/42wim/matterbridge/bridge/config" | ||||
| 	"github.com/matterbridge/discordgo" | ||||
| 	"github.com/bwmarrin/discordgo" | ||||
| 	"github.com/davecgh/go-spew/spew" | ||||
| ) | ||||
|  | ||||
| func (b *Bdiscord) messageDelete(s *discordgo.Session, m *discordgo.MessageDelete) { //nolint:unparam | ||||
| @@ -31,6 +32,10 @@ func (b *Bdiscord) messageDeleteBulk(s *discordgo.Session, m *discordgo.MessageD | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func (b *Bdiscord) messageEvent(s *discordgo.Session, m *discordgo.Event) { | ||||
| 	b.Log.Debug(spew.Sdump(m.Struct)) | ||||
| } | ||||
|  | ||||
| func (b *Bdiscord) messageTyping(s *discordgo.Session, m *discordgo.TypingStart) { | ||||
| 	if !b.GetBool("ShowUserTyping") { | ||||
| 		return | ||||
| @@ -51,7 +56,7 @@ func (b *Bdiscord) messageUpdate(s *discordgo.Session, m *discordgo.MessageUpdat | ||||
| 		return | ||||
| 	} | ||||
| 	// only when message is actually edited | ||||
| 	if m.Message.EditedTimestamp != "" { | ||||
| 	if m.Message.EditedTimestamp != nil { | ||||
| 		b.Log.Debugf("Sending edit message") | ||||
| 		m.Content += b.GetString("EditSuffix") | ||||
| 		msg := &discordgo.MessageCreate{ | ||||
| @@ -82,8 +87,9 @@ func (b *Bdiscord) messageCreate(s *discordgo.Session, m *discordgo.MessageCreat | ||||
|  | ||||
| 	rmsg := config.Message{Account: b.Account, Avatar: "https://cdn.discordapp.com/avatars/" + m.Author.ID + "/" + m.Author.Avatar + ".jpg", UserID: m.Author.ID, ID: m.ID} | ||||
|  | ||||
| 	b.Log.Debugf("== Receiving event %#v", m.Message) | ||||
|  | ||||
| 	if m.Content != "" { | ||||
| 		b.Log.Debugf("== Receiving event %#v", m.Message) | ||||
| 		m.Message.Content = b.replaceChannelMentions(m.Message.Content) | ||||
| 		rmsg.Text, err = m.ContentWithMoreMentionsReplaced(b.c) | ||||
| 		if err != nil { | ||||
|   | ||||
| @@ -3,7 +3,7 @@ package bdiscord | ||||
| import ( | ||||
| 	"testing" | ||||
|  | ||||
| 	"github.com/matterbridge/discordgo" | ||||
| 	"github.com/bwmarrin/discordgo" | ||||
| 	"github.com/stretchr/testify/assert" | ||||
| ) | ||||
|  | ||||
|   | ||||
| @@ -6,7 +6,7 @@ import ( | ||||
| 	"strings" | ||||
| 	"unicode" | ||||
|  | ||||
| 	"github.com/matterbridge/discordgo" | ||||
| 	"github.com/bwmarrin/discordgo" | ||||
| ) | ||||
|  | ||||
| func (b *Bdiscord) getAllowedMentions() *discordgo.MessageAllowedMentions { | ||||
|   | ||||
| @@ -20,7 +20,7 @@ import ( | ||||
| 	"sync" | ||||
| 	"time" | ||||
|  | ||||
| 	"github.com/matterbridge/discordgo" | ||||
| 	"github.com/bwmarrin/discordgo" | ||||
| 	log "github.com/sirupsen/logrus" | ||||
| ) | ||||
|  | ||||
|   | ||||
| @@ -1,7 +1,7 @@ | ||||
| package transmitter | ||||
|  | ||||
| import ( | ||||
| 	"github.com/matterbridge/discordgo" | ||||
| 	"github.com/bwmarrin/discordgo" | ||||
| ) | ||||
|  | ||||
| // isDiscordPermissionError returns false for nil, and true if a Discord RESTError with code discordgo.ErrorCodeMissionPermissions | ||||
|   | ||||
| @@ -5,7 +5,7 @@ import ( | ||||
|  | ||||
| 	"github.com/42wim/matterbridge/bridge/config" | ||||
| 	"github.com/42wim/matterbridge/bridge/helper" | ||||
| 	"github.com/matterbridge/discordgo" | ||||
| 	"github.com/bwmarrin/discordgo" | ||||
| ) | ||||
|  | ||||
| // shouldMessageUseWebhooks checks if have a channel specific webhook, if we're not using auto webhooks | ||||
| @@ -82,16 +82,14 @@ func (b *Bdiscord) webhookSend(msg *config.Message, channelID string) (*discordg | ||||
| 				ContentType: "", | ||||
| 				Reader:      bytes.NewReader(*fi.Data), | ||||
| 			} | ||||
| 			content := "" | ||||
| 			if msg.Text == "" { | ||||
| 				content = fi.Comment | ||||
| 			} | ||||
| 			content := fi.Comment | ||||
|  | ||||
| 			_, e2 := b.transmitter.Send( | ||||
| 				channelID, | ||||
| 				&discordgo.WebhookParams{ | ||||
| 					Username:        msg.Username, | ||||
| 					AvatarURL:       msg.Avatar, | ||||
| 					File:            &file, | ||||
| 					Files:           []*discordgo.File{&file}, | ||||
| 					Content:         content, | ||||
| 					AllowedMentions: b.getAllowedMentions(), | ||||
| 				}, | ||||
|   | ||||
							
								
								
									
										252
									
								
								bridge/harmony/harmony.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										252
									
								
								bridge/harmony/harmony.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,252 @@ | ||||
| package harmony | ||||
|  | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	"log" | ||||
| 	"strconv" | ||||
| 	"strings" | ||||
| 	"time" | ||||
|  | ||||
| 	"github.com/42wim/matterbridge/bridge" | ||||
| 	"github.com/42wim/matterbridge/bridge/config" | ||||
| 	"github.com/harmony-development/shibshib" | ||||
| 	chatv1 "github.com/harmony-development/shibshib/gen/chat/v1" | ||||
| 	typesv1 "github.com/harmony-development/shibshib/gen/harmonytypes/v1" | ||||
| 	profilev1 "github.com/harmony-development/shibshib/gen/profile/v1" | ||||
| ) | ||||
|  | ||||
| type cachedProfile struct { | ||||
| 	data        *profilev1.GetProfileResponse | ||||
| 	lastUpdated time.Time | ||||
| } | ||||
|  | ||||
| type Bharmony struct { | ||||
| 	*bridge.Config | ||||
|  | ||||
| 	c            *shibshib.Client | ||||
| 	profileCache map[uint64]cachedProfile | ||||
| } | ||||
|  | ||||
| func uToStr(in uint64) string { | ||||
| 	return strconv.FormatUint(in, 10) | ||||
| } | ||||
|  | ||||
| func strToU(in string) (uint64, error) { | ||||
| 	return strconv.ParseUint(in, 10, 64) | ||||
| } | ||||
|  | ||||
| func New(cfg *bridge.Config) bridge.Bridger { | ||||
| 	b := &Bharmony{ | ||||
| 		Config:       cfg, | ||||
| 		profileCache: map[uint64]cachedProfile{}, | ||||
| 	} | ||||
|  | ||||
| 	return b | ||||
| } | ||||
|  | ||||
| func (b *Bharmony) getProfile(u uint64) (*profilev1.GetProfileResponse, error) { | ||||
| 	if v, ok := b.profileCache[u]; ok && time.Since(v.lastUpdated) < time.Minute*10 { | ||||
| 		return v.data, nil | ||||
| 	} | ||||
|  | ||||
| 	resp, err := b.c.ProfileKit.GetProfile(&profilev1.GetProfileRequest{ | ||||
| 		UserId: u, | ||||
| 	}) | ||||
| 	if err != nil { | ||||
| 		if v, ok := b.profileCache[u]; ok { | ||||
| 			return v.data, nil | ||||
| 		} | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	b.profileCache[u] = cachedProfile{ | ||||
| 		data:        resp, | ||||
| 		lastUpdated: time.Now(), | ||||
| 	} | ||||
| 	return resp, nil | ||||
| } | ||||
|  | ||||
| func (b *Bharmony) avatarFor(m *chatv1.Message) string { | ||||
| 	if m.Overrides != nil { | ||||
| 		return m.Overrides.GetAvatar() | ||||
| 	} | ||||
|  | ||||
| 	profi, err := b.getProfile(m.AuthorId) | ||||
| 	if err != nil { | ||||
| 		return "" | ||||
| 	} | ||||
|  | ||||
| 	return b.c.TransformHMCURL(profi.Profile.GetUserAvatar()) | ||||
| } | ||||
|  | ||||
| func (b *Bharmony) usernameFor(m *chatv1.Message) string { | ||||
| 	if m.Overrides != nil { | ||||
| 		return m.Overrides.GetUsername() | ||||
| 	} | ||||
|  | ||||
| 	profi, err := b.getProfile(m.AuthorId) | ||||
| 	if err != nil { | ||||
| 		return "" | ||||
| 	} | ||||
|  | ||||
| 	return profi.Profile.UserName | ||||
| } | ||||
|  | ||||
| func (b *Bharmony) toMessage(msg *shibshib.LocatedMessage) config.Message { | ||||
| 	message := config.Message{} | ||||
| 	message.Account = b.Account | ||||
| 	message.UserID = uToStr(msg.Message.AuthorId) | ||||
| 	message.Avatar = b.avatarFor(msg.Message) | ||||
| 	message.Username = b.usernameFor(msg.Message) | ||||
| 	message.Channel = uToStr(msg.ChannelID) | ||||
| 	message.ID = uToStr(msg.MessageId) | ||||
|  | ||||
| 	switch content := msg.Message.Content.Content.(type) { | ||||
| 	case *chatv1.Content_EmbedMessage: | ||||
| 		message.Text = "Embed" | ||||
| 	case *chatv1.Content_AttachmentMessage: | ||||
| 		var s strings.Builder | ||||
| 		for idx, attach := range content.AttachmentMessage.Files { | ||||
| 			s.WriteString(b.c.TransformHMCURL(attach.Id)) | ||||
| 			if idx < len(content.AttachmentMessage.Files)-1 { | ||||
| 				s.WriteString(", ") | ||||
| 			} | ||||
| 		} | ||||
| 		message.Text = s.String() | ||||
| 	case *chatv1.Content_PhotoMessage: | ||||
| 		var s strings.Builder | ||||
| 		for idx, attach := range content.PhotoMessage.GetPhotos() { | ||||
| 			s.WriteString(attach.GetCaption().GetText()) | ||||
| 			s.WriteString("\n") | ||||
| 			s.WriteString(b.c.TransformHMCURL(attach.GetHmc())) | ||||
| 			if idx < len(content.PhotoMessage.GetPhotos())-1 { | ||||
| 				s.WriteString("\n\n") | ||||
| 			} | ||||
| 		} | ||||
| 		message.Text = s.String() | ||||
| 	case *chatv1.Content_TextMessage: | ||||
| 		message.Text = content.TextMessage.Content.Text | ||||
| 	} | ||||
|  | ||||
| 	return message | ||||
| } | ||||
|  | ||||
| func (b *Bharmony) outputMessages() { | ||||
| 	for { | ||||
| 		msg := <-b.c.EventsStream() | ||||
|  | ||||
| 		if msg.Message.AuthorId == b.c.UserID { | ||||
| 			continue | ||||
| 		} | ||||
|  | ||||
| 		b.Remote <- b.toMessage(msg) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func (b *Bharmony) GetUint64(conf string) uint64 { | ||||
| 	num, err := strToU(b.GetString(conf)) | ||||
| 	if err != nil { | ||||
| 		log.Fatal(err) | ||||
| 	} | ||||
|  | ||||
| 	return num | ||||
| } | ||||
|  | ||||
| func (b *Bharmony) Connect() (err error) { | ||||
| 	b.c, err = shibshib.NewClient(b.GetString("Homeserver"), b.GetString("Token"), b.GetUint64("UserID")) | ||||
| 	if err != nil { | ||||
| 		return | ||||
| 	} | ||||
| 	b.c.SubscribeToGuild(b.GetUint64("Community")) | ||||
|  | ||||
| 	go b.outputMessages() | ||||
|  | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| func (b *Bharmony) send(msg config.Message) (id string, err error) { | ||||
| 	msgChan, err := strToU(msg.Channel) | ||||
| 	if err != nil { | ||||
| 		return | ||||
| 	} | ||||
|  | ||||
| 	retID, err := b.c.ChatKit.SendMessage(&chatv1.SendMessageRequest{ | ||||
| 		GuildId:   b.GetUint64("Community"), | ||||
| 		ChannelId: msgChan, | ||||
| 		Content: &chatv1.Content{ | ||||
| 			Content: &chatv1.Content_TextMessage{ | ||||
| 				TextMessage: &chatv1.Content_TextContent{ | ||||
| 					Content: &chatv1.FormattedText{ | ||||
| 						Text: msg.Text, | ||||
| 					}, | ||||
| 				}, | ||||
| 			}, | ||||
| 		}, | ||||
| 		Overrides: &chatv1.Overrides{ | ||||
| 			Username: &msg.Username, | ||||
| 			Avatar:   &msg.Avatar, | ||||
| 			Reason:   &chatv1.Overrides_Bridge{Bridge: &typesv1.Empty{}}, | ||||
| 		}, | ||||
| 		InReplyTo: nil, | ||||
| 		EchoId:    nil, | ||||
| 		Metadata:  nil, | ||||
| 	}) | ||||
| 	if err != nil { | ||||
| 		err = fmt.Errorf("send: error sending message: %w", err) | ||||
| 		log.Println(err.Error()) | ||||
| 	} | ||||
|  | ||||
| 	return uToStr(retID.MessageId), err | ||||
| } | ||||
|  | ||||
| func (b *Bharmony) delete(msg config.Message) (id string, err error) { | ||||
| 	msgChan, err := strToU(msg.Channel) | ||||
| 	if err != nil { | ||||
| 		return "", err | ||||
| 	} | ||||
|  | ||||
| 	msgID, err := strToU(msg.ID) | ||||
| 	if err != nil { | ||||
| 		return "", err | ||||
| 	} | ||||
|  | ||||
| 	_, err = b.c.ChatKit.DeleteMessage(&chatv1.DeleteMessageRequest{ | ||||
| 		GuildId:   b.GetUint64("Community"), | ||||
| 		ChannelId: msgChan, | ||||
| 		MessageId: msgID, | ||||
| 	}) | ||||
| 	return "", err | ||||
| } | ||||
|  | ||||
| func (b *Bharmony) typing(msg config.Message) (id string, err error) { | ||||
| 	msgChan, err := strToU(msg.Channel) | ||||
| 	if err != nil { | ||||
| 		return "", err | ||||
| 	} | ||||
|  | ||||
| 	_, err = b.c.ChatKit.Typing(&chatv1.TypingRequest{ | ||||
| 		GuildId:   b.GetUint64("Community"), | ||||
| 		ChannelId: msgChan, | ||||
| 	}) | ||||
| 	return "", err | ||||
| } | ||||
|  | ||||
| func (b *Bharmony) Send(msg config.Message) (id string, err error) { | ||||
| 	switch msg.Event { | ||||
| 	case "": | ||||
| 		return b.send(msg) | ||||
| 	case config.EventMsgDelete: | ||||
| 		return b.delete(msg) | ||||
| 	case config.EventUserTyping: | ||||
| 		return b.typing(msg) | ||||
| 	default: | ||||
| 		return "", nil | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func (b *Bharmony) JoinChannel(channel config.ChannelInfo) error { | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| func (b *Bharmony) Disconnect() error { | ||||
| 	return nil | ||||
| } | ||||
| @@ -168,17 +168,23 @@ func HandleDownloadSize(logger *logrus.Entry, msg *config.Message, name string, | ||||
|  | ||||
| // HandleDownloadData adds the data for a remote file into a Matterbridge gateway message. | ||||
| func HandleDownloadData(logger *logrus.Entry, msg *config.Message, name, comment, url string, data *[]byte, general *config.Protocol) { | ||||
| 	HandleDownloadData2(logger, msg, name, "", comment, url, data, general) | ||||
| } | ||||
|  | ||||
| // HandleDownloadData adds the data for a remote file into a Matterbridge gateway message. | ||||
| func HandleDownloadData2(logger *logrus.Entry, msg *config.Message, name, id, comment, url string, data *[]byte, general *config.Protocol) { | ||||
| 	var avatar bool | ||||
| 	logger.Debugf("Download OK %#v %#v", name, len(*data)) | ||||
| 	if msg.Event == config.EventAvatarDownload { | ||||
| 		avatar = true | ||||
| 	} | ||||
| 	msg.Extra["file"] = append(msg.Extra["file"], config.FileInfo{ | ||||
| 		Name:    name, | ||||
| 		Data:    data, | ||||
| 		URL:     url, | ||||
| 		Comment: comment, | ||||
| 		Avatar:  avatar, | ||||
| 		Name:     name, | ||||
| 		Data:     data, | ||||
| 		URL:      url, | ||||
| 		Comment:  comment, | ||||
| 		Avatar:   avatar, | ||||
| 		NativeID: id, | ||||
| 	}) | ||||
| } | ||||
|  | ||||
|   | ||||
							
								
								
									
										32
									
								
								bridge/irc/charset.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								bridge/irc/charset.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,32 @@ | ||||
| package birc | ||||
|  | ||||
| import ( | ||||
| 	"golang.org/x/text/encoding" | ||||
| 	"golang.org/x/text/encoding/japanese" | ||||
| 	"golang.org/x/text/encoding/korean" | ||||
| 	"golang.org/x/text/encoding/simplifiedchinese" | ||||
| 	"golang.org/x/text/encoding/traditionalchinese" | ||||
| 	"golang.org/x/text/encoding/unicode" | ||||
| ) | ||||
|  | ||||
| var encoders = map[string]encoding.Encoding{ | ||||
| 	"utf-8":       unicode.UTF8, | ||||
| 	"iso-2022-jp": japanese.ISO2022JP, | ||||
| 	"big5":        traditionalchinese.Big5, | ||||
| 	"gbk":         simplifiedchinese.GBK, | ||||
| 	"euc-kr":      korean.EUCKR, | ||||
| 	"gb2312":      simplifiedchinese.HZGB2312, | ||||
| 	"shift-jis":   japanese.ShiftJIS, | ||||
| 	"euc-jp":      japanese.EUCJP, | ||||
| 	"gb18030":     simplifiedchinese.GB18030, | ||||
| } | ||||
|  | ||||
| func toUTF8(from string, input string) string { | ||||
| 	enc, ok := encoders[from] | ||||
| 	if !ok { | ||||
| 		return input | ||||
| 	} | ||||
|  | ||||
| 	res, _ := enc.NewDecoder().String(input) | ||||
| 	return res | ||||
| } | ||||
| @@ -11,7 +11,6 @@ import ( | ||||
| 	"github.com/42wim/matterbridge/bridge/config" | ||||
| 	"github.com/42wim/matterbridge/bridge/helper" | ||||
| 	"github.com/lrstanley/girc" | ||||
| 	"github.com/missdeer/golib/ic" | ||||
| 	"github.com/paulrosania/go-charset/charset" | ||||
| 	"github.com/saintfish/chardet" | ||||
|  | ||||
| @@ -24,12 +23,12 @@ func (b *Birc) handleCharset(msg *config.Message) error { | ||||
| 	if b.GetString("Charset") != "" { | ||||
| 		switch b.GetString("Charset") { | ||||
| 		case "gbk", "gb18030", "gb2312", "big5", "euc-kr", "euc-jp", "shift-jis", "iso-2022-jp": | ||||
| 			msg.Text = ic.ConvertString("utf-8", b.GetString("Charset"), msg.Text) | ||||
| 			msg.Text = toUTF8(b.GetString("Charset"), msg.Text) | ||||
| 		default: | ||||
| 			buf := new(bytes.Buffer) | ||||
| 			w, err := charset.NewWriter(b.GetString("Charset"), buf) | ||||
| 			if err != nil { | ||||
| 				b.Log.Errorf("charset from utf-8 conversion failed: %s", err) | ||||
| 				b.Log.Errorf("charset to utf-8 conversion failed: %s", err) | ||||
| 				return err | ||||
| 			} | ||||
| 			fmt.Fprint(w, msg.Text) | ||||
| @@ -227,7 +226,7 @@ func (b *Birc) handlePrivMsg(client *girc.Client, event girc.Event) { | ||||
| 	} | ||||
| 	switch mycharset { | ||||
| 	case "gbk", "gb18030", "gb2312", "big5", "euc-kr", "euc-jp", "shift-jis", "iso-2022-jp": | ||||
| 		rmsg.Text = ic.ConvertString("utf-8", b.GetString("Charset"), rmsg.Text) | ||||
| 		rmsg.Text = toUTF8(b.GetString("Charset"), rmsg.Text) | ||||
| 	default: | ||||
| 		r, err := charset.NewReader(mycharset, strings.NewReader(rmsg.Text)) | ||||
| 		if err != nil { | ||||
|   | ||||
| @@ -2,6 +2,7 @@ package birc | ||||
|  | ||||
| import ( | ||||
| 	"crypto/tls" | ||||
| 	"errors" | ||||
| 	"fmt" | ||||
| 	"hash/crc32" | ||||
| 	"io/ioutil" | ||||
| @@ -72,6 +73,10 @@ func (b *Birc) Command(msg *config.Message) string { | ||||
| } | ||||
|  | ||||
| func (b *Birc) Connect() error { | ||||
| 	if b.GetBool("UseSASL") && b.GetString("TLSClientCertificate") != "" { | ||||
| 		return errors.New("you can't enable SASL and TLSClientCertificate at the same time") | ||||
| 	} | ||||
|  | ||||
| 	b.Local = make(chan config.Message, b.MessageQueue+10) | ||||
| 	b.Log.Infof("Connecting %s", b.GetString("Server")) | ||||
|  | ||||
| @@ -300,6 +305,11 @@ func (b *Birc) getClient() (*girc.Client, error) { | ||||
|  | ||||
| 	b.Log.Debugf("setting pingdelay to %s", pingDelay) | ||||
|  | ||||
| 	tlsConfig, err := b.getTLSConfig() | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	i := girc.New(girc.Config{ | ||||
| 		Server:     server, | ||||
| 		ServerPass: b.GetString("Password"), | ||||
| @@ -308,7 +318,8 @@ func (b *Birc) getClient() (*girc.Client, error) { | ||||
| 		User:       user, | ||||
| 		Name:       realName, | ||||
| 		SSL:        b.GetBool("UseTLS"), | ||||
| 		TLSConfig:  &tls.Config{InsecureSkipVerify: b.GetBool("SkipTLSVerify"), ServerName: server}, //nolint:gosec | ||||
| 		Bind:       b.GetString("Bind"), | ||||
| 		TLSConfig:  tlsConfig, | ||||
| 		PingDelay:  pingDelay, | ||||
| 		// skip gIRC internal rate limiting, since we have our own throttling | ||||
| 		AllowFlood:    true, | ||||
| @@ -351,8 +362,10 @@ func (b *Birc) skipPrivMsg(event girc.Event) bool { | ||||
| 		return true | ||||
| 	} | ||||
| 	// don't forward message from ourself | ||||
| 	if event.Source.Name == b.Nick { | ||||
| 		return true | ||||
| 	if event.Source != nil { | ||||
| 		if event.Source.Name == b.Nick { | ||||
| 			return true | ||||
| 		} | ||||
| 	} | ||||
| 	// don't forward messages we sent via RELAYMSG | ||||
| 	if relayedNick, ok := event.Tags.Get("draft/relaymsg"); ok && relayedNick == b.Nick { | ||||
| @@ -380,3 +393,23 @@ func (b *Birc) storeNames(client *girc.Client, event girc.Event) { | ||||
| func (b *Birc) formatnicks(nicks []string) string { | ||||
| 	return strings.Join(nicks, ", ") + " currently on IRC" | ||||
| } | ||||
|  | ||||
| func (b *Birc) getTLSConfig() (*tls.Config, error) { | ||||
| 	server, _, _ := net.SplitHostPort(b.GetString("server")) | ||||
|  | ||||
| 	tlsConfig := &tls.Config{ | ||||
| 		InsecureSkipVerify: b.GetBool("skiptlsverify"), //nolint:gosec | ||||
| 		ServerName:         server, | ||||
| 	} | ||||
|  | ||||
| 	if filename := b.GetString("TLSClientCertificate"); filename != "" { | ||||
| 		cert, err := tls.LoadX509KeyPair(filename, filename) | ||||
| 		if err != nil { | ||||
| 			return nil, err | ||||
| 		} | ||||
|  | ||||
| 		tlsConfig.Certificates = []tls.Certificate{cert} | ||||
| 	} | ||||
|  | ||||
| 	return tlsConfig, nil | ||||
| } | ||||
|   | ||||
| @@ -48,8 +48,10 @@ type matrixUsername struct { | ||||
|  | ||||
| // SubTextMessage represents the new content of the message in edit messages. | ||||
| type SubTextMessage struct { | ||||
| 	MsgType string `json:"msgtype"` | ||||
| 	Body    string `json:"body"` | ||||
| 	MsgType       string `json:"msgtype"` | ||||
| 	Body          string `json:"body"` | ||||
| 	FormattedBody string `json:"formatted_body,omitempty"` | ||||
| 	Format        string `json:"format,omitempty"` | ||||
| } | ||||
|  | ||||
| // MessageRelation explains how the current message relates to a previous message. | ||||
| @@ -65,6 +67,19 @@ type EditedMessage struct { | ||||
| 	matrix.TextMessage | ||||
| } | ||||
|  | ||||
| type InReplyToRelationContent struct { | ||||
| 	EventID string `json:"event_id"` | ||||
| } | ||||
|  | ||||
| type InReplyToRelation struct { | ||||
| 	InReplyTo InReplyToRelationContent `json:"m.in_reply_to"` | ||||
| } | ||||
|  | ||||
| type ReplyMessage struct { | ||||
| 	RelatedTo InReplyToRelation `json:"m.relates_to"` | ||||
| 	matrix.TextMessage | ||||
| } | ||||
|  | ||||
| func New(cfg *bridge.Config) bridge.Bridger { | ||||
| 	b := &Bmatrix{Config: cfg} | ||||
| 	b.RoomMap = make(map[string]string) | ||||
| @@ -138,7 +153,13 @@ func (b *Bmatrix) Send(msg config.Message) (string, error) { | ||||
| 		m := matrix.TextMessage{ | ||||
| 			MsgType:       "m.emote", | ||||
| 			Body:          username.plain + msg.Text, | ||||
| 			FormattedBody: username.formatted + msg.Text, | ||||
| 			FormattedBody: username.formatted + helper.ParseMarkdown(msg.Text), | ||||
| 			Format:        "org.matrix.custom.html", | ||||
| 		} | ||||
|  | ||||
| 		if b.GetBool("HTMLDisable") { | ||||
| 			m.Format = "" | ||||
| 			m.FormattedBody = "" | ||||
| 		} | ||||
|  | ||||
| 		msgID := "" | ||||
| @@ -201,20 +222,29 @@ func (b *Bmatrix) Send(msg config.Message) (string, error) { | ||||
|  | ||||
| 	// Edit message if we have an ID | ||||
| 	if msg.ID != "" { | ||||
| 		rmsg := EditedMessage{TextMessage: matrix.TextMessage{ | ||||
| 			Body:    username.plain + msg.Text, | ||||
| 			MsgType: "m.text", | ||||
| 		}} | ||||
| 		if b.GetBool("HTMLDisable") { | ||||
| 			rmsg.TextMessage.FormattedBody = username.formatted + "* " + msg.Text | ||||
| 		} else { | ||||
| 			rmsg.Format = "org.matrix.custom.html" | ||||
| 			rmsg.TextMessage.FormattedBody = username.formatted + "* " + helper.ParseMarkdown(msg.Text) | ||||
| 		rmsg := EditedMessage{ | ||||
| 			TextMessage: matrix.TextMessage{ | ||||
| 				Body:          username.plain + msg.Text, | ||||
| 				MsgType:       "m.text", | ||||
| 				Format:        "org.matrix.custom.html", | ||||
| 				FormattedBody: username.formatted + helper.ParseMarkdown(msg.Text), | ||||
| 			}, | ||||
| 		} | ||||
|  | ||||
| 		rmsg.NewContent = SubTextMessage{ | ||||
| 			Body:    rmsg.TextMessage.Body, | ||||
| 			MsgType: "m.text", | ||||
| 			Body:          rmsg.TextMessage.Body, | ||||
| 			FormattedBody: rmsg.TextMessage.FormattedBody, | ||||
| 			Format:        rmsg.TextMessage.Format, | ||||
| 			MsgType:       "m.text", | ||||
| 		} | ||||
|  | ||||
| 		if b.GetBool("HTMLDisable") { | ||||
| 			rmsg.TextMessage.Format = "" | ||||
| 			rmsg.TextMessage.FormattedBody = "" | ||||
| 			rmsg.NewContent.Format = "" | ||||
| 			rmsg.NewContent.FormattedBody = "" | ||||
| 		} | ||||
|  | ||||
| 		rmsg.RelatedTo = MessageRelation{ | ||||
| 			EventID: msg.ID, | ||||
| 			Type:    "m.replace", | ||||
| @@ -238,6 +268,50 @@ func (b *Bmatrix) Send(msg config.Message) (string, error) { | ||||
| 			MsgType:       "m.notice", | ||||
| 			Body:          username.plain + msg.Text, | ||||
| 			FormattedBody: username.formatted + msg.Text, | ||||
| 			Format:        "org.matrix.custom.html", | ||||
| 		} | ||||
|  | ||||
| 		if b.GetBool("HTMLDisable") { | ||||
| 			m.Format = "" | ||||
| 			m.FormattedBody = "" | ||||
| 		} | ||||
|  | ||||
| 		var ( | ||||
| 			resp *matrix.RespSendEvent | ||||
| 			err  error | ||||
| 		) | ||||
|  | ||||
| 		err = b.retry(func() error { | ||||
| 			resp, err = b.mc.SendMessageEvent(channel, "m.room.message", m) | ||||
|  | ||||
| 			return err | ||||
| 		}) | ||||
| 		if err != nil { | ||||
| 			return "", err | ||||
| 		} | ||||
|  | ||||
| 		return resp.EventID, err | ||||
| 	} | ||||
|  | ||||
| 	if msg.ParentValid() { | ||||
| 		m := ReplyMessage{ | ||||
| 			TextMessage: matrix.TextMessage{ | ||||
| 				MsgType:       "m.text", | ||||
| 				Body:          username.plain + msg.Text, | ||||
| 				FormattedBody: username.formatted + helper.ParseMarkdown(msg.Text), | ||||
| 				Format:        "org.matrix.custom.html", | ||||
| 			}, | ||||
| 		} | ||||
|  | ||||
| 		if b.GetBool("HTMLDisable") { | ||||
| 			m.TextMessage.Format = "" | ||||
| 			m.TextMessage.FormattedBody = "" | ||||
| 		} | ||||
|  | ||||
| 		m.RelatedTo = InReplyToRelation{ | ||||
| 			InReplyTo: InReplyToRelationContent{ | ||||
| 				EventID: msg.ParentID, | ||||
| 			}, | ||||
| 		} | ||||
|  | ||||
| 		var ( | ||||
| @@ -301,6 +375,9 @@ func (b *Bmatrix) handlematrix() { | ||||
| 	syncer.OnEventType("m.room.member", b.handleMemberChange) | ||||
| 	go func() { | ||||
| 		for { | ||||
| 			if b == nil { | ||||
| 				return | ||||
| 			} | ||||
| 			if err := b.mc.Sync(); err != nil { | ||||
| 				b.Log.Println("Sync() returned ", err) | ||||
| 			} | ||||
| @@ -338,6 +415,35 @@ func (b *Bmatrix) handleEdit(ev *matrix.Event, rmsg config.Message) bool { | ||||
| 	return true | ||||
| } | ||||
|  | ||||
| func (b *Bmatrix) handleReply(ev *matrix.Event, rmsg config.Message) bool { | ||||
| 	relationInterface, present := ev.Content["m.relates_to"] | ||||
| 	if !present { | ||||
| 		return false | ||||
| 	} | ||||
|  | ||||
| 	var relation InReplyToRelation | ||||
| 	if err := interface2Struct(relationInterface, &relation); err != nil { | ||||
| 		// probably fine | ||||
| 		return false | ||||
| 	} | ||||
|  | ||||
| 	body := rmsg.Text | ||||
| 	for strings.HasPrefix(body, "> ") { | ||||
| 		lineIdx := strings.IndexRune(body, '\n') | ||||
| 		if lineIdx == -1 { | ||||
| 			body = "" | ||||
| 		} else { | ||||
| 			body = body[(lineIdx + 1):] | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	rmsg.Text = body | ||||
| 	rmsg.ParentID = relation.InReplyTo.EventID | ||||
| 	b.Remote <- rmsg | ||||
|  | ||||
| 	return true | ||||
| } | ||||
|  | ||||
| func (b *Bmatrix) handleMemberChange(ev *matrix.Event) { | ||||
| 	// Update the displayname on join messages, according to https://matrix.org/docs/spec/client_server/r0.6.1#events-on-change-of-profile-information | ||||
| 	if ev.Content["membership"] == "join" { | ||||
| @@ -400,6 +506,11 @@ func (b *Bmatrix) handleEvent(ev *matrix.Event) { | ||||
| 			return | ||||
| 		} | ||||
|  | ||||
| 		// Is it a reply? | ||||
| 		if b.handleReply(ev, rmsg) { | ||||
| 			return | ||||
| 		} | ||||
|  | ||||
| 		// Do we have attachments | ||||
| 		if b.containsAttachment(ev.Content) { | ||||
| 			err := b.handleDownloadFile(&rmsg, ev.Content) | ||||
|   | ||||
| @@ -140,9 +140,14 @@ func (b *Bmattermost) handleMatterClient(messages chan *config.Message) { | ||||
| 			continue | ||||
| 		} | ||||
|  | ||||
| 		channelName := b.getChannelName(message.Post.ChannelId) | ||||
| 		if channelName == "" { | ||||
| 			channelName = message.Channel | ||||
| 		} | ||||
|  | ||||
| 		// only download avatars if we have a place to upload them (configured mediaserver) | ||||
| 		if b.General.MediaServerUpload != "" || b.General.MediaDownloadPath != "" { | ||||
| 			b.handleDownloadAvatar(message.UserID, message.Channel) | ||||
| 			b.handleDownloadAvatar(message.UserID, channelName) | ||||
| 		} | ||||
|  | ||||
| 		b.Log.Debugf("== Receiving event %#v", message) | ||||
| @@ -150,7 +155,7 @@ func (b *Bmattermost) handleMatterClient(messages chan *config.Message) { | ||||
| 		rmsg := &config.Message{ | ||||
| 			Username: message.Username, | ||||
| 			UserID:   message.UserID, | ||||
| 			Channel:  message.Channel, | ||||
| 			Channel:  channelName, | ||||
| 			Text:     message.Text, | ||||
| 			ID:       message.Post.Id, | ||||
| 			ParentID: message.Post.RootId, // ParentID is obsolete with mattermost | ||||
| @@ -177,8 +182,10 @@ func (b *Bmattermost) handleMatterClient(messages chan *config.Message) { | ||||
| 		} | ||||
|  | ||||
| 		// Use nickname instead of username if defined | ||||
| 		if nick := b.mc.GetNickName(rmsg.UserID); nick != "" { | ||||
| 			rmsg.Username = nick | ||||
| 		if !b.GetBool("useusername") { | ||||
| 			if nick := b.mc.GetNickName(rmsg.UserID); nick != "" { | ||||
| 				rmsg.Username = nick | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| 		messages <- rmsg | ||||
| @@ -188,16 +195,21 @@ func (b *Bmattermost) handleMatterClient(messages chan *config.Message) { | ||||
| // nolint:cyclop | ||||
| func (b *Bmattermost) handleMatterClient6(messages chan *config.Message) { | ||||
| 	for message := range b.mc6.MessageChan { | ||||
| 		b.Log.Debugf("%#v", message.Raw.GetData()) | ||||
| 		b.Log.Debugf("%#v %#v", message.Raw.GetData(), message.Raw.EventType()) | ||||
|  | ||||
| 		if b.skipMessage6(message) { | ||||
| 			b.Log.Debugf("Skipped message: %#v", message) | ||||
| 			continue | ||||
| 		} | ||||
|  | ||||
| 		channelName := b.getChannelName(message.Post.ChannelId) | ||||
| 		if channelName == "" { | ||||
| 			channelName = message.Channel | ||||
| 		} | ||||
|  | ||||
| 		// only download avatars if we have a place to upload them (configured mediaserver) | ||||
| 		if b.General.MediaServerUpload != "" || b.General.MediaDownloadPath != "" { | ||||
| 			b.handleDownloadAvatar(message.UserID, message.Channel) | ||||
| 			b.handleDownloadAvatar(message.UserID, channelName) | ||||
| 		} | ||||
|  | ||||
| 		b.Log.Debugf("== Receiving event %#v", message) | ||||
| @@ -205,7 +217,7 @@ func (b *Bmattermost) handleMatterClient6(messages chan *config.Message) { | ||||
| 		rmsg := &config.Message{ | ||||
| 			Username: message.Username, | ||||
| 			UserID:   message.UserID, | ||||
| 			Channel:  message.Channel, | ||||
| 			Channel:  channelName, | ||||
| 			Text:     message.Text, | ||||
| 			ID:       message.Post.Id, | ||||
| 			ParentID: message.Post.RootId, // ParentID is obsolete with mattermost | ||||
| @@ -232,8 +244,10 @@ func (b *Bmattermost) handleMatterClient6(messages chan *config.Message) { | ||||
| 		} | ||||
|  | ||||
| 		// Use nickname instead of username if defined | ||||
| 		if nick := b.mc6.GetNickName(rmsg.UserID); nick != "" { | ||||
| 			rmsg.Username = nick | ||||
| 		if !b.GetBool("useusername") { | ||||
| 			if nick := b.mc6.GetNickName(rmsg.UserID); nick != "" { | ||||
| 				rmsg.Username = nick | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| 		messages <- rmsg | ||||
| @@ -244,6 +258,7 @@ func (b *Bmattermost) handleMatterHook(messages chan *config.Message) { | ||||
| 	for { | ||||
| 		message := b.mh.Receive() | ||||
| 		b.Log.Debugf("Receiving from matterhook %#v", message) | ||||
|  | ||||
| 		messages <- &config.Message{ | ||||
| 			UserID:   message.UserID, | ||||
| 			Username: message.UserName, | ||||
| @@ -261,7 +276,7 @@ func (b *Bmattermost) handleUploadFile(msg *config.Message) (string, error) { | ||||
|  | ||||
| 	var err error | ||||
| 	var res, id string | ||||
| 	channelID := b.mc.GetChannelId(msg.Channel, b.TeamID) | ||||
| 	channelID := b.getChannelID(msg.Channel) | ||||
| 	for _, f := range msg.Extra["file"] { | ||||
| 		fi := f.(config.FileInfo) | ||||
| 		id, err = b.mc.UploadFile(*fi.Data, channelID, fi.Name) | ||||
| @@ -281,7 +296,7 @@ func (b *Bmattermost) handleUploadFile(msg *config.Message) (string, error) { | ||||
| func (b *Bmattermost) handleUploadFile6(msg *config.Message) (string, error) { | ||||
| 	var err error | ||||
| 	var res, id string | ||||
| 	channelID := b.mc6.GetChannelID(msg.Channel, b.TeamID) | ||||
| 	channelID := b.getChannelID(msg.Channel) | ||||
| 	for _, f := range msg.Extra["file"] { | ||||
| 		fi := f.(config.FileInfo) | ||||
| 		id, err = b.mc6.UploadFile(*fi.Data, channelID, fi.Name) | ||||
|   | ||||
| @@ -241,11 +241,17 @@ func (b *Bmattermost) skipMessage(message *matterclient.Message) bool { | ||||
| 		if b.GetBool("nosendjoinpart") { | ||||
| 			return true | ||||
| 		} | ||||
|  | ||||
| 		channelName := b.getChannelName(message.Post.ChannelId) | ||||
| 		if channelName == "" { | ||||
| 			channelName = message.Channel | ||||
| 		} | ||||
|  | ||||
| 		b.Log.Debugf("Sending JOIN_LEAVE event from %s to gateway", b.Account) | ||||
| 		b.Remote <- config.Message{ | ||||
| 			Username: "system", | ||||
| 			Text:     message.Text, | ||||
| 			Channel:  message.Channel, | ||||
| 			Channel:  channelName, | ||||
| 			Account:  b.Account, | ||||
| 			Event:    config.EventJoinLeave, | ||||
| 		} | ||||
| @@ -304,11 +310,17 @@ func (b *Bmattermost) skipMessage6(message *matterclient6.Message) bool { | ||||
| 		if b.GetBool("nosendjoinpart") { | ||||
| 			return true | ||||
| 		} | ||||
|  | ||||
| 		channelName := b.getChannelName(message.Post.ChannelId) | ||||
| 		if channelName == "" { | ||||
| 			channelName = message.Channel | ||||
| 		} | ||||
|  | ||||
| 		b.Log.Debugf("Sending JOIN_LEAVE event from %s to gateway", b.Account) | ||||
| 		b.Remote <- config.Message{ | ||||
| 			Username: "system", | ||||
| 			Text:     message.Text, | ||||
| 			Channel:  message.Channel, | ||||
| 			Channel:  channelName, | ||||
| 			Account:  b.Account, | ||||
| 			Event:    config.EventJoinLeave, | ||||
| 		} | ||||
| @@ -329,13 +341,14 @@ func (b *Bmattermost) skipMessage6(message *matterclient6.Message) bool { | ||||
| 	// Ignore messages sent from matterbridge | ||||
| 	if message.Post.Props != nil { | ||||
| 		if _, ok := message.Post.Props["matterbridge_"+b.uuid].(bool); ok { | ||||
| 			b.Log.Debugf("sent by matterbridge, ignoring") | ||||
| 			b.Log.Debug("sent by matterbridge, ignoring") | ||||
| 			return true | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	// Ignore messages sent from a user logged in as the bot | ||||
| 	if b.mc6.User.Username == message.Username { | ||||
| 		b.Log.Debug("message from same user as bot, ignoring") | ||||
| 		return true | ||||
| 	} | ||||
|  | ||||
| @@ -346,6 +359,7 @@ func (b *Bmattermost) skipMessage6(message *matterclient6.Message) bool { | ||||
|  | ||||
| 	// ignore messages from other teams than ours | ||||
| 	if message.Raw.GetData()["team_id"].(string) != b.TeamID { | ||||
| 		b.Log.Debug("message from other team, ignoring") | ||||
| 		return true | ||||
| 	} | ||||
|  | ||||
| @@ -374,3 +388,30 @@ func (b *Bmattermost) getVersion() string { | ||||
|  | ||||
| 	return resp.Header.Get("X-Version-Id") | ||||
| } | ||||
|  | ||||
| func (b *Bmattermost) getChannelID(name string) string { | ||||
| 	idcheck := strings.Split(name, "ID:") | ||||
| 	if len(idcheck) > 1 { | ||||
| 		return idcheck[1] | ||||
| 	} | ||||
|  | ||||
| 	if b.mc6 != nil { | ||||
| 		return b.mc6.GetChannelID(name, b.TeamID) | ||||
| 	} | ||||
|  | ||||
| 	return b.mc.GetChannelId(name, b.TeamID) | ||||
| } | ||||
|  | ||||
| func (b *Bmattermost) getChannelName(id string) string { | ||||
| 	b.channelsMutex.RLock() | ||||
| 	defer b.channelsMutex.RUnlock() | ||||
|  | ||||
| 	for _, c := range b.channelInfoMap { | ||||
| 		if c.Name == "ID:"+id { | ||||
| 			// if we have ID: specified in our gateway configuration return this | ||||
| 			return c.Name | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	return "" | ||||
| } | ||||
|   | ||||
| @@ -4,6 +4,7 @@ import ( | ||||
| 	"errors" | ||||
| 	"fmt" | ||||
| 	"strings" | ||||
| 	"sync" | ||||
|  | ||||
| 	"github.com/42wim/matterbridge/bridge" | ||||
| 	"github.com/42wim/matterbridge/bridge/config" | ||||
| @@ -22,13 +23,19 @@ type Bmattermost struct { | ||||
| 	uuid   string | ||||
| 	TeamID string | ||||
| 	*bridge.Config | ||||
| 	avatarMap map[string]string | ||||
| 	avatarMap      map[string]string | ||||
| 	channelsMutex  sync.RWMutex | ||||
| 	channelInfoMap map[string]*config.ChannelInfo | ||||
| } | ||||
|  | ||||
| const mattermostPlugin = "mattermost.plugin" | ||||
|  | ||||
| func New(cfg *bridge.Config) bridge.Bridger { | ||||
| 	b := &Bmattermost{Config: cfg, avatarMap: make(map[string]string)} | ||||
| 	b := &Bmattermost{ | ||||
| 		Config:         cfg, | ||||
| 		avatarMap:      make(map[string]string), | ||||
| 		channelInfoMap: make(map[string]*config.ChannelInfo), | ||||
| 	} | ||||
|  | ||||
| 	b.v6 = b.GetBool("v6") | ||||
| 	b.uuid = xid.New().String() | ||||
| @@ -113,14 +120,14 @@ func (b *Bmattermost) JoinChannel(channel config.ChannelInfo) error { | ||||
| 	if b.Account == mattermostPlugin { | ||||
| 		return nil | ||||
| 	} | ||||
|  | ||||
| 	b.channelsMutex.Lock() | ||||
| 	b.channelInfoMap[channel.ID] = &channel | ||||
| 	b.channelsMutex.Unlock() | ||||
|  | ||||
| 	// we can only join channels using the API | ||||
| 	if b.GetString("WebhookURL") == "" && b.GetString("WebhookBindAddress") == "" { | ||||
| 		var id string | ||||
| 		if b.mc6 != nil { | ||||
| 			id = b.mc6.GetChannelID(channel.Name, b.TeamID) | ||||
| 		} else { | ||||
| 			id = b.mc.GetChannelId(channel.Name, b.TeamID) | ||||
| 		} | ||||
| 		id := b.getChannelID(channel.Name) | ||||
| 		if id == "" { | ||||
| 			return fmt.Errorf("Could not find channel ID for channel %s", channel.Name) | ||||
| 		} | ||||
| @@ -131,6 +138,7 @@ func (b *Bmattermost) JoinChannel(channel config.ChannelInfo) error { | ||||
|  | ||||
| 		return b.mc.JoinChannel(id) | ||||
| 	} | ||||
|  | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| @@ -180,13 +188,17 @@ func (b *Bmattermost) Send(msg config.Message) (string, error) { | ||||
| 			if err != nil { | ||||
| 				b.Log.Errorf("getting post %s failed: %s", msg.ParentID, err) | ||||
| 			} | ||||
| 			msg.ParentID = post.RootId | ||||
| 			if post.RootId != "" { | ||||
| 				msg.ParentID = post.RootId | ||||
| 			} | ||||
| 		} else { | ||||
| 			post, res := b.mc.Client.GetPost(msg.ParentID, "") | ||||
| 			if res.Error != nil { | ||||
| 				b.Log.Errorf("getting post %s failed: %s", msg.ParentID, res.Error.DetailedError) | ||||
| 			} | ||||
| 			msg.ParentID = post.RootId | ||||
| 			if post.RootId != "" { | ||||
| 				msg.ParentID = post.RootId | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| @@ -194,11 +206,11 @@ func (b *Bmattermost) Send(msg config.Message) (string, error) { | ||||
| 	if msg.Extra != nil { | ||||
| 		for _, rmsg := range helper.HandleExtra(&msg, b.General) { | ||||
| 			if b.mc6 != nil { | ||||
| 				if _, err := b.mc6.PostMessage(b.mc.GetChannelId(rmsg.Channel, b.TeamID), rmsg.Username+rmsg.Text, msg.ParentID); err != nil { | ||||
| 				if _, err := b.mc6.PostMessage(b.getChannelID(rmsg.Channel), rmsg.Username+rmsg.Text, msg.ParentID); err != nil { | ||||
| 					b.Log.Errorf("PostMessage failed: %s", err) | ||||
| 				} | ||||
| 			} else { | ||||
| 				if _, err := b.mc.PostMessage(b.mc.GetChannelId(rmsg.Channel, b.TeamID), rmsg.Username+rmsg.Text, msg.ParentID); err != nil { | ||||
| 				if _, err := b.mc.PostMessage(b.getChannelID(rmsg.Channel), rmsg.Username+rmsg.Text, msg.ParentID); err != nil { | ||||
| 					b.Log.Errorf("PostMessage failed: %s", err) | ||||
| 				} | ||||
| 			} | ||||
| @@ -224,8 +236,8 @@ func (b *Bmattermost) Send(msg config.Message) (string, error) { | ||||
|  | ||||
| 	// Post normal message | ||||
| 	if b.mc6 != nil { | ||||
| 		return b.mc6.PostMessage(b.mc6.GetChannelID(msg.Channel, b.TeamID), msg.Text, msg.ParentID) // nolint:wrapcheck | ||||
| 		return b.mc6.PostMessage(b.getChannelID(msg.Channel), msg.Text, msg.ParentID) // nolint:wrapcheck | ||||
| 	} | ||||
|  | ||||
| 	return b.mc.PostMessage(b.mc.GetChannelId(msg.Channel, b.TeamID), msg.Text, msg.ParentID) | ||||
| 	return b.mc.PostMessage(b.getChannelID(msg.Channel), msg.Text, msg.ParentID) | ||||
| } | ||||
|   | ||||
| @@ -19,8 +19,10 @@ import ( | ||||
| 	"golang.org/x/oauth2" | ||||
| ) | ||||
|  | ||||
| var defaultScopes = []string{"openid", "profile", "offline_access", "Group.Read.All", "Group.ReadWrite.All"} | ||||
| var attachRE = regexp.MustCompile(`<attachment id=.*?attachment>`) | ||||
| var ( | ||||
| 	defaultScopes = []string{"openid", "profile", "offline_access", "Group.Read.All", "Group.ReadWrite.All"} | ||||
| 	attachRE      = regexp.MustCompile(`<attachment id=.*?attachment>`) | ||||
| ) | ||||
|  | ||||
| type Bmsteams struct { | ||||
| 	gc    *msgraph.GraphServiceRequestBuilder | ||||
| @@ -50,7 +52,7 @@ func (b *Bmsteams) Connect() error { | ||||
| 		b.Log.Errorf("Couldn't save sessionfile in %s: %s", tokenCachePath, err) | ||||
| 	} | ||||
| 	// make file readable only for matterbridge user | ||||
| 	err = os.Chmod(tokenCachePath, 0600) | ||||
| 	err = os.Chmod(tokenCachePath, 0o600) | ||||
| 	if err != nil { | ||||
| 		b.Log.Errorf("Couldn't change permissions for %s: %s", tokenCachePath, err) | ||||
| 	} | ||||
| @@ -168,7 +170,7 @@ func (b *Bmsteams) poll(channelName string) error { | ||||
| 			} | ||||
|  | ||||
| 			// skip non-user message for now. | ||||
| 			if msg.From.User == nil { | ||||
| 			if msg.From == nil || msg.From.User == nil { | ||||
| 				continue | ||||
| 			} | ||||
|  | ||||
|   | ||||
							
								
								
									
										70
									
								
								bridge/mumble/codec.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										70
									
								
								bridge/mumble/codec.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,70 @@ | ||||
| package bmumble | ||||
|  | ||||
| import ( | ||||
| 	"fmt" | ||||
|  | ||||
| 	"layeh.com/gumble/gumble" | ||||
| ) | ||||
|  | ||||
| // This is a dummy implementation of a Gumble audio codec which claims | ||||
| // to implement Opus, but does not actually do anything.  This serves | ||||
| // as a workaround until https://github.com/layeh/gumble/pull/61 is | ||||
| // merged. | ||||
| // See https://github.com/42wim/matterbridge/issues/1750 for details. | ||||
|  | ||||
| const ( | ||||
| 	audioCodecIDOpus = 4 | ||||
| ) | ||||
|  | ||||
| func registerNullCodecAsOpus() { | ||||
| 	codec := &NullCodec{ | ||||
| 		encoder: &NullAudioEncoder{}, | ||||
| 		decoder: &NullAudioDecoder{}, | ||||
| 	} | ||||
| 	gumble.RegisterAudioCodec(audioCodecIDOpus, codec) | ||||
| } | ||||
|  | ||||
| type NullCodec struct { | ||||
| 	encoder *NullAudioEncoder | ||||
| 	decoder *NullAudioDecoder | ||||
| } | ||||
|  | ||||
| func (c *NullCodec) ID() int { | ||||
| 	return audioCodecIDOpus | ||||
| } | ||||
|  | ||||
| func (c *NullCodec) NewEncoder() gumble.AudioEncoder { | ||||
| 	e := &NullAudioEncoder{} | ||||
| 	return e | ||||
| } | ||||
|  | ||||
| func (c *NullCodec) NewDecoder() gumble.AudioDecoder { | ||||
| 	d := &NullAudioDecoder{} | ||||
| 	return d | ||||
| } | ||||
|  | ||||
| type NullAudioEncoder struct{} | ||||
|  | ||||
| func (e *NullAudioEncoder) ID() int { | ||||
| 	return audioCodecIDOpus | ||||
| } | ||||
|  | ||||
| func (e *NullAudioEncoder) Encode(pcm []int16, mframeSize, maxDataBytes int) ([]byte, error) { | ||||
| 	return nil, fmt.Errorf("not implemented") | ||||
| } | ||||
|  | ||||
| func (e *NullAudioEncoder) Reset() { | ||||
| } | ||||
|  | ||||
| type NullAudioDecoder struct{} | ||||
|  | ||||
| func (d *NullAudioDecoder) ID() int { | ||||
| 	return audioCodecIDOpus | ||||
| } | ||||
|  | ||||
| func (d *NullAudioDecoder) Decode(data []byte, frameSize int) ([]int16, error) { | ||||
| 	return nil, fmt.Errorf("not implemented") | ||||
| } | ||||
|  | ||||
| func (d *NullAudioDecoder) Reset() { | ||||
| } | ||||
| @@ -185,6 +185,7 @@ func (b *Bmumble) doConnect() error { | ||||
| 		gumbleConfig.Password = password | ||||
| 	} | ||||
|  | ||||
| 	registerNullCodecAsOpus() | ||||
| 	client, err := gumble.DialWithDialer(new(net.Dialer), b.GetString("Server"), gumbleConfig, &b.tlsConfig) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
|   | ||||
| @@ -27,7 +27,8 @@ func (b *Bslack) handleSlack() { | ||||
| 	b.Log.Debug("Start listening for Slack messages") | ||||
| 	for message := range messages { | ||||
| 		// don't do any action on deleted/typing messages | ||||
| 		if message.Event != config.EventUserTyping && message.Event != config.EventMsgDelete { | ||||
| 		if message.Event != config.EventUserTyping && message.Event != config.EventMsgDelete && | ||||
| 			message.Event != config.EventFileDelete { | ||||
| 			b.Log.Debugf("<= Sending message from %s on %s to gateway", message.Username, b.Account) | ||||
| 			// cleanup the message | ||||
| 			message.Text = b.replaceMention(message.Text) | ||||
| @@ -76,6 +77,13 @@ func (b *Bslack) handleSlackClient(messages chan *config.Message) { | ||||
| 				continue | ||||
| 			} | ||||
| 			messages <- rmsg | ||||
| 		case *slack.FileDeletedEvent: | ||||
| 			rmsg, err := b.handleFileDeletedEvent(ev) | ||||
| 			if err != nil { | ||||
| 				b.Log.Errorf("%#v", err) | ||||
| 				continue | ||||
| 			} | ||||
| 			messages <- rmsg | ||||
| 		case *slack.OutgoingErrorEvent: | ||||
| 			b.Log.Debugf("%#v", ev.Error()) | ||||
| 		case *slack.ChannelJoinedEvent: | ||||
| @@ -222,6 +230,26 @@ func (b *Bslack) handleMessageEvent(ev *slack.MessageEvent) (*config.Message, er | ||||
| 	return rmsg, nil | ||||
| } | ||||
|  | ||||
| func (b *Bslack) handleFileDeletedEvent(ev *slack.FileDeletedEvent) (*config.Message, error) { | ||||
| 	if rawChannel, ok := b.cache.Get(cfileDownloadChannel + ev.FileID); ok { | ||||
| 		channel, err := b.channels.getChannelByID(rawChannel.(string)) | ||||
| 		if err != nil { | ||||
| 			return nil, err | ||||
| 		} | ||||
|  | ||||
| 		return &config.Message{ | ||||
| 			Event:    config.EventFileDelete, | ||||
| 			Text:     config.EventFileDelete, | ||||
| 			Channel:  channel.Name, | ||||
| 			Account:  b.Account, | ||||
| 			ID:       ev.FileID, | ||||
| 			Protocol: b.Protocol, | ||||
| 		}, nil | ||||
| 	} | ||||
|  | ||||
| 	return nil, fmt.Errorf("channel ID for file ID %s not found", ev.FileID) | ||||
| } | ||||
|  | ||||
| func (b *Bslack) handleStatusEvent(ev *slack.MessageEvent, rmsg *config.Message) bool { | ||||
| 	switch ev.SubType { | ||||
| 	case sChannelJoined, sMemberJoined: | ||||
| @@ -281,6 +309,8 @@ func (b *Bslack) handleAttachments(ev *slack.MessageEvent, rmsg *config.Message) | ||||
|  | ||||
| 	// If we have files attached, download them (in memory) and put a pointer to it in msg.Extra. | ||||
| 	for i := range ev.Files { | ||||
| 		// keep reference in cache on which channel we added this file | ||||
| 		b.cache.Add(cfileDownloadChannel+ev.Files[i].ID, ev.Channel) | ||||
| 		if err := b.handleDownloadFile(rmsg, &ev.Files[i], false); err != nil { | ||||
| 			b.Log.Errorf("Could not download incoming file: %#v", err) | ||||
| 		} | ||||
| @@ -330,7 +360,7 @@ func (b *Bslack) handleDownloadFile(rmsg *config.Message, file *slack.File, retr | ||||
| 	// that the comment is not duplicated. | ||||
| 	comment := rmsg.Text | ||||
| 	rmsg.Text = "" | ||||
| 	helper.HandleDownloadData(b.Log, rmsg, file.Name, comment, file.URLPrivateDownload, data, b.General) | ||||
| 	helper.HandleDownloadData2(b.Log, rmsg, file.Name, file.ID, comment, file.URLPrivateDownload, data, b.General) | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -36,24 +36,25 @@ type Bslack struct { | ||||
| } | ||||
|  | ||||
| const ( | ||||
| 	sHello           = "hello" | ||||
| 	sChannelJoin     = "channel_join" | ||||
| 	sChannelLeave    = "channel_leave" | ||||
| 	sChannelJoined   = "channel_joined" | ||||
| 	sMemberJoined    = "member_joined_channel" | ||||
| 	sMessageChanged  = "message_changed" | ||||
| 	sMessageDeleted  = "message_deleted" | ||||
| 	sSlackAttachment = "slack_attachment" | ||||
| 	sPinnedItem      = "pinned_item" | ||||
| 	sUnpinnedItem    = "unpinned_item" | ||||
| 	sChannelTopic    = "channel_topic" | ||||
| 	sChannelPurpose  = "channel_purpose" | ||||
| 	sFileComment     = "file_comment" | ||||
| 	sMeMessage       = "me_message" | ||||
| 	sUserTyping      = "user_typing" | ||||
| 	sLatencyReport   = "latency_report" | ||||
| 	sSystemUser      = "system" | ||||
| 	sSlackBotUser    = "slackbot" | ||||
| 	sHello               = "hello" | ||||
| 	sChannelJoin         = "channel_join" | ||||
| 	sChannelLeave        = "channel_leave" | ||||
| 	sChannelJoined       = "channel_joined" | ||||
| 	sMemberJoined        = "member_joined_channel" | ||||
| 	sMessageChanged      = "message_changed" | ||||
| 	sMessageDeleted      = "message_deleted" | ||||
| 	sSlackAttachment     = "slack_attachment" | ||||
| 	sPinnedItem          = "pinned_item" | ||||
| 	sUnpinnedItem        = "unpinned_item" | ||||
| 	sChannelTopic        = "channel_topic" | ||||
| 	sChannelPurpose      = "channel_purpose" | ||||
| 	sFileComment         = "file_comment" | ||||
| 	sMeMessage           = "me_message" | ||||
| 	sUserTyping          = "user_typing" | ||||
| 	sLatencyReport       = "latency_report" | ||||
| 	sSystemUser          = "system" | ||||
| 	sSlackBotUser        = "slackbot" | ||||
| 	cfileDownloadChannel = "file_download_channel" | ||||
|  | ||||
| 	tokenConfig           = "Token" | ||||
| 	incomingWebhookConfig = "WebhookBindAddress" | ||||
|   | ||||
| @@ -291,6 +291,7 @@ func (b *channels) populateChannels(wait bool) { | ||||
| 	queryParams := &slack.GetConversationsParameters{ | ||||
| 		ExcludeArchived: true, | ||||
| 		Types:           []string{"public_channel,private_channel"}, | ||||
| 		Limit:           1000, | ||||
| 	} | ||||
| 	for { | ||||
| 		channels, nextCursor, err := b.sc.GetConversations(queryParams) | ||||
|   | ||||
| @@ -1,6 +1,7 @@ | ||||
| package btelegram | ||||
|  | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	"html" | ||||
| 	"path/filepath" | ||||
| 	"strconv" | ||||
| @@ -9,14 +10,27 @@ import ( | ||||
|  | ||||
| 	"github.com/42wim/matterbridge/bridge/config" | ||||
| 	"github.com/42wim/matterbridge/bridge/helper" | ||||
| 	tgbotapi "github.com/go-telegram-bot-api/telegram-bot-api" | ||||
| 	"github.com/davecgh/go-spew/spew" | ||||
| 	tgbotapi "github.com/go-telegram-bot-api/telegram-bot-api/v5" | ||||
| ) | ||||
|  | ||||
| func (b *Btelegram) handleUpdate(rmsg *config.Message, message, posted, edited *tgbotapi.Message) *tgbotapi.Message { | ||||
| 	// handle channels | ||||
| 	if posted != nil { | ||||
| 		message = posted | ||||
| 		rmsg.Text = message.Text | ||||
| 		if posted.Text == "/chatId" { | ||||
| 			chatID := strconv.FormatInt(posted.Chat.ID, 10) | ||||
|  | ||||
| 			_, err := b.Send(config.Message{ | ||||
| 				Channel: chatID, | ||||
| 				Text:    fmt.Sprintf("ID of this chat: %s", chatID), | ||||
| 			}) | ||||
| 			if err != nil { | ||||
| 				b.Log.Warnf("Unable to send chatID to %s", chatID) | ||||
| 			} | ||||
| 		} else { | ||||
| 			message = posted | ||||
| 			rmsg.Text = message.Text | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	// edited channel message | ||||
| @@ -43,6 +57,11 @@ func (b *Btelegram) handleForwarded(rmsg *config.Message, message *tgbotapi.Mess | ||||
| 		return | ||||
| 	} | ||||
|  | ||||
| 	if message.ForwardFromChat != nil && message.ForwardFrom == nil { | ||||
| 		rmsg.Text = "Forwarded from " + message.ForwardFromChat.Title + ": " + rmsg.Text | ||||
| 		return | ||||
| 	} | ||||
|  | ||||
| 	if message.ForwardFrom == nil { | ||||
| 		rmsg.Text = "Forwarded from " + unknownUser + ": " + rmsg.Text | ||||
| 		return | ||||
| @@ -94,7 +113,7 @@ func (b *Btelegram) handleQuoting(rmsg *config.Message, message *tgbotapi.Messag | ||||
| // handleUsername handles the correct setting of the username | ||||
| func (b *Btelegram) handleUsername(rmsg *config.Message, message *tgbotapi.Message) { | ||||
| 	if message.From != nil { | ||||
| 		rmsg.UserID = strconv.Itoa(message.From.ID) | ||||
| 		rmsg.UserID = strconv.FormatInt(message.From.ID, 10) | ||||
| 		if b.GetBool("UseFirstName") { | ||||
| 			rmsg.Username = message.From.FirstName | ||||
| 		} | ||||
| @@ -110,6 +129,25 @@ func (b *Btelegram) handleUsername(rmsg *config.Message, message *tgbotapi.Messa | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	if message.SenderChat != nil { //nolint:nestif | ||||
| 		rmsg.UserID = strconv.FormatInt(message.SenderChat.ID, 10) | ||||
| 		if b.GetBool("UseFirstName") { | ||||
| 			rmsg.Username = message.SenderChat.FirstName | ||||
| 		} | ||||
|  | ||||
| 		if rmsg.Username == "" || rmsg.Username == "Channel_Bot" { | ||||
| 			rmsg.Username = message.SenderChat.UserName | ||||
|  | ||||
| 			if rmsg.Username == "" || rmsg.Username == "Channel_Bot" { | ||||
| 				rmsg.Username = message.SenderChat.FirstName | ||||
| 			} | ||||
| 		} | ||||
| 		// only download avatars if we have a place to upload them (configured mediaserver) | ||||
| 		if b.General.MediaServerUpload != "" || (b.General.MediaServerDownload != "" && b.General.MediaDownloadPath != "") { | ||||
| 			b.handleDownloadAvatar(message.SenderChat.ID, rmsg.Channel) | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	// if we really didn't find a username, set it to unknown | ||||
| 	if rmsg.Username == "" { | ||||
| 		rmsg.Username = unknownUser | ||||
| @@ -126,6 +164,10 @@ func (b *Btelegram) handleRecv(updates <-chan tgbotapi.Update) { | ||||
| 			continue | ||||
| 		} | ||||
|  | ||||
| 		if b.GetInt("debuglevel") == 1 { | ||||
| 			spew.Dump(update.Message) | ||||
| 		} | ||||
|  | ||||
| 		var message *tgbotapi.Message | ||||
|  | ||||
| 		rmsg := config.Message{Account: b.Account, Extra: make(map[string][]interface{})} | ||||
| @@ -145,6 +187,9 @@ func (b *Btelegram) handleRecv(updates <-chan tgbotapi.Update) { | ||||
| 		rmsg.ID = strconv.Itoa(message.MessageID) | ||||
| 		rmsg.Channel = strconv.FormatInt(message.Chat.ID, 10) | ||||
|  | ||||
| 		// handle entities (adding URLs) | ||||
| 		b.handleEntities(&rmsg, message) | ||||
|  | ||||
| 		// handle username | ||||
| 		b.handleUsername(&rmsg, message) | ||||
|  | ||||
| @@ -160,14 +205,12 @@ func (b *Btelegram) handleRecv(updates <-chan tgbotapi.Update) { | ||||
| 		// quote the previous message | ||||
| 		b.handleQuoting(&rmsg, message) | ||||
|  | ||||
| 		// handle entities (adding URLs) | ||||
| 		b.handleEntities(&rmsg, message) | ||||
|  | ||||
| 		if rmsg.Text != "" || len(rmsg.Extra) > 0 { | ||||
| 			rmsg.Text = helper.RemoveEmptyNewLines(rmsg.Text) | ||||
| 			// Comment the next line out due to avoid removing empty lines in Telegram | ||||
| 			// rmsg.Text = helper.RemoveEmptyNewLines(rmsg.Text) | ||||
| 			// channels don't have (always?) user information. see #410 | ||||
| 			if message.From != nil { | ||||
| 				rmsg.Avatar = helper.GetAvatar(b.avatarMap, strconv.Itoa(message.From.ID), b.General) | ||||
| 				rmsg.Avatar = helper.GetAvatar(b.avatarMap, strconv.FormatInt(message.From.ID, 10), b.General) | ||||
| 			} | ||||
|  | ||||
| 			b.Log.Debugf("<= Sending message from %s on %s to gateway", rmsg.Username, b.Account) | ||||
| @@ -180,42 +223,44 @@ func (b *Btelegram) handleRecv(updates <-chan tgbotapi.Update) { | ||||
| // handleDownloadAvatar downloads the avatar of userid from channel | ||||
| // sends a EVENT_AVATAR_DOWNLOAD message to the gateway if successful. | ||||
| // logs an error message if it fails | ||||
| func (b *Btelegram) handleDownloadAvatar(userid int, channel string) { | ||||
| func (b *Btelegram) handleDownloadAvatar(userid int64, channel string) { | ||||
| 	rmsg := config.Message{ | ||||
| 		Username: "system", | ||||
| 		Text:     "avatar", | ||||
| 		Channel:  channel, | ||||
| 		Account:  b.Account, | ||||
| 		UserID:   strconv.Itoa(userid), | ||||
| 		UserID:   strconv.FormatInt(userid, 10), | ||||
| 		Event:    config.EventAvatarDownload, | ||||
| 		Extra:    make(map[string][]interface{}), | ||||
| 	} | ||||
|  | ||||
| 	if _, ok := b.avatarMap[strconv.Itoa(userid)]; !ok { | ||||
| 		photos, err := b.c.GetUserProfilePhotos(tgbotapi.UserProfilePhotosConfig{UserID: userid, Limit: 1}) | ||||
| 	if _, ok := b.avatarMap[strconv.FormatInt(userid, 10)]; ok { | ||||
| 		return | ||||
| 	} | ||||
|  | ||||
| 	photos, err := b.c.GetUserProfilePhotos(tgbotapi.UserProfilePhotosConfig{UserID: userid, Limit: 1}) | ||||
| 	if err != nil { | ||||
| 		b.Log.Errorf("Userprofile download failed for %#v %s", userid, err) | ||||
| 	} | ||||
|  | ||||
| 	if len(photos.Photos) > 0 { | ||||
| 		photo := photos.Photos[0][0] | ||||
| 		url := b.getFileDirectURL(photo.FileID) | ||||
| 		name := strconv.FormatInt(userid, 10) + ".png" | ||||
| 		b.Log.Debugf("trying to download %#v fileid %#v with size %#v", name, photo.FileID, photo.FileSize) | ||||
|  | ||||
| 		err := helper.HandleDownloadSize(b.Log, &rmsg, name, int64(photo.FileSize), b.General) | ||||
| 		if err != nil { | ||||
| 			b.Log.Errorf("Userprofile download failed for %#v %s", userid, err) | ||||
| 			b.Log.Error(err) | ||||
| 			return | ||||
| 		} | ||||
|  | ||||
| 		if len(photos.Photos) > 0 { | ||||
| 			photo := photos.Photos[0][0] | ||||
| 			url := b.getFileDirectURL(photo.FileID) | ||||
| 			name := strconv.Itoa(userid) + ".png" | ||||
| 			b.Log.Debugf("trying to download %#v fileid %#v with size %#v", name, photo.FileID, photo.FileSize) | ||||
|  | ||||
| 			err := helper.HandleDownloadSize(b.Log, &rmsg, name, int64(photo.FileSize), b.General) | ||||
| 			if err != nil { | ||||
| 				b.Log.Error(err) | ||||
| 				return | ||||
| 			} | ||||
| 			data, err := helper.DownloadFile(url) | ||||
| 			if err != nil { | ||||
| 				b.Log.Errorf("download %s failed %#v", url, err) | ||||
| 				return | ||||
| 			} | ||||
| 			helper.HandleDownloadData(b.Log, &rmsg, name, rmsg.Text, "", data, b.General) | ||||
| 			b.Remote <- rmsg | ||||
| 		data, err := helper.DownloadFile(url) | ||||
| 		if err != nil { | ||||
| 			b.Log.Errorf("download %s failed %#v", url, err) | ||||
| 			return | ||||
| 		} | ||||
| 		helper.HandleDownloadData(b.Log, &rmsg, name, rmsg.Text, "", data, b.General) | ||||
| 		b.Remote <- rmsg | ||||
| 	} | ||||
| } | ||||
|  | ||||
| @@ -272,7 +317,7 @@ func (b *Btelegram) handleDownload(rmsg *config.Message, message *tgbotapi.Messa | ||||
| 		name = message.Document.FileName | ||||
| 		text = " " + message.Document.FileName + " : " + url | ||||
| 	case message.Photo != nil: | ||||
| 		photos := *message.Photo | ||||
| 		photos := message.Photo | ||||
| 		size = photos[len(photos)-1].FileSize | ||||
| 		text, name, url = b.getDownloadInfo(photos[len(photos)-1].FileID, "", true) | ||||
| 	} | ||||
| @@ -331,11 +376,15 @@ func (b *Btelegram) handleDelete(msg *config.Message, chatid int64) (string, err | ||||
| 	if msg.ID == "" { | ||||
| 		return "", nil | ||||
| 	} | ||||
|  | ||||
| 	msgid, err := strconv.Atoi(msg.ID) | ||||
| 	if err != nil { | ||||
| 		return "", err | ||||
| 	} | ||||
| 	_, err = b.c.DeleteMessage(tgbotapi.DeleteMessageConfig{ChatID: chatid, MessageID: msgid}) | ||||
|  | ||||
| 	cfg := tgbotapi.NewDeleteMessage(chatid, msgid) | ||||
| 	_, err = b.c.Send(cfg) | ||||
|  | ||||
| 	return "", err | ||||
| } | ||||
|  | ||||
| @@ -383,23 +432,23 @@ func (b *Btelegram) handleUploadFile(msg *config.Message, chatid int64) string { | ||||
| 		} | ||||
| 		switch filepath.Ext(fi.Name) { | ||||
| 		case ".jpg", ".jpe", ".png": | ||||
| 			pc := tgbotapi.NewPhotoUpload(chatid, file) | ||||
| 			pc := tgbotapi.NewPhoto(chatid, file) | ||||
| 			pc.Caption, pc.ParseMode = TGGetParseMode(b, msg.Username, fi.Comment) | ||||
| 			c = pc | ||||
| 		case ".mp4", ".m4v": | ||||
| 			vc := tgbotapi.NewVideoUpload(chatid, file) | ||||
| 			vc := tgbotapi.NewVideo(chatid, file) | ||||
| 			vc.Caption, vc.ParseMode = TGGetParseMode(b, msg.Username, fi.Comment) | ||||
| 			c = vc | ||||
| 		case ".mp3", ".oga": | ||||
| 			ac := tgbotapi.NewAudioUpload(chatid, file) | ||||
| 			ac := tgbotapi.NewAudio(chatid, file) | ||||
| 			ac.Caption, ac.ParseMode = TGGetParseMode(b, msg.Username, fi.Comment) | ||||
| 			c = ac | ||||
| 		case ".ogg": | ||||
| 			voc := tgbotapi.NewVoiceUpload(chatid, file) | ||||
| 			voc := tgbotapi.NewVoice(chatid, file) | ||||
| 			voc.Caption, voc.ParseMode = TGGetParseMode(b, msg.Username, fi.Comment) | ||||
| 			c = voc | ||||
| 		default: | ||||
| 			dc := tgbotapi.NewDocumentUpload(chatid, file) | ||||
| 			dc := tgbotapi.NewDocument(chatid, file) | ||||
| 			dc.Caption, dc.ParseMode = TGGetParseMode(b, msg.Username, fi.Comment) | ||||
| 			c = dc | ||||
| 		} | ||||
| @@ -435,21 +484,56 @@ func (b *Btelegram) handleEntities(rmsg *config.Message, message *tgbotapi.Messa | ||||
| 	if message.Entities == nil { | ||||
| 		return | ||||
| 	} | ||||
|  | ||||
| 	indexMovedBy := 0 | ||||
|  | ||||
| 	// for now only do URL replacements | ||||
| 	for _, e := range *message.Entities { | ||||
| 	for _, e := range message.Entities { | ||||
|  | ||||
| 		asRunes := utf16.Encode([]rune(rmsg.Text)) | ||||
|  | ||||
| 		if e.Type == "text_link" { | ||||
| 			offset := e.Offset + indexMovedBy | ||||
| 			url, err := e.ParseURL() | ||||
| 			if err != nil { | ||||
| 				b.Log.Errorf("entity text_link url parse failed: %s", err) | ||||
| 				continue | ||||
| 			} | ||||
| 			utfEncodedString := utf16.Encode([]rune(rmsg.Text)) | ||||
| 			if e.Offset+e.Length > len(utfEncodedString) { | ||||
| 				b.Log.Errorf("entity length is too long %d > %d", e.Offset+e.Length, len(utfEncodedString)) | ||||
| 			if offset+e.Length > len(utfEncodedString) { | ||||
| 				b.Log.Errorf("entity length is too long %d > %d", offset+e.Length, len(utfEncodedString)) | ||||
| 				continue | ||||
| 			} | ||||
| 			link := utf16.Decode(utfEncodedString[e.Offset : e.Offset+e.Length]) | ||||
| 			rmsg.Text = strings.Replace(rmsg.Text, string(link), url.String(), 1) | ||||
| 			rmsg.Text = string(utf16.Decode(asRunes[:offset+e.Length])) + " (" + url.String() + ")" + string(utf16.Decode(asRunes[offset+e.Length:])) | ||||
| 			indexMovedBy += len(url.String()) + 3 | ||||
| 		} | ||||
|  | ||||
| 		if e.Type == "code" { | ||||
| 			offset := e.Offset + indexMovedBy | ||||
| 			rmsg.Text = string(utf16.Decode(asRunes[:offset])) + "`" + string(utf16.Decode(asRunes[offset:offset+e.Length])) + "`" + string(utf16.Decode(asRunes[offset+e.Length:])) | ||||
| 			indexMovedBy += 2 | ||||
| 		} | ||||
|  | ||||
| 		if e.Type == "pre" { | ||||
| 			offset := e.Offset + indexMovedBy | ||||
| 			rmsg.Text = string(utf16.Decode(asRunes[:offset])) + "```\n" + string(utf16.Decode(asRunes[offset:offset+e.Length])) + "```\n" + string(utf16.Decode(asRunes[offset+e.Length:])) | ||||
| 			indexMovedBy += 8 | ||||
| 		} | ||||
|  | ||||
| 		if e.Type == "bold" { | ||||
| 			offset := e.Offset + indexMovedBy | ||||
| 			rmsg.Text = string(utf16.Decode(asRunes[:offset])) + "*" + string(utf16.Decode(asRunes[offset:offset+e.Length])) + "*" + string(utf16.Decode(asRunes[offset+e.Length:])) | ||||
| 			indexMovedBy += 2 | ||||
| 		} | ||||
| 		if e.Type == "italic" { | ||||
| 			offset := e.Offset + indexMovedBy | ||||
| 			rmsg.Text = string(utf16.Decode(asRunes[:offset])) + "_" + string(utf16.Decode(asRunes[offset:offset+e.Length])) + "_" + string(utf16.Decode(asRunes[offset+e.Length:])) | ||||
| 			indexMovedBy += 2 | ||||
| 		} | ||||
| 		if e.Type == "strike" { | ||||
| 			offset := e.Offset + indexMovedBy | ||||
| 			rmsg.Text = string(utf16.Decode(asRunes[:offset])) + "~" + string(utf16.Decode(asRunes[offset:offset+e.Length])) + "~" + string(utf16.Decode(asRunes[offset+e.Length:])) | ||||
| 			indexMovedBy += 2 | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|   | ||||
| @@ -9,7 +9,7 @@ import ( | ||||
| 	"github.com/42wim/matterbridge/bridge" | ||||
| 	"github.com/42wim/matterbridge/bridge/config" | ||||
| 	"github.com/42wim/matterbridge/bridge/helper" | ||||
| 	tgbotapi "github.com/go-telegram-bot-api/telegram-bot-api" | ||||
| 	tgbotapi "github.com/go-telegram-bot-api/telegram-bot-api/v5" | ||||
| ) | ||||
|  | ||||
| const ( | ||||
| @@ -49,11 +49,7 @@ func (b *Btelegram) Connect() error { | ||||
| 	} | ||||
| 	u := tgbotapi.NewUpdate(0) | ||||
| 	u.Timeout = 60 | ||||
| 	updates, err := b.c.GetUpdatesChan(u) | ||||
| 	if err != nil { | ||||
| 		b.Log.Debugf("%#v", err) | ||||
| 		return err | ||||
| 	} | ||||
| 	updates := b.c.GetUpdatesChan(u) | ||||
| 	b.Log.Info("Connection succeeded") | ||||
| 	go b.handleRecv(updates) | ||||
| 	return nil | ||||
|   | ||||
| @@ -34,6 +34,7 @@ type user struct { | ||||
|  | ||||
| type Bvk struct { | ||||
| 	c            *api.VK | ||||
| 	lp           *longpoll.LongPoll | ||||
| 	usernamesMap map[int]user // cache of user names and avatar URLs | ||||
| 	*bridge.Config | ||||
| } | ||||
| @@ -45,21 +46,23 @@ func New(cfg *bridge.Config) bridge.Bridger { | ||||
| func (b *Bvk) Connect() error { | ||||
| 	b.Log.Info("Connecting") | ||||
| 	b.c = api.NewVK(b.GetString("Token")) | ||||
| 	lp, err := longpoll.NewLongPoll(b.c, b.GetInt("GroupID")) | ||||
|  | ||||
| 	var err error | ||||
| 	b.lp, err = longpoll.NewLongPollCommunity(b.c) | ||||
| 	if err != nil { | ||||
| 		b.Log.Debugf("%#v", err) | ||||
|  | ||||
| 		return err | ||||
| 	} | ||||
|  | ||||
| 	lp.MessageNew(func(ctx context.Context, obj events.MessageNewObject) { | ||||
| 	b.lp.MessageNew(func(ctx context.Context, obj events.MessageNewObject) { | ||||
| 		b.handleMessage(obj.Message, false) | ||||
| 	}) | ||||
|  | ||||
| 	b.Log.Info("Connection succeeded") | ||||
|  | ||||
| 	go func() { | ||||
| 		err := lp.Run() | ||||
| 		err := b.lp.Run() | ||||
| 		if err != nil { | ||||
| 			b.Log.Fatal("Enable longpoll in group management") | ||||
| 		} | ||||
| @@ -69,6 +72,8 @@ func (b *Bvk) Connect() error { | ||||
| } | ||||
|  | ||||
| func (b *Bvk) Disconnect() error { | ||||
| 	b.lp.Shutdown() | ||||
|  | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -293,7 +293,11 @@ func (b *Bwhatsapp) Send(msg config.Message) (string, error) { | ||||
| 	if msg.ID != "" { | ||||
| 		b.Log.Debugf("updating message with id %s", msg.ID) | ||||
|  | ||||
| 		msg.Text += " (edited)" | ||||
| 		if b.GetString("editsuffix") != "" { | ||||
| 			msg.Text += b.GetString("EditSuffix") | ||||
| 		} else { | ||||
| 			msg.Text += " (edited)" | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	// Handle Upload a file | ||||
|   | ||||
| @@ -128,7 +128,6 @@ func (b *Bxmpp) Send(msg config.Message) (string, error) { | ||||
| 	var msgReplaceID string | ||||
| 	msgID := xid.New().String() | ||||
| 	if msg.ID != "" { | ||||
| 		msgID = msg.ID | ||||
| 		msgReplaceID = msg.ID | ||||
| 	} | ||||
| 	b.Log.Debugf("=> Sending message %#v", msg) | ||||
| @@ -284,7 +283,13 @@ func (b *Bxmpp) handleXMPP() error { | ||||
| 	for { | ||||
| 		m, err := b.xc.Recv() | ||||
| 		if err != nil { | ||||
| 			return err | ||||
| 			// An error together with AvatarData is non-fatal | ||||
| 			switch m.(type) { | ||||
| 			case xmpp.AvatarData: | ||||
| 				continue | ||||
| 			default: | ||||
| 				return err | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| 		switch v := m.(type) { | ||||
|   | ||||
| @@ -2,6 +2,7 @@ package bzulip | ||||
|  | ||||
| import ( | ||||
| 	"encoding/json" | ||||
| 	"fmt" | ||||
| 	"io/ioutil" | ||||
| 	"strconv" | ||||
| 	"strings" | ||||
| @@ -11,6 +12,7 @@ import ( | ||||
| 	"github.com/42wim/matterbridge/bridge" | ||||
| 	"github.com/42wim/matterbridge/bridge/config" | ||||
| 	"github.com/42wim/matterbridge/bridge/helper" | ||||
| 	"github.com/42wim/matterbridge/version" | ||||
| 	gzb "github.com/matterbridge/gozulipbot" | ||||
| ) | ||||
|  | ||||
| @@ -27,7 +29,7 @@ func New(cfg *bridge.Config) bridge.Bridger { | ||||
| } | ||||
|  | ||||
| func (b *Bzulip) Connect() error { | ||||
| 	bot := gzb.Bot{APIKey: b.GetString("token"), APIURL: b.GetString("server") + "/api/v1/", Email: b.GetString("login")} | ||||
| 	bot := gzb.Bot{APIKey: b.GetString("token"), APIURL: b.GetString("server") + "/api/v1/", Email: b.GetString("login"), UserAgent: fmt.Sprintf("matterbridge/%s", version.Release)} | ||||
| 	bot.Init() | ||||
| 	q, err := bot.RegisterAll() | ||||
| 	b.q = q | ||||
| @@ -125,6 +127,7 @@ func (b *Bzulip) handleQueue() error { | ||||
| 			b.Log.Debug("heartbeat received.") | ||||
| 		default: | ||||
| 			b.Log.Debugf("receiving error: %#v", err) | ||||
| 			time.Sleep(time.Second * 10) | ||||
| 		} | ||||
| 		if err != nil { | ||||
| 			continue | ||||
|   | ||||
							
								
								
									
										86
									
								
								changelog.md
									
									
									
									
									
								
							
							
						
						
									
										86
									
								
								changelog.md
									
									
									
									
									
								
							| @@ -1,3 +1,87 @@ | ||||
| # v1.24.1 | ||||
|  | ||||
| ## Enhancements | ||||
|  | ||||
| - discord: Switch to discordgo upstream again (#1759) | ||||
| - general: Update dependencies and vendor (#1761) | ||||
| - general: Create inmessage-logger.tengo (#1688) (#1747) | ||||
| - general: Add OpenRC service file (#1746) | ||||
| - irc: Refactor utf-8 conversion (irc) (#1767) | ||||
|  | ||||
| ## Bugfixes | ||||
|  | ||||
| - irc: Fix panic in irc. Closes #1751 (#1760) | ||||
| - mumble: Implement a workaround to signal Opus support (mumble) (#1764) | ||||
| - telegram: Fix for complex-formatted Telegram text (#1765) | ||||
| - telegram: Fix Telegram channel title in forwards (#1753) | ||||
| - telegram: Fix Telegram Problem (unforwarded formatting and skipping of linebreaks) (#1749) | ||||
|  | ||||
| This release couldn't exist without the following contributors: | ||||
| @s3lph, @ValdikSS, @reckel-jm, @CyberTailor | ||||
|  | ||||
| # v1.24.0 | ||||
|  | ||||
| ## New features | ||||
|  | ||||
| - harmony: new protocol added: Add support for Harmony (#1656) | ||||
| - irc: Allow binding to IP on IRC (#1640) | ||||
| - irc: Add support for client certificate (irc) (#1710) | ||||
| - mattermost: Add UseUsername option (mattermost). Fixes #1665 (#1714) | ||||
| - mattermost: Add support for using ID in channel config (mattermost) (#1715) | ||||
| - matrix: Reply support for Matrix (#1664) | ||||
| - telegram: Add Telegram Bot Command /chatId (telegram) (#1703) | ||||
|  | ||||
| ## Enhancements | ||||
|  | ||||
| - general: Update dependencies/vendor (#1659) | ||||
| - discord: Add more debug options for discord (#1712) | ||||
| - docker: Use Alpine stable again in Dockerfile (#1643) | ||||
| - mattermost: Log eventtype in debug (mattermost) (#1676) | ||||
| - mattermost: Add more ignore debug messages (mattermost) (#1678) | ||||
| - slack: Add support for deleting files from slack to discord. Fixes #1705 (#1709) | ||||
| - telegram: Add support for code blocks in telegram (#1650) | ||||
| - telegram: Update telegram-bot-api to v5 (#1660) | ||||
| - telegram: Add comments to messages (telegram) (#1652) | ||||
| - telegram: Add support for sender_chat (telegram) (#1677) | ||||
| - vk: Remove GroupID (vk) (#1668) | ||||
|  | ||||
| ## Bugfix | ||||
|  | ||||
| - mattermost: Use current parentID if rootId is not set (mattermost) (#1675) | ||||
| - matrix: Make HTMLDisable work correct (matrix) (#1716) | ||||
| - whatsapp: Make EditSuffix option actually work (whatsapp). Fixes #1510 (#1728) | ||||
|  | ||||
| This release couldn't exist without the following contributors: | ||||
| @DavyJohnesev, @GoliathLabs, @pontaoski, @PeGaSuS-Coder, @dependabot[bot], @vpzomtrrfrt, @SevereCloud, @soloam, @YashRE42, @danwalmsley, @SuperSandro2000, @inzanity | ||||
|  | ||||
| # v1.23.2 | ||||
|  | ||||
| If you're running whatsapp you should update. | ||||
|  | ||||
| ## Bugfix | ||||
|  | ||||
| - whatsapp: Update go-whatsapp version (#1630) | ||||
|  | ||||
| This release couldn't exist without the following contributors: | ||||
| @snikpic | ||||
|  | ||||
| # v1.23.1 | ||||
|  | ||||
| If you're running mattermost 6 you should update. | ||||
|  | ||||
| ## Bugfix | ||||
|  | ||||
| - mattermost: Do not check cache on deleted messages (mattermost). Fixes #1555 (#1624) | ||||
| - mattermost: Fix crash on users updating info. Update matterclient dep. Fixes #1617 | ||||
| - matrix: Keep the logger on a disabled bridge. Fixes #1616 (#1621) | ||||
| - msteams: Fix panic in msteams. Fixes #1588 (#1622) | ||||
| - xmpp: Do not fail on no avatar data (xmpp) #1529 (#1627) | ||||
| - xmpp: Use a new msgID when replacing messages (xmpp). Fixes #1584 (#1623) | ||||
| - zulip: Add better error handling on Zulip (#1589) | ||||
|  | ||||
| This release couldn't exist without the following contributors: | ||||
| @Polynomdivision, @minecraftchest1, @alexmv | ||||
|  | ||||
| # v1.23.0 | ||||
|  | ||||
| ## New features | ||||
| @@ -24,8 +108,6 @@ | ||||
| This release couldn't exist without the following contributors: | ||||
| @powerjungle, @gary-kim, @KingPin, @Benau, @keenan-v1, @tytan652, @KidA001,@minecraftchest1, @irydacea | ||||
|  | ||||
| ## | ||||
|  | ||||
| # v1.22.3 | ||||
|  | ||||
| ## Bugfixes | ||||
|   | ||||
							
								
								
									
										15
									
								
								contrib/inmessage-logger.tengo
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								contrib/inmessage-logger.tengo
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,15 @@ | ||||
| fmt := import("fmt") | ||||
| os := import("os") | ||||
| times := import("times") | ||||
|  | ||||
| if msgText != "" && msgUsername != "system" { | ||||
|     os.chdir("/var/www/matterbridge") | ||||
|     file := os.open_file("inmessage.log", os.o_append|os.o_wronly|os.o_create, 0644) | ||||
|     file.write_string(fmt.sprintf( | ||||
|         "[%s] <%s> %s\n", | ||||
|         times.time_format(times.now(), times.format_rfc1123), | ||||
|         msgUsername, | ||||
|         msgText | ||||
|     )) | ||||
|     file.close() | ||||
| } | ||||
							
								
								
									
										19
									
								
								contrib/matterbridge.openrc
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										19
									
								
								contrib/matterbridge.openrc
									
									
									
									
									
										Executable file
									
								
							| @@ -0,0 +1,19 @@ | ||||
| #!/sbin/openrc-run | ||||
| # Copyright 2021-2022 Gentoo Authors | ||||
| # Distributed under the terms of the GNU General Public License v2 | ||||
|  | ||||
| command=/usr/bin/matterbridge | ||||
| command_args="-conf ${MATTERBRIDGE_CONF:-/etc/matterbridge/bridge.toml} ${MATTERBRIDGE_ARGS}" | ||||
| command_user="matterbridge:matterbridge" | ||||
| pidfile="/run/${RC_SVCNAME}.pid" | ||||
| command_background=1 | ||||
| output_log="/var/log/${RC_SVCNAME}.log" | ||||
| error_log="${output_log}" | ||||
|  | ||||
| depend() { | ||||
| 	need net | ||||
| } | ||||
|  | ||||
| start_pre() { | ||||
| 	checkpath -f "${output_log}" -o "${command_user}" || return 1 | ||||
| } | ||||
							
								
								
									
										12
									
								
								gateway/bridgemap/bharmony.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								gateway/bridgemap/bharmony.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,12 @@ | ||||
| //go:build !noharmony | ||||
| // +build !noharmony | ||||
|  | ||||
| package bridgemap | ||||
|  | ||||
| import ( | ||||
| 	bharmony "github.com/42wim/matterbridge/bridge/harmony" | ||||
| ) | ||||
|  | ||||
| func init() { | ||||
| 	FullMap["harmony"] = bharmony.New | ||||
| } | ||||
| @@ -66,7 +66,7 @@ func New(rootLogger *logrus.Logger, cfg *config.Gateway, r *Router) *Gateway { | ||||
| func (gw *Gateway) FindCanonicalMsgID(protocol string, mID string) string { | ||||
| 	ID := protocol + " " + mID | ||||
| 	if gw.Messages.Contains(ID) { | ||||
| 		return mID | ||||
| 		return ID | ||||
| 	} | ||||
|  | ||||
| 	// If not keyed, iterate through cache for downstream, and infer upstream. | ||||
| @@ -75,7 +75,7 @@ func (gw *Gateway) FindCanonicalMsgID(protocol string, mID string) string { | ||||
| 		ids := v.([]*BrMsgID) | ||||
| 		for _, downstreamMsgObj := range ids { | ||||
| 			if ID == downstreamMsgObj.ID { | ||||
| 				return strings.Replace(mid.(string), protocol+" ", "", 1) | ||||
| 				return mid.(string) | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| @@ -447,16 +447,19 @@ func (gw *Gateway) SendMessage( | ||||
| 	msg.Avatar = gw.modifyAvatar(rmsg, dest) | ||||
| 	msg.Username = gw.modifyUsername(rmsg, dest) | ||||
|  | ||||
| 	msg.ID = gw.getDestMsgID(rmsg.Protocol+" "+rmsg.ID, dest, channel) | ||||
| 	// exclude file delete event as the msg ID here is the native file ID that needs to be deleted | ||||
| 	if msg.Event != config.EventFileDelete { | ||||
| 		msg.ID = gw.getDestMsgID(rmsg.Protocol+" "+rmsg.ID, dest, channel) | ||||
| 	} | ||||
|  | ||||
| 	// for api we need originchannel as channel | ||||
| 	if dest.Protocol == apiProtocol { | ||||
| 		msg.Channel = rmsg.Channel | ||||
| 	} | ||||
|  | ||||
| 	msg.ParentID = gw.getDestMsgID(rmsg.Protocol+" "+canonicalParentMsgID, dest, channel) | ||||
| 	msg.ParentID = gw.getDestMsgID(canonicalParentMsgID, dest, channel) | ||||
| 	if msg.ParentID == "" { | ||||
| 		msg.ParentID = canonicalParentMsgID | ||||
| 		msg.ParentID = strings.Replace(canonicalParentMsgID, dest.Protocol+" ", "", 1) | ||||
| 	} | ||||
|  | ||||
| 	// if the parentID is still empty and we have a parentID set in the original message | ||||
|   | ||||
| @@ -110,7 +110,9 @@ func (r *Router) disableBridge(br *bridge.Bridge, err error) bool { | ||||
| 	if r.BridgeValues().General.IgnoreFailureOnStart { | ||||
| 		r.logger.Error(err) | ||||
| 		// setting this bridge empty | ||||
| 		*br = bridge.Bridge{} | ||||
| 		*br = bridge.Bridge{ | ||||
| 			Log: br.Log, | ||||
| 		} | ||||
| 		return true | ||||
| 	} | ||||
| 	return false | ||||
|   | ||||
							
								
								
									
										86
									
								
								go.mod
									
									
									
									
									
								
							
							
						
						
									
										86
									
								
								go.mod
									
									
									
									
									
								
							| @@ -5,33 +5,33 @@ require ( | ||||
| 	github.com/Baozisoftware/qrcode-terminal-go v0.0.0-20170407111555-c0650d8dff0f | ||||
| 	github.com/Benau/tgsconverter v0.0.0-20210809170556-99f4a4f6337f | ||||
| 	github.com/Philipp15b/go-steam v1.0.1-0.20200727090957-6ae9b3c0a560 | ||||
| 	github.com/Rhymen/go-whatsapp v0.1.2-0.20210615184944-2b8a3e9b8aa2 | ||||
| 	github.com/SevereCloud/vksdk/v2 v2.10.0 | ||||
| 	github.com/d5/tengo/v2 v2.8.0 | ||||
| 	github.com/Rhymen/go-whatsapp v0.1.2-0.20211102134409-31a2e740845c | ||||
| 	github.com/SevereCloud/vksdk/v2 v2.13.1 | ||||
| 	github.com/bwmarrin/discordgo v0.24.0 | ||||
| 	github.com/d5/tengo/v2 v2.10.1 | ||||
| 	github.com/davecgh/go-spew v1.1.1 | ||||
| 	github.com/fsnotify/fsnotify v1.5.1 | ||||
| 	github.com/go-telegram-bot-api/telegram-bot-api v1.0.1-0.20200524105306-7434b0456e81 | ||||
| 	github.com/gomarkdown/markdown v0.0.0-20210918233619-6c1113f12c4a | ||||
| 	github.com/google/gops v0.3.21 | ||||
| 	github.com/go-telegram-bot-api/telegram-bot-api/v5 v5.5.1 | ||||
| 	github.com/gomarkdown/markdown v0.0.0-20220310201231-552c6011c0b8 | ||||
| 	github.com/google/gops v0.3.22 | ||||
| 	github.com/gorilla/schema v1.2.0 | ||||
| 	github.com/gorilla/websocket v1.4.2 | ||||
| 	github.com/gorilla/websocket v1.5.0 | ||||
| 	github.com/harmony-development/shibshib v0.0.0-20220101224523-c98059d09cfa | ||||
| 	github.com/hashicorp/golang-lru v0.5.4 | ||||
| 	github.com/jpillora/backoff v1.0.0 | ||||
| 	github.com/keybase/go-keybase-chat-bot v0.0.0-20211004153716-fd2ee4d6be11 | ||||
| 	github.com/kyokomi/emoji/v2 v2.2.8 | ||||
| 	github.com/labstack/echo/v4 v4.6.1 | ||||
| 	github.com/lrstanley/girc v0.0.0-20210611213246-771323f1624b | ||||
| 	github.com/keybase/go-keybase-chat-bot v0.0.0-20211201215354-ee4b23828b55 | ||||
| 	github.com/kyokomi/emoji/v2 v2.2.9 | ||||
| 	github.com/labstack/echo/v4 v4.7.0 | ||||
| 	github.com/lrstanley/girc v0.0.0-20211023233735-147f0ff77566 | ||||
| 	github.com/matrix-org/gomatrix v0.0.0-20210324163249-be2af5ef2e16 | ||||
| 	github.com/matterbridge/Rocket.Chat.Go.SDK v0.0.0-20211016222428-79310a412696 | ||||
| 	github.com/matterbridge/discordgo v0.21.2-0.20210201201054-fb39a175b4f7 | ||||
| 	github.com/matterbridge/go-xmpp v0.0.0-20210731150933-5702291c239f | ||||
| 	github.com/matterbridge/gozulipbot v0.0.0-20200820220548-be5824faa913 | ||||
| 	github.com/matterbridge/go-xmpp v0.0.0-20211030125215-791a06c5f1be | ||||
| 	github.com/matterbridge/gozulipbot v0.0.0-20211023205727-a19d6c1f3b75 | ||||
| 	github.com/matterbridge/logrus-prefixed-formatter v0.5.3-0.20200523233437-d971309a77ba | ||||
| 	github.com/matterbridge/matterclient v0.0.0-20211016195328-346acac403d8 | ||||
| 	github.com/mattermost/mattermost-server/v5 v5.39.0 | ||||
| 	github.com/mattermost/mattermost-server/v6 v6.0.0 | ||||
| 	github.com/matterbridge/matterclient v0.0.0-20211107234719-faca3cd42315 | ||||
| 	github.com/mattermost/mattermost-server/v5 v5.39.3 | ||||
| 	github.com/mattermost/mattermost-server/v6 v6.4.2 | ||||
| 	github.com/mattn/godown v0.0.1 | ||||
| 	github.com/missdeer/golib v1.0.4 | ||||
| 	github.com/nelsonken/gomf v0.0.0-20180504123937-a9dd2f9deae9 | ||||
| 	github.com/paulrosania/go-charset v0.0.0-20190326053356-55c9d7a5834c | ||||
| 	github.com/rs/xid v1.3.0 | ||||
| @@ -39,15 +39,16 @@ require ( | ||||
| 	github.com/saintfish/chardet v0.0.0-20120816061221-3af4cd4741ca | ||||
| 	github.com/shazow/ssh-chat v1.10.1 | ||||
| 	github.com/sirupsen/logrus v1.8.1 | ||||
| 	github.com/slack-go/slack v0.9.5 | ||||
| 	github.com/spf13/viper v1.9.0 | ||||
| 	github.com/slack-go/slack v0.10.2 | ||||
| 	github.com/spf13/viper v1.10.1 | ||||
| 	github.com/stretchr/testify v1.7.0 | ||||
| 	github.com/vincent-petithory/dataurl v0.0.0-20191104211930-d1553a71de50 | ||||
| 	github.com/vincent-petithory/dataurl v1.0.0 | ||||
| 	github.com/writeas/go-strip-markdown v2.0.1+incompatible | ||||
| 	github.com/yaegashi/msgraph.go v0.1.4 | ||||
| 	github.com/zfjagann/golang-ring v0.0.0-20210116075443-7c86fdb43134 | ||||
| 	golang.org/x/image v0.0.0-20210628002857-a66eb6448b8d | ||||
| 	golang.org/x/oauth2 v0.0.0-20211005180243-6b3c2da341f1 | ||||
| 	golang.org/x/image v0.0.0-20220302094943-723b81ca9867 | ||||
| 	golang.org/x/oauth2 v0.0.0-20220309155454-6242fa91716a | ||||
| 	golang.org/x/text v0.3.7 | ||||
| 	gomod.garykim.dev/nc-talk v0.3.0 | ||||
| 	gopkg.in/olahol/melody.v1 v1.0.0-20170518105555-d52139073376 | ||||
| 	layeh.com/gumble v0.0.0-20200818122324-146f9205029b | ||||
| @@ -65,31 +66,32 @@ require ( | ||||
| 	github.com/go-asn1-ber/asn1-ber v1.5.3 // indirect | ||||
| 	github.com/golang-jwt/jwt v3.2.2+incompatible // indirect | ||||
| 	github.com/golang/protobuf v1.5.2 // indirect | ||||
| 	github.com/google/uuid v1.2.0 // indirect | ||||
| 	github.com/google/uuid v1.3.0 // indirect | ||||
| 	github.com/gopackage/ddp v0.0.3 // indirect | ||||
| 	github.com/hashicorp/errwrap v1.1.0 // indirect | ||||
| 	github.com/hashicorp/go-multierror v1.1.1 // indirect | ||||
| 	github.com/hashicorp/hcl v1.0.0 // indirect | ||||
| 	github.com/json-iterator/go v1.1.11 // indirect | ||||
| 	github.com/json-iterator/go v1.1.12 // indirect | ||||
| 	github.com/kettek/apng v0.0.0-20191108220231-414630eed80f // indirect | ||||
| 	github.com/klauspost/cpuid/v2 v2.0.6 // indirect | ||||
| 	github.com/labstack/gommon v0.3.0 // indirect | ||||
| 	github.com/klauspost/compress v1.14.2 // indirect | ||||
| 	github.com/klauspost/cpuid/v2 v2.0.9 // indirect | ||||
| 	github.com/labstack/gommon v0.3.1 // indirect | ||||
| 	github.com/magiconair/properties v1.8.5 // indirect | ||||
| 	github.com/mattermost/go-i18n v1.11.0 // indirect | ||||
| 	github.com/mattermost/go-i18n v1.11.1-0.20211013152124-5c415071e404 // indirect | ||||
| 	github.com/mattermost/ldap v0.0.0-20201202150706-ee0e6284187d // indirect | ||||
| 	github.com/mattermost/logr v1.0.13 // indirect | ||||
| 	github.com/mattermost/logr/v2 v2.0.10 // indirect | ||||
| 	github.com/mattn/go-colorable v0.1.8 // indirect | ||||
| 	github.com/mattermost/logr/v2 v2.0.15 // indirect | ||||
| 	github.com/mattn/go-colorable v0.1.12 // indirect | ||||
| 	github.com/mattn/go-isatty v0.0.14 // indirect | ||||
| 	github.com/mattn/go-runewidth v0.0.13 // indirect | ||||
| 	github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d // indirect | ||||
| 	github.com/minio/md5-simd v1.1.2 // indirect | ||||
| 	github.com/minio/minio-go/v7 v7.0.11 // indirect | ||||
| 	github.com/minio/minio-go/v7 v7.0.16 // indirect | ||||
| 	github.com/minio/sha256-simd v1.0.0 // indirect | ||||
| 	github.com/mitchellh/go-homedir v1.1.0 // indirect | ||||
| 	github.com/mitchellh/mapstructure v1.4.2 // indirect | ||||
| 	github.com/mitchellh/mapstructure v1.4.3 // indirect | ||||
| 	github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect | ||||
| 	github.com/modern-go/reflect2 v1.0.1 // indirect | ||||
| 	github.com/modern-go/reflect2 v1.0.2 // indirect | ||||
| 	github.com/monaco-io/request v1.0.5 // indirect | ||||
| 	github.com/mreiferson/go-httpclient v0.0.0-20201222173833-5e475fde3a4d // indirect | ||||
| 	github.com/mrexodia/wray v0.0.0-20160318003008-78a2c1f284ff // indirect | ||||
| @@ -109,28 +111,30 @@ require ( | ||||
| 	github.com/spf13/jwalterweatherman v1.1.0 // indirect | ||||
| 	github.com/spf13/pflag v1.0.5 // indirect | ||||
| 	github.com/subosito/gotenv v1.2.0 // indirect | ||||
| 	github.com/technoweenie/multipartstreamer v1.0.1 // indirect | ||||
| 	github.com/tinylib/msgp v1.1.6 // indirect | ||||
| 	github.com/valyala/bytebufferpool v1.0.0 // indirect | ||||
| 	github.com/valyala/fasttemplate v1.2.1 // indirect | ||||
| 	github.com/vmihailenco/msgpack/v5 v5.3.5 // indirect | ||||
| 	github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect | ||||
| 	github.com/wiggin77/cfg v1.0.2 // indirect | ||||
| 	github.com/wiggin77/merror v1.0.3 // indirect | ||||
| 	github.com/wiggin77/srslog v1.0.1 // indirect | ||||
| 	go.uber.org/atomic v1.8.0 // indirect | ||||
| 	go.uber.org/atomic v1.9.0 // indirect | ||||
| 	go.uber.org/multierr v1.7.0 // indirect | ||||
| 	go.uber.org/zap v1.17.0 // indirect | ||||
| 	golang.org/x/crypto v0.0.0-20210817164053-32db794688a5 // indirect | ||||
| 	golang.org/x/net v0.0.0-20210913180222-943fd674d43e // indirect | ||||
| 	golang.org/x/sys v0.0.0-20210910150752-751e447fb3d0 // indirect | ||||
| 	golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1 // indirect | ||||
| 	golang.org/x/text v0.3.7 // indirect | ||||
| 	golang.org/x/crypto v0.0.0-20211117183948-ae814b36b871 // indirect | ||||
| 	golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd // indirect | ||||
| 	golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e // indirect | ||||
| 	golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 // indirect | ||||
| 	golang.org/x/time v0.0.0-20201208040808-7e3f01d25324 // indirect | ||||
| 	google.golang.org/appengine v1.6.7 // indirect | ||||
| 	google.golang.org/protobuf v1.27.1 // indirect | ||||
| 	gopkg.in/ini.v1 v1.63.2 // indirect | ||||
| 	gopkg.in/ini.v1 v1.66.2 // indirect | ||||
| 	gopkg.in/natefinch/lumberjack.v2 v2.0.0 // indirect | ||||
| 	gopkg.in/yaml.v2 v2.4.0 // indirect | ||||
| 	gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect | ||||
| ) | ||||
|  | ||||
| replace github.com/matrix-org/gomatrix => github.com/matterbridge/gomatrix v0.0.0-20220205235239-607eb9ee6419 | ||||
|  | ||||
| go 1.17 | ||||
|   | ||||
| @@ -7,6 +7,7 @@ import ( | ||||
| 	"log" | ||||
| 	"net" | ||||
| 	"net/http" | ||||
| 	"regexp" | ||||
| ) | ||||
|  | ||||
| // Message for rocketchat outgoing webhook. | ||||
| @@ -68,7 +69,6 @@ func (c *Client) ServeHTTP(w http.ResponseWriter, r *http.Request) { | ||||
| 	} | ||||
| 	msg := Message{} | ||||
| 	body, err := ioutil.ReadAll(r.Body) | ||||
| 	log.Println(string(body)) | ||||
| 	if err != nil { | ||||
| 		log.Println(err) | ||||
| 		http.NotFound(w, r) | ||||
| @@ -89,7 +89,11 @@ func (c *Client) ServeHTTP(w http.ResponseWriter, r *http.Request) { | ||||
| 	msg.ChannelName = "#" + msg.ChannelName | ||||
| 	if c.Token != "" { | ||||
| 		if msg.Token != c.Token { | ||||
| 			log.Println("invalid token " + msg.Token + " from " + r.RemoteAddr) | ||||
| 			if regexp.MustCompile(`[^a-zA-Z0-9]+`).MatchString(msg.Token) { | ||||
| 				log.Println("invalid token " + msg.Token + " from " + r.RemoteAddr) | ||||
| 			} else { | ||||
| 				log.Println("invalid token from " + r.RemoteAddr) | ||||
| 			} | ||||
| 			http.NotFound(w, r) | ||||
| 			return | ||||
| 		} | ||||
|   | ||||
| @@ -10,15 +10,13 @@ import ( | ||||
| 	"github.com/42wim/matterbridge/bridge/config" | ||||
| 	"github.com/42wim/matterbridge/gateway" | ||||
| 	"github.com/42wim/matterbridge/gateway/bridgemap" | ||||
| 	"github.com/42wim/matterbridge/version" | ||||
| 	"github.com/google/gops/agent" | ||||
| 	prefixed "github.com/matterbridge/logrus-prefixed-formatter" | ||||
| 	"github.com/sirupsen/logrus" | ||||
| ) | ||||
|  | ||||
| var ( | ||||
| 	version = "1.23.0" | ||||
| 	githash string | ||||
|  | ||||
| 	flagConfig  = flag.String("conf", "matterbridge.toml", "config file") | ||||
| 	flagDebug   = flag.Bool("debug", false, "enable debug") | ||||
| 	flagVersion = flag.Bool("version", false, "show version") | ||||
| @@ -28,7 +26,7 @@ var ( | ||||
| func main() { | ||||
| 	flag.Parse() | ||||
| 	if *flagVersion { | ||||
| 		fmt.Printf("version: %s %s\n", version, githash) | ||||
| 		fmt.Printf("version: %s %s\n", version.Release, version.GitHash) | ||||
| 		return | ||||
| 	} | ||||
|  | ||||
| @@ -43,8 +41,8 @@ func main() { | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	logger.Printf("Running version %s %s", version, githash) | ||||
| 	if strings.Contains(version, "-dev") { | ||||
| 	logger.Printf("Running version %s %s", version.Release, version.GitHash) | ||||
| 	if strings.Contains(version.Release, "-dev") { | ||||
| 		logger.Println("WARNING: THIS IS A DEVELOPMENT VERSION. Things may break.") | ||||
| 	} | ||||
|  | ||||
|   | ||||
| @@ -24,6 +24,13 @@ Password="" | ||||
| #OPTIONAL (default false) | ||||
| UseTLS=false | ||||
|  | ||||
| #Use client certificate - see CertFP https://libera.chat/guides/certfp.html | ||||
| #Specify filename which contains private key and cert | ||||
| #OPTIONAL (default "") | ||||
| # | ||||
| #TLSClientCertificate="cert.pem" | ||||
| TLSClientCertificate="" | ||||
|  | ||||
| #Enable SASL (PLAIN) authentication. (libera requires this from eg AWS hosts) | ||||
| #It uses NickServNick and NickServPassword as login and password | ||||
| #OPTIONAL (default false) | ||||
| @@ -34,6 +41,11 @@ UseSASL=false | ||||
| #OPTIONAL (default false) | ||||
| SkipTLSVerify=true | ||||
|  | ||||
| #Local address to use for server connection | ||||
| #Note that Server and Bind must resolve to addresses of the same family. | ||||
| #OPTIONAL (default "") | ||||
| Bind="" | ||||
|  | ||||
| #If you know your charset, you can specify it manually. | ||||
| #Otherwise it tries to detect this automatically. Select one below | ||||
| # "iso-8859-2:1987", "iso-8859-9:1989", "866", "latin9", "iso-8859-10:1992", "iso-ir-109", "hebrew", | ||||
| @@ -396,6 +408,10 @@ SkipTLSVerify=true | ||||
| ## RELOADABLE SETTINGS | ||||
| ## Settings below can be reloaded by editing the file | ||||
|  | ||||
| # UseUserName shows the username instead of the server nickname | ||||
| # OPTIONAL (default false) | ||||
| UseUserName=false | ||||
|  | ||||
| #how to format the list of IRC nicks when displayed in mattermost. | ||||
| #Possible options are "table" and "plain" | ||||
| #OPTIONAL (default plain) | ||||
| @@ -1534,10 +1550,6 @@ MessageClipped="<clipped message>" | ||||
| #See https://vk.com/dev/bots_docs | ||||
| Token="Yourtokenhere" | ||||
|  | ||||
| #Group ID | ||||
| #For example in URL https://vk.com/public168963511 group ID is 168963511 | ||||
| GroupID=123456789 | ||||
|  | ||||
| ################################################################### | ||||
| # WhatsApp | ||||
| ################################################################### | ||||
| @@ -1655,6 +1667,18 @@ StripNick=false | ||||
| #OPTIONAL (default false) | ||||
| ShowTopicChange=false | ||||
|  | ||||
| ################################################################### | ||||
| # Harmony | ||||
| ################################################################### | ||||
|  | ||||
| [harmony.chat_harmonyapp_io] | ||||
| Homeserver = "https://chat.harmonyapp.io:2289" | ||||
| Token = "your token goes here" | ||||
| UserID = "user id of the bot account" | ||||
| Community = "community id that channels will be located in" | ||||
| UseUserName = true | ||||
| RemoteNickFormat = "{NICK}" | ||||
|  | ||||
| ################################################################### | ||||
| #API | ||||
| ################################################################### | ||||
| @@ -1700,6 +1724,7 @@ RemoteNickFormat="{NICK}" | ||||
|  | ||||
| #RemoteNickFormat defines how remote users appear on this bridge | ||||
| #The string "{NICK}" (case sensitive) will be replaced by the actual nick. | ||||
| #The string "{NOPINGNICK}" (case sensitive) will be replaced by the actual nick / username, but with a ZWSP inside the nick, so the irc user with the same nick won't get pinged. | ||||
| #The string "{USERID}" (case sensitive) will be replaced by the user ID. | ||||
| #The string "{BRIDGE}" (case sensitive) will be replaced by the sending bridge | ||||
| #The string "{LABEL}" (case sensitive) will be replaced by label= field of the sending bridge | ||||
| @@ -1872,7 +1897,8 @@ enable=true | ||||
|     # ------------------------------------------------------------------------------------------------------------------------------------- | ||||
|     #    irc     |      channel       |            #general           | The # symbol is required and should be lowercase! | ||||
|     # ------------------------------------------------------------------------------------------------------------------------------------- | ||||
|     # mattermost |      channel       |            general            | This is the channel name as seen in the URL, not the display name | ||||
|     #            |      channel       |            general            | This is the channel name as seen in the URL, not the display name | ||||
|     # mattermost |    channel id      | ID:oc4wifyuojgw5f3nsuweesmz8w | This is the channel ID (only use if you know what you're doing) | ||||
|     # ------------------------------------------------------------------------------------------------------------------------------------- | ||||
|     #   matrix   | #channel:server    |    #yourchannel:matrix.org    | Encrypted rooms are not supported in matrix | ||||
|     # ------------------------------------------------------------------------------------------------------------------------------------- | ||||
| @@ -1898,7 +1924,7 @@ enable=true | ||||
|     # ------------------------------------------------------------------------------------------------------------------------------------- | ||||
|     #    xmpp    |      channel       |            general            | The room name | ||||
|     # ------------------------------------------------------------------------------------------------------------------------------------- | ||||
|     #   zulip    | stream/topic:topic |     general/off-topic:food    | Do not use the # when specifying a topic | ||||
|     #   zulip    | stream/topic:topic |      general/topic:food       | Do not use the # when specifying a topic | ||||
|     # ------------------------------------------------------------------------------------------------------------------------------------- | ||||
|  | ||||
|     # | ||||
| @@ -1947,6 +1973,10 @@ enable=true | ||||
|     account="zulip.streamchat" | ||||
|     channel="general/topic:mytopic" | ||||
|  | ||||
|     [[gateway.inout]] | ||||
|     account="harmony.chat_harmonyapp_io" | ||||
|     channel="channel id goes here" | ||||
|  | ||||
|     #API example | ||||
|     #[[gateway.inout]] | ||||
|     #account="api.local" | ||||
|   | ||||
| @@ -9,7 +9,7 @@ import ( | ||||
| func (m *MMClient) parseActionPost(rmsg *Message) { | ||||
| 	// add post to cache, if it already exists don't relay this again. | ||||
| 	// this should fix reposts | ||||
| 	if ok, _ := m.lruCache.ContainsOrAdd(digestString(rmsg.Raw.Data["post"].(string)), true); ok { | ||||
| 	if ok, _ := m.lruCache.ContainsOrAdd(digestString(rmsg.Raw.Data["post"].(string)), true); ok && rmsg.Raw.Event != model.WEBSOCKET_EVENT_POST_DELETED { | ||||
| 		m.logger.Debugf("message %#v in cache, not processing again", rmsg.Raw.Data["post"].(string)) | ||||
| 		rmsg.Text = "" | ||||
| 		return | ||||
|   | ||||
| @@ -5,7 +5,7 @@ RUN apk add \ | ||||
|     go \ | ||||
|     git \ | ||||
|   && cd /go/src/matterbridge \ | ||||
|   && go build -mod vendor -ldflags "-X main.githash=$(git log --pretty=format:'%h' -n 1)" -o /bin/matterbridge | ||||
|   && CGO_ENABLED=0 go build -mod vendor -ldflags "-X github.com/42wim/matterbridge/version.GitHash=$(git log --pretty=format:'%h' -n 1)" -o /bin/matterbridge | ||||
|  | ||||
| FROM alpine | ||||
| RUN apk --no-cache add \ | ||||
|   | ||||
							
								
								
									
										2
									
								
								vendor/github.com/Rhymen/go-whatsapp/README.md
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								vendor/github.com/Rhymen/go-whatsapp/README.md
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -70,7 +70,7 @@ func (myHandler) HandleContactMessage(message whatsapp.ContactMessage) { | ||||
| 	fmt.Println(message) | ||||
| } | ||||
|  | ||||
| func (myHandler) HandleBatteryMessage(msg whatsapp.BatteryMessage) { | ||||
| func (myHandler) HandleBatteryMessage(message whatsapp.BatteryMessage) { | ||||
| 	fmt.Println(message) | ||||
| } | ||||
|  | ||||
|   | ||||
							
								
								
									
										4
									
								
								vendor/github.com/Rhymen/go-whatsapp/session.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								vendor/github.com/Rhymen/go-whatsapp/session.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -18,7 +18,7 @@ import ( | ||||
| ) | ||||
|  | ||||
| //represents the WhatsAppWeb client version | ||||
| var waVersion = []int{2, 2121, 6} | ||||
| var waVersion = []int{2, 2142, 12} | ||||
|  | ||||
| /* | ||||
| Session contains session individual information. To be able to resume the connection without scanning the qr code | ||||
| @@ -526,5 +526,7 @@ func (wac *Conn) Logout() error { | ||||
| 		return fmt.Errorf("error writing logout: %v\n", err) | ||||
| 	} | ||||
|  | ||||
| 	wac.loggedIn = false | ||||
|  | ||||
| 	return nil | ||||
| } | ||||
|   | ||||
							
								
								
									
										14
									
								
								vendor/github.com/SevereCloud/vksdk/v2/.golangci.yml
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										14
									
								
								vendor/github.com/SevereCloud/vksdk/v2/.golangci.yml
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -48,10 +48,18 @@ linters: | ||||
|     - nilerr | ||||
|     - revive | ||||
|     - wastedassign | ||||
|     - bidichk | ||||
|     - contextcheck | ||||
|     - ireturn | ||||
|     - nilnil | ||||
|     - tenv | ||||
|     - nestif | ||||
|     - grouper | ||||
|     - decorder | ||||
|     - containedctx | ||||
|  | ||||
| # - wrapcheck # TODO: v3 Fix | ||||
| # - testpackage # TODO: Fix testpackage | ||||
| # - nestif # TODO: Fix nestif | ||||
| # - noctx # TODO: Fix noctx | ||||
|  | ||||
| # don't enable: | ||||
| @@ -75,6 +83,10 @@ linters: | ||||
| # - cyclop | ||||
| # - promlinter | ||||
| # - tagliatelle | ||||
| # - errname | ||||
| # - varnamelen | ||||
| # - errchkjson | ||||
| # - maintidx | ||||
|  | ||||
| # depricated | ||||
| # - maligned | ||||
|   | ||||
							
								
								
									
										1
									
								
								vendor/github.com/SevereCloud/vksdk/v2/.markdownlint.yml
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								vendor/github.com/SevereCloud/vksdk/v2/.markdownlint.yml
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,2 +1,3 @@ | ||||
| --- | ||||
| no-hard-tabs: false | ||||
| no-duplicate-heading: false | ||||
|   | ||||
							
								
								
									
										20
									
								
								vendor/github.com/SevereCloud/vksdk/v2/.travis.yml
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										20
									
								
								vendor/github.com/SevereCloud/vksdk/v2/.travis.yml
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,20 +0,0 @@ | ||||
| --- | ||||
| language: go | ||||
|  | ||||
| cache: | ||||
|   directories: | ||||
|     - $HOME/.cache/go-build | ||||
|     - $HOME/gopath/pkg/mod | ||||
|  | ||||
| go: | ||||
|   - 1.x | ||||
|  | ||||
| before_script: | ||||
|   - git fetch --depth=1 origin +refs/tags/*:refs/tags/* | ||||
|   - git describe --tags $(git rev-list --tags --max-count=1) --always | ||||
|  | ||||
| script: | ||||
|   - go test -v -race -coverprofile=coverage.txt -covermode=atomic -p=1 ./... | ||||
|  | ||||
| after_success: | ||||
|   - bash <(curl -s https://codecov.io/bash) | ||||
							
								
								
									
										4
									
								
								vendor/github.com/SevereCloud/vksdk/v2/CONTRIBUTING.md
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								vendor/github.com/SevereCloud/vksdk/v2/CONTRIBUTING.md
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -6,7 +6,7 @@ | ||||
|  | ||||
| Требования: | ||||
|  | ||||
| - [Go 1.13+](https://golang.org/doc/install) | ||||
| - [Go 1.16+](https://golang.org/doc/install) | ||||
| - [golangci-lint](https://github.com/golangci/golangci-lint) | ||||
| - [global .gitignore](https://help.github.com/en/articles/ignoring-files#create-a-global-gitignore) | ||||
|  | ||||
| @@ -39,6 +39,7 @@ golangci-lint run | ||||
| # CLIENT_SECRET="" | ||||
| # USER_TOKEN="" | ||||
| # WIDGET_TOKEN="" | ||||
| # MARUSIA_TOKEN="" | ||||
| # CLIENT_ID="123456" | ||||
| # GROUP_ID="123456" | ||||
| # ACCOUNT_ID="123456" | ||||
| @@ -56,6 +57,7 @@ go test ./... | ||||
|     "go.testEnvVars": { | ||||
|         "SERVICE_TOKEN": "", | ||||
|         "WIDGET_TOKEN": "", | ||||
|         "MARUSIA_TOKEN": "", | ||||
|         "GROUP_TOKEN": "", | ||||
|         "CLIENT_SECRET": "", | ||||
|         "USER_TOKEN": "", | ||||
|   | ||||
							
								
								
									
										8
									
								
								vendor/github.com/SevereCloud/vksdk/v2/README.md
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										8
									
								
								vendor/github.com/SevereCloud/vksdk/v2/README.md
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,6 +1,5 @@ | ||||
| # VK SDK for Golang | ||||
|  | ||||
| [](https://travis-ci.com/SevereCloud/vksdk) | ||||
| [](https://pkg.go.dev/github.com/SevereCloud/vksdk/v2?tab=subdirectories) | ||||
| [](https://vk.com/dev/) | ||||
| [](https://codecov.io/gh/SevereCloud/vksdk) | ||||
| @@ -17,11 +16,13 @@ | ||||
| Version API 5.131. | ||||
|  | ||||
| - [API](https://pkg.go.dev/github.com/SevereCloud/vksdk/v2/api) | ||||
|   - 400+ methods | ||||
|   - Ability to change the request handler | ||||
|   - 500+ methods | ||||
|   - Ability to modify HTTP client | ||||
|   - Request Limiter | ||||
|   - Support [zstd](https://pkg.go.dev/github.com/SevereCloud/vksdk/v2/api#VK.EnableZstd) | ||||
| and [MessagePack](https://pkg.go.dev/github.com/SevereCloud/vksdk/v2/api#VK.EnableMessagePack) | ||||
|   - Token pool | ||||
|   - [OAuth](https://pkg.go.dev/github.com/SevereCloud/vksdk/v2/api/oauth) | ||||
| - [Callback API](https://pkg.go.dev/github.com/SevereCloud/vksdk/v2/callback) | ||||
|   - Tracking tool for users activity in your VK communities | ||||
|   - Supports all events | ||||
| @@ -61,6 +62,7 @@ go get github.com/SevereCloud/vksdk/v2@latest | ||||
|  | ||||
| ## Use by | ||||
|  | ||||
| - A simple chat bridge: <https://github.com/42wim/matterbridge> | ||||
| - [Joe](https://github.com/go-joe/joe) adapter: <https://github.com/tdakkota/joe-vk-adapter> | ||||
| - [Logrus](https://github.com/sirupsen/logrus) hook: <https://github.com/SevereCloud/vkrus> | ||||
|  | ||||
|   | ||||
							
								
								
									
										50
									
								
								vendor/github.com/SevereCloud/vksdk/v2/api/README.md
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										50
									
								
								vendor/github.com/SevereCloud/vksdk/v2/api/README.md
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -3,7 +3,7 @@ | ||||
| [](https://pkg.go.dev/github.com/SevereCloud/vksdk/v2/api) | ||||
| [](https://vk.com/dev/first_guide) | ||||
|  | ||||
| Данная библиотека поддерживает версию API **5.122**. | ||||
| Данная библиотека поддерживает версию API **5.131**. | ||||
|  | ||||
| ## Запросы | ||||
|  | ||||
| @@ -80,6 +80,54 @@ if errors.As(err, &e) { | ||||
|  | ||||
| Для Execute существует отдельная ошибка `ExecuteErrors` | ||||
|  | ||||
| ### Поддержка MessagePack и zstd | ||||
|  | ||||
| > Результат перехода с gzip (JSON) на zstd (msgpack): | ||||
| > | ||||
| > - в 7 раз быстрее сжатие (–1 мкс); | ||||
| > - на 10% меньше размер данных (8 Кбайт вместо 9 Кбайт); | ||||
| > - продуктовый эффект не статзначимый :( | ||||
| > | ||||
| > [Как мы отказались от JPEG, JSON, TCP и ускорили ВКонтакте в два раза](https://habr.com/ru/company/vk/blog/594633/) | ||||
|  | ||||
| VK API способно возвращать ответ в виде [MessagePack](https://msgpack.org/). | ||||
| Это эффективный формат двоичной сериализации, похожий на JSON, только быстрее | ||||
| и меньше по размеру. | ||||
|  | ||||
| ВНИМАНИЕ, C MessagePack НЕКОТОРЫЕ МЕТОДЫ МОГУТ ВОЗВРАЩАТЬ | ||||
| СЛОМАННУЮ КОДИРОВКУ. | ||||
|  | ||||
| Для сжатия, вместо классического gzip, можно использовать | ||||
| [zstd](https://github.com/facebook/zstd). Сейчас vksdk поддерживает zstd без | ||||
| словаря. Если кто знает как получать словарь, | ||||
| [отпишитесь сюда](https://github.com/SevereCloud/vksdk/issues/180). | ||||
|  | ||||
| ```go | ||||
| vk := api.NewVK(os.Getenv("USER_TOKEN")) | ||||
|  | ||||
| method := "store.getStickersKeywords" | ||||
| params := api.Params{ | ||||
| 	"aliases":       true, | ||||
| 	"all_products":  true, | ||||
| 	"need_stickers": true, | ||||
| } | ||||
|  | ||||
| r, err := vk.Request(method, params) // Content-Length: 44758 | ||||
| if err != nil { | ||||
| 	log.Fatal(err) | ||||
| } | ||||
| log.Println("json:", len(r)) // json: 814231 | ||||
|  | ||||
| vk.EnableMessagePack() // Включаем поддержку MessagePack | ||||
| vk.EnableZstd() // Включаем поддержку zstd | ||||
|  | ||||
| r, err = vk.Request(method, params) // Content-Length: 35755 | ||||
| if err != nil { | ||||
| 	log.Fatal(err) | ||||
| } | ||||
| log.Println("msgpack:", len(r)) // msgpack: 650775 | ||||
| ``` | ||||
|  | ||||
| ### Запрос любого метода | ||||
|  | ||||
| Пример запроса [users.get](https://vk.com/dev/users.get) | ||||
|   | ||||
							
								
								
									
										21
									
								
								vendor/github.com/SevereCloud/vksdk/v2/api/ads.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										21
									
								
								vendor/github.com/SevereCloud/vksdk/v2/api/ads.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,9 +1,11 @@ | ||||
| package api // import "github.com/SevereCloud/vksdk/v2/api" | ||||
|  | ||||
| import ( | ||||
| 	"bytes" | ||||
| 	"encoding/json" | ||||
|  | ||||
| 	"github.com/SevereCloud/vksdk/v2/object" | ||||
| 	"github.com/vmihailenco/msgpack/v5" | ||||
| ) | ||||
|  | ||||
| // AdsAddOfficeUsersItem struct. | ||||
| @@ -21,6 +23,23 @@ func (r *AdsAddOfficeUsersItem) UnmarshalJSON(data []byte) (err error) { | ||||
| 	return | ||||
| } | ||||
|  | ||||
| // DecodeMsgpack func. | ||||
| func (r *AdsAddOfficeUsersItem) DecodeMsgpack(dec *msgpack.Decoder) error { | ||||
| 	data, err := dec.DecodeRaw() | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
|  | ||||
| 	if msgpack.Unmarshal(data, &r.OK) != nil { | ||||
| 		d := msgpack.NewDecoder(bytes.NewReader(data)) | ||||
| 		d.SetCustomStructTag("json") | ||||
|  | ||||
| 		return d.Decode(&r.Error) | ||||
| 	} | ||||
|  | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // AdsAddOfficeUsersResponse struct. | ||||
| type AdsAddOfficeUsersResponse []AdsAddOfficeUsersItem | ||||
|  | ||||
| @@ -349,7 +368,7 @@ func (vk *VK) AdsGetAdsLayout(params Params) (response AdsGetAdsLayoutResponse, | ||||
|  | ||||
| // AdsGetMusiciansResponse struct. | ||||
| type AdsGetMusiciansResponse struct { | ||||
| 	Items []object.BaseObjectWithName | ||||
| 	Items []object.AdsMusician | ||||
| } | ||||
|  | ||||
| // AdsGetMusicians returns a list of musicians. | ||||
|   | ||||
							
								
								
									
										98
									
								
								vendor/github.com/SevereCloud/vksdk/v2/api/api.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										98
									
								
								vendor/github.com/SevereCloud/vksdk/v2/api/api.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -7,9 +7,11 @@ package api // import "github.com/SevereCloud/vksdk/v2/api" | ||||
|  | ||||
| import ( | ||||
| 	"bytes" | ||||
| 	"compress/gzip" | ||||
| 	"context" | ||||
| 	"encoding/json" | ||||
| 	"fmt" | ||||
| 	"io" | ||||
| 	"mime" | ||||
| 	"net/http" | ||||
| 	"net/url" | ||||
| @@ -21,6 +23,8 @@ import ( | ||||
| 	"github.com/SevereCloud/vksdk/v2" | ||||
| 	"github.com/SevereCloud/vksdk/v2/internal" | ||||
| 	"github.com/SevereCloud/vksdk/v2/object" | ||||
| 	"github.com/klauspost/compress/zstd" | ||||
| 	"github.com/vmihailenco/msgpack/v5" | ||||
| ) | ||||
|  | ||||
| // Api constants. | ||||
| @@ -91,6 +95,9 @@ type VK struct { | ||||
| 	UserAgent    string | ||||
| 	Handler      func(method string, params ...Params) (Response, error) | ||||
|  | ||||
| 	msgpack bool | ||||
| 	zstd    bool | ||||
|  | ||||
| 	mux      sync.Mutex | ||||
| 	lastTime time.Time | ||||
| 	rps      int | ||||
| @@ -98,9 +105,9 @@ type VK struct { | ||||
|  | ||||
| // Response struct. | ||||
| type Response struct { | ||||
| 	Response      json.RawMessage `json:"response"` | ||||
| 	Error         Error           `json:"error"` | ||||
| 	ExecuteErrors ExecuteErrors   `json:"execute_errors"` | ||||
| 	Response      object.RawMessage `json:"response"` | ||||
| 	Error         Error             `json:"error"` | ||||
| 	ExecuteErrors ExecuteErrors     `json:"execute_errors"` | ||||
| } | ||||
|  | ||||
| // NewVK returns a new VK. | ||||
| @@ -121,7 +128,7 @@ func NewVK(tokens ...string) *VK { | ||||
| 	vk.accessTokens = tokens | ||||
| 	vk.Version = Version | ||||
|  | ||||
| 	vk.Handler = vk.defaultHandler | ||||
| 	vk.Handler = vk.DefaultHandler | ||||
|  | ||||
| 	vk.MethodURL = MethodURL | ||||
| 	vk.Client = http.DefaultClient | ||||
| @@ -207,8 +214,8 @@ func buildQuery(sliceParams ...Params) (context.Context, url.Values) { | ||||
| 	return ctx, query | ||||
| } | ||||
|  | ||||
| // defaultHandler provides access to VK API methods. | ||||
| func (vk *VK) defaultHandler(method string, sliceParams ...Params) (Response, error) { | ||||
| // DefaultHandler provides access to VK API methods. | ||||
| func (vk *VK) DefaultHandler(method string, sliceParams ...Params) (Response, error) { | ||||
| 	u := vk.MethodURL + method | ||||
| 	ctx, query := buildQuery(sliceParams...) | ||||
| 	attempt := 0 | ||||
| @@ -243,24 +250,58 @@ func (vk *VK) defaultHandler(method string, sliceParams ...Params) (Response, er | ||||
| 			return response, err | ||||
| 		} | ||||
|  | ||||
| 		acceptEncoding := "gzip" | ||||
| 		if vk.zstd { | ||||
| 			acceptEncoding = "zstd" | ||||
| 		} | ||||
|  | ||||
| 		req.Header.Set("User-Agent", vk.UserAgent) | ||||
| 		req.Header.Set("Content-Type", "application/x-www-form-urlencoded") | ||||
|  | ||||
| 		req.Header.Set("Accept-Encoding", acceptEncoding) | ||||
|  | ||||
| 		var reader io.Reader | ||||
|  | ||||
| 		resp, err := vk.Client.Do(req) | ||||
| 		if err != nil { | ||||
| 			return response, err | ||||
| 		} | ||||
|  | ||||
| 		mediatype, _, _ := mime.ParseMediaType(resp.Header.Get("Content-Type")) | ||||
| 		if mediatype != "application/json" { | ||||
| 			_ = resp.Body.Close() | ||||
| 			return response, &InvalidContentType{mediatype} | ||||
| 		switch resp.Header.Get("Content-Encoding") { | ||||
| 		case "zstd": | ||||
| 			zstdReader, _ := zstd.NewReader(resp.Body) | ||||
| 			defer zstdReader.Close() | ||||
|  | ||||
| 			reader = zstdReader | ||||
| 		case "gzip": | ||||
| 			gzipReader, _ := gzip.NewReader(resp.Body) | ||||
| 			defer gzipReader.Close() | ||||
|  | ||||
| 			reader = gzipReader | ||||
| 		default: | ||||
| 			reader = resp.Body | ||||
| 		} | ||||
|  | ||||
| 		err = json.NewDecoder(resp.Body).Decode(&response) | ||||
| 		if err != nil { | ||||
| 		mediatype, _, _ := mime.ParseMediaType(resp.Header.Get("Content-Type")) | ||||
| 		switch mediatype { | ||||
| 		case "application/json": | ||||
| 			err = json.NewDecoder(reader).Decode(&response) | ||||
| 			if err != nil { | ||||
| 				_ = resp.Body.Close() | ||||
| 				return response, err | ||||
| 			} | ||||
| 		case "application/x-msgpack": | ||||
| 			dec := msgpack.NewDecoder(reader) | ||||
| 			dec.SetCustomStructTag("json") | ||||
|  | ||||
| 			err = dec.Decode(&response) | ||||
| 			if err != nil { | ||||
| 				_ = resp.Body.Close() | ||||
| 				return response, err | ||||
| 			} | ||||
| 		default: | ||||
| 			_ = resp.Body.Close() | ||||
| 			return response, err | ||||
| 			return response, &InvalidContentType{mediatype} | ||||
| 		} | ||||
|  | ||||
| 		_ = resp.Body.Close() | ||||
| @@ -291,6 +332,10 @@ func (vk *VK) Request(method string, sliceParams ...Params) ([]byte, error) { | ||||
|  | ||||
| 	sliceParams = append(sliceParams, reqParams) | ||||
|  | ||||
| 	if vk.msgpack { | ||||
| 		method += ".msgpack" | ||||
| 	} | ||||
|  | ||||
| 	resp, err := vk.Handler(method, sliceParams...) | ||||
|  | ||||
| 	return resp.Response, err | ||||
| @@ -303,7 +348,32 @@ func (vk *VK) RequestUnmarshal(method string, obj interface{}, sliceParams ...Pa | ||||
| 		return err | ||||
| 	} | ||||
|  | ||||
| 	return json.Unmarshal(rawResponse, &obj) | ||||
| 	if vk.msgpack { | ||||
| 		dec := msgpack.NewDecoder(bytes.NewReader(rawResponse)) | ||||
| 		dec.SetCustomStructTag("json") | ||||
|  | ||||
| 		err = dec.Decode(&obj) | ||||
| 	} else { | ||||
| 		err = json.Unmarshal(rawResponse, &obj) | ||||
| 	} | ||||
|  | ||||
| 	return err | ||||
| } | ||||
|  | ||||
| // EnableMessagePack enable using MessagePack instead of JSON. | ||||
| // | ||||
| // THIS IS EXPERIMENTAL FUNCTION! Broken encoding returned in some methods. | ||||
| // | ||||
| // See https://msgpack.org | ||||
| func (vk *VK) EnableMessagePack() { | ||||
| 	vk.msgpack = true | ||||
| } | ||||
|  | ||||
| // EnableZstd enable using zstd instead of gzip. | ||||
| // | ||||
| // This not use dict. | ||||
| func (vk *VK) EnableZstd() { | ||||
| 	vk.zstd = true | ||||
| } | ||||
|  | ||||
| func fmtReflectValue(value reflect.Value, depth int) string { | ||||
|   | ||||
							
								
								
									
										59
									
								
								vendor/github.com/SevereCloud/vksdk/v2/api/auth.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										59
									
								
								vendor/github.com/SevereCloud/vksdk/v2/api/auth.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,5 +1,9 @@ | ||||
| package api // import "github.com/SevereCloud/vksdk/v2/api" | ||||
|  | ||||
| import ( | ||||
| 	"github.com/SevereCloud/vksdk/v2/object" | ||||
| ) | ||||
|  | ||||
| // AuthCheckPhone checks a user's phone number for correctness. | ||||
| // | ||||
| // https://vk.com/dev/auth.checkPhone | ||||
| @@ -24,3 +28,58 @@ func (vk *VK) AuthRestore(params Params) (response AuthRestoreResponse, err erro | ||||
| 	err = vk.RequestUnmarshal("auth.restore", &response, params) | ||||
| 	return | ||||
| } | ||||
|  | ||||
| // AuthGetProfileInfoBySilentTokenResponse struct. | ||||
| type AuthGetProfileInfoBySilentTokenResponse struct { | ||||
| 	Success []object.AuthSilentTokenProfile `json:"success"` | ||||
| 	Errors  []AuthSilentTokenError          `json:"errors"` | ||||
| } | ||||
|  | ||||
| // AuthGetProfileInfoBySilentToken method. | ||||
| // | ||||
| // https://platform.vk.com/?p=DocsDashboard&docs=tokens_silent-token | ||||
| func (vk *VK) AuthGetProfileInfoBySilentToken(params Params) (response AuthGetProfileInfoBySilentTokenResponse, err error) { | ||||
| 	err = vk.RequestUnmarshal("auth.getProfileInfoBySilentToken", &response, params) | ||||
| 	return | ||||
| } | ||||
|  | ||||
| // ExchangeSilentTokenSource call conditions exchangeSilentToken. | ||||
| // | ||||
| // 	0	Unknown | ||||
| // 	1	Silent authentication | ||||
| // 	2	Auth by login and password | ||||
| // 	3	Extended registration | ||||
| // 	4	Auth by exchange token | ||||
| // 	5	Auth by exchange token on reset password | ||||
| // 	6	Auth by exchange token on unblock | ||||
| // 	7	Auth by exchange token on reset session | ||||
| // 	8	Auth by exchange token on change password | ||||
| // 	9	Finish phone validation on authentication | ||||
| // 	10	Auth by code | ||||
| // 	11	Auth by external oauth | ||||
| // 	12	Reactivation | ||||
| // 	15	Auth by SDK temporary access-token | ||||
| type ExchangeSilentTokenSource int | ||||
|  | ||||
| // AuthExchangeSilentAuthTokenResponse struct. | ||||
| type AuthExchangeSilentAuthTokenResponse struct { | ||||
| 	AccessToken              string                    `json:"access_token"` | ||||
| 	AccessTokenID            string                    `json:"access_token_id"` | ||||
| 	UserID                   int                       `json:"user_id"` | ||||
| 	Phone                    string                    `json:"phone"` | ||||
| 	PhoneValidated           interface{}               `json:"phone_validated"` | ||||
| 	IsPartial                bool                      `json:"is_partial"` | ||||
| 	IsService                bool                      `json:"is_service"` | ||||
| 	AdditionalSignupRequired bool                      `json:"additional_signup_required"` | ||||
| 	Email                    string                    `json:"email"` | ||||
| 	Source                   ExchangeSilentTokenSource `json:"source"` | ||||
| 	SourceDescription        string                    `json:"source_description"` | ||||
| } | ||||
|  | ||||
| // AuthExchangeSilentAuthToken method. | ||||
| // | ||||
| // https://platform.vk.com/?p=DocsDashboard&docs=tokens_access-token | ||||
| func (vk *VK) AuthExchangeSilentAuthToken(params Params) (response AuthExchangeSilentAuthTokenResponse, err error) { | ||||
| 	err = vk.RequestUnmarshal("auth.exchangeSilentAuthToken", &response, params) | ||||
| 	return | ||||
| } | ||||
|   | ||||
							
								
								
									
										82
									
								
								vendor/github.com/SevereCloud/vksdk/v2/api/errors.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										82
									
								
								vendor/github.com/SevereCloud/vksdk/v2/api/errors.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -159,6 +159,9 @@ const ( | ||||
| 	ErrRateLimit      ErrorType = 29 | ||||
| 	ErrPrivateProfile ErrorType = 30 // This profile is private | ||||
|  | ||||
| 	// Client version deprecated. | ||||
| 	ErrClientVersionDeprecated ErrorType = 34 | ||||
|  | ||||
| 	// Method execution was interrupted due to timeout. | ||||
| 	ErrExecutionTimeout ErrorType = 36 | ||||
|  | ||||
| @@ -177,6 +180,9 @@ const ( | ||||
| 	// Additional signup required. | ||||
| 	ErrAdditionalSignupRequired ErrorType = 41 | ||||
|  | ||||
| 	// IP is not allowed. | ||||
| 	ErrIPNotAllowed ErrorType = 42 | ||||
|  | ||||
| 	// One of the parameters specified was missing or invalid | ||||
| 	// | ||||
| 	// Check the required parameters list and their format on a method | ||||
| @@ -586,6 +592,18 @@ const ( | ||||
| 	// Can't send message, reply timed out. | ||||
| 	ErrMessagesReplyTimedOut ErrorType = 950 | ||||
|  | ||||
| 	// You can't access donut chat without subscription. | ||||
| 	ErrMessagesAccessDonutChat ErrorType = 962 | ||||
|  | ||||
| 	// This user can't be added to the work chat, as they aren't an employe. | ||||
| 	ErrMessagesAccessWorkChat ErrorType = 967 | ||||
|  | ||||
| 	// Message cannot be forwarded. | ||||
| 	ErrMessagesCantForwarded ErrorType = 969 | ||||
|  | ||||
| 	// Cannot pin an expiring message. | ||||
| 	ErrMessagesPinExpiringMessage ErrorType = 970 | ||||
|  | ||||
| 	// Invalid phone number. | ||||
| 	ErrParamPhone ErrorType = 1000 | ||||
|  | ||||
| @@ -598,6 +616,12 @@ const ( | ||||
| 	// Processing.. Try later. | ||||
| 	ErrAuthDelay ErrorType = 1112 | ||||
|  | ||||
| 	// Anonymous token has expired. | ||||
| 	ErrAnonymousTokenExpired ErrorType = 1114 | ||||
|  | ||||
| 	// Anonymous token is invalid. | ||||
| 	ErrAnonymousTokenInvalid ErrorType = 1116 | ||||
|  | ||||
| 	// Invalid document id. | ||||
| 	ErrParamDocID ErrorType = 1150 | ||||
|  | ||||
| @@ -724,6 +748,9 @@ const ( | ||||
| 	// Market was already disabled in this group. | ||||
| 	ErrMarketAlreadyDisabled ErrorType = 1432 | ||||
|  | ||||
| 	// Main album can not be hidden. | ||||
| 	ErrMainAlbumCantHidden ErrorType = 1446 | ||||
|  | ||||
| 	// Story has already expired. | ||||
| 	ErrStoryExpired ErrorType = 1600 | ||||
|  | ||||
| @@ -783,6 +810,33 @@ const ( | ||||
|  | ||||
| 	// Can't set AliExpress tag to this type of object. | ||||
| 	ErrAliExpressTag ErrorType = 3800 | ||||
|  | ||||
| 	// Invalid upload response. | ||||
| 	ErrInvalidUploadResponse ErrorType = 5701 | ||||
|  | ||||
| 	// Invalid upload hash. | ||||
| 	ErrInvalidUploadHash ErrorType = 5702 | ||||
|  | ||||
| 	// Invalid upload user. | ||||
| 	ErrInvalidUploadUser ErrorType = 5703 | ||||
|  | ||||
| 	// Invalid upload group. | ||||
| 	ErrInvalidUploadGroup ErrorType = 5704 | ||||
|  | ||||
| 	// Invalid crop data. | ||||
| 	ErrInvalidCropData ErrorType = 5705 | ||||
|  | ||||
| 	// To small avatar. | ||||
| 	ErrToSmallAvatar ErrorType = 5706 | ||||
|  | ||||
| 	// Photo not found. | ||||
| 	ErrPhotoNotFound ErrorType = 5708 | ||||
|  | ||||
| 	// Invalid Photo. | ||||
| 	ErrInvalidPhoto ErrorType = 5709 | ||||
|  | ||||
| 	// Invalid hash. | ||||
| 	ErrInvalidHash ErrorType = 5710 | ||||
| ) | ||||
|  | ||||
| // ErrorSubtype is the subtype of an error. | ||||
| @@ -946,3 +1000,31 @@ func (e AdsError) Is(target error) bool { | ||||
|  | ||||
| 	return false | ||||
| } | ||||
|  | ||||
| // AuthSilentTokenError struct. | ||||
| type AuthSilentTokenError struct { | ||||
| 	Token       string    `json:"token"` | ||||
| 	Code        ErrorType `json:"code"` | ||||
| 	Description string    `json:"description"` | ||||
| } | ||||
|  | ||||
| // Error returns the description of a AuthSilentTokenError. | ||||
| func (e AuthSilentTokenError) Error() string { | ||||
| 	return "api: " + e.Description | ||||
| } | ||||
|  | ||||
| // Is unwraps its first argument sequentially looking for an error that matches | ||||
| // the second. | ||||
| func (e AuthSilentTokenError) Is(target error) bool { | ||||
| 	var tError *AuthSilentTokenError | ||||
| 	if errors.As(target, &tError) { | ||||
| 		return e.Code == tError.Code && e.Description == tError.Description | ||||
| 	} | ||||
|  | ||||
| 	var tErrorType ErrorType | ||||
| 	if errors.As(target, &tErrorType) { | ||||
| 		return e.Code == tErrorType | ||||
| 	} | ||||
|  | ||||
| 	return false | ||||
| } | ||||
|   | ||||
							
								
								
									
										26
									
								
								vendor/github.com/SevereCloud/vksdk/v2/api/execute.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										26
									
								
								vendor/github.com/SevereCloud/vksdk/v2/api/execute.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,6 +1,11 @@ | ||||
| package api | ||||
|  | ||||
| import "encoding/json" | ||||
| import ( | ||||
| 	"bytes" | ||||
| 	"encoding/json" | ||||
|  | ||||
| 	"github.com/vmihailenco/msgpack/v5" | ||||
| ) | ||||
|  | ||||
| // ExecuteWithArgs a universal method for calling a sequence of other methods | ||||
| // while saving and filtering interim results. | ||||
| @@ -22,10 +27,23 @@ func (vk *VK) ExecuteWithArgs(code string, params Params, obj interface{}) error | ||||
| 	} | ||||
|  | ||||
| 	resp, err := vk.Handler("execute", params, reqParams) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
|  | ||||
| 	jsonErr := json.Unmarshal(resp.Response, &obj) | ||||
| 	if jsonErr != nil { | ||||
| 		return jsonErr | ||||
| 	var decoderErr error | ||||
|  | ||||
| 	if vk.msgpack { | ||||
| 		dec := msgpack.NewDecoder(bytes.NewReader(resp.Response)) | ||||
| 		dec.SetCustomStructTag("json") | ||||
|  | ||||
| 		decoderErr = dec.Decode(&obj) | ||||
| 	} else { | ||||
| 		decoderErr = json.Unmarshal(resp.Response, &obj) | ||||
| 	} | ||||
|  | ||||
| 	if decoderErr != nil { | ||||
| 		return decoderErr | ||||
| 	} | ||||
|  | ||||
| 	if resp.ExecuteErrors != nil { | ||||
|   | ||||
							
								
								
									
										17
									
								
								vendor/github.com/SevereCloud/vksdk/v2/api/market.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										17
									
								
								vendor/github.com/SevereCloud/vksdk/v2/api/market.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -20,6 +20,7 @@ func (vk *VK) MarketAdd(params Params) (response MarketAddResponse, err error) { | ||||
| // MarketAddAlbumResponse struct. | ||||
| type MarketAddAlbumResponse struct { | ||||
| 	MarketAlbumID int `json:"market_album_id"` // Album ID | ||||
| 	AlbumsCount   int `json:"albums_count"` | ||||
| } | ||||
|  | ||||
| // MarketAddAlbum creates new collection of items. | ||||
| @@ -318,3 +319,19 @@ func (vk *VK) MarketSearch(params Params) (response MarketSearchResponse, err er | ||||
| 	err = vk.RequestUnmarshal("market.search", &response, params) | ||||
| 	return | ||||
| } | ||||
|  | ||||
| // MarketSearchItemsResponse struct. | ||||
| type MarketSearchItemsResponse struct { | ||||
| 	Count    int                       `json:"count"` | ||||
| 	ViewType int                       `json:"view_type"` | ||||
| 	Items    []object.MarketMarketItem `json:"items"` | ||||
| 	Groups   []object.GroupsGroup      `json:"groups,omitempty"` | ||||
| } | ||||
|  | ||||
| // MarketSearchItems method. | ||||
| // | ||||
| // https://vk.com/dev/market.searchItems | ||||
| func (vk *VK) MarketSearchItems(params Params) (response MarketSearchItemsResponse, err error) { | ||||
| 	err = vk.RequestUnmarshal("market.searchItems", &response, params) | ||||
| 	return | ||||
| } | ||||
|   | ||||
							
								
								
									
										103
									
								
								vendor/github.com/SevereCloud/vksdk/v2/api/marusia.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										103
									
								
								vendor/github.com/SevereCloud/vksdk/v2/api/marusia.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,103 @@ | ||||
| package api // import "github.com/SevereCloud/vksdk/v2/api" | ||||
|  | ||||
| import ( | ||||
| 	"github.com/SevereCloud/vksdk/v2/object" | ||||
| ) | ||||
|  | ||||
| // MarusiaGetPictureUploadLinkResponse struct. | ||||
| type MarusiaGetPictureUploadLinkResponse struct { | ||||
| 	PictureUploadLink string `json:"picture_upload_link"` // Link | ||||
| } | ||||
|  | ||||
| // MarusiaGetPictureUploadLink method. | ||||
| // | ||||
| // https://vk.com/dev/marusia_skill_docs10 | ||||
| func (vk *VK) MarusiaGetPictureUploadLink(params Params) (response MarusiaGetPictureUploadLinkResponse, err error) { | ||||
| 	err = vk.RequestUnmarshal("marusia.getPictureUploadLink", &response, params) | ||||
| 	return | ||||
| } | ||||
|  | ||||
| // MarusiaSavePictureResponse struct. | ||||
| type MarusiaSavePictureResponse struct { | ||||
| 	AppID   int `json:"app_id"` | ||||
| 	PhotoID int `json:"photo_id"` | ||||
| } | ||||
|  | ||||
| // MarusiaSavePicture method. | ||||
| // | ||||
| // https://vk.com/dev/marusia_skill_docs10 | ||||
| func (vk *VK) MarusiaSavePicture(params Params) (response MarusiaSavePictureResponse, err error) { | ||||
| 	err = vk.RequestUnmarshal("marusia.savePicture", &response, params) | ||||
| 	return | ||||
| } | ||||
|  | ||||
| // MarusiaGetPicturesResponse struct. | ||||
| type MarusiaGetPicturesResponse struct { | ||||
| 	Count int                     `json:"count"` | ||||
| 	Items []object.MarusiaPicture `json:"items"` | ||||
| } | ||||
|  | ||||
| // MarusiaGetPictures method. | ||||
| // | ||||
| // https://vk.com/dev/marusia_skill_docs10 | ||||
| func (vk *VK) MarusiaGetPictures(params Params) (response MarusiaGetPicturesResponse, err error) { | ||||
| 	err = vk.RequestUnmarshal("marusia.getPictures", &response, params) | ||||
| 	return | ||||
| } | ||||
|  | ||||
| // MarusiaDeletePicture delete picture. | ||||
| // | ||||
| // https://vk.com/dev/marusia_skill_docs10 | ||||
| func (vk *VK) MarusiaDeletePicture(params Params) (response int, err error) { | ||||
| 	err = vk.RequestUnmarshal("marusia.deletePicture", &response, params) | ||||
| 	return | ||||
| } | ||||
|  | ||||
| // MarusiaGetAudioUploadLinkResponse struct. | ||||
| type MarusiaGetAudioUploadLinkResponse struct { | ||||
| 	AudioUploadLink string `json:"audio_upload_link"` // Link | ||||
| } | ||||
|  | ||||
| // MarusiaGetAudioUploadLink method. | ||||
| // | ||||
| // https://vk.com/dev/marusia_skill_docs10 | ||||
| func (vk *VK) MarusiaGetAudioUploadLink(params Params) (response MarusiaGetAudioUploadLinkResponse, err error) { | ||||
| 	err = vk.RequestUnmarshal("marusia.getAudioUploadLink", &response, params) | ||||
| 	return | ||||
| } | ||||
|  | ||||
| // MarusiaCreateAudioResponse struct. | ||||
| type MarusiaCreateAudioResponse struct { | ||||
| 	ID    int    `json:"id"` | ||||
| 	Title string `json:"title"` | ||||
| } | ||||
|  | ||||
| // MarusiaCreateAudio method. | ||||
| // | ||||
| // https://vk.com/dev/marusia_skill_docs10 | ||||
| func (vk *VK) MarusiaCreateAudio(params Params) (response MarusiaCreateAudioResponse, err error) { | ||||
| 	err = vk.RequestUnmarshal("marusia.createAudio", &response, params) | ||||
| 	return | ||||
| } | ||||
|  | ||||
| // MarusiaGetAudiosResponse struct. | ||||
| type MarusiaGetAudiosResponse struct { | ||||
| 	Count  int                   `json:"count"` | ||||
| 	Audios []object.MarusiaAudio `json:"audios"` | ||||
| } | ||||
|  | ||||
| // MarusiaGetAudios method. | ||||
| // | ||||
| // https://vk.com/dev/marusia_skill_docs10 | ||||
| func (vk *VK) MarusiaGetAudios(params Params) (response MarusiaGetAudiosResponse, err error) { | ||||
| 	err = vk.RequestUnmarshal("marusia.getAudios", &response, params) | ||||
| 	return | ||||
| } | ||||
|  | ||||
| // MarusiaDeleteAudio delete audio. | ||||
| // | ||||
| // https://vk.com/dev/marusia_skill_docs10 | ||||
| func (vk *VK) MarusiaDeleteAudio(params Params) (response int, err error) { | ||||
| 	err = vk.RequestUnmarshal("marusia.deleteAudio", &response, params) | ||||
| 	return | ||||
| } | ||||
							
								
								
									
										26
									
								
								vendor/github.com/SevereCloud/vksdk/v2/api/messages.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										26
									
								
								vendor/github.com/SevereCloud/vksdk/v2/api/messages.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,7 +1,10 @@ | ||||
| package api // import "github.com/SevereCloud/vksdk/v2/api" | ||||
|  | ||||
| import ( | ||||
| 	"strconv" | ||||
|  | ||||
| 	"github.com/SevereCloud/vksdk/v2/object" | ||||
| 	"github.com/vmihailenco/msgpack/v5" | ||||
| ) | ||||
|  | ||||
| // MessagesAddChatUser adds a new user to a chat. | ||||
| @@ -31,11 +34,34 @@ func (vk *VK) MessagesCreateChat(params Params) (response int, err error) { | ||||
| // MessagesDeleteResponse struct. | ||||
| type MessagesDeleteResponse map[string]int | ||||
|  | ||||
| // DecodeMsgpack funcion. | ||||
| func (resp *MessagesDeleteResponse) DecodeMsgpack(dec *msgpack.Decoder) error { | ||||
| 	data, err := dec.DecodeRaw() | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
|  | ||||
| 	var respMap map[int]int | ||||
|  | ||||
| 	err = msgpack.Unmarshal(data, &respMap) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
|  | ||||
| 	*resp = make(MessagesDeleteResponse) | ||||
| 	for key, val := range respMap { | ||||
| 		(*resp)[strconv.Itoa(key)] = val | ||||
| 	} | ||||
|  | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // MessagesDelete deletes one or more messages. | ||||
| // | ||||
| // https://vk.com/dev/messages.delete | ||||
| func (vk *VK) MessagesDelete(params Params) (response MessagesDeleteResponse, err error) { | ||||
| 	err = vk.RequestUnmarshal("messages.delete", &response, params) | ||||
|  | ||||
| 	return | ||||
| } | ||||
|  | ||||
|   | ||||
							
								
								
									
										13
									
								
								vendor/github.com/SevereCloud/vksdk/v2/api/photos.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										13
									
								
								vendor/github.com/SevereCloud/vksdk/v2/api/photos.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -571,12 +571,13 @@ func (vk *VK) PhotosSaveOwnerCoverPhoto(params Params) (response PhotosSaveOwner | ||||
|  | ||||
| // PhotosSaveOwnerPhotoResponse struct. | ||||
| type PhotosSaveOwnerPhotoResponse struct { | ||||
| 	PhotoHash     string `json:"photo_hash"` | ||||
| 	PhotoSrc      string `json:"photo_src"` | ||||
| 	PhotoSrcBig   string `json:"photo_src_big"` | ||||
| 	PhotoSrcSmall string `json:"photo_src_small"` | ||||
| 	Saved         int    `json:"saved"` | ||||
| 	PostID        int    `json:"post_id"` | ||||
| 	PhotoHash string `json:"photo_hash"` | ||||
| 	// BUG(VK): returns false | ||||
| 	// PhotoSrc      string `json:"photo_src"` | ||||
| 	// PhotoSrcBig   string `json:"photo_src_big"` | ||||
| 	// PhotoSrcSmall string `json:"photo_src_small"` | ||||
| 	Saved  int `json:"saved"` | ||||
| 	PostID int `json:"post_id"` | ||||
| } | ||||
|  | ||||
| // PhotosSaveOwnerPhoto saves a profile or community photo. | ||||
|   | ||||
							
								
								
									
										54
									
								
								vendor/github.com/SevereCloud/vksdk/v2/api/upload.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										54
									
								
								vendor/github.com/SevereCloud/vksdk/v2/api/upload.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -959,3 +959,57 @@ func (vk *VK) UploadGroupImage(imageType string, file io.Reader) (response objec | ||||
|  | ||||
| 	return | ||||
| } | ||||
|  | ||||
| // UploadMarusiaPicture uploading picture. | ||||
| // | ||||
| // Limits: height not more than 600 px, | ||||
| // aspect ratio of at least 2:1. | ||||
| func (vk *VK) UploadMarusiaPicture(file io.Reader) (response MarusiaSavePictureResponse, err error) { | ||||
| 	uploadServer, err := vk.MarusiaGetPictureUploadLink(nil) | ||||
| 	if err != nil { | ||||
| 		return | ||||
| 	} | ||||
|  | ||||
| 	bodyContent, err := vk.UploadFile(uploadServer.PictureUploadLink, file, "photo", "photo.jpg") | ||||
| 	if err != nil { | ||||
| 		return | ||||
| 	} | ||||
|  | ||||
| 	var handler object.MarusiaPictureUploadResponse | ||||
|  | ||||
| 	err = json.Unmarshal(bodyContent, &handler) | ||||
| 	if err != nil { | ||||
| 		return | ||||
| 	} | ||||
|  | ||||
| 	photo, _ := json.Marshal(handler.Photo) | ||||
|  | ||||
| 	response, err = vk.MarusiaSavePicture(Params{ | ||||
| 		"server": handler.Server, | ||||
| 		"photo":  string(photo), | ||||
| 		"hash":   handler.Hash, | ||||
| 	}) | ||||
|  | ||||
| 	return | ||||
| } | ||||
|  | ||||
| // UploadMarusiaAudio uploading audio. | ||||
| // | ||||
| // https://vk.com/dev/marusia_skill_docs10 | ||||
| func (vk *VK) UploadMarusiaAudio(file io.Reader) (response MarusiaCreateAudioResponse, err error) { | ||||
| 	uploadServer, err := vk.MarusiaGetAudioUploadLink(nil) | ||||
| 	if err != nil { | ||||
| 		return | ||||
| 	} | ||||
|  | ||||
| 	bodyContent, err := vk.UploadFile(uploadServer.AudioUploadLink, file, "file", "audio.mp3") | ||||
| 	if err != nil { | ||||
| 		return | ||||
| 	} | ||||
|  | ||||
| 	response, err = vk.MarusiaCreateAudio(Params{ | ||||
| 		"audio_meta": string(bodyContent), | ||||
| 	}) | ||||
|  | ||||
| 	return | ||||
| } | ||||
|   | ||||
							
								
								
									
										36
									
								
								vendor/github.com/SevereCloud/vksdk/v2/api/utils.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										36
									
								
								vendor/github.com/SevereCloud/vksdk/v2/api/utils.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,9 +1,8 @@ | ||||
| package api // import "github.com/SevereCloud/vksdk/v2/api" | ||||
|  | ||||
| import ( | ||||
| 	"encoding/json" | ||||
|  | ||||
| 	"github.com/SevereCloud/vksdk/v2/object" | ||||
| 	"github.com/vmihailenco/msgpack/v5" | ||||
| ) | ||||
|  | ||||
| // UtilsCheckLinkResponse struct. | ||||
| @@ -89,17 +88,34 @@ func (vk *VK) UtilsGetShortLink(params Params) (response UtilsGetShortLinkRespon | ||||
| // UtilsResolveScreenNameResponse struct. | ||||
| type UtilsResolveScreenNameResponse object.UtilsDomainResolved | ||||
|  | ||||
| // UnmarshalJSON UtilsResolveScreenNameResponse. | ||||
| // | ||||
| // BUG(VK): UtilsResolveScreenNameResponse return []. | ||||
| func (resp *UtilsResolveScreenNameResponse) UnmarshalJSON(data []byte) error { | ||||
| 	var p object.UtilsDomainResolved | ||||
| 	err := p.UnmarshalJSON(data) | ||||
|  | ||||
| 	*resp = UtilsResolveScreenNameResponse(p) | ||||
|  | ||||
| 	return err | ||||
| } | ||||
|  | ||||
| // DecodeMsgpack UtilsResolveScreenNameResponse. | ||||
| // | ||||
| // BUG(VK): UtilsResolveScreenNameResponse return []. | ||||
| func (resp *UtilsResolveScreenNameResponse) DecodeMsgpack(dec *msgpack.Decoder) error { | ||||
| 	var p object.UtilsDomainResolved | ||||
| 	err := p.DecodeMsgpack(dec) | ||||
|  | ||||
| 	*resp = UtilsResolveScreenNameResponse(p) | ||||
|  | ||||
| 	return err | ||||
| } | ||||
|  | ||||
| // UtilsResolveScreenName detects a type of object (e.g., user, community, application) and its ID by screen name. | ||||
| // | ||||
| // https://vk.com/dev/utils.resolveScreenName | ||||
| func (vk *VK) UtilsResolveScreenName(params Params) (response UtilsResolveScreenNameResponse, err error) { | ||||
| 	rawResponse, err := vk.Request("utils.resolveScreenName", params) | ||||
| 	// Если короткое имя screen_name не занято, то будет возвращён пустой объект. | ||||
| 	if err != nil || string(rawResponse) == "[]" { | ||||
| 		return | ||||
| 	} | ||||
|  | ||||
| 	err = json.Unmarshal(rawResponse, &response) | ||||
|  | ||||
| 	err = vk.RequestUnmarshal("utils.resolveScreenName", &response, params) | ||||
| 	return | ||||
| } | ||||
|   | ||||
							
								
								
									
										2
									
								
								vendor/github.com/SevereCloud/vksdk/v2/doc.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								vendor/github.com/SevereCloud/vksdk/v2/doc.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -7,6 +7,6 @@ package vksdk | ||||
|  | ||||
| // Module constants. | ||||
| const ( | ||||
| 	Version = "2.10.0" | ||||
| 	Version = "2.13.1" | ||||
| 	API     = "5.131" | ||||
| ) | ||||
|   | ||||
							
								
								
									
										2
									
								
								vendor/github.com/SevereCloud/vksdk/v2/longpoll-bot/README.md
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								vendor/github.com/SevereCloud/vksdk/v2/longpoll-bot/README.md
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -10,7 +10,7 @@ Long Poll настраивается автоматически. Вам не т | ||||
|  | ||||
| ### Версия API | ||||
|  | ||||
| Данная библиотека поддерживает версию API **5.122**. | ||||
| Данная библиотека поддерживает версию API **5.131**. | ||||
|  | ||||
| ### Инициализация | ||||
|  | ||||
|   | ||||
							
								
								
									
										58
									
								
								vendor/github.com/SevereCloud/vksdk/v2/longpoll-bot/longpoll.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										58
									
								
								vendor/github.com/SevereCloud/vksdk/v2/longpoll-bot/longpoll.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -8,8 +8,11 @@ package longpoll // import "github.com/SevereCloud/vksdk/v2/longpoll-bot" | ||||
| import ( | ||||
| 	"context" | ||||
| 	"encoding/json" | ||||
| 	"errors" | ||||
| 	"fmt" | ||||
| 	"io" | ||||
| 	"net/http" | ||||
| 	"strconv" | ||||
|  | ||||
| 	"github.com/SevereCloud/vksdk/v2" | ||||
| 	"github.com/SevereCloud/vksdk/v2/api" | ||||
| @@ -117,7 +120,7 @@ func (lp *LongPoll) check(ctx context.Context) (response Response, err error) { | ||||
| 	} | ||||
| 	defer resp.Body.Close() | ||||
|  | ||||
| 	err = json.NewDecoder(resp.Body).Decode(&response) | ||||
| 	response, err = parseResponse(resp.Body) | ||||
| 	if err != nil { | ||||
| 		return response, err | ||||
| 	} | ||||
| @@ -127,6 +130,59 @@ func (lp *LongPoll) check(ctx context.Context) (response Response, err error) { | ||||
| 	return response, err | ||||
| } | ||||
|  | ||||
| func parseResponse(reader io.Reader) (response Response, err error) { | ||||
| 	decoder := json.NewDecoder(reader) | ||||
| 	for decoder.More() { | ||||
| 		token, err := decoder.Token() | ||||
| 		if err != nil { | ||||
| 			if errors.Is(err, io.EOF) { | ||||
| 				break | ||||
| 			} | ||||
|  | ||||
| 			return response, err | ||||
| 		} | ||||
|  | ||||
| 		t, ok := token.(string) | ||||
| 		if !ok { | ||||
| 			continue | ||||
| 		} | ||||
|  | ||||
| 		switch t { | ||||
| 		case "failed": | ||||
| 			raw, err := decoder.Token() | ||||
| 			if err != nil { | ||||
| 				return response, err | ||||
| 			} | ||||
|  | ||||
| 			response.Failed = int(raw.(float64)) | ||||
| 		case "updates": | ||||
| 			var updates []events.GroupEvent | ||||
|  | ||||
| 			err = decoder.Decode(&updates) | ||||
| 			if err != nil { | ||||
| 				return response, err | ||||
| 			} | ||||
|  | ||||
| 			response.Updates = updates | ||||
| 		case "ts": | ||||
| 			// can be a number in the response with "failed" field: {"ts":8,"failed":1} | ||||
| 			// or string, e.g. {"ts":"8","updates":[]} | ||||
| 			rawTs, err := decoder.Token() | ||||
| 			if err != nil { | ||||
| 				return response, err | ||||
| 			} | ||||
|  | ||||
| 			if ts, isNumber := rawTs.(float64); isNumber { | ||||
| 				response.Ts = strconv.Itoa(int(ts)) | ||||
| 			} else { | ||||
| 				response.Ts = rawTs.(string) | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	return response, err | ||||
| } | ||||
|  | ||||
| func (lp *LongPoll) checkResponse(response Response) (err error) { | ||||
| 	switch response.Failed { | ||||
| 	case 0: | ||||
|   | ||||
							
								
								
									
										34
									
								
								vendor/github.com/SevereCloud/vksdk/v2/object/account.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										34
									
								
								vendor/github.com/SevereCloud/vksdk/v2/object/account.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -62,21 +62,24 @@ type AccountOffer struct { | ||||
|  | ||||
| // AccountAccountCounters struct. | ||||
| type AccountAccountCounters struct { | ||||
| 	AppRequests            int `json:"app_requests"`            // New app requests number | ||||
| 	Events                 int `json:"events"`                  // New events number | ||||
| 	Friends                int `json:"friends"`                 // New friends requests number | ||||
| 	FriendsRecommendations int `json:"friends_recommendations"` // New friends recommendations number | ||||
| 	FriendsSuggestions     int `json:"friends_suggestions"`     // New friends suggestions number | ||||
| 	Gifts                  int `json:"gifts"`                   // New gifts number | ||||
| 	Groups                 int `json:"groups"`                  // New groups number | ||||
| 	Messages               int `json:"messages"`                // New messages number | ||||
| 	Notifications          int `json:"notifications"`           // New notifications number | ||||
| 	Photos                 int `json:"photos"`                  // New photo tags number | ||||
| 	SDK                    int `json:"sdk"`                     // New SDK number | ||||
| 	MenuDiscoverBadge      int `json:"menu_discover_badge"`     // New menu discover badge number | ||||
| 	MenuClipsBadge         int `json:"menu_clips_badge"`        // New menu clips badge number | ||||
| 	Videos                 int `json:"videos"`                  // New video tags number | ||||
| 	Faves                  int `json:"faves"`                   // New faves number | ||||
| 	AppRequests              int `json:"app_requests"`            // New app requests number | ||||
| 	Events                   int `json:"events"`                  // New events number | ||||
| 	Friends                  int `json:"friends"`                 // New friends requests number | ||||
| 	FriendsRecommendations   int `json:"friends_recommendations"` // New friends recommendations number | ||||
| 	FriendsSuggestions       int `json:"friends_suggestions"`     // New friends suggestions number | ||||
| 	Gifts                    int `json:"gifts"`                   // New gifts number | ||||
| 	Groups                   int `json:"groups"`                  // New groups number | ||||
| 	Messages                 int `json:"messages"`                // New messages number | ||||
| 	Notifications            int `json:"notifications"`           // New notifications number | ||||
| 	Photos                   int `json:"photos"`                  // New photo tags number | ||||
| 	SDK                      int `json:"sdk"`                     // New SDK number | ||||
| 	MenuDiscoverBadge        int `json:"menu_discover_badge"`     // New menu discover badge number | ||||
| 	MenuClipsBadge           int `json:"menu_clips_badge"`        // New menu clips badge number | ||||
| 	Videos                   int `json:"videos"`                  // New video tags number | ||||
| 	Faves                    int `json:"faves"`                   // New faves number | ||||
| 	Calls                    int `json:"calls"`                   // New calls number | ||||
| 	MenuSuperappFriendsBadge int `json:"menu_superapp_friends_badge"` | ||||
| 	MenuNewClipsBadge        int `json:"menu_new_clips_badge"` | ||||
| } | ||||
|  | ||||
| // AccountInfo struct. | ||||
| @@ -107,6 +110,7 @@ type AccountInfo struct { | ||||
| 	IsLiveStreamingEnabled    BaseBoolInt       `json:"is_live_streaming_enabled"` | ||||
| 	IsNewLiveStreamingEnabled BaseBoolInt       `json:"is_new_live_streaming_enabled"` | ||||
| 	LinkRedirects             map[string]string `json:"link_redirects"` | ||||
| 	VkPayEndpointV2           string            `json:"vk_pay_endpoint_v2"` | ||||
| } | ||||
|  | ||||
| // AccountPushSettings struct. | ||||
|   | ||||
							
								
								
									
										20
									
								
								vendor/github.com/SevereCloud/vksdk/v2/object/ads.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										20
									
								
								vendor/github.com/SevereCloud/vksdk/v2/object/ads.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -8,12 +8,13 @@ type AdsAccesses struct { | ||||
|  | ||||
| // AdsAccount struct. | ||||
| type AdsAccount struct { | ||||
| 	AccessRole    string      `json:"access_role"` | ||||
| 	AccountID     int         `json:"account_id"` // Account ID | ||||
| 	AccountName   string      `json:"account_name"` | ||||
| 	AccountStatus BaseBoolInt `json:"account_status"` // Information whether account is active | ||||
| 	CanViewBudget BaseBoolInt `json:"can_view_budget"` | ||||
| 	AccountType   string      `json:"account_type"` | ||||
| 	AccessRole                  string      `json:"access_role"` | ||||
| 	AccountID                   int         `json:"account_id"` // Account ID | ||||
| 	AccountName                 string      `json:"account_name"` | ||||
| 	AccountStatus               BaseBoolInt `json:"account_status"` // Information whether account is active | ||||
| 	CanViewBudget               BaseBoolInt `json:"can_view_budget"` | ||||
| 	AdNetworkAllowedPotentially BaseBoolInt `json:"ad_network_allowed_potentially"` | ||||
| 	AccountType                 string      `json:"account_type"` | ||||
| } | ||||
|  | ||||
| // AdsAdLayout struct. | ||||
| @@ -318,3 +319,10 @@ type AdsPromotedPostReach struct { | ||||
| 	VideoViews75p    int `json:"video_views_75p"`   // Video views for 75 percent | ||||
| 	VideoViewsStart  int `json:"video_views_start"` // Video starts | ||||
| } | ||||
|  | ||||
| // AdsMusician struct. | ||||
| type AdsMusician struct { | ||||
| 	ID     int    `json:"id"`               // Targeting music artist ID | ||||
| 	Name   string `json:"name"`             // Music artist name | ||||
| 	Avatar string `json:"avatar,omitempty"` // Music artist photo. | ||||
| } | ||||
|   | ||||
							
								
								
									
										3
									
								
								vendor/github.com/SevereCloud/vksdk/v2/object/apps.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										3
									
								
								vendor/github.com/SevereCloud/vksdk/v2/object/apps.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -60,6 +60,7 @@ type AppsApp struct { | ||||
| 	IsNew           BaseBoolInt `json:"is_new"` | ||||
| 	New             BaseBoolInt `json:"new"` | ||||
| 	IsInstalled     BaseBoolInt `json:"is_installed"` | ||||
| 	HasVkConnect    BaseBoolInt `json:"has_vk_connect"` | ||||
| 	LeaderboardType int         `json:"leaderboard_type"` | ||||
| 	MembersCount    int         `json:"members_count"` // Members number | ||||
| 	PlatformID      int         `json:"platform_id"`   // Application ID in store | ||||
| @@ -78,7 +79,7 @@ type AppsApp struct { | ||||
|  | ||||
| 	// mobile_controls_type = 0 - прозрачный элемент управления поверх области с игрой; | ||||
| 	// mobile_controls_type = 1 - чёрная полоска над областью с игрой; | ||||
| 	// mobile_controls_type = 2 - только для vk apps, без контроллов. | ||||
| 	// mobile_controls_type = 2 - только для vk apps, без элементов управления'. | ||||
| 	MobileControlsType int `json:"mobile_controls_type"` | ||||
|  | ||||
| 	// mobile_view_support_type = 0 - игра не использует нижнюю часть экрана на iPhoneX, черная полоса есть. | ||||
|   | ||||
							
								
								
									
										17
									
								
								vendor/github.com/SevereCloud/vksdk/v2/object/auth.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								vendor/github.com/SevereCloud/vksdk/v2/object/auth.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,17 @@ | ||||
| package object // import "github.com/SevereCloud/vksdk/v2/object" | ||||
|  | ||||
| // AuthSilentTokenProfile struct. | ||||
| type AuthSilentTokenProfile struct { | ||||
| 	Token          string      `json:"token"` | ||||
| 	Expires        int         `json:"expires"` | ||||
| 	FirstName      string      `json:"first_name"` | ||||
| 	LastName       string      `json:"last_name"` | ||||
| 	Photo50        string      `json:"photo_50"` | ||||
| 	Photo100       string      `json:"photo_100"` | ||||
| 	Photo200       string      `json:"photo_200"` | ||||
| 	Phone          string      `json:"phone"` | ||||
| 	PhoneValidated interface{} `json:"phone_validated"` // int | bool | ||||
| 	UserID         int         `json:"user_id"` | ||||
| 	IsPartial      BaseBoolInt `json:"is_partial"` | ||||
| 	IsService      BaseBoolInt `json:"is_service"` | ||||
| } | ||||
							
								
								
									
										6
									
								
								vendor/github.com/SevereCloud/vksdk/v2/object/database.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										6
									
								
								vendor/github.com/SevereCloud/vksdk/v2/object/database.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -4,9 +4,9 @@ package object // import "github.com/SevereCloud/vksdk/v2/object" | ||||
| type DatabaseCity struct { | ||||
| 	ID        int         `json:"id"`    // City ID | ||||
| 	Title     string      `json:"title"` // City title | ||||
| 	Area      string      `json:"area"` | ||||
| 	Region    string      `json:"region"` | ||||
| 	Important BaseBoolInt `json:"important"` | ||||
| 	Area      string      `json:"area,omitempty"` | ||||
| 	Region    string      `json:"region,omitempty"` | ||||
| 	Important BaseBoolInt `json:"important,omitempty"` | ||||
| } | ||||
|  | ||||
| // DatabaseMetroStation  struct. | ||||
|   | ||||
							
								
								
									
										325
									
								
								vendor/github.com/SevereCloud/vksdk/v2/object/groups.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										325
									
								
								vendor/github.com/SevereCloud/vksdk/v2/object/groups.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,9 +1,13 @@ | ||||
| package object // import "github.com/SevereCloud/vksdk/v2/object" | ||||
|  | ||||
| import ( | ||||
| 	"bytes" | ||||
| 	"encoding/json" | ||||
| 	"fmt" | ||||
| 	"reflect" | ||||
|  | ||||
| 	"github.com/vmihailenco/msgpack/v5" | ||||
| 	"github.com/vmihailenco/msgpack/v5/msgpcode" | ||||
| ) | ||||
|  | ||||
| // GroupsAddress WorkInfoStatus of information about timetable. | ||||
| @@ -110,112 +114,113 @@ const ( | ||||
|  | ||||
| // GroupsGroup struct. | ||||
| type GroupsGroup struct { | ||||
| 	AdminLevel   int              `json:"admin_level"` | ||||
| 	Deactivated  string           `json:"deactivated"` // Information whether community is banned | ||||
| 	FinishDate   int              `json:"finish_date"` // Finish date in Unixtime format | ||||
| 	ID           int              `json:"id"`          // Community ID | ||||
| 	Name         string           `json:"name"`        // Community name | ||||
| 	Photo100     string           `json:"photo_100"`   // URL of square photo of the community with 100 pixels in width | ||||
| 	Photo200     string           `json:"photo_200"`   // URL of square photo of the community with 200 pixels in width | ||||
| 	Photo50      string           `json:"photo_50"`    // URL of square photo of the community with 50 pixels in width | ||||
| 	ScreenName   string           `json:"screen_name"` // Domain of the community page | ||||
| 	StartDate    int              `json:"start_date"`  // Start date in Unixtime format | ||||
| 	Type         string           `json:"type"` | ||||
| 	Market       GroupsMarketInfo `json:"market"` | ||||
| 	MemberStatus int              `json:"member_status"` // Current user's member status | ||||
| 	IsClosed     int              `json:"is_closed"` | ||||
| 	City         BaseObject       `json:"city"` | ||||
| 	Country      BaseCountry      `json:"country"` | ||||
| 	AdminLevel   int              `json:"admin_level,omitempty"` | ||||
| 	Deactivated  string           `json:"deactivated,omitempty"` // Information whether community is banned | ||||
| 	FinishDate   int              `json:"finish_date,omitempty"` // Finish date in Unixtime format | ||||
| 	Photo100     string           `json:"photo_100,omitempty"`   // URL of square photo of the community with 100 pixels in width | ||||
| 	Photo200     string           `json:"photo_200,omitempty"`   // URL of square photo of the community with 200 pixels in width | ||||
| 	Photo50      string           `json:"photo_50,omitempty"`    // URL of square photo of the community with 50 pixels in width | ||||
| 	StartDate    int              `json:"start_date,omitempty"`  // Start date in Unixtime format | ||||
| 	Market       GroupsMarketInfo `json:"market,omitempty"` | ||||
| 	MemberStatus int              `json:"member_status,omitempty"` // Current user's member status | ||||
| 	City         BaseObject       `json:"city,omitempty"` | ||||
| 	Country      BaseCountry      `json:"country,omitempty"` | ||||
|  | ||||
| 	// Information whether current user is administrator. | ||||
| 	IsAdmin BaseBoolInt `json:"is_admin"` | ||||
|  | ||||
| 	// Information whether current user is advertiser. | ||||
| 	IsAdvertiser BaseBoolInt `json:"is_advertiser"` | ||||
| 	IsAdvertiser BaseBoolInt `json:"is_advertiser,omitempty"` | ||||
|  | ||||
| 	// Information whether current user is member. | ||||
| 	IsMember BaseBoolInt `json:"is_member"` | ||||
| 	IsMember BaseBoolInt `json:"is_member,omitempty"` | ||||
|  | ||||
| 	// Information whether community is in faves. | ||||
| 	IsFavorite BaseBoolInt `json:"is_favorite"` | ||||
| 	IsFavorite BaseBoolInt `json:"is_favorite,omitempty"` | ||||
|  | ||||
| 	// Information whether community is adult. | ||||
| 	IsAdult BaseBoolInt `json:"is_adult"` | ||||
| 	IsAdult BaseBoolInt `json:"is_adult,omitempty"` | ||||
|  | ||||
| 	// Information whether current user is subscribed. | ||||
| 	IsSubscribed BaseBoolInt `json:"is_subscribed"` | ||||
| 	IsSubscribed BaseBoolInt `json:"is_subscribed,omitempty"` | ||||
|  | ||||
| 	// Information whether current user can post on community's wall. | ||||
| 	CanPost BaseBoolInt `json:"can_post"` | ||||
| 	CanPost BaseBoolInt `json:"can_post,omitempty"` | ||||
|  | ||||
| 	// Information whether current user can see all posts on community's wall. | ||||
| 	CanSeeAllPosts BaseBoolInt `json:"can_see_all_posts"` | ||||
| 	CanSeeAllPosts BaseBoolInt `json:"can_see_all_posts,omitempty"` | ||||
|  | ||||
| 	// Information whether current user can create topic. | ||||
| 	CanCreateTopic BaseBoolInt `json:"can_create_topic"` | ||||
| 	CanCreateTopic BaseBoolInt `json:"can_create_topic,omitempty"` | ||||
|  | ||||
| 	// Information whether current user can upload video. | ||||
| 	CanUploadVideo BaseBoolInt `json:"can_upload_video"` | ||||
| 	CanUploadVideo BaseBoolInt `json:"can_upload_video,omitempty"` | ||||
|  | ||||
| 	// Information whether current user can upload doc. | ||||
| 	CanUploadDoc BaseBoolInt `json:"can_upload_doc"` | ||||
| 	CanUploadDoc BaseBoolInt `json:"can_upload_doc,omitempty"` | ||||
|  | ||||
| 	// Information whether community has photo. | ||||
| 	HasPhoto BaseBoolInt `json:"has_photo"` | ||||
| 	HasPhoto BaseBoolInt `json:"has_photo,omitempty"` | ||||
|  | ||||
| 	// Information whether current user can send a message to community. | ||||
| 	CanMessage BaseBoolInt `json:"can_message"` | ||||
| 	CanMessage BaseBoolInt `json:"can_message,omitempty"` | ||||
|  | ||||
| 	// Information whether community can send a message to current user. | ||||
| 	IsMessagesBlocked BaseBoolInt `json:"is_messages_blocked"` | ||||
| 	IsMessagesBlocked BaseBoolInt `json:"is_messages_blocked,omitempty"` | ||||
|  | ||||
| 	// Information whether community can send notifications by phone number to current user. | ||||
| 	CanSendNotify BaseBoolInt `json:"can_send_notify"` | ||||
| 	CanSendNotify BaseBoolInt `json:"can_send_notify,omitempty"` | ||||
|  | ||||
| 	// Information whether current user is subscribed to podcasts. | ||||
| 	IsSubscribedPodcasts BaseBoolInt `json:"is_subscribed_podcasts"` | ||||
| 	IsSubscribedPodcasts BaseBoolInt `json:"is_subscribed_podcasts,omitempty"` | ||||
|  | ||||
| 	// Owner in whitelist or not. | ||||
| 	CanSubscribePodcasts BaseBoolInt `json:"can_subscribe_podcasts"` | ||||
| 	CanSubscribePodcasts BaseBoolInt `json:"can_subscribe_podcasts,omitempty"` | ||||
|  | ||||
| 	// Can subscribe to wall. | ||||
| 	CanSubscribePosts BaseBoolInt `json:"can_subscribe_posts"` | ||||
| 	CanSubscribePosts BaseBoolInt `json:"can_subscribe_posts,omitempty"` | ||||
|  | ||||
| 	// Information whether community has market app. | ||||
| 	HasMarketApp        BaseBoolInt `json:"has_market_app"` | ||||
| 	IsHiddenFromFeed    BaseBoolInt `json:"is_hidden_from_feed"` | ||||
| 	IsMarketCartEnabled BaseBoolInt `json:"is_market_cart_enabled"` | ||||
| 	Verified            BaseBoolInt `json:"verified"` // Information whether community is verified | ||||
| 	HasMarketApp        BaseBoolInt `json:"has_market_app,omitempty"` | ||||
| 	IsHiddenFromFeed    BaseBoolInt `json:"is_hidden_from_feed,omitempty"` | ||||
| 	IsMarketCartEnabled BaseBoolInt `json:"is_market_cart_enabled,omitempty"` | ||||
| 	Verified            BaseBoolInt `json:"verified,omitempty"` // Information whether community is verified | ||||
|  | ||||
| 	// Information whether the community has a fire pictogram. | ||||
| 	Trending     BaseBoolInt         `json:"trending"` | ||||
| 	Description  string              `json:"description"`   // Community description | ||||
| 	WikiPage     string              `json:"wiki_page"`     // Community's main wiki page title | ||||
| 	MembersCount int                 `json:"members_count"` // Community members number | ||||
| 	Counters     GroupsCountersGroup `json:"counters"` | ||||
| 	Cover        GroupsCover         `json:"cover"` | ||||
| 	Trending     BaseBoolInt         `json:"trending,omitempty"` | ||||
| 	Description  string              `json:"description,omitempty"`   // Community description | ||||
| 	WikiPage     string              `json:"wiki_page,omitempty"`     // Community's main wiki page title | ||||
| 	MembersCount int                 `json:"members_count,omitempty"` // Community members number | ||||
| 	Counters     GroupsCountersGroup `json:"counters,omitempty"` | ||||
| 	Cover        GroupsCover         `json:"cover,omitempty"` | ||||
|  | ||||
| 	// Type of group, start date of event or category of public page. | ||||
| 	Activity        string               `json:"activity"` | ||||
| 	FixedPost       int                  `json:"fixed_post"`    // Fixed post ID | ||||
| 	Status          string               `json:"status"`        // Community status | ||||
| 	MainAlbumID     int                  `json:"main_album_id"` // Community's main photo album ID | ||||
| 	Links           []GroupsLinksItem    `json:"links"` | ||||
| 	Contacts        []GroupsContactsItem `json:"contacts"` | ||||
| 	Site            string               `json:"site"` // Community's website | ||||
| 	MainSection     int                  `json:"main_section"` | ||||
| 	OnlineStatus    GroupsOnlineStatus   `json:"online_status"` // Status of replies in community messages | ||||
| 	AgeLimits       int                  `json:"age_limits"`    // Information whether age limit | ||||
| 	BanInfo         GroupsGroupBanInfo   `json:"ban_info"`      // User ban info | ||||
| 	Addresses       GroupsAddressesInfo  `json:"addresses"`     // Info about addresses in Groups | ||||
| 	LiveCovers      GroupsLiveCovers     `json:"live_covers"` | ||||
| 	CropPhoto       UsersCropPhoto       `json:"crop_photo"` | ||||
| 	Wall            int                  `json:"wall"` | ||||
| 	ActionButton    GroupsActionButton   `json:"action_button"` | ||||
| 	TrackCode       string               `json:"track_code"` | ||||
| 	PublicDateLabel string               `json:"public_date_label"` | ||||
| 	AuthorID        int                  `json:"author_id"` | ||||
| 	Phone           string               `json:"phone"` | ||||
| 	Activity        string               `json:"activity,omitempty"` | ||||
| 	FixedPost       int                  `json:"fixed_post,omitempty"`    // Fixed post ID | ||||
| 	Status          string               `json:"status,omitempty"`        // Community status | ||||
| 	MainAlbumID     int                  `json:"main_album_id,omitempty"` // Community's main photo album ID | ||||
| 	Links           []GroupsLinksItem    `json:"links,omitempty"` | ||||
| 	Contacts        []GroupsContactsItem `json:"contacts,omitempty"` | ||||
| 	Site            string               `json:"site,omitempty"` // Community's website | ||||
| 	MainSection     int                  `json:"main_section,omitempty"` | ||||
| 	OnlineStatus    GroupsOnlineStatus   `json:"online_status,omitempty"` // Status of replies in community messages | ||||
| 	AgeLimits       int                  `json:"age_limits,omitempty"`    // Information whether age limit | ||||
| 	BanInfo         GroupsGroupBanInfo   `json:"ban_info,omitempty"`      // User ban info | ||||
| 	Addresses       GroupsAddressesInfo  `json:"addresses,omitempty"`     // Info about addresses in Groups | ||||
| 	LiveCovers      GroupsLiveCovers     `json:"live_covers,omitempty"` | ||||
| 	CropPhoto       UsersCropPhoto       `json:"crop_photo,omitempty"` | ||||
| 	Wall            int                  `json:"wall,omitempty"` | ||||
| 	ActionButton    GroupsActionButton   `json:"action_button,omitempty"` | ||||
| 	TrackCode       string               `json:"track_code,omitempty"` | ||||
| 	PublicDateLabel string               `json:"public_date_label,omitempty"` | ||||
| 	AuthorID        int                  `json:"author_id,omitempty"` | ||||
| 	Phone           string               `json:"phone,omitempty"` | ||||
| 	Like            GroupsGroupLike      `json:"like"` | ||||
| } | ||||
|  | ||||
| // ToMention return mention. | ||||
| @@ -223,6 +228,18 @@ func (group GroupsGroup) ToMention() string { | ||||
| 	return fmt.Sprintf("[club%d|%s]", group.ID, group.Name) | ||||
| } | ||||
|  | ||||
| // GroupsGroupLike struct. | ||||
| type GroupsGroupLike struct { | ||||
| 	IsLiked BaseBoolInt            `json:"is_liked"` | ||||
| 	Friends GroupsGroupLikeFriends `json:"friends"` | ||||
| } | ||||
|  | ||||
| // GroupsGroupLikeFriends struct. | ||||
| type GroupsGroupLikeFriends struct { | ||||
| 	Count   int   `json:"count"` | ||||
| 	Preview []int `json:"preview"` | ||||
| } | ||||
|  | ||||
| // GroupsLiveCovers struct. | ||||
| type GroupsLiveCovers struct { | ||||
| 	IsEnabled  BaseBoolInt `json:"is_enabled"` | ||||
| @@ -275,16 +292,70 @@ type GroupsContactsItem struct { | ||||
|  | ||||
| // GroupsCountersGroup struct. | ||||
| type GroupsCountersGroup struct { | ||||
| 	Addresses  int `json:"addresses"`  // Addresses number | ||||
| 	Albums     int `json:"albums"`     // Photo albums number | ||||
| 	Articles   int `json:"articles"`   // Articles number | ||||
| 	Audios     int `json:"audios"`     // Audios number | ||||
| 	Docs       int `json:"docs"`       // Docs number | ||||
| 	Market     int `json:"market"`     // Market items number | ||||
| 	Photos     int `json:"photos"`     // Photos number | ||||
| 	Topics     int `json:"topics"`     // Topics number | ||||
| 	Videos     int `json:"videos"`     // Videos number | ||||
| 	Narratives int `json:"narratives"` // Narratives number | ||||
| 	Addresses      int `json:"addresses"`       // Addresses number | ||||
| 	Albums         int `json:"albums"`          // Photo albums number | ||||
| 	Articles       int `json:"articles"`        // Articles number | ||||
| 	Audios         int `json:"audios"`          // Audios number | ||||
| 	Docs           int `json:"docs"`            // Docs number | ||||
| 	Market         int `json:"market"`          // Market items number | ||||
| 	Photos         int `json:"photos"`          // Photos number | ||||
| 	Topics         int `json:"topics"`          // Topics number | ||||
| 	Videos         int `json:"videos"`          // Videos number | ||||
| 	Narratives     int `json:"narratives"`      // Narratives number | ||||
| 	Clips          int `json:"clips"`           // Clips number | ||||
| 	ClipsFollowers int `json:"clips_followers"` // Clips followers number | ||||
| } | ||||
|  | ||||
| // UnmarshalJSON GroupsCountersGroup. | ||||
| // | ||||
| // BUG(VK): GroupsCountersGroup return []. | ||||
| func (personal *GroupsCountersGroup) UnmarshalJSON(data []byte) error { | ||||
| 	if bytes.Equal(data, []byte("[]")) { | ||||
| 		return nil | ||||
| 	} | ||||
|  | ||||
| 	type renamedGroupsCountersGroup GroupsCountersGroup | ||||
|  | ||||
| 	var r renamedGroupsCountersGroup | ||||
|  | ||||
| 	err := json.Unmarshal(data, &r) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
|  | ||||
| 	*personal = GroupsCountersGroup(r) | ||||
|  | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // DecodeMsgpack GroupsCountersGroup. | ||||
| // | ||||
| // BUG(VK): GroupsCountersGroup return []. | ||||
| func (personal *GroupsCountersGroup) DecodeMsgpack(dec *msgpack.Decoder) error { | ||||
| 	data, err := dec.DecodeRaw() | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
|  | ||||
| 	if bytes.Equal(data, []byte{msgpcode.FixedArrayLow}) { | ||||
| 		return nil | ||||
| 	} | ||||
|  | ||||
| 	type renamedGroupsCountersGroup GroupsCountersGroup | ||||
|  | ||||
| 	var r renamedGroupsCountersGroup | ||||
|  | ||||
| 	d := msgpack.NewDecoder(bytes.NewReader(data)) | ||||
| 	d.SetCustomStructTag("json") | ||||
|  | ||||
| 	err = d.Decode(&r) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
|  | ||||
| 	*personal = GroupsCountersGroup(r) | ||||
|  | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // GroupsCover struct. | ||||
| @@ -479,6 +550,70 @@ type GroupsGroupSettings struct { | ||||
| 	SecondarySection int                  `json:"secondary_section"` | ||||
| 	ActionButton     GroupsActionButton   `json:"action_button"` | ||||
| 	Phone            string               `json:"phone"` | ||||
|  | ||||
| 	RecognizePhoto int `json:"recognize_photo"` | ||||
|  | ||||
| 	MarketServices GroupsMarketServices `json:"market_services"` | ||||
| 	Narratives     int                  `json:"narratives"` | ||||
| 	Clips          int                  `json:"clips"` | ||||
| 	Textlives      int                  `json:"textlives"` | ||||
| 	Youla          GroupsYoula          `json:"youla"` | ||||
| } | ||||
|  | ||||
| // GroupsMarketServices struct. | ||||
| type GroupsMarketServices struct { | ||||
| 	Enabled         BaseBoolInt         `json:"enabled"` | ||||
| 	CanMessage      BaseBoolInt         `json:"can_message"` | ||||
| 	CommentsEnabled BaseBoolInt         `json:"comments_enabled"` | ||||
| 	ContactID       int                 `json:"contact_id"` | ||||
| 	Currency        MarketCurrency      `json:"currency"` | ||||
| 	ViewType        GroupsSelectedItems `json:"view_type"` | ||||
| 	BlockName       GroupsSelectedItems `json:"block_name"` | ||||
| 	ButtonLabel     GroupsSelectedItems `json:"button_label"` | ||||
| } | ||||
|  | ||||
| // GroupsSelectedItems struct. | ||||
| type GroupsSelectedItems struct { | ||||
| 	SelectedItemID int64                `json:"selected_item_id"` | ||||
| 	Items          []BaseObjectWithName `json:"items"` | ||||
| } | ||||
|  | ||||
| // GroupsYoula struct. | ||||
| type GroupsYoula struct { | ||||
| 	CategoryTree  GroupsYoulaCategory `json:"category_tree"` | ||||
| 	GroupSettings GroupsYoulaSettings `json:"group_settings"` | ||||
| } | ||||
|  | ||||
| // GroupsYoulaCategory struct. | ||||
| type GroupsYoulaCategory struct { | ||||
| 	ID            int                      `json:"id"` | ||||
| 	Title         string                   `json:"title"` | ||||
| 	Subcategories []GroupsYoulaSubcategory `json:"subcategories"` | ||||
| } | ||||
|  | ||||
| // GroupsYoulaSubcategory struct. | ||||
| type GroupsYoulaSubcategory struct { | ||||
| 	ID            int                      `json:"id"` | ||||
| 	Title         string                   `json:"title"` | ||||
| 	ParentID      int                      `json:"parent_id"` | ||||
| 	Subcategories []GroupsYoulaSubcategory `json:"subcategories"` | ||||
| } | ||||
|  | ||||
| // GroupsYoulaSettings struct. | ||||
| type GroupsYoulaSettings struct { | ||||
| 	IsActive              BaseBoolInt `json:"is_active"` | ||||
| 	IsModerated           BaseBoolInt `json:"is_moderated"` | ||||
| 	ShowModerationSetting BaseBoolInt `json:"show_moderation_setting"` | ||||
| 	ModerationStatus      int         `json:"moderation_status"` | ||||
| 	DeclineReason         string      `json:"decline_reason"` | ||||
| 	GroupMode             int         `json:"group_mode"` | ||||
| 	SelectedCategoryIDS   []int       `json:"selected_category_ids"` | ||||
| 	Lat                   float64     `json:"lat"` | ||||
| 	Long                  float64     `json:"long"` | ||||
| 	Radius                float64     `json:"radius"` | ||||
| 	RadiusArea            string      `json:"radius_area"` | ||||
| 	Address               string      `json:"address"` | ||||
| 	Radiuses              []float64   `json:"radiuses"` | ||||
| } | ||||
|  | ||||
| // GroupsSectionsList struct. | ||||
| @@ -532,6 +667,53 @@ func (g *GroupsSectionsList) UnmarshalJSON(data []byte) error { | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // DecodeMsgpack need for decode dynamic array (Example: [1, "Фотографии"]) to struct. | ||||
| func (g *GroupsSectionsList) DecodeMsgpack(dec *msgpack.Decoder) error { | ||||
| 	data, err := dec.DecodeRaw() | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
|  | ||||
| 	var alias []interface{} | ||||
|  | ||||
| 	err = msgpack.Unmarshal(data, &alias) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
|  | ||||
| 	if len(alias) != 2 { | ||||
| 		return &json.UnmarshalTypeError{ | ||||
| 			Value: string(data), | ||||
| 			Type:  reflect.TypeOf((*GroupsSectionsList)(nil)), | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	id, ok := alias[0].(int8) | ||||
| 	if !ok { | ||||
| 		return &json.UnmarshalTypeError{ | ||||
| 			Value:  string(data), | ||||
| 			Type:   reflect.TypeOf((*GroupsSectionsList)(nil)), | ||||
| 			Struct: "GroupsSectionsList", | ||||
| 			Field:  "ID", | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	name, ok := alias[1].(string) | ||||
| 	if !ok { | ||||
| 		return &json.UnmarshalTypeError{ | ||||
| 			Value:  string(data), | ||||
| 			Type:   reflect.TypeOf((*GroupsSectionsList)(nil)), | ||||
| 			Struct: "GroupsSectionsList", | ||||
| 			Field:  "Name", | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	g.ID = int(id) | ||||
| 	g.Name = name | ||||
|  | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // GroupsActionType for action_button in groups. | ||||
| type GroupsActionType string | ||||
|  | ||||
| @@ -685,7 +867,10 @@ type GroupsLongPollServer struct { | ||||
| 	Ts     string `json:"ts"`     // Number of the last event | ||||
| } | ||||
|  | ||||
| // TODO: func (g GroupsLongPollServer) GetURL() string { | ||||
| // GetURL return link. | ||||
| func (lp GroupsLongPollServer) GetURL(wait int) string { | ||||
| 	return fmt.Sprintf("%s?act=a_check&key=%s&ts=%s&wait=%d", lp.Server, lp.Key, lp.Ts, wait) | ||||
| } | ||||
|  | ||||
| // GroupsLongPollSettings struct. | ||||
| type GroupsLongPollSettings struct { | ||||
| @@ -714,12 +899,14 @@ type GroupsMarketInfo struct { | ||||
| 	Enabled         BaseBoolInt       `json:"enabled"`                 // Information whether the market is enabled | ||||
| 	CommentsEnabled BaseBoolInt       `json:"comments_enabled,omitempty"` | ||||
| 	CanMessage      BaseBoolInt       `json:"can_message,omitempty"` | ||||
| 	IsHsEnabled     BaseBoolInt       `json:"is_hs_enabled,omitempty"` | ||||
| 	MainAlbumID     int               `json:"main_album_id,omitempty"` // Main market album ID | ||||
| 	PriceMax        string            `json:"price_max,omitempty"`     // Maximum price | ||||
| 	PriceMin        string            `json:"price_min,omitempty"`     // Minimum price | ||||
| 	Wiki            PagesWikipageFull `json:"wiki,omitempty"` | ||||
| 	CityIDs         []int             `json:"city_ids"` | ||||
| 	CountryIDs      []int             `json:"country_ids,omitempty"` | ||||
| 	MinOrderPrice   MarketPrice       `json:"min_order_price,omitempty"` | ||||
| } | ||||
|  | ||||
| // GroupsGroupRole Role type. | ||||
|   | ||||
							
								
								
									
										65
									
								
								vendor/github.com/SevereCloud/vksdk/v2/object/market.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										65
									
								
								vendor/github.com/SevereCloud/vksdk/v2/object/market.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -4,6 +4,9 @@ import ( | ||||
| 	"bytes" | ||||
| 	"encoding/json" | ||||
| 	"fmt" | ||||
|  | ||||
| 	"github.com/vmihailenco/msgpack/v5" | ||||
| 	"github.com/vmihailenco/msgpack/v5/msgpcode" | ||||
| ) | ||||
|  | ||||
| // Information whether the MarketMarketItem is available. | ||||
| @@ -28,6 +31,8 @@ type MarketMarketAlbum struct { | ||||
| 	Photo       PhotosPhoto `json:"photo"` | ||||
| 	Title       string      `json:"title"`        // Market album title | ||||
| 	UpdatedTime int         `json:"updated_time"` // Date when album has been updated last time in Unixtime | ||||
| 	IsMain      BaseBoolInt `json:"is_main"` | ||||
| 	IsHidden    BaseBoolInt `json:"is_hidden"` | ||||
| } | ||||
|  | ||||
| // ToAttachment return attachment format. | ||||
| @@ -98,6 +103,36 @@ func (market *MarketMarketItem) UnmarshalJSON(data []byte) error { | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // DecodeMsgpack MarketMarketItem. | ||||
| // | ||||
| // BUG(VK): https://github.com/SevereCloud/vksdk/issues/147 | ||||
| func (market *MarketMarketItem) DecodeMsgpack(dec *msgpack.Decoder) error { | ||||
| 	data, err := dec.DecodeRaw() | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
|  | ||||
| 	if bytes.Equal(data, []byte{msgpcode.False}) { | ||||
| 		return nil | ||||
| 	} | ||||
|  | ||||
| 	type renamedMarketMarketItem MarketMarketItem | ||||
|  | ||||
| 	var r renamedMarketMarketItem | ||||
|  | ||||
| 	d := msgpack.NewDecoder(bytes.NewReader(data)) | ||||
| 	d.SetCustomStructTag("json") | ||||
|  | ||||
| 	err = d.Decode(&r) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
|  | ||||
| 	*market = MarketMarketItem(r) | ||||
|  | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // MarketMarketItemProperty struct. | ||||
| type MarketMarketItemProperty struct { | ||||
| 	VariantID    int    `json:"variant_id"` | ||||
| @@ -149,6 +184,36 @@ func (m *MarketPrice) UnmarshalJSON(data []byte) error { | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // DecodeMsgpack MarketPrice. | ||||
| // | ||||
| // BUG(VK): unavailable product, in fave.get return []. | ||||
| func (m *MarketPrice) DecodeMsgpack(dec *msgpack.Decoder) error { | ||||
| 	data, err := dec.DecodeRaw() | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
|  | ||||
| 	if bytes.Equal(data, []byte{msgpcode.FixedArrayLow}) { | ||||
| 		return nil | ||||
| 	} | ||||
|  | ||||
| 	type renamedMarketPrice MarketPrice | ||||
|  | ||||
| 	var r renamedMarketPrice | ||||
|  | ||||
| 	d := msgpack.NewDecoder(bytes.NewReader(data)) | ||||
| 	d.SetCustomStructTag("json") | ||||
|  | ||||
| 	err = d.Decode(&r) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
|  | ||||
| 	*m = MarketPrice(r) | ||||
|  | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // MarketSection struct. | ||||
| type MarketSection struct { | ||||
| 	ID   int    `json:"id"`   // Section ID | ||||
|   | ||||
							
								
								
									
										52
									
								
								vendor/github.com/SevereCloud/vksdk/v2/object/marusia.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										52
									
								
								vendor/github.com/SevereCloud/vksdk/v2/object/marusia.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,52 @@ | ||||
| package object // import "github.com/SevereCloud/vksdk/v2/object" | ||||
|  | ||||
| import ( | ||||
| 	"encoding/json" | ||||
| ) | ||||
|  | ||||
| // MarusiaPicture struct. | ||||
| type MarusiaPicture struct { | ||||
| 	ID      int `json:"id"` | ||||
| 	OwnerID int `json:"owner_id"` | ||||
| } | ||||
|  | ||||
| // MarusiaPictureUploadResponse struct. | ||||
| type MarusiaPictureUploadResponse struct { | ||||
| 	Hash        string          `json:"hash"`   // Uploading hash | ||||
| 	Photo       json.RawMessage `json:"photo"`  // Uploaded photo data | ||||
| 	Server      int             `json:"server"` // Upload server number | ||||
| 	AID         int             `json:"aid"` | ||||
| 	MessageCode int             `json:"message_code"` | ||||
| } | ||||
|  | ||||
| // MarusiaAudio struct. | ||||
| type MarusiaAudio struct { | ||||
| 	ID      int    `json:"id"` | ||||
| 	Title   string `json:"title"` | ||||
| 	OwnerID int    `json:"owner_id"` | ||||
| } | ||||
|  | ||||
| // MarusiaAudioUploadResponse struct. | ||||
| type MarusiaAudioUploadResponse struct { | ||||
| 	Sha       string           `json:"sha"` | ||||
| 	Secret    string           `json:"secret"` | ||||
| 	Meta      MarusiaAudioMeta `json:"meta"` | ||||
| 	Hash      string           `json:"hash"` | ||||
| 	Server    string           `json:"server"` | ||||
| 	UserID    int              `json:"user_id"` | ||||
| 	RequestID string           `json:"request_id"` | ||||
| } | ||||
|  | ||||
| // MarusiaAudioMeta struct. | ||||
| type MarusiaAudioMeta struct { | ||||
| 	Album       string `json:"album"` | ||||
| 	Artist      string `json:"artist"` | ||||
| 	Bitrate     string `json:"bitrate"` | ||||
| 	Duration    string `json:"duration"` | ||||
| 	Genre       string `json:"genre"` | ||||
| 	Kad         string `json:"kad"` | ||||
| 	Md5         string `json:"md5"` | ||||
| 	Md5DataSize string `json:"md5_data_size"` | ||||
| 	Samplerate  string `json:"samplerate"` | ||||
| 	Title       string `json:"title"` | ||||
| } | ||||
							
								
								
									
										53
									
								
								vendor/github.com/SevereCloud/vksdk/v2/object/messages.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										53
									
								
								vendor/github.com/SevereCloud/vksdk/v2/object/messages.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -79,6 +79,7 @@ type MessagesMessage struct { | ||||
| 	UpdateTime   int    `json:"update_time"`   // Date when the message has been updated in Unixtime | ||||
| 	MembersCount int    `json:"members_count"` // Members number | ||||
| 	ExpireTTL    int    `json:"expire_ttl"` | ||||
| 	MessageTag   string `json:"message_tag"` // for https://notify.mail.ru/ | ||||
| } | ||||
|  | ||||
| // MessagesBasePayload struct. | ||||
| @@ -375,17 +376,18 @@ type MessagesTemplateElement struct { | ||||
|  | ||||
| // MessagesTemplateElementCarousel struct. | ||||
| type MessagesTemplateElementCarousel struct { | ||||
| 	Title       string                                `json:"title"` | ||||
| 	Action      MessagesTemplateElementCarouselAction `json:"action"` | ||||
| 	Description string                                `json:"description"` | ||||
| 	Photo       PhotosPhoto                           `json:"photo"` | ||||
| 	Buttons     []MessagesKeyboardButton              `json:"buttons"` | ||||
| 	Title       string                                `json:"title,omitempty"` | ||||
| 	Action      MessagesTemplateElementCarouselAction `json:"action,omitempty"` | ||||
| 	Description string                                `json:"description,omitempty"` | ||||
| 	Photo       *PhotosPhoto                          `json:"photo,omitempty"`    // Only read | ||||
| 	PhotoID     string                                `json:"photo_id,omitempty"` // Only for send | ||||
| 	Buttons     []MessagesKeyboardButton              `json:"buttons,omitempty"` | ||||
| } | ||||
|  | ||||
| // MessagesTemplateElementCarouselAction struct. | ||||
| type MessagesTemplateElementCarouselAction struct { | ||||
| 	Type string `json:"type"` | ||||
| 	Link string `json:"link"` | ||||
| 	Link string `json:"link,omitempty"` | ||||
| } | ||||
|  | ||||
| // MessageContentSourceMessage ... | ||||
| @@ -443,6 +445,7 @@ type MessagesChat struct { | ||||
| 	AdminID        int         `json:"admin_id"` // Chat creator ID | ||||
| 	ID             int         `json:"id"`       // Chat ID | ||||
| 	IsDefaultPhoto BaseBoolInt `json:"is_default_photo"` | ||||
| 	IsGroupChannel BaseBoolInt `json:"is_group_channel"` | ||||
| 	Photo100       string      `json:"photo_100"` // URL of the preview image with 100 px in width | ||||
| 	Photo200       string      `json:"photo_200"` // URL of the preview image with 200 px in width | ||||
| 	Photo50        string      `json:"photo_50"`  // URL of the preview image with 50 px in width | ||||
| @@ -473,20 +476,24 @@ type MessagesChatPushSettings struct { | ||||
|  | ||||
| // MessagesChatSettingsPhoto struct. | ||||
| type MessagesChatSettingsPhoto struct { | ||||
| 	Photo100       string      `json:"photo_100"` | ||||
| 	Photo200       string      `json:"photo_200"` | ||||
| 	Photo50        string      `json:"photo_50"` | ||||
| 	IsDefaultPhoto BaseBoolInt `json:"is_default_photo"` | ||||
| 	Photo100           string      `json:"photo_100"` | ||||
| 	Photo200           string      `json:"photo_200"` | ||||
| 	Photo50            string      `json:"photo_50"` | ||||
| 	IsDefaultPhoto     BaseBoolInt `json:"is_default_photo"` | ||||
| 	IsDefaultCallPhoto bool        `json:"is_default_call_photo"` | ||||
| } | ||||
|  | ||||
| // MessagesConversation struct. | ||||
| type MessagesConversation struct { | ||||
| 	CanWrite       MessagesConversationCanWrite     `json:"can_write"` | ||||
| 	ChatSettings   MessagesConversationChatSettings `json:"chat_settings"` | ||||
| 	InRead         int                              `json:"in_read"`         // Last message user have read | ||||
| 	LastMessageID  int                              `json:"last_message_id"` // ID of the last message in conversation | ||||
| 	Mentions       []int                            `json:"mentions"`        // IDs of messages with mentions | ||||
| 	MessageRequest string                           `json:"message_request"` | ||||
| 	CanWrite                  MessagesConversationCanWrite     `json:"can_write"` | ||||
| 	ChatSettings              MessagesConversationChatSettings `json:"chat_settings"` | ||||
| 	InRead                    int                              `json:"in_read"`         // Last message user have read | ||||
| 	LastMessageID             int                              `json:"last_message_id"` // ID of the last message in conversation | ||||
| 	Mentions                  []int                            `json:"mentions"`        // IDs of messages with mentions | ||||
| 	MessageRequest            string                           `json:"message_request"` | ||||
| 	LastConversationMessageID int                              `json:"last_conversation_message_id"` | ||||
| 	InReadCMID                int                              `json:"in_read_cmid"` | ||||
| 	OutReadCMID               int                              `json:"out_read_cmid"` | ||||
|  | ||||
| 	// Last outcoming message have been read by the opponent. | ||||
| 	OutRead         int                              `json:"out_read"` | ||||
| @@ -495,6 +502,10 @@ type MessagesConversation struct { | ||||
| 	Important       BaseBoolInt                      `json:"important"` | ||||
| 	Unanswered      BaseBoolInt                      `json:"unanswered"` | ||||
| 	IsMarkedUnread  BaseBoolInt                      `json:"is_marked_unread"` | ||||
| 	CanSendMoney    BaseBoolInt                      `json:"can_send_money"` | ||||
| 	CanReceiveMoney BaseBoolInt                      `json:"can_receive_money"` | ||||
| 	IsNew           BaseBoolInt                      `json:"is_new"` | ||||
| 	IsArchived      BaseBoolInt                      `json:"is_archived"` | ||||
| 	UnreadCount     int                              `json:"unread_count"` // Unread messages number | ||||
| 	CurrentKeyboard MessagesKeyboard                 `json:"current_keyboard"` | ||||
| 	SortID          struct { | ||||
| @@ -530,6 +541,7 @@ type MessagesConversationChatSettings struct { | ||||
| 		CanCall              BaseBoolInt `json:"can_call"` | ||||
| 		CanUseMassMentions   BaseBoolInt `json:"can_use_mass_mentions"` | ||||
| 		CanChangeServiceType BaseBoolInt `json:"can_change_service_type"` | ||||
| 		CanChangeStyle       BaseBoolInt `json:"can_change_style"` | ||||
| 	} `json:"acl"` | ||||
| 	IsGroupChannel   BaseBoolInt             `json:"is_group_channel"` | ||||
| 	IsDisappearing   BaseBoolInt             `json:"is_disappearing"` | ||||
| @@ -559,6 +571,7 @@ type MessagesChatPermissions struct { | ||||
| 	SeeInviteLink   MessagesChatPermission `json:"see_invite_link"` | ||||
| 	Call            MessagesChatPermission `json:"call"` | ||||
| 	ChangeAdmins    MessagesChatPermission `json:"change_admins"` | ||||
| 	ChangeStyle     MessagesChatPermission `json:"change_style"` | ||||
| } | ||||
|  | ||||
| // MessagesConversationPeer struct. | ||||
| @@ -570,9 +583,11 @@ type MessagesConversationPeer struct { | ||||
|  | ||||
| // MessagesConversationPushSettings struct. | ||||
| type MessagesConversationPushSettings struct { | ||||
| 	DisabledUntil   int         `json:"disabled_until"` | ||||
| 	DisabledForever BaseBoolInt `json:"disabled_forever"` | ||||
| 	NoSound         BaseBoolInt `json:"no_sound"` | ||||
| 	DisabledUntil        int         `json:"disabled_until"` | ||||
| 	DisabledForever      BaseBoolInt `json:"disabled_forever"` | ||||
| 	NoSound              BaseBoolInt `json:"no_sound"` | ||||
| 	DisabledMentions     BaseBoolInt `json:"disabled_mentions"` | ||||
| 	DisabledMassMentions BaseBoolInt `json:"disabled_mass_mentions"` | ||||
| } | ||||
|  | ||||
| // MessagesConversationWithMessage struct. | ||||
|   | ||||
							
								
								
									
										6
									
								
								vendor/github.com/SevereCloud/vksdk/v2/object/notifications.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										6
									
								
								vendor/github.com/SevereCloud/vksdk/v2/object/notifications.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,7 +1,5 @@ | ||||
| package object // import "github.com/SevereCloud/vksdk/v2/object" | ||||
|  | ||||
| import "encoding/json" | ||||
|  | ||||
| // NotificationsFeedback struct. | ||||
| type NotificationsFeedback struct { | ||||
| 	Attachments []WallWallpostAttachment `json:"attachments"` | ||||
| @@ -16,8 +14,8 @@ type NotificationsFeedback struct { | ||||
| // NotificationsNotification struct. | ||||
| type NotificationsNotification struct { | ||||
| 	Date     int                `json:"date"` // Date when the event has been occurred | ||||
| 	Feedback json.RawMessage    `json:"feedback"` | ||||
| 	Parent   json.RawMessage    `json:"parent"` | ||||
| 	Feedback RawMessage         `json:"feedback"` | ||||
| 	Parent   RawMessage         `json:"parent"` | ||||
| 	Reply    NotificationsReply `json:"reply"` | ||||
| 	Type     string             `json:"type"` // Notification type | ||||
| } | ||||
|   | ||||
							
								
								
									
										71
									
								
								vendor/github.com/SevereCloud/vksdk/v2/object/object.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										71
									
								
								vendor/github.com/SevereCloud/vksdk/v2/object/object.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -9,6 +9,8 @@ import ( | ||||
| 	"bytes" | ||||
| 	"encoding/json" | ||||
| 	"reflect" | ||||
|  | ||||
| 	"github.com/vmihailenco/msgpack/v5" | ||||
| ) | ||||
|  | ||||
| // Attachment interface. | ||||
| @@ -42,6 +44,44 @@ func (b *BaseBoolInt) UnmarshalJSON(data []byte) (err error) { | ||||
| 	return | ||||
| } | ||||
|  | ||||
| // DecodeMsgpack func. | ||||
| func (b *BaseBoolInt) DecodeMsgpack(dec *msgpack.Decoder) (err error) { | ||||
| 	data, err := dec.DecodeRaw() | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
|  | ||||
| 	var ( | ||||
| 		valueInt  int | ||||
| 		valueBool bool | ||||
| 	) | ||||
|  | ||||
| 	switch { | ||||
| 	case msgpack.Unmarshal(data, &valueBool) == nil: | ||||
| 		*b = BaseBoolInt(valueBool) | ||||
| 	case msgpack.Unmarshal(data, &valueInt) == nil: | ||||
| 		if valueInt == 1 { | ||||
| 			*b = true | ||||
| 			break | ||||
| 		} | ||||
|  | ||||
| 		if valueInt == 0 { | ||||
| 			*b = false | ||||
| 			break | ||||
| 		} | ||||
|  | ||||
| 		fallthrough | ||||
| 	default: | ||||
| 		// return msgpack error | ||||
| 		err = &json.UnmarshalTypeError{ | ||||
| 			Value: string(data), | ||||
| 			Type:  reflect.TypeOf((*BaseBoolInt)(nil)), | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	return err | ||||
| } | ||||
|  | ||||
| // BaseCountry struct. | ||||
| type BaseCountry struct { | ||||
| 	ID    int    `json:"id"` | ||||
| @@ -151,6 +191,33 @@ func (obj *BaseImage) UnmarshalJSON(data []byte) (err error) { | ||||
| 	return err | ||||
| } | ||||
|  | ||||
| // DecodeMsgpack is required to support images with `src` field. | ||||
| func (obj *BaseImage) DecodeMsgpack(dec *msgpack.Decoder) (err error) { | ||||
| 	type renamedBaseImage struct { | ||||
| 		Height float64 `msgpack:"height"` | ||||
| 		URL    string  `msgpack:"url"` | ||||
| 		Src    string  `msgpack:"src"` | ||||
| 		Width  float64 `msgpack:"width"` | ||||
| 		Type   string  `msgpack:"type"` | ||||
| 	} | ||||
|  | ||||
| 	var renamedObj renamedBaseImage | ||||
|  | ||||
| 	err = dec.Decode(&renamedObj) | ||||
|  | ||||
| 	obj.Height = renamedObj.Height | ||||
| 	obj.Width = renamedObj.Width | ||||
| 	obj.Type = renamedObj.Type | ||||
|  | ||||
| 	if renamedObj.Src == "" { | ||||
| 		obj.URL = renamedObj.URL | ||||
| 	} else { | ||||
| 		obj.URL = renamedObj.Src | ||||
| 	} | ||||
|  | ||||
| 	return err | ||||
| } | ||||
|  | ||||
| // BaseLikes struct. | ||||
| type BaseLikes struct { | ||||
| 	UserLikes BaseBoolInt `json:"user_likes"` // Information whether current user likes | ||||
| @@ -346,9 +413,11 @@ const ( | ||||
| type Privacy struct { | ||||
| 	Category PrivacyCategory `json:"category,omitempty"` | ||||
| 	Lists    struct { | ||||
| 		Allowed []int `json:"allowed"` | ||||
| 		Allowed  []int `json:"allowed"` | ||||
| 		Excluded []int `json:"excluded"` | ||||
| 	} `json:"lists,omitempty"` | ||||
| 	Owners struct { | ||||
| 		Allowed  []int `json:"allowed"` | ||||
| 		Excluded []int `json:"excluded"` | ||||
| 	} `json:"owners,omitempty"` | ||||
| } | ||||
|   | ||||
							
								
								
									
										1
									
								
								vendor/github.com/SevereCloud/vksdk/v2/object/photos.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								vendor/github.com/SevereCloud/vksdk/v2/object/photos.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -239,6 +239,7 @@ type PhotosPhotoFull struct { | ||||
| 	Photo1280  string             `json:"photo_1280"` // URL of image with 1280 px width | ||||
| 	Photo2560  string             `json:"photo_2560"` // URL of image with 2560 px width | ||||
| 	Sizes      []PhotosPhotoSizes `json:"sizes"` | ||||
| 	OrigPhoto  PhotosPhotoSizes   `json:"orig_photo"` | ||||
| } | ||||
|  | ||||
| // ToAttachment return attachment format. | ||||
|   | ||||
							
								
								
									
										39
									
								
								vendor/github.com/SevereCloud/vksdk/v2/object/raw.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										39
									
								
								vendor/github.com/SevereCloud/vksdk/v2/object/raw.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,39 @@ | ||||
| package object // import "github.com/SevereCloud/vksdk/v2/object" | ||||
|  | ||||
| import "github.com/vmihailenco/msgpack/v5" | ||||
|  | ||||
| // RawMessage is a raw encoded JSON or MessagePack value. | ||||
| type RawMessage []byte | ||||
|  | ||||
| // MarshalJSON returns m as the JSON encoding of m. | ||||
| func (m RawMessage) MarshalJSON() ([]byte, error) { | ||||
| 	if m == nil { | ||||
| 		return []byte("null"), nil | ||||
| 	} | ||||
|  | ||||
| 	return m, nil | ||||
| } | ||||
|  | ||||
| // UnmarshalJSON sets *m to a copy of data. | ||||
| func (m *RawMessage) UnmarshalJSON(data []byte) error { | ||||
| 	*m = append((*m)[0:0], data...) | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // EncodeMsgpack write m as the MessagePack encoding of m. | ||||
| func (m RawMessage) EncodeMsgpack(enc *msgpack.Encoder) error { | ||||
| 	_, err := enc.Writer().Write(m) | ||||
| 	return err | ||||
| } | ||||
|  | ||||
| // DecodeMsgpack sets *m to a copy of data. | ||||
| func (m *RawMessage) DecodeMsgpack(dec *msgpack.Decoder) error { | ||||
| 	msg, err := dec.DecodeRaw() | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
|  | ||||
| 	*m = RawMessage(msg) | ||||
|  | ||||
| 	return nil | ||||
| } | ||||
							
								
								
									
										37
									
								
								vendor/github.com/SevereCloud/vksdk/v2/object/stories.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										37
									
								
								vendor/github.com/SevereCloud/vksdk/v2/object/stories.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -127,6 +127,7 @@ type StoriesStory struct { | ||||
| 	Seen                 BaseBoolInt              `json:"seen"` | ||||
| 	IsOwnerPinned        BaseBoolInt              `json:"is_owner_pinned"` | ||||
| 	IsOneTime            BaseBoolInt              `json:"is_one_time"` | ||||
| 	IsAdvice             BaseBoolInt              `json:"is_advice,omitempty"` | ||||
| 	NeedMute             BaseBoolInt              `json:"need_mute"` | ||||
| 	MuteReply            BaseBoolInt              `json:"mute_reply"` | ||||
| 	CanLike              BaseBoolInt              `json:"can_like"` | ||||
| @@ -152,6 +153,7 @@ type StoriesStory struct { | ||||
| 	NarrativesCount      int                      `json:"narratives_count"` | ||||
| 	FirstNarrativeTitle  string                   `json:"first_narrative_title"` | ||||
| 	Questions            StoriesQuestions         `json:"questions"` | ||||
| 	ReactionSetID        string                   `json:"reaction_set_id"` | ||||
| } | ||||
|  | ||||
| // StoriesFeedItemType type. | ||||
| @@ -251,8 +253,10 @@ type StoriesClickableSticker struct { // nolint: maligned | ||||
| 	StickerID     int `json:"sticker_id,omitempty"` | ||||
| 	StickerPackID int `json:"sticker_pack_id,omitempty"` | ||||
|  | ||||
| 	// type=place | ||||
| 	// type=place or geo | ||||
| 	PlaceID int `json:"place_id,omitempty"` | ||||
| 	// Title | ||||
| 	CategoryID int `json:"category_id,omitempty"` | ||||
|  | ||||
| 	// type=question | ||||
| 	Question               string      `json:"question,omitempty"` | ||||
| @@ -267,8 +271,14 @@ type StoriesClickableSticker struct { // nolint: maligned | ||||
| 	Hashtag string `json:"hashtag,omitempty"` | ||||
|  | ||||
| 	// type=link | ||||
| 	LinkObject  BaseLink `json:"link_object,omitempty"` | ||||
| 	TooltipText string   `json:"tooltip_text,omitempty"` | ||||
| 	LinkObject     BaseLink `json:"link_object,omitempty"` | ||||
| 	TooltipText    string   `json:"tooltip_text,omitempty"` | ||||
| 	TooltipTextKey string   `json:"tooltip_text_key,omitempty"` | ||||
|  | ||||
| 	// type=time | ||||
| 	TimestampMs int64  `json:"timestamp_ms,omitempty"` | ||||
| 	Date        string `json:"date,omitempty"` | ||||
| 	Title       string `json:"title,omitempty"` | ||||
|  | ||||
| 	// type=market_item | ||||
| 	Subtype string `json:"subtype,omitempty"` | ||||
| @@ -290,10 +300,19 @@ type StoriesClickableSticker struct { // nolint: maligned | ||||
| 	AudioStartTime int        `json:"audio_start_time,omitempty"` | ||||
|  | ||||
| 	// type=app | ||||
| 	App                      AppsApp     `json:"app"` | ||||
| 	AppContext               string      `json:"app_context"` | ||||
| 	HasNewInteractions       BaseBoolInt `json:"has_new_interactions"` | ||||
| 	IsBroadcastNotifyAllowed BaseBoolInt `json:"is_broadcast_notify_allowed"` | ||||
| 	App                      AppsApp     `json:"app,omitempty"` | ||||
| 	AppContext               string      `json:"app_context,omitempty"` | ||||
| 	HasNewInteractions       BaseBoolInt `json:"has_new_interactions,omitempty"` | ||||
| 	IsBroadcastNotifyAllowed BaseBoolInt `json:"is_broadcast_notify_allowed,omitempty"` | ||||
|  | ||||
| 	// type=emoji | ||||
| 	Emoji string `json:"emoji,omitempty"` | ||||
|  | ||||
| 	// type=text | ||||
| 	Text            string `json:"text,omitempty"` | ||||
| 	BackgroundStyle string `json:"background_style,omitempty"` | ||||
| 	Alignment       string `json:"alignment,omitempty"` | ||||
| 	SelectionColor  string `json:"selection_color,omitempty"` | ||||
| } | ||||
|  | ||||
| // TODO: сделать несколько структур для кликабельного стикера | ||||
| @@ -313,6 +332,10 @@ const ( | ||||
| 	ClickableStickerPoll       = "poll" | ||||
| 	ClickableStickerMusic      = "music" | ||||
| 	ClickableStickerApp        = "app" | ||||
| 	ClickableStickerTime       = "time" | ||||
| 	ClickableStickerEmoji      = "emoji" | ||||
| 	ClickableStickerGeo        = "geo" | ||||
| 	ClickableStickerText       = "text" | ||||
| ) | ||||
|  | ||||
| // Subtype of clickable sticker. | ||||
|   | ||||
							
								
								
									
										33
									
								
								vendor/github.com/SevereCloud/vksdk/v2/object/users.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										33
									
								
								vendor/github.com/SevereCloud/vksdk/v2/object/users.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -4,6 +4,9 @@ import ( | ||||
| 	"bytes" | ||||
| 	"encoding/json" | ||||
| 	"fmt" | ||||
|  | ||||
| 	"github.com/vmihailenco/msgpack/v5" | ||||
| 	"github.com/vmihailenco/msgpack/v5/msgpcode" | ||||
| ) | ||||
|  | ||||
| // User relationship status. | ||||
| @@ -258,6 +261,36 @@ func (personal *UsersPersonal) UnmarshalJSON(data []byte) error { | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // DecodeMsgpack UsersPersonal. | ||||
| // | ||||
| // BUG(VK): UsersPersonal return []. | ||||
| func (personal *UsersPersonal) DecodeMsgpack(dec *msgpack.Decoder) error { | ||||
| 	data, err := dec.DecodeRaw() | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
|  | ||||
| 	if bytes.Equal(data, []byte{msgpcode.FixedArrayLow}) { | ||||
| 		return nil | ||||
| 	} | ||||
|  | ||||
| 	type renamedUsersPersonal UsersPersonal | ||||
|  | ||||
| 	var r renamedUsersPersonal | ||||
|  | ||||
| 	d := msgpack.NewDecoder(bytes.NewReader(data)) | ||||
| 	d.SetCustomStructTag("json") | ||||
|  | ||||
| 	err = d.Decode(&r) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
|  | ||||
| 	*personal = UsersPersonal(r) | ||||
|  | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // UsersRelative struct. | ||||
| type UsersRelative struct { | ||||
| 	BirthDate string `json:"birth_date"` // Date of child birthday (format dd.mm.yyyy) | ||||
|   | ||||
							
								
								
									
										60
									
								
								vendor/github.com/SevereCloud/vksdk/v2/object/utils.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										60
									
								
								vendor/github.com/SevereCloud/vksdk/v2/object/utils.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,5 +1,13 @@ | ||||
| package object // import "github.com/SevereCloud/vksdk/v2/object" | ||||
|  | ||||
| import ( | ||||
| 	"bytes" | ||||
| 	"encoding/json" | ||||
|  | ||||
| 	"github.com/vmihailenco/msgpack/v5" | ||||
| 	"github.com/vmihailenco/msgpack/v5/msgpcode" | ||||
| ) | ||||
|  | ||||
| // UtilsDomainResolvedType object type. | ||||
| const ( | ||||
| 	UtilsDomainResolvedTypeUser        = "user" | ||||
| @@ -15,6 +23,58 @@ type UtilsDomainResolved struct { | ||||
| 	Type     string `json:"type"` | ||||
| } | ||||
|  | ||||
| // UnmarshalJSON UtilsDomainResolved. | ||||
| // | ||||
| // BUG(VK): UtilsDomainResolved return []. | ||||
| func (link *UtilsDomainResolved) UnmarshalJSON(data []byte) error { | ||||
| 	if bytes.Equal(data, []byte("[]")) { | ||||
| 		return nil | ||||
| 	} | ||||
|  | ||||
| 	type renamedUtilsDomainResolved UtilsDomainResolved | ||||
|  | ||||
| 	var r renamedUtilsDomainResolved | ||||
|  | ||||
| 	err := json.Unmarshal(data, &r) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
|  | ||||
| 	*link = UtilsDomainResolved(r) | ||||
|  | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // DecodeMsgpack UtilsDomainResolved. | ||||
| // | ||||
| // BUG(VK): UtilsDomainResolved return []. | ||||
| func (link *UtilsDomainResolved) DecodeMsgpack(dec *msgpack.Decoder) error { | ||||
| 	data, err := dec.DecodeRaw() | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
|  | ||||
| 	if bytes.Equal(data, []byte{msgpcode.FixedArrayLow}) { | ||||
| 		return nil | ||||
| 	} | ||||
|  | ||||
| 	type renamedUtilsDomainResolved UtilsDomainResolved | ||||
|  | ||||
| 	var r renamedUtilsDomainResolved | ||||
|  | ||||
| 	d := msgpack.NewDecoder(bytes.NewReader(data)) | ||||
| 	d.SetCustomStructTag("json") | ||||
|  | ||||
| 	err = d.Decode(&r) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
|  | ||||
| 	*link = UtilsDomainResolved(r) | ||||
|  | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // UtilsLastShortenedLink struct. | ||||
| type UtilsLastShortenedLink struct { | ||||
| 	AccessKey string `json:"access_key"` // Access key for private stats | ||||
|   | ||||
							
								
								
									
										71
									
								
								vendor/github.com/SevereCloud/vksdk/v2/object/video.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										71
									
								
								vendor/github.com/SevereCloud/vksdk/v2/object/video.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -12,6 +12,9 @@ type VideoVideo struct { | ||||
| 	// Date when the video has been added in Unixtime. | ||||
| 	AddingDate int `json:"adding_date"` | ||||
|  | ||||
| 	// Date when the video has been released in Unixtime. | ||||
| 	ReleaseDate int `json:"release_date"` | ||||
|  | ||||
| 	// Information whether current user can add the video. | ||||
| 	CanAdd BaseBoolInt `json:"can_add"` | ||||
|  | ||||
| @@ -27,12 +30,17 @@ type VideoVideo struct { | ||||
| 	// Information whether current user can like the video. | ||||
| 	CanLike BaseBoolInt `json:"can_like"` | ||||
|  | ||||
| 	// Information whether current user can download the video. | ||||
| 	CanDownload BaseBoolInt `json:"can_download"` | ||||
|  | ||||
| 	// Information whether current user can repost this video. | ||||
| 	CanRepost         BaseBoolInt       `json:"can_repost"` | ||||
| 	CanSubscribe      BaseBoolInt       `json:"can_subscribe"` | ||||
| 	CanAttachLink     BaseBoolInt       `json:"can_attach_link"` | ||||
| 	IsFavorite        BaseBoolInt       `json:"is_favorite"` | ||||
| 	IsPrivate         BaseBoolInt       `json:"is_private"` | ||||
| 	IsExplicit        BaseBoolInt       `json:"is_explicit"` | ||||
| 	IsSubscribed      BaseBoolInt       `json:"is_subscribed"` | ||||
| 	Added             BaseBoolInt       `json:"added"` | ||||
| 	Repeat            BaseBoolInt       `json:"repeat"` // Information whether the video is repeated | ||||
| 	ContentRestricted int               `json:"content_restricted"` | ||||
| @@ -43,6 +51,7 @@ type VideoVideo struct { | ||||
| 	Description       string            `json:"description"` // Video description | ||||
| 	Duration          int               `json:"duration"`    // Video duration in seconds | ||||
| 	Files             VideoVideoFiles   `json:"files"` | ||||
| 	Trailer           VideoVideoFiles   `json:"trailer,omitempty"` | ||||
| 	FirstFrame        []VideoVideoImage `json:"first_frame"` | ||||
| 	Image             []VideoVideoImage `json:"image"` | ||||
| 	Height            int               `json:"height"`   // Video height | ||||
| @@ -56,22 +65,27 @@ type VideoVideo struct { | ||||
| 	Photo1280         string            `json:"photo_1280"` // URL of the preview image with 1280 px in width | ||||
|  | ||||
| 	// URL of the page with a player that can be used to play the video in the browser. | ||||
| 	Player                   string            `json:"player"` | ||||
| 	Processing               int               `json:"processing"` // Returns if the video is processing | ||||
| 	Title                    string            `json:"title"`      // Video title | ||||
| 	Type                     string            `json:"type"` | ||||
| 	Views                    int               `json:"views"` // Number of views | ||||
| 	Width                    int               `json:"width"` // Video width | ||||
| 	Platform                 string            `json:"platform"` | ||||
| 	LocalViews               int               `json:"local_views"` | ||||
| 	Likes                    BaseLikesInfo     `json:"likes"`   // Count of likes | ||||
| 	Reposts                  BaseRepostsInfo   `json:"reposts"` // Count of views | ||||
| 	TrackCode                string            `json:"track_code"` | ||||
| 	PrivacyView              Privacy           `json:"privacy_view"` | ||||
| 	PrivacyComment           Privacy           `json:"privacy_comment"` | ||||
| 	ActionButton             VideoActionButton `json:"action_button"` | ||||
| 	Restriction              VideoRestriction  `json:"restriction"` | ||||
| 	ContentRestrictedMessage string            `json:"content_restricted_message"` | ||||
| 	Player                   string               `json:"player"` | ||||
| 	Processing               int                  `json:"processing"` // Returns if the video is processing | ||||
| 	Title                    string               `json:"title"`      // Video title | ||||
| 	Subtitle                 string               `json:"subtitle"`   // Video subtitle | ||||
| 	Type                     string               `json:"type"` | ||||
| 	Views                    int                  `json:"views"` // Number of views | ||||
| 	Width                    int                  `json:"width"` // Video width | ||||
| 	Platform                 string               `json:"platform"` | ||||
| 	LocalViews               int                  `json:"local_views"` | ||||
| 	Likes                    BaseLikesInfo        `json:"likes"`   // Count of likes | ||||
| 	Reposts                  BaseRepostsInfo      `json:"reposts"` // Count of views | ||||
| 	TrackCode                string               `json:"track_code"` | ||||
| 	PrivacyView              Privacy              `json:"privacy_view"` | ||||
| 	PrivacyComment           Privacy              `json:"privacy_comment"` | ||||
| 	ActionButton             VideoActionButton    `json:"action_button"` | ||||
| 	Restriction              VideoRestriction     `json:"restriction"` | ||||
| 	ContentRestrictedMessage string               `json:"content_restricted_message"` | ||||
| 	MainArtists              []AudioAudioArtist   `json:"main_artists"` | ||||
| 	FeaturedArtists          []AudioAudioArtist   `json:"featured_artists"` | ||||
| 	Genres                   []BaseObjectWithName `json:"genres"` | ||||
| 	OvID                     string               `json:"ov_id,omitempty"` | ||||
| } | ||||
|  | ||||
| // ToAttachment return attachment format. | ||||
| @@ -112,16 +126,20 @@ type VideoSnippet struct { | ||||
|  | ||||
| // VideoVideoFiles struct. | ||||
| type VideoVideoFiles struct { | ||||
| 	External string `json:"external"` // URL of the external player | ||||
| 	Mp4_1080 string `json:"mp4_1080"` // URL of the mpeg4 file with 1080p quality | ||||
| 	Mp4_1440 string `json:"mp4_1440"` // URL of the mpeg4 file with 2k quality | ||||
| 	Mp4_2160 string `json:"mp4_2160"` // URL of the mpeg4 file with 4k quality | ||||
| 	Mp4_240  string `json:"mp4_240"`  // URL of the mpeg4 file with 240p quality | ||||
| 	Mp4_360  string `json:"mp4_360"`  // URL of the mpeg4 file with 360p quality | ||||
| 	Mp4_480  string `json:"mp4_480"`  // URL of the mpeg4 file with 480p quality | ||||
| 	Mp4_720  string `json:"mp4_720"`  // URL of the mpeg4 file with 720p quality | ||||
| 	Live     string `json:"live"` | ||||
| 	HLS      string `json:"hls"` | ||||
| 	External     string `json:"external,omitempty"` // URL of the external player | ||||
| 	Mp4_1080     string `json:"mp4_1080,omitempty"` // URL of the mpeg4 file with 1080p quality | ||||
| 	Mp4_1440     string `json:"mp4_1440,omitempty"` // URL of the mpeg4 file with 2k quality | ||||
| 	Mp4_2160     string `json:"mp4_2160,omitempty"` // URL of the mpeg4 file with 4k quality | ||||
| 	Mp4_240      string `json:"mp4_240,omitempty"`  // URL of the mpeg4 file with 240p quality | ||||
| 	Mp4_360      string `json:"mp4_360,omitempty"`  // URL of the mpeg4 file with 360p quality | ||||
| 	Mp4_480      string `json:"mp4_480,omitempty"`  // URL of the mpeg4 file with 480p quality | ||||
| 	Mp4_720      string `json:"mp4_720,omitempty"`  // URL of the mpeg4 file with 720p quality | ||||
| 	Live         string `json:"live,omitempty"` | ||||
| 	HLS          string `json:"hls,omitempty"` | ||||
| 	DashUni      string `json:"dash_uni,omitempty"` | ||||
| 	DashSep      string `json:"dash_sep,omitempty"` | ||||
| 	DashWebm     string `json:"dash_webm,omitempty"` | ||||
| 	FailoverHost string `json:"failover_host,omitempty"` | ||||
| } | ||||
|  | ||||
| // VideoCatBlock struct. | ||||
| @@ -213,6 +231,7 @@ type VideoVideoFull struct { | ||||
| 	Description   string          `json:"description"` // Video description | ||||
| 	Duration      int             `json:"duration"`    // Video duration in seconds | ||||
| 	Files         VideoVideoFiles `json:"files"` | ||||
| 	Trailer       VideoVideoFiles `json:"trailer"` | ||||
| 	ID            int             `json:"id"` // Video ID | ||||
| 	Likes         BaseLikes       `json:"likes"` | ||||
| 	Live          int             `json:"live"`     // Returns if the video is live translation | ||||
|   | ||||
							
								
								
									
										23
									
								
								vendor/github.com/SevereCloud/vksdk/v2/object/wall.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										23
									
								
								vendor/github.com/SevereCloud/vksdk/v2/object/wall.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -128,7 +128,7 @@ const ( | ||||
| 	WallPostTypeSuggest  = "suggest" | ||||
| ) | ||||
|  | ||||
| // WallWallpost  struct. | ||||
| // WallWallpost struct. | ||||
| type WallWallpost struct { | ||||
| 	AccessKey      string                   `json:"access_key"` // Access key to private object | ||||
| 	ID             int                      `json:"id"`         // Post ID | ||||
| @@ -156,14 +156,17 @@ type WallWallpost struct { | ||||
| 	IsPinned       BaseBoolInt              `json:"is_pinned"` | ||||
| 	IsFavorite     BaseBoolInt              `json:"is_favorite"` // Information whether the post in favorites list | ||||
| 	IsArchived     BaseBoolInt              `json:"is_archived"` // Is post archived, only for post owners | ||||
| 	IsDeleted      BaseBoolInt              `json:"is_deleted"` | ||||
| 	MarkedAsAds    BaseBoolInt              `json:"marked_as_ads"` | ||||
| 	Edited         int                      `json:"edited"` // Date of editing in Unixtime | ||||
| 	Copyright      WallPostCopyright        `json:"copyright"` | ||||
| 	PostID         int                      `json:"post_id"` | ||||
| 	ParentsStack   []int                    `json:"parents_stack"` | ||||
| 	Donut          WallWallpostDonut        `json:"donut"` // need api v5.125 | ||||
| 	Donut          WallWallpostDonut        `json:"donut"` | ||||
| 	ShortTextRate  float64                  `json:"short_text_rate"` | ||||
| 	CarouselOffset int                      `json:"carousel_offset"` | ||||
| 	Header         WallWallpostHeader       `json:"header"` | ||||
| 	Hash           string                   `json:"hash"` | ||||
| } | ||||
|  | ||||
| // Attachment type. | ||||
| @@ -235,8 +238,10 @@ type WallWallpostToID struct { | ||||
| 	IsFavorite    BaseBoolInt              `json:"is_favorite"` // Information whether the post in favorites list | ||||
| 	MarkedAsAds   BaseBoolInt              `json:"marked_as_ads"` | ||||
| 	ParentsStack  []int                    `json:"parents_stack"` | ||||
| 	Donut         WallWallpostDonut        `json:"donut"` // need api v5.125 | ||||
| 	Donut         WallWallpostDonut        `json:"donut"` | ||||
| 	ShortTextRate float64                  `json:"short_text_rate"` | ||||
| 	Views         WallViews                `json:"views"` // Count of views | ||||
| 	Header        WallWallpostHeader       `json:"header"` | ||||
| } | ||||
|  | ||||
| // WallWallpostDonut info about VK Donut. | ||||
| @@ -255,3 +260,15 @@ type WallPostCopyright struct { | ||||
| 	Type string `json:"type"` | ||||
| 	Name string `json:"name"` | ||||
| } | ||||
|  | ||||
| // WallWallpostHeader struct. | ||||
| type WallWallpostHeader struct { | ||||
| 	Type              string                              `json:"type"` | ||||
| 	CustomDescription WallWallpostHeaderCustomDescription `json:"custom_description"` | ||||
| } | ||||
|  | ||||
| // WallWallpostHeaderCustomDescription struct. | ||||
| type WallWallpostHeaderCustomDescription struct { | ||||
| 	SourceID int `json:"source_id"` | ||||
| 	Date     int `json:"date"` | ||||
| } | ||||
|   | ||||
							
								
								
									
										3
									
								
								vendor/github.com/SevereCloud/vksdk/v2/object/widgets.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										3
									
								
								vendor/github.com/SevereCloud/vksdk/v2/object/widgets.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -45,6 +45,9 @@ type WidgetsWidgetComment struct { | ||||
| 	Views       struct { | ||||
| 		Count int `json:"count"` | ||||
| 	} `json:"views"` | ||||
| 	Donut         WallWallpostDonut  `json:"donut"` | ||||
| 	ShortTextRate float64            `json:"short_text_rate"` | ||||
| 	Header        WallWallpostHeader `json:"header"` | ||||
| } | ||||
|  | ||||
| // WidgetsWidgetLikes struct. | ||||
|   | ||||
							
								
								
									
										5
									
								
								vendor/github.com/bwmarrin/discordgo/.gitignore
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								vendor/github.com/bwmarrin/discordgo/.gitignore
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,5 @@ | ||||
| # IDE-specific metadata | ||||
| .idea/ | ||||
|  | ||||
| # Environment variables. Useful for examples. | ||||
| .env | ||||
							
								
								
									
										19
									
								
								vendor/github.com/bwmarrin/discordgo/.golangci.yml
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								vendor/github.com/bwmarrin/discordgo/.golangci.yml
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,19 @@ | ||||
| linters: | ||||
|   disable-all: true | ||||
|   enable: | ||||
|     # - staticcheck | ||||
|     # - unused | ||||
|     - golint | ||||
|  | ||||
| linters-settings: | ||||
|   staticcheck: | ||||
|     go: "1.13" | ||||
|  | ||||
|     checks: ["all"] | ||||
|  | ||||
|   unused: | ||||
|     go: "1.13" | ||||
|  | ||||
| issues: | ||||
|   include: | ||||
|     - EXC0002 | ||||
| @@ -3,6 +3,7 @@ go: | ||||
|     - 1.13.x | ||||
|     - 1.14.x | ||||
|     - 1.15.x | ||||
|     - 1.16.x | ||||
| env: | ||||
|     - GO111MODULE=on | ||||
| install: | ||||
| @@ -1,8 +1,8 @@ | ||||
| # DiscordGo | ||||
| 
 | ||||
| [](https://godoc.org/github.com/bwmarrin/discordgo) [](http://goreportcard.com/report/bwmarrin/discordgo) [](https://travis-ci.org/bwmarrin/discordgo) [](https://discord.gg/0f1SbxBZjYoCtNPP) [](https://discord.com/invite/discord-api) | ||||
| [](https://pkg.go.dev/github.com/bwmarrin/discordgo) [](https://goreportcard.com/report/github.com/bwmarrin/discordgo) [](https://travis-ci.com/bwmarrin/discordgo) [](https://discord.gg/golang) [](https://discord.com/invite/discord-api) | ||||
| 
 | ||||
| <img align="right" src="http://bwmarrin.github.io/discordgo/img/discordgo.png"> | ||||
| <img align="right" alt="DiscordGo logo" src="docs/img/discordgo.svg" width="400"> | ||||
| 
 | ||||
| DiscordGo is a [Go](https://golang.org/) package that provides low level  | ||||
| bindings to the [Discord](https://discord.com/) chat client API. DiscordGo  | ||||
| @@ -22,7 +22,7 @@ tool that wraps `ffmpeg` to create opus encoded audio appropriate for use with | ||||
| Discord (and DiscordGo). | ||||
| 
 | ||||
| **For help with this package or general Go discussion, please join the [Discord  | ||||
| Gophers](https://discord.gg/0f1SbxBZjYq9jLBk) chat server.** | ||||
| Gophers](https://discord.gg/golang) chat server.** | ||||
| 
 | ||||
| ## Getting Started | ||||
| 
 | ||||
| @@ -64,8 +64,8 @@ The DiscordGo code is fairly well documented at this point and is currently | ||||
| the only documentation available.  Both GoDoc and GoWalker (below) present | ||||
| that information in a nice format. | ||||
| 
 | ||||
| - [](https://godoc.org/github.com/bwmarrin/discordgo)  | ||||
| - [](https://gowalker.org/github.com/bwmarrin/discordgo)  | ||||
| - [](https://pkg.go.dev/github.com/bwmarrin/discordgo) | ||||
| - [](https://gowalker.org/github.com/bwmarrin/discordgo)  | ||||
| - Hand crafted documentation coming eventually. | ||||
| 
 | ||||
| 
 | ||||
							
								
								
									
										241
									
								
								vendor/github.com/bwmarrin/discordgo/components.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										241
									
								
								vendor/github.com/bwmarrin/discordgo/components.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,241 @@ | ||||
| package discordgo | ||||
|  | ||||
| import ( | ||||
| 	"encoding/json" | ||||
| 	"fmt" | ||||
| ) | ||||
|  | ||||
| // ComponentType is type of component. | ||||
| type ComponentType uint | ||||
|  | ||||
| // MessageComponent types. | ||||
| const ( | ||||
| 	ActionsRowComponent ComponentType = 1 | ||||
| 	ButtonComponent     ComponentType = 2 | ||||
| 	SelectMenuComponent ComponentType = 3 | ||||
| 	TextInputComponent  ComponentType = 4 | ||||
| ) | ||||
|  | ||||
| // MessageComponent is a base interface for all message components. | ||||
| type MessageComponent interface { | ||||
| 	json.Marshaler | ||||
| 	Type() ComponentType | ||||
| } | ||||
|  | ||||
| type unmarshalableMessageComponent struct { | ||||
| 	MessageComponent | ||||
| } | ||||
|  | ||||
| // UnmarshalJSON is a helper function to unmarshal MessageComponent object. | ||||
| func (umc *unmarshalableMessageComponent) UnmarshalJSON(src []byte) error { | ||||
| 	var v struct { | ||||
| 		Type ComponentType `json:"type"` | ||||
| 	} | ||||
| 	err := json.Unmarshal(src, &v) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
|  | ||||
| 	switch v.Type { | ||||
| 	case ActionsRowComponent: | ||||
| 		umc.MessageComponent = &ActionsRow{} | ||||
| 	case ButtonComponent: | ||||
| 		umc.MessageComponent = &Button{} | ||||
| 	case SelectMenuComponent: | ||||
| 		umc.MessageComponent = &SelectMenu{} | ||||
| 	case TextInputComponent: | ||||
| 		umc.MessageComponent = &TextInput{} | ||||
| 	default: | ||||
| 		return fmt.Errorf("unknown component type: %d", v.Type) | ||||
| 	} | ||||
| 	return json.Unmarshal(src, umc.MessageComponent) | ||||
| } | ||||
|  | ||||
| // MessageComponentFromJSON is a helper function for unmarshaling message components | ||||
| func MessageComponentFromJSON(b []byte) (MessageComponent, error) { | ||||
| 	var u unmarshalableMessageComponent | ||||
| 	err := u.UnmarshalJSON(b) | ||||
| 	if err != nil { | ||||
| 		return nil, fmt.Errorf("failed to unmarshal into MessageComponent: %w", err) | ||||
| 	} | ||||
| 	return u.MessageComponent, nil | ||||
| } | ||||
|  | ||||
| // ActionsRow is a container for components within one row. | ||||
| type ActionsRow struct { | ||||
| 	Components []MessageComponent `json:"components"` | ||||
| } | ||||
|  | ||||
| // MarshalJSON is a method for marshaling ActionsRow to a JSON object. | ||||
| func (r ActionsRow) MarshalJSON() ([]byte, error) { | ||||
| 	type actionsRow ActionsRow | ||||
|  | ||||
| 	return json.Marshal(struct { | ||||
| 		actionsRow | ||||
| 		Type ComponentType `json:"type"` | ||||
| 	}{ | ||||
| 		actionsRow: actionsRow(r), | ||||
| 		Type:       r.Type(), | ||||
| 	}) | ||||
| } | ||||
|  | ||||
| // UnmarshalJSON is a helper function to unmarshal Actions Row. | ||||
| func (r *ActionsRow) UnmarshalJSON(data []byte) error { | ||||
| 	var v struct { | ||||
| 		RawComponents []unmarshalableMessageComponent `json:"components"` | ||||
| 	} | ||||
| 	err := json.Unmarshal(data, &v) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	r.Components = make([]MessageComponent, len(v.RawComponents)) | ||||
| 	for i, v := range v.RawComponents { | ||||
| 		r.Components[i] = v.MessageComponent | ||||
| 	} | ||||
|  | ||||
| 	return err | ||||
| } | ||||
|  | ||||
| // Type is a method to get the type of a component. | ||||
| func (r ActionsRow) Type() ComponentType { | ||||
| 	return ActionsRowComponent | ||||
| } | ||||
|  | ||||
| // ButtonStyle is style of button. | ||||
| type ButtonStyle uint | ||||
|  | ||||
| // Button styles. | ||||
| const ( | ||||
| 	// PrimaryButton is a button with blurple color. | ||||
| 	PrimaryButton ButtonStyle = 1 | ||||
| 	// SecondaryButton is a button with grey color. | ||||
| 	SecondaryButton ButtonStyle = 2 | ||||
| 	// SuccessButton is a button with green color. | ||||
| 	SuccessButton ButtonStyle = 3 | ||||
| 	// DangerButton is a button with red color. | ||||
| 	DangerButton ButtonStyle = 4 | ||||
| 	// LinkButton is a special type of button which navigates to a URL. Has grey color. | ||||
| 	LinkButton ButtonStyle = 5 | ||||
| ) | ||||
|  | ||||
| // ComponentEmoji represents button emoji, if it does have one. | ||||
| type ComponentEmoji struct { | ||||
| 	Name     string `json:"name,omitempty"` | ||||
| 	ID       string `json:"id,omitempty"` | ||||
| 	Animated bool   `json:"animated,omitempty"` | ||||
| } | ||||
|  | ||||
| // Button represents button component. | ||||
| type Button struct { | ||||
| 	Label    string         `json:"label"` | ||||
| 	Style    ButtonStyle    `json:"style"` | ||||
| 	Disabled bool           `json:"disabled"` | ||||
| 	Emoji    ComponentEmoji `json:"emoji"` | ||||
|  | ||||
| 	// NOTE: Only button with LinkButton style can have link. Also, URL is mutually exclusive with CustomID. | ||||
| 	URL      string `json:"url,omitempty"` | ||||
| 	CustomID string `json:"custom_id,omitempty"` | ||||
| } | ||||
|  | ||||
| // MarshalJSON is a method for marshaling Button to a JSON object. | ||||
| func (b Button) MarshalJSON() ([]byte, error) { | ||||
| 	type button Button | ||||
|  | ||||
| 	if b.Style == 0 { | ||||
| 		b.Style = PrimaryButton | ||||
| 	} | ||||
|  | ||||
| 	return json.Marshal(struct { | ||||
| 		button | ||||
| 		Type ComponentType `json:"type"` | ||||
| 	}{ | ||||
| 		button: button(b), | ||||
| 		Type:   b.Type(), | ||||
| 	}) | ||||
| } | ||||
|  | ||||
| // Type is a method to get the type of a component. | ||||
| func (Button) Type() ComponentType { | ||||
| 	return ButtonComponent | ||||
| } | ||||
|  | ||||
| // SelectMenuOption represents an option for a select menu. | ||||
| type SelectMenuOption struct { | ||||
| 	Label       string         `json:"label,omitempty"` | ||||
| 	Value       string         `json:"value"` | ||||
| 	Description string         `json:"description"` | ||||
| 	Emoji       ComponentEmoji `json:"emoji"` | ||||
| 	// Determines whenever option is selected by default or not. | ||||
| 	Default bool `json:"default"` | ||||
| } | ||||
|  | ||||
| // SelectMenu represents select menu component. | ||||
| type SelectMenu struct { | ||||
| 	CustomID string `json:"custom_id,omitempty"` | ||||
| 	// The text which will be shown in the menu if there's no default options or all options was deselected and component was closed. | ||||
| 	Placeholder string `json:"placeholder"` | ||||
| 	// This value determines the minimal amount of selected items in the menu. | ||||
| 	MinValues *int `json:"min_values,omitempty"` | ||||
| 	// This value determines the maximal amount of selected items in the menu. | ||||
| 	// If MaxValues or MinValues are greater than one then the user can select multiple items in the component. | ||||
| 	MaxValues int                `json:"max_values,omitempty"` | ||||
| 	Options   []SelectMenuOption `json:"options"` | ||||
| 	Disabled  bool               `json:"disabled"` | ||||
| } | ||||
|  | ||||
| // Type is a method to get the type of a component. | ||||
| func (SelectMenu) Type() ComponentType { | ||||
| 	return SelectMenuComponent | ||||
| } | ||||
|  | ||||
| // MarshalJSON is a method for marshaling SelectMenu to a JSON object. | ||||
| func (m SelectMenu) MarshalJSON() ([]byte, error) { | ||||
| 	type selectMenu SelectMenu | ||||
|  | ||||
| 	return json.Marshal(struct { | ||||
| 		selectMenu | ||||
| 		Type ComponentType `json:"type"` | ||||
| 	}{ | ||||
| 		selectMenu: selectMenu(m), | ||||
| 		Type:       m.Type(), | ||||
| 	}) | ||||
| } | ||||
|  | ||||
| // TextInput represents text input component. | ||||
| type TextInput struct { | ||||
| 	CustomID    string         `json:"custom_id"` | ||||
| 	Label       string         `json:"label"` | ||||
| 	Style       TextInputStyle `json:"style"` | ||||
| 	Placeholder string         `json:"placeholder,omitempty"` | ||||
| 	Value       string         `json:"value,omitempty"` | ||||
| 	Required    bool           `json:"required,omitempty"` | ||||
| 	MinLength   int            `json:"min_length,omitempty"` | ||||
| 	MaxLength   int            `json:"max_length,omitempty"` | ||||
| } | ||||
|  | ||||
| // Type is a method to get the type of a component. | ||||
| func (TextInput) Type() ComponentType { | ||||
| 	return TextInputComponent | ||||
| } | ||||
|  | ||||
| // MarshalJSON is a method for marshaling TextInput to a JSON object. | ||||
| func (m TextInput) MarshalJSON() ([]byte, error) { | ||||
| 	type inputText TextInput | ||||
|  | ||||
| 	return json.Marshal(struct { | ||||
| 		inputText | ||||
| 		Type ComponentType `json:"type"` | ||||
| 	}{ | ||||
| 		inputText: inputText(m), | ||||
| 		Type:      m.Type(), | ||||
| 	}) | ||||
| } | ||||
|  | ||||
| // TextInputStyle is style of text in TextInput component. | ||||
| type TextInputStyle uint | ||||
|  | ||||
| // Text styles | ||||
| const ( | ||||
| 	TextInputShort     TextInputStyle = 1 | ||||
| 	TextInputParagraph TextInputStyle = 2 | ||||
| ) | ||||
							
								
								
									
										60
									
								
								vendor/github.com/bwmarrin/discordgo/discord.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										60
									
								
								vendor/github.com/bwmarrin/discordgo/discord.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,60 @@ | ||||
| // Discordgo - Discord bindings for Go | ||||
| // Available at https://github.com/bwmarrin/discordgo | ||||
|  | ||||
| // Copyright 2015-2016 Bruce Marriner <bruce@sqls.net>.  All rights reserved. | ||||
| // Use of this source code is governed by a BSD-style | ||||
| // license that can be found in the LICENSE file. | ||||
|  | ||||
| // This file contains high level helper functions and easy entry points for the | ||||
| // entire discordgo package.  These functions are being developed and are very | ||||
| // experimental at this point.  They will most likely change so please use the | ||||
| // low level functions if that's a problem. | ||||
|  | ||||
| // Package discordgo provides Discord binding for Go | ||||
| package discordgo | ||||
|  | ||||
| import ( | ||||
| 	"net/http" | ||||
| 	"runtime" | ||||
| 	"time" | ||||
| ) | ||||
|  | ||||
| // VERSION of DiscordGo, follows Semantic Versioning. (http://semver.org/) | ||||
| const VERSION = "0.24.0" | ||||
|  | ||||
| // New creates a new Discord session with provided token. | ||||
| // If the token is for a bot, it must be prefixed with "Bot " | ||||
| // 		e.g. "Bot ..." | ||||
| // Or if it is an OAuth2 token, it must be prefixed with "Bearer " | ||||
| //		e.g. "Bearer ..." | ||||
| func New(token string) (s *Session, err error) { | ||||
|  | ||||
| 	// Create an empty Session interface. | ||||
| 	s = &Session{ | ||||
| 		State:                  NewState(), | ||||
| 		Ratelimiter:            NewRatelimiter(), | ||||
| 		StateEnabled:           true, | ||||
| 		Compress:               true, | ||||
| 		ShouldReconnectOnError: true, | ||||
| 		ShardID:                0, | ||||
| 		ShardCount:             1, | ||||
| 		MaxRestRetries:         3, | ||||
| 		Client:                 &http.Client{Timeout: (20 * time.Second)}, | ||||
| 		UserAgent:              "DiscordBot (https://github.com/bwmarrin/discordgo, v" + VERSION + ")", | ||||
| 		sequence:               new(int64), | ||||
| 		LastHeartbeatAck:       time.Now().UTC(), | ||||
| 	} | ||||
|  | ||||
| 	// Initilize the Identify Package with defaults | ||||
| 	// These can be modified prior to calling Open() | ||||
| 	s.Identify.Compress = true | ||||
| 	s.Identify.LargeThreshold = 250 | ||||
| 	s.Identify.GuildSubscriptions = true | ||||
| 	s.Identify.Properties.OS = runtime.GOOS | ||||
| 	s.Identify.Properties.Browser = "DiscordGo v" + VERSION | ||||
| 	s.Identify.Intents = IntentsAllWithoutPrivileged | ||||
| 	s.Identify.Token = token | ||||
| 	s.Token = token | ||||
|  | ||||
| 	return | ||||
| } | ||||
							
								
								
									
										210
									
								
								vendor/github.com/bwmarrin/discordgo/endpoints.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										210
									
								
								vendor/github.com/bwmarrin/discordgo/endpoints.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,210 @@ | ||||
| // Discordgo - Discord bindings for Go | ||||
| // Available at https://github.com/bwmarrin/discordgo | ||||
|  | ||||
| // Copyright 2015-2016 Bruce Marriner <bruce@sqls.net>.  All rights reserved. | ||||
| // Use of this source code is governed by a BSD-style | ||||
| // license that can be found in the LICENSE file. | ||||
|  | ||||
| // This file contains variables for all known Discord end points.  All functions | ||||
| // throughout the Discordgo package use these variables for all connections | ||||
| // to Discord.  These are all exported and you may modify them if needed. | ||||
|  | ||||
| package discordgo | ||||
|  | ||||
| import "strconv" | ||||
|  | ||||
| // APIVersion is the Discord API version used for the REST and Websocket API. | ||||
| var APIVersion = "9" | ||||
|  | ||||
| // Known Discord API Endpoints. | ||||
| var ( | ||||
| 	EndpointStatus     = "https://status.discord.com/api/v2/" | ||||
| 	EndpointSm         = EndpointStatus + "scheduled-maintenances/" | ||||
| 	EndpointSmActive   = EndpointSm + "active.json" | ||||
| 	EndpointSmUpcoming = EndpointSm + "upcoming.json" | ||||
|  | ||||
| 	EndpointDiscord    = "https://discord.com/" | ||||
| 	EndpointAPI        = EndpointDiscord + "api/v" + APIVersion + "/" | ||||
| 	EndpointGuilds     = EndpointAPI + "guilds/" | ||||
| 	EndpointChannels   = EndpointAPI + "channels/" | ||||
| 	EndpointUsers      = EndpointAPI + "users/" | ||||
| 	EndpointGateway    = EndpointAPI + "gateway" | ||||
| 	EndpointGatewayBot = EndpointGateway + "/bot" | ||||
| 	EndpointWebhooks   = EndpointAPI + "webhooks/" | ||||
| 	EndpointStickers   = EndpointAPI + "stickers/" | ||||
|  | ||||
| 	EndpointCDN             = "https://cdn.discordapp.com/" | ||||
| 	EndpointCDNAttachments  = EndpointCDN + "attachments/" | ||||
| 	EndpointCDNAvatars      = EndpointCDN + "avatars/" | ||||
| 	EndpointCDNIcons        = EndpointCDN + "icons/" | ||||
| 	EndpointCDNSplashes     = EndpointCDN + "splashes/" | ||||
| 	EndpointCDNChannelIcons = EndpointCDN + "channel-icons/" | ||||
| 	EndpointCDNBanners      = EndpointCDN + "banners/" | ||||
| 	EndpointCDNGuilds       = EndpointCDN + "guilds/" | ||||
|  | ||||
| 	EndpointVoice        = EndpointAPI + "/voice/" | ||||
| 	EndpointVoiceRegions = EndpointVoice + "regions" | ||||
|  | ||||
| 	// TODO: EndpointUserGuildMember | ||||
|  | ||||
| 	EndpointUser               = func(uID string) string { return EndpointUsers + uID } | ||||
| 	EndpointUserAvatar         = func(uID, aID string) string { return EndpointCDNAvatars + uID + "/" + aID + ".png" } | ||||
| 	EndpointUserAvatarAnimated = func(uID, aID string) string { return EndpointCDNAvatars + uID + "/" + aID + ".gif" } | ||||
| 	EndpointDefaultUserAvatar  = func(uDiscriminator string) string { | ||||
| 		uDiscriminatorInt, _ := strconv.Atoi(uDiscriminator) | ||||
| 		return EndpointCDN + "embed/avatars/" + strconv.Itoa(uDiscriminatorInt%5) + ".png" | ||||
| 	} | ||||
| 	EndpointUserBanner = func(uID, cID string) string { | ||||
| 		return EndpointCDNBanners + uID + "/" + cID + ".png" | ||||
| 	} | ||||
| 	EndpointUserBannerAnimated = func(uID, cID string) string { | ||||
| 		return EndpointCDNBanners + uID + "/" + cID + ".gif" | ||||
| 	} | ||||
|  | ||||
| 	EndpointUserGuilds      = func(uID string) string { return EndpointUsers + uID + "/guilds" } | ||||
| 	EndpointUserGuild       = func(uID, gID string) string { return EndpointUsers + uID + "/guilds/" + gID } | ||||
| 	EndpointUserChannels    = func(uID string) string { return EndpointUsers + uID + "/channels" } | ||||
| 	EndpointUserConnections = func(uID string) string { return EndpointUsers + uID + "/connections" } | ||||
|  | ||||
| 	EndpointGuild                    = func(gID string) string { return EndpointGuilds + gID } | ||||
| 	EndpointGuildThreads             = func(gID string) string { return EndpointGuild(gID) + "/threads" } | ||||
| 	EndpointGuildActiveThreads       = func(gID string) string { return EndpointGuildThreads(gID) + "/active" } | ||||
| 	EndpointGuildPreview             = func(gID string) string { return EndpointGuilds + gID + "/preview" } | ||||
| 	EndpointGuildChannels            = func(gID string) string { return EndpointGuilds + gID + "/channels" } | ||||
| 	EndpointGuildMembers             = func(gID string) string { return EndpointGuilds + gID + "/members" } | ||||
| 	EndpointGuildMember              = func(gID, uID string) string { return EndpointGuilds + gID + "/members/" + uID } | ||||
| 	EndpointGuildMemberRole          = func(gID, uID, rID string) string { return EndpointGuilds + gID + "/members/" + uID + "/roles/" + rID } | ||||
| 	EndpointGuildBans                = func(gID string) string { return EndpointGuilds + gID + "/bans" } | ||||
| 	EndpointGuildBan                 = func(gID, uID string) string { return EndpointGuilds + gID + "/bans/" + uID } | ||||
| 	EndpointGuildIntegrations        = func(gID string) string { return EndpointGuilds + gID + "/integrations" } | ||||
| 	EndpointGuildIntegration         = func(gID, iID string) string { return EndpointGuilds + gID + "/integrations/" + iID } | ||||
| 	EndpointGuildRoles               = func(gID string) string { return EndpointGuilds + gID + "/roles" } | ||||
| 	EndpointGuildRole                = func(gID, rID string) string { return EndpointGuilds + gID + "/roles/" + rID } | ||||
| 	EndpointGuildInvites             = func(gID string) string { return EndpointGuilds + gID + "/invites" } | ||||
| 	EndpointGuildWidget              = func(gID string) string { return EndpointGuilds + gID + "/widget" } | ||||
| 	EndpointGuildEmbed               = EndpointGuildWidget | ||||
| 	EndpointGuildPrune               = func(gID string) string { return EndpointGuilds + gID + "/prune" } | ||||
| 	EndpointGuildIcon                = func(gID, hash string) string { return EndpointCDNIcons + gID + "/" + hash + ".png" } | ||||
| 	EndpointGuildIconAnimated        = func(gID, hash string) string { return EndpointCDNIcons + gID + "/" + hash + ".gif" } | ||||
| 	EndpointGuildSplash              = func(gID, hash string) string { return EndpointCDNSplashes + gID + "/" + hash + ".png" } | ||||
| 	EndpointGuildWebhooks            = func(gID string) string { return EndpointGuilds + gID + "/webhooks" } | ||||
| 	EndpointGuildAuditLogs           = func(gID string) string { return EndpointGuilds + gID + "/audit-logs" } | ||||
| 	EndpointGuildEmojis              = func(gID string) string { return EndpointGuilds + gID + "/emojis" } | ||||
| 	EndpointGuildEmoji               = func(gID, eID string) string { return EndpointGuilds + gID + "/emojis/" + eID } | ||||
| 	EndpointGuildBanner              = func(gID, hash string) string { return EndpointCDNBanners + gID + "/" + hash + ".png" } | ||||
| 	EndpointGuildStickers            = func(gID string) string { return EndpointGuilds + gID + "/stickers" } | ||||
| 	EndpointGuildSticker             = func(gID, sID string) string { return EndpointGuilds + gID + "/stickers/" + sID } | ||||
| 	EndpointGuildScheduledEvents     = func(gID string) string { return EndpointGuilds + gID + "/scheduled-events" } | ||||
| 	EndpointGuildScheduledEvent      = func(gID, eID string) string { return EndpointGuilds + gID + "/scheduled-events/" + eID } | ||||
| 	EndpointGuildScheduledEventUsers = func(gID, eID string) string { return EndpointGuildScheduledEvent(gID, eID) + "/users" } | ||||
| 	EndpointGuildTemplate            = func(tID string) string { return EndpointGuilds + "/templates/" + tID } | ||||
| 	EndpointGuildTemplates           = func(gID string) string { return EndpointGuilds + gID + "/templates" } | ||||
| 	EndpointGuildTemplateSync        = func(gID, tID string) string { return EndpointGuilds + gID + "/templates/" + tID } | ||||
| 	EndpointGuildMemberAvatar        = func(gId, uID, aID string) string { | ||||
| 		return EndpointCDNGuilds + gId + "/users/" + uID + "/avatars/" + aID + ".png" | ||||
| 	} | ||||
| 	EndpointGuildMemberAvatarAnimated = func(gId, uID, aID string) string { | ||||
| 		return EndpointCDNGuilds + gId + "/users/" + uID + "/avatars/" + aID + ".gif" | ||||
| 	} | ||||
|  | ||||
| 	EndpointChannel                             = func(cID string) string { return EndpointChannels + cID } | ||||
| 	EndpointChannelThreads                      = func(cID string) string { return EndpointChannel(cID) + "/threads" } | ||||
| 	EndpointChannelActiveThreads                = func(cID string) string { return EndpointChannelThreads(cID) + "/active" } | ||||
| 	EndpointChannelPublicArchivedThreads        = func(cID string) string { return EndpointChannelThreads(cID) + "/archived/public" } | ||||
| 	EndpointChannelPrivateArchivedThreads       = func(cID string) string { return EndpointChannelThreads(cID) + "/archived/private" } | ||||
| 	EndpointChannelJoinedPrivateArchivedThreads = func(cID string) string { return EndpointChannel(cID) + "/users/@me/threads/archived/private" } | ||||
| 	EndpointChannelPermissions                  = func(cID string) string { return EndpointChannels + cID + "/permissions" } | ||||
| 	EndpointChannelPermission                   = func(cID, tID string) string { return EndpointChannels + cID + "/permissions/" + tID } | ||||
| 	EndpointChannelInvites                      = func(cID string) string { return EndpointChannels + cID + "/invites" } | ||||
| 	EndpointChannelTyping                       = func(cID string) string { return EndpointChannels + cID + "/typing" } | ||||
| 	EndpointChannelMessages                     = func(cID string) string { return EndpointChannels + cID + "/messages" } | ||||
| 	EndpointChannelMessage                      = func(cID, mID string) string { return EndpointChannels + cID + "/messages/" + mID } | ||||
| 	EndpointChannelMessageThread                = func(cID, mID string) string { return EndpointChannelMessage(cID, mID) + "/threads" } | ||||
| 	EndpointChannelMessagesBulkDelete           = func(cID string) string { return EndpointChannel(cID) + "/messages/bulk-delete" } | ||||
| 	EndpointChannelMessagesPins                 = func(cID string) string { return EndpointChannel(cID) + "/pins" } | ||||
| 	EndpointChannelMessagePin                   = func(cID, mID string) string { return EndpointChannel(cID) + "/pins/" + mID } | ||||
| 	EndpointChannelMessageCrosspost             = func(cID, mID string) string { return EndpointChannel(cID) + "/messages/" + mID + "/crosspost" } | ||||
| 	EndpointChannelFollow                       = func(cID string) string { return EndpointChannel(cID) + "/followers" } | ||||
| 	EndpointThreadMembers                       = func(tID string) string { return EndpointChannel(tID) + "/thread-members" } | ||||
| 	EndpointThreadMember                        = func(tID, mID string) string { return EndpointThreadMembers(tID) + "/" + mID } | ||||
|  | ||||
| 	EndpointGroupIcon = func(cID, hash string) string { return EndpointCDNChannelIcons + cID + "/" + hash + ".png" } | ||||
|  | ||||
| 	EndpointSticker            = func(sID string) string { return EndpointStickers + sID } | ||||
| 	EndpointNitroStickersPacks = EndpointAPI + "/sticker-packs" | ||||
|  | ||||
| 	EndpointChannelWebhooks = func(cID string) string { return EndpointChannel(cID) + "/webhooks" } | ||||
| 	EndpointWebhook         = func(wID string) string { return EndpointWebhooks + wID } | ||||
| 	EndpointWebhookToken    = func(wID, token string) string { return EndpointWebhooks + wID + "/" + token } | ||||
| 	EndpointWebhookMessage  = func(wID, token, messageID string) string { | ||||
| 		return EndpointWebhookToken(wID, token) + "/messages/" + messageID | ||||
| 	} | ||||
|  | ||||
| 	EndpointMessageReactionsAll = func(cID, mID string) string { | ||||
| 		return EndpointChannelMessage(cID, mID) + "/reactions" | ||||
| 	} | ||||
| 	EndpointMessageReactions = func(cID, mID, eID string) string { | ||||
| 		return EndpointChannelMessage(cID, mID) + "/reactions/" + eID | ||||
| 	} | ||||
| 	EndpointMessageReaction = func(cID, mID, eID, uID string) string { | ||||
| 		return EndpointMessageReactions(cID, mID, eID) + "/" + uID | ||||
| 	} | ||||
|  | ||||
| 	EndpointApplicationGlobalCommands = func(aID string) string { | ||||
| 		return EndpointApplication(aID) + "/commands" | ||||
| 	} | ||||
| 	EndpointApplicationGlobalCommand = func(aID, cID string) string { | ||||
| 		return EndpointApplicationGlobalCommands(aID) + "/" + cID | ||||
| 	} | ||||
|  | ||||
| 	EndpointApplicationGuildCommands = func(aID, gID string) string { | ||||
| 		return EndpointApplication(aID) + "/guilds/" + gID + "/commands" | ||||
| 	} | ||||
| 	EndpointApplicationGuildCommand = func(aID, gID, cID string) string { | ||||
| 		return EndpointApplicationGuildCommands(aID, gID) + "/" + cID | ||||
| 	} | ||||
| 	EndpointApplicationCommandPermissions = func(aID, gID, cID string) string { | ||||
| 		return EndpointApplicationGuildCommand(aID, gID, cID) + "/permissions" | ||||
| 	} | ||||
| 	EndpointApplicationCommandsGuildPermissions = func(aID, gID string) string { | ||||
| 		return EndpointApplicationGuildCommands(aID, gID) + "/permissions" | ||||
| 	} | ||||
| 	EndpointInteraction = func(aID, iToken string) string { | ||||
| 		return EndpointAPI + "interactions/" + aID + "/" + iToken | ||||
| 	} | ||||
| 	EndpointInteractionResponse = func(iID, iToken string) string { | ||||
| 		return EndpointInteraction(iID, iToken) + "/callback" | ||||
| 	} | ||||
| 	EndpointInteractionResponseActions = func(aID, iToken string) string { | ||||
| 		return EndpointWebhookMessage(aID, iToken, "@original") | ||||
| 	} | ||||
| 	EndpointFollowupMessage = func(aID, iToken string) string { | ||||
| 		return EndpointWebhookToken(aID, iToken) | ||||
| 	} | ||||
| 	EndpointFollowupMessageActions = func(aID, iToken, mID string) string { | ||||
| 		return EndpointWebhookMessage(aID, iToken, mID) | ||||
| 	} | ||||
|  | ||||
| 	EndpointGuildCreate = EndpointAPI + "guilds" | ||||
|  | ||||
| 	EndpointInvite = func(iID string) string { return EndpointAPI + "invites/" + iID } | ||||
|  | ||||
| 	EndpointEmoji         = func(eID string) string { return EndpointCDN + "emojis/" + eID + ".png" } | ||||
| 	EndpointEmojiAnimated = func(eID string) string { return EndpointCDN + "emojis/" + eID + ".gif" } | ||||
|  | ||||
| 	EndpointApplications = EndpointAPI + "applications" | ||||
| 	EndpointApplication  = func(aID string) string { return EndpointApplications + "/" + aID } | ||||
|  | ||||
| 	EndpointOAuth2                  = EndpointAPI + "oauth2/" | ||||
| 	EndpointOAuth2Applications      = EndpointOAuth2 + "applications" | ||||
| 	EndpointOAuth2Application       = func(aID string) string { return EndpointOAuth2Applications + "/" + aID } | ||||
| 	EndpointOAuth2ApplicationsBot   = func(aID string) string { return EndpointOAuth2Applications + "/" + aID + "/bot" } | ||||
| 	EndpointOAuth2ApplicationAssets = func(aID string) string { return EndpointOAuth2Applications + "/" + aID + "/assets" } | ||||
|  | ||||
| 	// TODO: Deprecated, remove in the next release | ||||
| 	EndpointOauth2                  = EndpointOAuth2 | ||||
| 	EndpointOauth2Applications      = EndpointOAuth2Applications | ||||
| 	EndpointOauth2Application       = EndpointOAuth2Application | ||||
| 	EndpointOauth2ApplicationsBot   = EndpointOAuth2ApplicationsBot | ||||
| 	EndpointOauth2ApplicationAssets = EndpointOAuth2ApplicationAssets | ||||
| ) | ||||
| @@ -157,7 +157,7 @@ func (s *Session) removeEventHandlerInstance(t string, ehi *eventHandlerInstance | ||||
| 	onceHandlers := s.onceHandlers[t] | ||||
| 	for i := range onceHandlers { | ||||
| 		if onceHandlers[i] == ehi { | ||||
| 			s.onceHandlers[t] = append(onceHandlers[:i], handlers[i+1:]...) | ||||
| 			s.onceHandlers[t] = append(onceHandlers[:i], onceHandlers[i+1:]...) | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| @@ -7,50 +7,62 @@ package discordgo | ||||
| // Event type values are used to match the events returned by Discord. | ||||
| // EventTypes surrounded by __ are synthetic and are internal to DiscordGo. | ||||
| const ( | ||||
| 	channelCreateEventType            = "CHANNEL_CREATE" | ||||
| 	channelDeleteEventType            = "CHANNEL_DELETE" | ||||
| 	channelPinsUpdateEventType        = "CHANNEL_PINS_UPDATE" | ||||
| 	channelUpdateEventType            = "CHANNEL_UPDATE" | ||||
| 	connectEventType                  = "__CONNECT__" | ||||
| 	disconnectEventType               = "__DISCONNECT__" | ||||
| 	eventEventType                    = "__EVENT__" | ||||
| 	guildBanAddEventType              = "GUILD_BAN_ADD" | ||||
| 	guildBanRemoveEventType           = "GUILD_BAN_REMOVE" | ||||
| 	guildCreateEventType              = "GUILD_CREATE" | ||||
| 	guildDeleteEventType              = "GUILD_DELETE" | ||||
| 	guildEmojisUpdateEventType        = "GUILD_EMOJIS_UPDATE" | ||||
| 	guildIntegrationsUpdateEventType  = "GUILD_INTEGRATIONS_UPDATE" | ||||
| 	guildMemberAddEventType           = "GUILD_MEMBER_ADD" | ||||
| 	guildMemberRemoveEventType        = "GUILD_MEMBER_REMOVE" | ||||
| 	guildMemberUpdateEventType        = "GUILD_MEMBER_UPDATE" | ||||
| 	guildMembersChunkEventType        = "GUILD_MEMBERS_CHUNK" | ||||
| 	guildRoleCreateEventType          = "GUILD_ROLE_CREATE" | ||||
| 	guildRoleDeleteEventType          = "GUILD_ROLE_DELETE" | ||||
| 	guildRoleUpdateEventType          = "GUILD_ROLE_UPDATE" | ||||
| 	guildUpdateEventType              = "GUILD_UPDATE" | ||||
| 	messageAckEventType               = "MESSAGE_ACK" | ||||
| 	messageCreateEventType            = "MESSAGE_CREATE" | ||||
| 	messageDeleteEventType            = "MESSAGE_DELETE" | ||||
| 	messageDeleteBulkEventType        = "MESSAGE_DELETE_BULK" | ||||
| 	messageReactionAddEventType       = "MESSAGE_REACTION_ADD" | ||||
| 	messageReactionRemoveEventType    = "MESSAGE_REACTION_REMOVE" | ||||
| 	messageReactionRemoveAllEventType = "MESSAGE_REACTION_REMOVE_ALL" | ||||
| 	messageUpdateEventType            = "MESSAGE_UPDATE" | ||||
| 	presenceUpdateEventType           = "PRESENCE_UPDATE" | ||||
| 	presencesReplaceEventType         = "PRESENCES_REPLACE" | ||||
| 	rateLimitEventType                = "__RATE_LIMIT__" | ||||
| 	readyEventType                    = "READY" | ||||
| 	relationshipAddEventType          = "RELATIONSHIP_ADD" | ||||
| 	relationshipRemoveEventType       = "RELATIONSHIP_REMOVE" | ||||
| 	resumedEventType                  = "RESUMED" | ||||
| 	typingStartEventType              = "TYPING_START" | ||||
| 	userGuildSettingsUpdateEventType  = "USER_GUILD_SETTINGS_UPDATE" | ||||
| 	userNoteUpdateEventType           = "USER_NOTE_UPDATE" | ||||
| 	userSettingsUpdateEventType       = "USER_SETTINGS_UPDATE" | ||||
| 	userUpdateEventType               = "USER_UPDATE" | ||||
| 	voiceServerUpdateEventType        = "VOICE_SERVER_UPDATE" | ||||
| 	voiceStateUpdateEventType         = "VOICE_STATE_UPDATE" | ||||
| 	webhooksUpdateEventType           = "WEBHOOKS_UPDATE" | ||||
| 	channelCreateEventType             = "CHANNEL_CREATE" | ||||
| 	channelDeleteEventType             = "CHANNEL_DELETE" | ||||
| 	channelPinsUpdateEventType         = "CHANNEL_PINS_UPDATE" | ||||
| 	channelUpdateEventType             = "CHANNEL_UPDATE" | ||||
| 	connectEventType                   = "__CONNECT__" | ||||
| 	disconnectEventType                = "__DISCONNECT__" | ||||
| 	eventEventType                     = "__EVENT__" | ||||
| 	guildBanAddEventType               = "GUILD_BAN_ADD" | ||||
| 	guildBanRemoveEventType            = "GUILD_BAN_REMOVE" | ||||
| 	guildCreateEventType               = "GUILD_CREATE" | ||||
| 	guildDeleteEventType               = "GUILD_DELETE" | ||||
| 	guildEmojisUpdateEventType         = "GUILD_EMOJIS_UPDATE" | ||||
| 	guildIntegrationsUpdateEventType   = "GUILD_INTEGRATIONS_UPDATE" | ||||
| 	guildMemberAddEventType            = "GUILD_MEMBER_ADD" | ||||
| 	guildMemberRemoveEventType         = "GUILD_MEMBER_REMOVE" | ||||
| 	guildMemberUpdateEventType         = "GUILD_MEMBER_UPDATE" | ||||
| 	guildMembersChunkEventType         = "GUILD_MEMBERS_CHUNK" | ||||
| 	guildRoleCreateEventType           = "GUILD_ROLE_CREATE" | ||||
| 	guildRoleDeleteEventType           = "GUILD_ROLE_DELETE" | ||||
| 	guildRoleUpdateEventType           = "GUILD_ROLE_UPDATE" | ||||
| 	guildUpdateEventType               = "GUILD_UPDATE" | ||||
| 	guildScheduledEventCreateEventType = "GUILD_SCHEDULED_EVENT_CREATE" | ||||
| 	guildScheduledEventUpdateEventType = "GUILD_SCHEDULED_EVENT_UPDATE" | ||||
| 	guildScheduledEventDeleteEventType = "GUILD_SCHEDULED_EVENT_DELETE" | ||||
| 	interactionCreateEventType         = "INTERACTION_CREATE" | ||||
| 	inviteCreateEventType              = "INVITE_CREATE" | ||||
| 	inviteDeleteEventType              = "INVITE_DELETE" | ||||
| 	messageAckEventType                = "MESSAGE_ACK" | ||||
| 	messageCreateEventType             = "MESSAGE_CREATE" | ||||
| 	messageDeleteEventType             = "MESSAGE_DELETE" | ||||
| 	messageDeleteBulkEventType         = "MESSAGE_DELETE_BULK" | ||||
| 	messageReactionAddEventType        = "MESSAGE_REACTION_ADD" | ||||
| 	messageReactionRemoveEventType     = "MESSAGE_REACTION_REMOVE" | ||||
| 	messageReactionRemoveAllEventType  = "MESSAGE_REACTION_REMOVE_ALL" | ||||
| 	messageUpdateEventType             = "MESSAGE_UPDATE" | ||||
| 	presenceUpdateEventType            = "PRESENCE_UPDATE" | ||||
| 	presencesReplaceEventType          = "PRESENCES_REPLACE" | ||||
| 	rateLimitEventType                 = "__RATE_LIMIT__" | ||||
| 	readyEventType                     = "READY" | ||||
| 	relationshipAddEventType           = "RELATIONSHIP_ADD" | ||||
| 	relationshipRemoveEventType        = "RELATIONSHIP_REMOVE" | ||||
| 	resumedEventType                   = "RESUMED" | ||||
| 	threadCreateEventType              = "THREAD_CREATE" | ||||
| 	threadDeleteEventType              = "THREAD_DELETE" | ||||
| 	threadListSyncEventType            = "THREAD_LIST_SYNC" | ||||
| 	threadMemberUpdateEventType        = "THREAD_MEMBER_UPDATE" | ||||
| 	threadMembersUpdateEventType       = "THREAD_MEMBERS_UPDATE" | ||||
| 	threadUpdateEventType              = "THREAD_UPDATE" | ||||
| 	typingStartEventType               = "TYPING_START" | ||||
| 	userGuildSettingsUpdateEventType   = "USER_GUILD_SETTINGS_UPDATE" | ||||
| 	userNoteUpdateEventType            = "USER_NOTE_UPDATE" | ||||
| 	userSettingsUpdateEventType        = "USER_SETTINGS_UPDATE" | ||||
| 	userUpdateEventType                = "USER_UPDATE" | ||||
| 	voiceServerUpdateEventType         = "VOICE_SERVER_UPDATE" | ||||
| 	voiceStateUpdateEventType          = "VOICE_STATE_UPDATE" | ||||
| 	webhooksUpdateEventType            = "WEBHOOKS_UPDATE" | ||||
| ) | ||||
| 
 | ||||
| // channelCreateEventHandler is an event handler for ChannelCreate events. | ||||
| @@ -298,6 +310,66 @@ func (eh guildIntegrationsUpdateEventHandler) Handle(s *Session, i interface{}) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // guildScheduledEventCreateEventHandler is an event handler for GuildScheduledEventCreate events. | ||||
| type guildScheduledEventCreateEventHandler func(*Session, *GuildScheduledEventCreate) | ||||
| 
 | ||||
| // Type returns the event type for GuildScheduledEventCreate events. | ||||
| func (eh guildScheduledEventCreateEventHandler) Type() string { | ||||
| 	return guildScheduledEventCreateEventType | ||||
| } | ||||
| 
 | ||||
| // New returns a new instance of GuildScheduledEventCreate. | ||||
| func (eh guildScheduledEventCreateEventHandler) New() interface{} { | ||||
| 	return &GuildScheduledEventCreate{} | ||||
| } | ||||
| 
 | ||||
| // Handle is the handler for GuildScheduledEventCreate events. | ||||
| func (eh guildScheduledEventCreateEventHandler) Handle(s *Session, i interface{}) { | ||||
| 	if t, ok := i.(*GuildScheduledEventCreate); ok { | ||||
| 		eh(s, t) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // guildScheduledEventUpdateEventHandler is an event handler for GuildScheduledEventUpdate events. | ||||
| type guildScheduledEventUpdateEventHandler func(*Session, *GuildScheduledEventUpdate) | ||||
| 
 | ||||
| // Type returns the event type for GuildScheduledEventUpdate events. | ||||
| func (eh guildScheduledEventUpdateEventHandler) Type() string { | ||||
| 	return guildScheduledEventUpdateEventType | ||||
| } | ||||
| 
 | ||||
| // New returns a new instance of GuildScheduledEventUpdate. | ||||
| func (eh guildScheduledEventUpdateEventHandler) New() interface{} { | ||||
| 	return &GuildScheduledEventUpdate{} | ||||
| } | ||||
| 
 | ||||
| // Handle is the handler for GuildScheduledEventUpdate events. | ||||
| func (eh guildScheduledEventUpdateEventHandler) Handle(s *Session, i interface{}) { | ||||
| 	if t, ok := i.(*GuildScheduledEventUpdate); ok { | ||||
| 		eh(s, t) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // guildScheduledEventDeleteEventHandler is an event handler for GuildScheduledEventDelete events. | ||||
| type guildScheduledEventDeleteEventHandler func(*Session, *GuildScheduledEventDelete) | ||||
| 
 | ||||
| // Type returns the event type for GuildScheduledEventDelete events. | ||||
| func (eh guildScheduledEventDeleteEventHandler) Type() string { | ||||
| 	return guildScheduledEventDeleteEventType | ||||
| } | ||||
| 
 | ||||
| // New returns a new instance of GuildScheduledEventDelete. | ||||
| func (eh guildScheduledEventDeleteEventHandler) New() interface{} { | ||||
| 	return &GuildScheduledEventDelete{} | ||||
| } | ||||
| 
 | ||||
| // Handle is the handler for GuildScheduledEventDelete events. | ||||
| func (eh guildScheduledEventDeleteEventHandler) Handle(s *Session, i interface{}) { | ||||
| 	if t, ok := i.(*GuildScheduledEventDelete); ok { | ||||
| 		eh(s, t) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // guildMemberAddEventHandler is an event handler for GuildMemberAdd events. | ||||
| type guildMemberAddEventHandler func(*Session, *GuildMemberAdd) | ||||
| 
 | ||||
| @@ -458,6 +530,66 @@ func (eh guildUpdateEventHandler) Handle(s *Session, i interface{}) { | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // interactionCreateEventHandler is an event handler for InteractionCreate events. | ||||
| type interactionCreateEventHandler func(*Session, *InteractionCreate) | ||||
| 
 | ||||
| // Type returns the event type for InteractionCreate events. | ||||
| func (eh interactionCreateEventHandler) Type() string { | ||||
| 	return interactionCreateEventType | ||||
| } | ||||
| 
 | ||||
| // New returns a new instance of InteractionCreate. | ||||
| func (eh interactionCreateEventHandler) New() interface{} { | ||||
| 	return &InteractionCreate{} | ||||
| } | ||||
| 
 | ||||
| // Handle is the handler for InteractionCreate events. | ||||
| func (eh interactionCreateEventHandler) Handle(s *Session, i interface{}) { | ||||
| 	if t, ok := i.(*InteractionCreate); ok { | ||||
| 		eh(s, t) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // inviteCreateEventHandler is an event handler for InviteCreate events. | ||||
| type inviteCreateEventHandler func(*Session, *InviteCreate) | ||||
| 
 | ||||
| // Type returns the event type for InviteCreate events. | ||||
| func (eh inviteCreateEventHandler) Type() string { | ||||
| 	return inviteCreateEventType | ||||
| } | ||||
| 
 | ||||
| // New returns a new instance of InviteCreate. | ||||
| func (eh inviteCreateEventHandler) New() interface{} { | ||||
| 	return &InviteCreate{} | ||||
| } | ||||
| 
 | ||||
| // Handle is the handler for InviteCreate events. | ||||
| func (eh inviteCreateEventHandler) Handle(s *Session, i interface{}) { | ||||
| 	if t, ok := i.(*InviteCreate); ok { | ||||
| 		eh(s, t) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // inviteDeleteEventHandler is an event handler for InviteDelete events. | ||||
| type inviteDeleteEventHandler func(*Session, *InviteDelete) | ||||
| 
 | ||||
| // Type returns the event type for InviteDelete events. | ||||
| func (eh inviteDeleteEventHandler) Type() string { | ||||
| 	return inviteDeleteEventType | ||||
| } | ||||
| 
 | ||||
| // New returns a new instance of InviteDelete. | ||||
| func (eh inviteDeleteEventHandler) New() interface{} { | ||||
| 	return &InviteDelete{} | ||||
| } | ||||
| 
 | ||||
| // Handle is the handler for InviteDelete events. | ||||
| func (eh inviteDeleteEventHandler) Handle(s *Session, i interface{}) { | ||||
| 	if t, ok := i.(*InviteDelete); ok { | ||||
| 		eh(s, t) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // messageAckEventHandler is an event handler for MessageAck events. | ||||
| type messageAckEventHandler func(*Session, *MessageAck) | ||||
| 
 | ||||
| @@ -753,6 +885,126 @@ func (eh resumedEventHandler) Handle(s *Session, i interface{}) { | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // threadCreateEventHandler is an event handler for ThreadCreate events. | ||||
| type threadCreateEventHandler func(*Session, *ThreadCreate) | ||||
| 
 | ||||
| // Type returns the event type for ThreadCreate events. | ||||
| func (eh threadCreateEventHandler) Type() string { | ||||
| 	return threadCreateEventType | ||||
| } | ||||
| 
 | ||||
| // New returns a new instance of ThreadCreate. | ||||
| func (eh threadCreateEventHandler) New() interface{} { | ||||
| 	return &ThreadCreate{} | ||||
| } | ||||
| 
 | ||||
| // Handle is the handler for ThreadCreate events. | ||||
| func (eh threadCreateEventHandler) Handle(s *Session, i interface{}) { | ||||
| 	if t, ok := i.(*ThreadCreate); ok { | ||||
| 		eh(s, t) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // threadDeleteEventHandler is an event handler for ThreadDelete events. | ||||
| type threadDeleteEventHandler func(*Session, *ThreadDelete) | ||||
| 
 | ||||
| // Type returns the event type for ThreadDelete events. | ||||
| func (eh threadDeleteEventHandler) Type() string { | ||||
| 	return threadDeleteEventType | ||||
| } | ||||
| 
 | ||||
| // New returns a new instance of ThreadDelete. | ||||
| func (eh threadDeleteEventHandler) New() interface{} { | ||||
| 	return &ThreadDelete{} | ||||
| } | ||||
| 
 | ||||
| // Handle is the handler for ThreadDelete events. | ||||
| func (eh threadDeleteEventHandler) Handle(s *Session, i interface{}) { | ||||
| 	if t, ok := i.(*ThreadDelete); ok { | ||||
| 		eh(s, t) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // threadListSyncEventHandler is an event handler for ThreadListSync events. | ||||
| type threadListSyncEventHandler func(*Session, *ThreadListSync) | ||||
| 
 | ||||
| // Type returns the event type for ThreadListSync events. | ||||
| func (eh threadListSyncEventHandler) Type() string { | ||||
| 	return threadListSyncEventType | ||||
| } | ||||
| 
 | ||||
| // New returns a new instance of ThreadListSync. | ||||
| func (eh threadListSyncEventHandler) New() interface{} { | ||||
| 	return &ThreadListSync{} | ||||
| } | ||||
| 
 | ||||
| // Handle is the handler for ThreadListSync events. | ||||
| func (eh threadListSyncEventHandler) Handle(s *Session, i interface{}) { | ||||
| 	if t, ok := i.(*ThreadListSync); ok { | ||||
| 		eh(s, t) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // threadMemberUpdateEventHandler is an event handler for ThreadMemberUpdate events. | ||||
| type threadMemberUpdateEventHandler func(*Session, *ThreadMemberUpdate) | ||||
| 
 | ||||
| // Type returns the event type for ThreadMemberUpdate events. | ||||
| func (eh threadMemberUpdateEventHandler) Type() string { | ||||
| 	return threadMemberUpdateEventType | ||||
| } | ||||
| 
 | ||||
| // New returns a new instance of ThreadMemberUpdate. | ||||
| func (eh threadMemberUpdateEventHandler) New() interface{} { | ||||
| 	return &ThreadMemberUpdate{} | ||||
| } | ||||
| 
 | ||||
| // Handle is the handler for ThreadMemberUpdate events. | ||||
| func (eh threadMemberUpdateEventHandler) Handle(s *Session, i interface{}) { | ||||
| 	if t, ok := i.(*ThreadMemberUpdate); ok { | ||||
| 		eh(s, t) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // threadMembersUpdateEventHandler is an event handler for ThreadMembersUpdate events. | ||||
| type threadMembersUpdateEventHandler func(*Session, *ThreadMembersUpdate) | ||||
| 
 | ||||
| // Type returns the event type for ThreadMembersUpdate events. | ||||
| func (eh threadMembersUpdateEventHandler) Type() string { | ||||
| 	return threadMembersUpdateEventType | ||||
| } | ||||
| 
 | ||||
| // New returns a new instance of ThreadMembersUpdate. | ||||
| func (eh threadMembersUpdateEventHandler) New() interface{} { | ||||
| 	return &ThreadMembersUpdate{} | ||||
| } | ||||
| 
 | ||||
| // Handle is the handler for ThreadMembersUpdate events. | ||||
| func (eh threadMembersUpdateEventHandler) Handle(s *Session, i interface{}) { | ||||
| 	if t, ok := i.(*ThreadMembersUpdate); ok { | ||||
| 		eh(s, t) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // threadUpdateEventHandler is an event handler for ThreadUpdate events. | ||||
| type threadUpdateEventHandler func(*Session, *ThreadUpdate) | ||||
| 
 | ||||
| // Type returns the event type for ThreadUpdate events. | ||||
| func (eh threadUpdateEventHandler) Type() string { | ||||
| 	return threadUpdateEventType | ||||
| } | ||||
| 
 | ||||
| // New returns a new instance of ThreadUpdate. | ||||
| func (eh threadUpdateEventHandler) New() interface{} { | ||||
| 	return &ThreadUpdate{} | ||||
| } | ||||
| 
 | ||||
| // Handle is the handler for ThreadUpdate events. | ||||
| func (eh threadUpdateEventHandler) Handle(s *Session, i interface{}) { | ||||
| 	if t, ok := i.(*ThreadUpdate); ok { | ||||
| 		eh(s, t) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // typingStartEventHandler is an event handler for TypingStart events. | ||||
| type typingStartEventHandler func(*Session, *TypingStart) | ||||
| 
 | ||||
| @@ -943,6 +1195,12 @@ func handlerForInterface(handler interface{}) EventHandler { | ||||
| 		return guildEmojisUpdateEventHandler(v) | ||||
| 	case func(*Session, *GuildIntegrationsUpdate): | ||||
| 		return guildIntegrationsUpdateEventHandler(v) | ||||
| 	case func(*Session, *GuildScheduledEventCreate): | ||||
| 		return guildScheduledEventCreateEventHandler(v) | ||||
| 	case func(*Session, *GuildScheduledEventUpdate): | ||||
| 		return guildScheduledEventUpdateEventHandler(v) | ||||
| 	case func(*Session, *GuildScheduledEventDelete): | ||||
| 		return guildScheduledEventDeleteEventHandler(v) | ||||
| 	case func(*Session, *GuildMemberAdd): | ||||
| 		return guildMemberAddEventHandler(v) | ||||
| 	case func(*Session, *GuildMemberRemove): | ||||
| @@ -959,6 +1217,12 @@ func handlerForInterface(handler interface{}) EventHandler { | ||||
| 		return guildRoleUpdateEventHandler(v) | ||||
| 	case func(*Session, *GuildUpdate): | ||||
| 		return guildUpdateEventHandler(v) | ||||
| 	case func(*Session, *InteractionCreate): | ||||
| 		return interactionCreateEventHandler(v) | ||||
| 	case func(*Session, *InviteCreate): | ||||
| 		return inviteCreateEventHandler(v) | ||||
| 	case func(*Session, *InviteDelete): | ||||
| 		return inviteDeleteEventHandler(v) | ||||
| 	case func(*Session, *MessageAck): | ||||
| 		return messageAckEventHandler(v) | ||||
| 	case func(*Session, *MessageCreate): | ||||
| @@ -989,6 +1253,18 @@ func handlerForInterface(handler interface{}) EventHandler { | ||||
| 		return relationshipRemoveEventHandler(v) | ||||
| 	case func(*Session, *Resumed): | ||||
| 		return resumedEventHandler(v) | ||||
| 	case func(*Session, *ThreadCreate): | ||||
| 		return threadCreateEventHandler(v) | ||||
| 	case func(*Session, *ThreadDelete): | ||||
| 		return threadDeleteEventHandler(v) | ||||
| 	case func(*Session, *ThreadListSync): | ||||
| 		return threadListSyncEventHandler(v) | ||||
| 	case func(*Session, *ThreadMemberUpdate): | ||||
| 		return threadMemberUpdateEventHandler(v) | ||||
| 	case func(*Session, *ThreadMembersUpdate): | ||||
| 		return threadMembersUpdateEventHandler(v) | ||||
| 	case func(*Session, *ThreadUpdate): | ||||
| 		return threadUpdateEventHandler(v) | ||||
| 	case func(*Session, *TypingStart): | ||||
| 		return typingStartEventHandler(v) | ||||
| 	case func(*Session, *UserGuildSettingsUpdate): | ||||
| @@ -1021,6 +1297,9 @@ func init() { | ||||
| 	registerInterfaceProvider(guildDeleteEventHandler(nil)) | ||||
| 	registerInterfaceProvider(guildEmojisUpdateEventHandler(nil)) | ||||
| 	registerInterfaceProvider(guildIntegrationsUpdateEventHandler(nil)) | ||||
| 	registerInterfaceProvider(guildScheduledEventCreateEventHandler(nil)) | ||||
| 	registerInterfaceProvider(guildScheduledEventUpdateEventHandler(nil)) | ||||
| 	registerInterfaceProvider(guildScheduledEventDeleteEventHandler(nil)) | ||||
| 	registerInterfaceProvider(guildMemberAddEventHandler(nil)) | ||||
| 	registerInterfaceProvider(guildMemberRemoveEventHandler(nil)) | ||||
| 	registerInterfaceProvider(guildMemberUpdateEventHandler(nil)) | ||||
| @@ -1029,6 +1308,9 @@ func init() { | ||||
| 	registerInterfaceProvider(guildRoleDeleteEventHandler(nil)) | ||||
| 	registerInterfaceProvider(guildRoleUpdateEventHandler(nil)) | ||||
| 	registerInterfaceProvider(guildUpdateEventHandler(nil)) | ||||
| 	registerInterfaceProvider(interactionCreateEventHandler(nil)) | ||||
| 	registerInterfaceProvider(inviteCreateEventHandler(nil)) | ||||
| 	registerInterfaceProvider(inviteDeleteEventHandler(nil)) | ||||
| 	registerInterfaceProvider(messageAckEventHandler(nil)) | ||||
| 	registerInterfaceProvider(messageCreateEventHandler(nil)) | ||||
| 	registerInterfaceProvider(messageDeleteEventHandler(nil)) | ||||
| @@ -1043,6 +1325,12 @@ func init() { | ||||
| 	registerInterfaceProvider(relationshipAddEventHandler(nil)) | ||||
| 	registerInterfaceProvider(relationshipRemoveEventHandler(nil)) | ||||
| 	registerInterfaceProvider(resumedEventHandler(nil)) | ||||
| 	registerInterfaceProvider(threadCreateEventHandler(nil)) | ||||
| 	registerInterfaceProvider(threadDeleteEventHandler(nil)) | ||||
| 	registerInterfaceProvider(threadListSyncEventHandler(nil)) | ||||
| 	registerInterfaceProvider(threadMemberUpdateEventHandler(nil)) | ||||
| 	registerInterfaceProvider(threadMembersUpdateEventHandler(nil)) | ||||
| 	registerInterfaceProvider(threadUpdateEventHandler(nil)) | ||||
| 	registerInterfaceProvider(typingStartEventHandler(nil)) | ||||
| 	registerInterfaceProvider(userGuildSettingsUpdateEventHandler(nil)) | ||||
| 	registerInterfaceProvider(userNoteUpdateEventHandler(nil)) | ||||
| @@ -73,6 +73,53 @@ type ChannelPinsUpdate struct { | ||||
| 	GuildID          string `json:"guild_id,omitempty"` | ||||
| } | ||||
| 
 | ||||
| // ThreadCreate is the data for a ThreadCreate event. | ||||
| type ThreadCreate struct { | ||||
| 	*Channel | ||||
| 	NewlyCreated bool `json:"newly_created"` | ||||
| } | ||||
| 
 | ||||
| // ThreadUpdate is the data for a ThreadUpdate event. | ||||
| type ThreadUpdate struct { | ||||
| 	*Channel | ||||
| 	BeforeUpdate *Channel `json:"-"` | ||||
| } | ||||
| 
 | ||||
| // ThreadDelete is the data for a ThreadDelete event. | ||||
| type ThreadDelete struct { | ||||
| 	*Channel | ||||
| } | ||||
| 
 | ||||
| // ThreadListSync is the data for a ThreadListSync event. | ||||
| type ThreadListSync struct { | ||||
| 	// The id of the guild | ||||
| 	GuildID string `json:"guild_id"` | ||||
| 	// The parent channel ids whose threads are being synced. | ||||
| 	// If omitted, then threads were synced for the entire guild. | ||||
| 	// This array may contain channel_ids that have no active threads as well, so you know to clear that data. | ||||
| 	ChannelIDs []string `json:"channel_ids"` | ||||
| 	// All active threads in the given channels that the current user can access | ||||
| 	Threads []*Channel `json:"threads"` | ||||
| 	// All thread member objects from the synced threads for the current user, | ||||
| 	// indicating which threads the current user has been added to | ||||
| 	Members []*ThreadMember `json:"members"` | ||||
| } | ||||
| 
 | ||||
| // ThreadMemberUpdate is the data for a ThreadMemberUpdate event. | ||||
| type ThreadMemberUpdate struct { | ||||
| 	*ThreadMember | ||||
| 	GuildID string `json:"guild_id"` | ||||
| } | ||||
| 
 | ||||
| // ThreadMembersUpdate is the data for a ThreadMembersUpdate event. | ||||
| type ThreadMembersUpdate struct { | ||||
| 	ID             string              `json:"id"` | ||||
| 	GuildID        string              `json:"guild_id"` | ||||
| 	MemberCount    int                 `json:"member_count"` | ||||
| 	AddedMembers   []AddedThreadMember `json:"added_members"` | ||||
| 	RemovedMembers []string            `json:"removed_member_ids"` | ||||
| } | ||||
| 
 | ||||
| // GuildCreate is the data for a GuildCreate event. | ||||
| type GuildCreate struct { | ||||
| 	*Guild | ||||
| @@ -86,6 +133,7 @@ type GuildUpdate struct { | ||||
| // GuildDelete is the data for a GuildDelete event. | ||||
| type GuildDelete struct { | ||||
| 	*Guild | ||||
| 	BeforeDelete *Guild `json:"-"` | ||||
| } | ||||
| 
 | ||||
| // GuildBanAdd is the data for a GuildBanAdd event. | ||||
| @@ -151,6 +199,21 @@ type GuildIntegrationsUpdate struct { | ||||
| 	GuildID string `json:"guild_id"` | ||||
| } | ||||
| 
 | ||||
| // GuildScheduledEventCreate is the data for a GuildScheduledEventCreate event. | ||||
| type GuildScheduledEventCreate struct { | ||||
| 	*GuildScheduledEvent | ||||
| } | ||||
| 
 | ||||
| // GuildScheduledEventUpdate is the data for a GuildScheduledEventUpdate event. | ||||
| type GuildScheduledEventUpdate struct { | ||||
| 	*GuildScheduledEvent | ||||
| } | ||||
| 
 | ||||
| // GuildScheduledEventDelete is the data for a GuildScheduledEventDelete event. | ||||
| type GuildScheduledEventDelete struct { | ||||
| 	*GuildScheduledEvent | ||||
| } | ||||
| 
 | ||||
| // MessageAck is the data for a MessageAck event. | ||||
| type MessageAck struct { | ||||
| 	MessageID string `json:"message_id"` | ||||
| @@ -162,6 +225,11 @@ type MessageCreate struct { | ||||
| 	*Message | ||||
| } | ||||
| 
 | ||||
| // UnmarshalJSON is a helper function to unmarshal MessageCreate object. | ||||
| func (m *MessageCreate) UnmarshalJSON(b []byte) error { | ||||
| 	return json.Unmarshal(b, &m.Message) | ||||
| } | ||||
| 
 | ||||
| // MessageUpdate is the data for a MessageUpdate event. | ||||
| type MessageUpdate struct { | ||||
| 	*Message | ||||
| @@ -169,15 +237,26 @@ type MessageUpdate struct { | ||||
| 	BeforeUpdate *Message `json:"-"` | ||||
| } | ||||
| 
 | ||||
| // UnmarshalJSON is a helper function to unmarshal MessageUpdate object. | ||||
| func (m *MessageUpdate) UnmarshalJSON(b []byte) error { | ||||
| 	return json.Unmarshal(b, &m.Message) | ||||
| } | ||||
| 
 | ||||
| // MessageDelete is the data for a MessageDelete event. | ||||
| type MessageDelete struct { | ||||
| 	*Message | ||||
| 	BeforeDelete *Message `json:"-"` | ||||
| } | ||||
| 
 | ||||
| // UnmarshalJSON is a helper function to unmarshal MessageDelete object. | ||||
| func (m *MessageDelete) UnmarshalJSON(b []byte) error { | ||||
| 	return json.Unmarshal(b, &m.Message) | ||||
| } | ||||
| 
 | ||||
| // MessageReactionAdd is the data for a MessageReactionAdd event. | ||||
| type MessageReactionAdd struct { | ||||
| 	*MessageReaction | ||||
| 	Member *Member `json:"member,omitempty"` | ||||
| } | ||||
| 
 | ||||
| // MessageReactionRemove is the data for a MessageReactionRemove event. | ||||
| @@ -267,3 +346,27 @@ type WebhooksUpdate struct { | ||||
| 	GuildID   string `json:"guild_id"` | ||||
| 	ChannelID string `json:"channel_id"` | ||||
| } | ||||
| 
 | ||||
| // InteractionCreate is the data for a InteractionCreate event | ||||
| type InteractionCreate struct { | ||||
| 	*Interaction | ||||
| } | ||||
| 
 | ||||
| // UnmarshalJSON is a helper function to unmarshal Interaction object. | ||||
| func (i *InteractionCreate) UnmarshalJSON(b []byte) error { | ||||
| 	return json.Unmarshal(b, &i.Interaction) | ||||
| } | ||||
| 
 | ||||
| // InviteCreate is the data for a InviteCreate event | ||||
| type InviteCreate struct { | ||||
| 	*Invite | ||||
| 	ChannelID string `json:"channel_id"` | ||||
| 	GuildID   string `json:"guild_id"` | ||||
| } | ||||
| 
 | ||||
| // InviteDelete is the data for a InviteDelete event | ||||
| type InviteDelete struct { | ||||
| 	ChannelID string `json:"channel_id"` | ||||
| 	GuildID   string `json:"guild_id"` | ||||
| 	Code      string `json:"code"` | ||||
| } | ||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user