| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169 |
- // Copyright (c) 2021 Tulir Asokan
- //
- // This Source Code Form is subject to the terms of the Mozilla Public
- // License, v. 2.0. If a copy of the MPL was not distributed with this
- // file, You can obtain one at http://mozilla.org/MPL/2.0/.
- package whatsmeow
- import (
- "context"
- "strconv"
- "time"
- waBinary "git.bobomao.top/joey/testwh/binary"
- "git.bobomao.top/joey/testwh/types"
- "git.bobomao.top/joey/testwh/types/events"
- )
- // TryFetchPrivacySettings will fetch the user's privacy settings, either from the in-memory cache or from the server.
- func (cli *Client) TryFetchPrivacySettings(ctx context.Context, ignoreCache bool) (*types.PrivacySettings, error) {
- if cli == nil {
- return nil, ErrClientIsNil
- } else if val := cli.privacySettingsCache.Load(); val != nil && !ignoreCache {
- return val.(*types.PrivacySettings), nil
- }
- resp, err := cli.sendIQ(ctx, infoQuery{
- Namespace: "privacy",
- Type: iqGet,
- To: types.ServerJID,
- Content: []waBinary.Node{{Tag: "privacy"}},
- })
- if err != nil {
- return nil, err
- }
- privacyNode, ok := resp.GetOptionalChildByTag("privacy")
- if !ok {
- return nil, &ElementMissingError{Tag: "privacy", In: "response to privacy settings query"}
- }
- var settings types.PrivacySettings
- cli.parsePrivacySettings(&privacyNode, &settings)
- cli.privacySettingsCache.Store(&settings)
- return &settings, nil
- }
- // GetPrivacySettings will get the user's privacy settings. If an error occurs while fetching them, the error will be
- // logged, but the method will just return an empty struct.
- func (cli *Client) GetPrivacySettings(ctx context.Context) (settings types.PrivacySettings) {
- if cli == nil || cli.MessengerConfig != nil {
- return
- }
- settingsPtr, err := cli.TryFetchPrivacySettings(ctx, false)
- if err != nil {
- cli.Log.Errorf("Failed to fetch privacy settings: %v", err)
- } else {
- settings = *settingsPtr
- }
- return
- }
- // SetPrivacySetting will set the given privacy setting to the given value.
- // The privacy settings will be fetched from the server after the change and the new settings will be returned.
- // If an error occurs while fetching the new settings, will return an empty struct.
- func (cli *Client) SetPrivacySetting(ctx context.Context, name types.PrivacySettingType, value types.PrivacySetting) (settings types.PrivacySettings, err error) {
- settingsPtr, err := cli.TryFetchPrivacySettings(ctx, false)
- if err != nil {
- return settings, err
- }
- _, err = cli.sendIQ(ctx, infoQuery{
- Namespace: "privacy",
- Type: iqSet,
- To: types.ServerJID,
- Content: []waBinary.Node{{
- Tag: "privacy",
- Content: []waBinary.Node{{
- Tag: "category",
- Attrs: waBinary.Attrs{
- "name": string(name),
- "value": string(value),
- },
- }},
- }},
- })
- if err != nil {
- return settings, err
- }
- settings = *settingsPtr
- switch name {
- case types.PrivacySettingTypeGroupAdd:
- settings.GroupAdd = value
- case types.PrivacySettingTypeLastSeen:
- settings.LastSeen = value
- case types.PrivacySettingTypeStatus:
- settings.Status = value
- case types.PrivacySettingTypeProfile:
- settings.Profile = value
- case types.PrivacySettingTypeReadReceipts:
- settings.ReadReceipts = value
- case types.PrivacySettingTypeOnline:
- settings.Online = value
- case types.PrivacySettingTypeCallAdd:
- settings.CallAdd = value
- }
- cli.privacySettingsCache.Store(&settings)
- return
- }
- // SetDefaultDisappearingTimer will set the default disappearing message timer.
- func (cli *Client) SetDefaultDisappearingTimer(ctx context.Context, timer time.Duration) (err error) {
- _, err = cli.sendIQ(ctx, infoQuery{
- Namespace: "disappearing_mode",
- Type: iqSet,
- To: types.ServerJID,
- Content: []waBinary.Node{{
- Tag: "disappearing_mode",
- Attrs: waBinary.Attrs{
- "duration": strconv.Itoa(int(timer.Seconds())),
- },
- }},
- })
- return
- }
- func (cli *Client) parsePrivacySettings(privacyNode *waBinary.Node, settings *types.PrivacySettings) *events.PrivacySettings {
- var evt events.PrivacySettings
- for _, child := range privacyNode.GetChildren() {
- if child.Tag != "category" {
- continue
- }
- ag := child.AttrGetter()
- name := types.PrivacySettingType(ag.String("name"))
- value := types.PrivacySetting(ag.String("value"))
- switch name {
- case types.PrivacySettingTypeGroupAdd:
- settings.GroupAdd = value
- evt.GroupAddChanged = true
- case types.PrivacySettingTypeLastSeen:
- settings.LastSeen = value
- evt.LastSeenChanged = true
- case types.PrivacySettingTypeStatus:
- settings.Status = value
- evt.StatusChanged = true
- case types.PrivacySettingTypeProfile:
- settings.Profile = value
- evt.ProfileChanged = true
- case types.PrivacySettingTypeReadReceipts:
- settings.ReadReceipts = value
- evt.ReadReceiptsChanged = true
- case types.PrivacySettingTypeOnline:
- settings.Online = value
- evt.OnlineChanged = true
- case types.PrivacySettingTypeCallAdd:
- settings.CallAdd = value
- evt.CallAddChanged = true
- }
- }
- return &evt
- }
- func (cli *Client) handlePrivacySettingsNotification(ctx context.Context, privacyNode *waBinary.Node) {
- cli.Log.Debugf("Parsing privacy settings change notification")
- settings, err := cli.TryFetchPrivacySettings(ctx, false)
- if err != nil {
- cli.Log.Errorf("Failed to fetch privacy settings when handling change: %v", err)
- return
- }
- evt := cli.parsePrivacySettings(privacyNode, settings)
- cli.privacySettingsCache.Store(settings)
- cli.dispatchEvent(evt)
- }
|