From db267072825ebcdce883dc0d5b5c271ac88dd327 Mon Sep 17 00:00:00 2001 From: cuiko Date: Fri, 5 Jun 2026 16:35:00 +0800 Subject: [PATCH 1/3] feat(contact): Add `contact report` to report a peer, with optional ban `tg contact report ` reports a user/bot/group/channel to Telegram via account.reportPeer. --reason picks the category (spam default; violence, porn, child-abuse, copyright, fake, drugs, personal-details, geo-irrelevant, other), --message attaches a moderation comment, and --ban also blocks the peer after a successful report. Confirmation prompts unless --yes, mirroring block/ban. Routes through the daemon (contact.report) like the other contact mutations. --- README.md | 1 + internal/action/contact/report.go | 72 +++++++++++++++++++ internal/action/contact/report_test.go | 60 ++++++++++++++++ internal/cli/contact/contact.go | 4 +- internal/cli/contact/report/report.go | 99 ++++++++++++++++++++++++++ internal/daemon/handlers.go | 11 +++ internal/daemon/handlers_test.go | 1 + internal/telegram/contacts.go | 49 +++++++++++++ 8 files changed, 296 insertions(+), 1 deletion(-) create mode 100644 internal/action/contact/report.go create mode 100644 internal/action/contact/report_test.go create mode 100644 internal/cli/contact/report/report.go diff --git a/README.md b/README.md index bcfc3d8..9913bd1 100644 --- a/README.md +++ b/README.md @@ -159,6 +159,7 @@ client commands route through when present). | `tg contact delete ` | Delete a contact. | | `tg contact block ` | Block a user, bot, or channel. | | `tg contact unblock ` | Unblock a user, bot, or channel. | +| `tg contact report ` | Report a peer to Telegram. `--reason` (spam (default), violence, porn, child-abuse, copyright, fake, drugs, personal-details, geo-irrelevant, other), `--message `, `--ban` (also block). Prompts unless `--yes`. | | `tg me` | Print the current Telegram identity. | | `tg profile set-name ` | Set first name; `--last` sets or clears last name. | | `tg profile set-username ` | Set or clear the public username. | diff --git a/internal/action/contact/report.go b/internal/action/contact/report.go new file mode 100644 index 0000000..3de7022 --- /dev/null +++ b/internal/action/contact/report.go @@ -0,0 +1,72 @@ +package contact + +import ( + "context" + "fmt" + + "github.com/vika2603/telegram-cli/internal/command" + "github.com/vika2603/telegram-cli/internal/ref" + "github.com/vika2603/telegram-cli/internal/ui" +) + +// ReportReasons are the keywords accepted by `tg contact report --reason`, +// mapped (in the telegram layer) to a tg.ReportReasonClass. +var ReportReasons = map[string]bool{ + "spam": true, + "violence": true, + "porn": true, + "child-abuse": true, + "copyright": true, + "fake": true, + "drugs": true, + "personal-details": true, + "geo-irrelevant": true, + "other": true, +} + +// ReportRequest is the raw request for `tg contact report`. +type ReportRequest struct { + RawRef string + Reason string + Message string + Ban bool // also block the peer after reporting + Yes bool + Prompter ui.Prompter +} + +// ReportQuery is the validated payload passed to the Telegram layer. +type ReportQuery struct { + Ref ref.Ref + Reason string + Message string + Ban bool +} + +// ReportFunc reports one peer after request validation. +type ReportFunc func(context.Context, ReportQuery) error + +// Report validates a report request, confirms it, and delegates the call. +func Report(ctx context.Context, req ReportRequest, do ReportFunc) error { + parsed, err := ref.ParseRef(req.RawRef) + if err != nil { + return fmt.Errorf("%w: %s", command.ErrUsage, err.Error()) + } + reason := req.Reason + if reason == "" { + reason = "spam" + } + if !ReportReasons[reason] { + return fmt.Errorf("%w: unknown report reason %q (valid: spam violence porn child-abuse copyright fake drugs personal-details geo-irrelevant other)", command.ErrUsage, reason) + } + if do == nil { + return fmt.Errorf("%w: contact report called without report function", command.ErrPrecondition) + } + prompt := fmt.Sprintf("report %s for %s?", req.RawRef, reason) + if req.Ban { + prompt = fmt.Sprintf("report %s for %s and block them?", req.RawRef, reason) + } + if err := ui.ConfirmDestructive(req.Prompter, prompt, req.Yes); err != nil { + return err + } + return do(ctx, ReportQuery{Ref: parsed, Reason: reason, Message: req.Message, Ban: req.Ban}) +} diff --git a/internal/action/contact/report_test.go b/internal/action/contact/report_test.go new file mode 100644 index 0000000..f4c1c29 --- /dev/null +++ b/internal/action/contact/report_test.go @@ -0,0 +1,60 @@ +package contact_test + +import ( + "context" + "testing" + + "github.com/stretchr/testify/require" + + "github.com/vika2603/telegram-cli/internal/action/contact" + "github.com/vika2603/telegram-cli/internal/command" +) + +func TestReportRequiresFunction(t *testing.T) { + err := contact.Report(context.Background(), contact.ReportRequest{RawRef: "@bob", Yes: true}, nil) + require.ErrorIs(t, err, command.ErrPrecondition) +} + +func TestReportDefaultsToSpam(t *testing.T) { + err := contact.Report(context.Background(), contact.ReportRequest{RawRef: "@bob", Yes: true}, + func(_ context.Context, q contact.ReportQuery) error { + require.Equal(t, "bob", q.Ref.Value) + require.Equal(t, "spam", q.Reason) + require.False(t, q.Ban) + return nil + }) + require.NoError(t, err) +} + +func TestReportPassesReasonMessageAndBan(t *testing.T) { + err := contact.Report(context.Background(), contact.ReportRequest{ + RawRef: "@bob", Reason: "fake", Message: "scam", Ban: true, Yes: true, + }, func(_ context.Context, q contact.ReportQuery) error { + require.Equal(t, "fake", q.Reason) + require.Equal(t, "scam", q.Message) + require.True(t, q.Ban) + return nil + }) + require.NoError(t, err) +} + +func TestReportRejectsUnknownReason(t *testing.T) { + err := contact.Report(context.Background(), contact.ReportRequest{RawRef: "@bob", Reason: "bogus", Yes: true}, + func(context.Context, contact.ReportQuery) error { + t.Fatal("must not dispatch with an unknown reason") + return nil + }) + require.ErrorIs(t, err, command.ErrUsage) +} + +func TestReportDeclined(t *testing.T) { + called := false + err := contact.Report(context.Background(), contact.ReportRequest{ + RawRef: "@bob", Prompter: stubPrompter{ok: false}, + }, func(context.Context, contact.ReportQuery) error { + called = true + return nil + }) + require.ErrorIs(t, err, command.ErrNotConfirmed) + require.False(t, called) +} diff --git a/internal/cli/contact/contact.go b/internal/cli/contact/contact.go index 6aa55c7..618af1c 100644 --- a/internal/cli/contact/contact.go +++ b/internal/cli/contact/contact.go @@ -8,6 +8,7 @@ import ( "github.com/vika2603/telegram-cli/internal/cli/contact/block" del "github.com/vika2603/telegram-cli/internal/cli/contact/delete" "github.com/vika2603/telegram-cli/internal/cli/contact/list" + "github.com/vika2603/telegram-cli/internal/cli/contact/report" "github.com/vika2603/telegram-cli/internal/cli/contact/unblock" "github.com/vika2603/telegram-cli/internal/runtime" ) @@ -16,7 +17,7 @@ import ( func New(f *runtime.Invocation) *cobra.Command { cmd := &cobra.Command{ Use: "contact", - Short: "Address book: list, add, delete, block, unblock", + Short: "Address book: list, add, delete, block, unblock, report", GroupID: "core", } cmd.AddCommand(list.New(f, nil)) @@ -24,5 +25,6 @@ func New(f *runtime.Invocation) *cobra.Command { cmd.AddCommand(del.New(f, nil)) cmd.AddCommand(block.New(f, nil)) cmd.AddCommand(unblock.New(f, nil)) + cmd.AddCommand(report.New(f, nil)) return cmd } diff --git a/internal/cli/contact/report/report.go b/internal/cli/contact/report/report.go new file mode 100644 index 0000000..cc2d0c9 --- /dev/null +++ b/internal/cli/contact/report/report.go @@ -0,0 +1,99 @@ +// Package report implements "tg contact report ". +package report + +import ( + "context" + "fmt" + + "github.com/gotd/td/telegram/peers" + "github.com/gotd/td/tg" + "github.com/spf13/cobra" + + actioncontact "github.com/vika2603/telegram-cli/internal/action/contact" + "github.com/vika2603/telegram-cli/internal/command" + "github.com/vika2603/telegram-cli/internal/runtime" + "github.com/vika2603/telegram-cli/internal/telegram" + "github.com/vika2603/telegram-cli/internal/telegram/peer" + "github.com/vika2603/telegram-cli/internal/ui" +) + +// Options holds the resolved flags and injected dependencies for Run. +type Options struct { + RawRef string + Reason string + Message string + Ban bool + Yes bool + + IOStreams *ui.IOStreams + Prompter ui.Prompter + + // Report is the closure that performs the actual Telegram call. Production + // code sets it via newReport; tests stub it directly. + Report actioncontact.ReportFunc +} + +// New builds the cobra command for "tg contact report". +func New(f *runtime.Invocation, runF func(*Options) error) *cobra.Command { + opts := &Options{} + cmd := &cobra.Command{ + Use: "report ", + Short: "Report a user, bot, group, or channel to Telegram", + Args: cobra.ExactArgs(1), + RunE: func(cmd *cobra.Command, args []string) error { + opts.RawRef = args[0] + opts.IOStreams = f.IOStreams + opts.Prompter = f.Prompter + if runF != nil { + return runF(opts) + } + opts.Report = newReport(f) + return Run(cmd.Context(), opts) + }, + } + cmd.Flags().StringVar(&opts.Reason, "reason", "spam", "Report reason: spam, violence, porn, child-abuse, copyright, fake, drugs, personal-details, geo-irrelevant, other") + cmd.Flags().StringVar(&opts.Message, "message", "", "Optional comment for report moderation") + cmd.Flags().BoolVar(&opts.Ban, "ban", false, "Also block the peer after reporting") + cmd.Flags().BoolVarP(&opts.Yes, "yes", "y", false, "Skip confirmation prompt") + command.SetMeta(cmd, command.Meta{NeedsAccount: true, NeedsClient: true}) + return cmd +} + +// Run collects the raw request, delegates validation/mutation, and renders status. +func Run(ctx context.Context, opts *Options) error { + if err := actioncontact.Report(ctx, actioncontact.ReportRequest{ + RawRef: opts.RawRef, + Reason: opts.Reason, + Message: opts.Message, + Ban: opts.Ban, + Yes: opts.Yes, + Prompter: opts.Prompter, + }, opts.Report); err != nil { + return err + } + verb := "reported" + if opts.Ban { + verb = "reported+blocked" + } + _, _ = fmt.Fprintf(opts.IOStreams.Out, "%s\t%s\n", verb, opts.RawRef) + return nil +} + +// newReport returns the production Report closure that calls the Telegram API. +func newReport(f *runtime.Invocation) actioncontact.ReportFunc { + return func(ctx context.Context, q actioncontact.ReportQuery) error { + acct, err := f.Account("") + if err != nil { + return err + } + if cl, _ := runtime.MaybeDialDaemon(ctx, f, acct); cl != nil { + defer func() { _ = cl.Close() }() + _, err := cl.Call(ctx, "contact.report", q) + return err + } + return f.WithPeers(ctx, acct, runtime.ClientOptsFrom(f, acct), + func(ctx context.Context, api *tg.Client, _ *peers.Manager, res *peer.Resolver) error { + return telegram.ReportPeer(ctx, api, res, q) + }) + } +} diff --git a/internal/daemon/handlers.go b/internal/daemon/handlers.go index 27d9f72..8a62d38 100644 --- a/internal/daemon/handlers.go +++ b/internal/daemon/handlers.go @@ -274,6 +274,17 @@ func registerHandlers( return json.RawMessage("true"), nil }) + srv.Register("contact.report", func(ctx context.Context, params json.RawMessage) (json.RawMessage, error) { + var q actioncontact.ReportQuery + if err := json.Unmarshal(params, &q); err != nil { //nolint:musttag + return nil, fmt.Errorf("invalid contact.report params: %w", err) + } + if err := telegram.ReportPeer(ctx, api, res, q); err != nil { + return nil, err + } + return json.RawMessage("true"), nil + }) + srv.Register("profile.set_name", func(ctx context.Context, params json.RawMessage) (json.RawMessage, error) { var q actionprofile.SetNameRequest if err := json.Unmarshal(params, &q); err != nil { //nolint:musttag diff --git a/internal/daemon/handlers_test.go b/internal/daemon/handlers_test.go index f31b54e..8dcdf57 100644 --- a/internal/daemon/handlers_test.go +++ b/internal/daemon/handlers_test.go @@ -42,6 +42,7 @@ func TestRegisterHandlers_BindsExpectedMethods(t *testing.T) { "contact.delete", "contact.block", "contact.unblock", + "contact.report", "profile.set_name", "profile.set_bio", "profile.set_username", diff --git a/internal/telegram/contacts.go b/internal/telegram/contacts.go index 5bab94d..339f3a7 100644 --- a/internal/telegram/contacts.go +++ b/internal/telegram/contacts.go @@ -115,6 +115,55 @@ func UnblockContact(ctx context.Context, api *tg.Client, resolver *peer.Resolver return err } +// ReportPeer reports one resolved peer to Telegram moderation via +// account.reportPeer with the given reason and optional comment. When q.Ban is +// set it also blocks the peer (contacts.block) after a successful report. +func ReportPeer(ctx context.Context, api *tg.Client, resolver *peer.Resolver, q actioncontact.ReportQuery) error { + resolved, err := resolver.Resolve(ctx, q.Ref) + if err != nil { + return err + } + if _, err := api.AccountReportPeer(ctx, &tg.AccountReportPeerRequest{ + Peer: resolved.InputPeer, + Reason: reportReason(q.Reason), + Message: q.Message, + }); err != nil { + return err + } + if q.Ban { + if _, err := api.ContactsBlock(ctx, &tg.ContactsBlockRequest{ID: resolved.InputPeer}); err != nil { + return err + } + } + return nil +} + +// reportReason maps a validated reason keyword to a tg.ReportReasonClass. +func reportReason(reason string) tg.ReportReasonClass { + switch reason { + case "violence": + return &tg.InputReportReasonViolence{} + case "porn": + return &tg.InputReportReasonPornography{} + case "child-abuse": + return &tg.InputReportReasonChildAbuse{} + case "copyright": + return &tg.InputReportReasonCopyright{} + case "fake": + return &tg.InputReportReasonFake{} + case "drugs": + return &tg.InputReportReasonIllegalDrugs{} + case "personal-details": + return &tg.InputReportReasonPersonalDetails{} + case "geo-irrelevant": + return &tg.InputReportReasonGeoIrrelevant{} + case "other": + return &tg.InputReportReasonOther{} + default: + return &tg.InputReportReasonSpam{} + } +} + func listBlockedContacts(ctx context.Context, api *tg.Client) ([]output.ContactRow, error) { var out []output.ContactRow err := query.GetBlocked(api).ForEach(ctx, func(_ context.Context, e blocked.Elem) error { From b2ee5b59035c5f90dfbbe7477914c990a04d63bc Mon Sep 17 00:00:00 2001 From: cuiko Date: Fri, 5 Jun 2026 16:36:47 +0800 Subject: [PATCH 2/3] docs(contact): Cross-reference report reason keyword lists The accepted --reason keywords live in both ReportReasons (action, validation) and reportReason (telegram, mapping); the layers can't share a source. Add sync notes so adding a reason to one without the other doesn't silently report as spam. --- internal/action/contact/report.go | 6 ++++-- internal/telegram/contacts.go | 5 ++++- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/internal/action/contact/report.go b/internal/action/contact/report.go index 3de7022..7ffa17f 100644 --- a/internal/action/contact/report.go +++ b/internal/action/contact/report.go @@ -9,8 +9,10 @@ import ( "github.com/vika2603/telegram-cli/internal/ui" ) -// ReportReasons are the keywords accepted by `tg contact report --reason`, -// mapped (in the telegram layer) to a tg.ReportReasonClass. +// ReportReasons are the keywords accepted by `tg contact report --reason`. +// Keep this set in sync with reportReason() in internal/telegram/contacts.go, +// which maps each keyword to a tg.ReportReasonClass — a keyword present here but +// missing there would silently report as spam. var ReportReasons = map[string]bool{ "spam": true, "violence": true, diff --git a/internal/telegram/contacts.go b/internal/telegram/contacts.go index 339f3a7..e43b153 100644 --- a/internal/telegram/contacts.go +++ b/internal/telegram/contacts.go @@ -138,7 +138,10 @@ func ReportPeer(ctx context.Context, api *tg.Client, resolver *peer.Resolver, q return nil } -// reportReason maps a validated reason keyword to a tg.ReportReasonClass. +// reportReason maps a validated reason keyword to a tg.ReportReasonClass. Keep +// the cases in sync with ReportReasons in internal/action/contact/report.go; +// the action layer validates the keyword before it reaches here, so the default +// is only a safety net. func reportReason(reason string) tg.ReportReasonClass { switch reason { case "violence": From 162e322b2e3a6115686d0437e255fb4d85153d42 Mon Sep 17 00:00:00 2001 From: cuiko Date: Fri, 5 Jun 2026 17:20:34 +0800 Subject: [PATCH 3/3] ref(contact): Rename report --ban to --block for naming consistency The flag invokes contacts.block, not channels.editBanned, so call it --block. This keeps the terminology unambiguous: "ban" is group/channel scope (chat ban/unban), "block" is account scope (contact block/unblock, report --block). Also reword the chat ban help so "block" isn't used for a group ban. --- README.md | 4 ++-- internal/action/contact/report.go | 8 ++++---- internal/action/contact/report_test.go | 8 ++++---- internal/cli/contact/report/report.go | 8 ++++---- internal/telegram/contacts.go | 6 +++--- 5 files changed, 17 insertions(+), 17 deletions(-) diff --git a/README.md b/README.md index 9913bd1..1906f8e 100644 --- a/README.md +++ b/README.md @@ -123,7 +123,7 @@ client commands route through when present). | `tg chat invite create ` | Create an invite link. `--title`, `--expire `, `--usage-limit `, `--request-needed`. | | `tg chat invite list ` | List invite links. `--revoked`, `--admin `, `--limit`. | | `tg chat invite revoke ` / `delete ` | Revoke a link, or delete a revoked one. | -| `tg chat ban ` / `tg chat unban ` | Ban (remove + block) or unban a member. Ban prompts unless `--yes`. | +| `tg chat ban ` / `tg chat unban ` | Ban (remove + restrict) or unban a member of a group/channel. Ban prompts unless `--yes`. | | `tg chat admin promote ` / `tg chat admin demote ` | Grant or revoke admin rights. `--rights ` grants a specific set (`info,post,edit,delete,ban,invite,pin,add_admins,anonymous,call,topics,post_stories,edit_stories,delete_stories`); omit `--rights` for a broad default set. `--title ` sets a custom admin title (≤16 chars); omit `--title` to keep the current title, pass `--title ""` to clear it. | | `tg chat member set-perms ` | Set a member's permissions with `--deny`/`--allow` keywords (`send,media,stickers,bots,polls,links,invite,pin,info,topics`) and optional `--until ` (default permanent). | | `tg chat member unset-perms ` | Clear all permission restrictions on a member. | @@ -159,7 +159,7 @@ client commands route through when present). | `tg contact delete ` | Delete a contact. | | `tg contact block ` | Block a user, bot, or channel. | | `tg contact unblock ` | Unblock a user, bot, or channel. | -| `tg contact report ` | Report a peer to Telegram. `--reason` (spam (default), violence, porn, child-abuse, copyright, fake, drugs, personal-details, geo-irrelevant, other), `--message `, `--ban` (also block). Prompts unless `--yes`. | +| `tg contact report ` | Report a peer to Telegram. `--reason` (spam (default), violence, porn, child-abuse, copyright, fake, drugs, personal-details, geo-irrelevant, other), `--message `, `--block` (also block the peer). Prompts unless `--yes`. | | `tg me` | Print the current Telegram identity. | | `tg profile set-name ` | Set first name; `--last` sets or clears last name. | | `tg profile set-username ` | Set or clear the public username. | diff --git a/internal/action/contact/report.go b/internal/action/contact/report.go index 7ffa17f..ce577f0 100644 --- a/internal/action/contact/report.go +++ b/internal/action/contact/report.go @@ -31,7 +31,7 @@ type ReportRequest struct { RawRef string Reason string Message string - Ban bool // also block the peer after reporting + Block bool // also block the peer after reporting Yes bool Prompter ui.Prompter } @@ -41,7 +41,7 @@ type ReportQuery struct { Ref ref.Ref Reason string Message string - Ban bool + Block bool } // ReportFunc reports one peer after request validation. @@ -64,11 +64,11 @@ func Report(ctx context.Context, req ReportRequest, do ReportFunc) error { return fmt.Errorf("%w: contact report called without report function", command.ErrPrecondition) } prompt := fmt.Sprintf("report %s for %s?", req.RawRef, reason) - if req.Ban { + if req.Block { prompt = fmt.Sprintf("report %s for %s and block them?", req.RawRef, reason) } if err := ui.ConfirmDestructive(req.Prompter, prompt, req.Yes); err != nil { return err } - return do(ctx, ReportQuery{Ref: parsed, Reason: reason, Message: req.Message, Ban: req.Ban}) + return do(ctx, ReportQuery{Ref: parsed, Reason: reason, Message: req.Message, Block: req.Block}) } diff --git a/internal/action/contact/report_test.go b/internal/action/contact/report_test.go index f4c1c29..4595eb6 100644 --- a/internal/action/contact/report_test.go +++ b/internal/action/contact/report_test.go @@ -20,19 +20,19 @@ func TestReportDefaultsToSpam(t *testing.T) { func(_ context.Context, q contact.ReportQuery) error { require.Equal(t, "bob", q.Ref.Value) require.Equal(t, "spam", q.Reason) - require.False(t, q.Ban) + require.False(t, q.Block) return nil }) require.NoError(t, err) } -func TestReportPassesReasonMessageAndBan(t *testing.T) { +func TestReportPassesReasonMessageAndBlock(t *testing.T) { err := contact.Report(context.Background(), contact.ReportRequest{ - RawRef: "@bob", Reason: "fake", Message: "scam", Ban: true, Yes: true, + RawRef: "@bob", Reason: "fake", Message: "scam", Block: true, Yes: true, }, func(_ context.Context, q contact.ReportQuery) error { require.Equal(t, "fake", q.Reason) require.Equal(t, "scam", q.Message) - require.True(t, q.Ban) + require.True(t, q.Block) return nil }) require.NoError(t, err) diff --git a/internal/cli/contact/report/report.go b/internal/cli/contact/report/report.go index cc2d0c9..afb3840 100644 --- a/internal/cli/contact/report/report.go +++ b/internal/cli/contact/report/report.go @@ -22,7 +22,7 @@ type Options struct { RawRef string Reason string Message string - Ban bool + Block bool Yes bool IOStreams *ui.IOStreams @@ -53,7 +53,7 @@ func New(f *runtime.Invocation, runF func(*Options) error) *cobra.Command { } cmd.Flags().StringVar(&opts.Reason, "reason", "spam", "Report reason: spam, violence, porn, child-abuse, copyright, fake, drugs, personal-details, geo-irrelevant, other") cmd.Flags().StringVar(&opts.Message, "message", "", "Optional comment for report moderation") - cmd.Flags().BoolVar(&opts.Ban, "ban", false, "Also block the peer after reporting") + cmd.Flags().BoolVar(&opts.Block, "block", false, "Also block the peer after reporting") cmd.Flags().BoolVarP(&opts.Yes, "yes", "y", false, "Skip confirmation prompt") command.SetMeta(cmd, command.Meta{NeedsAccount: true, NeedsClient: true}) return cmd @@ -65,14 +65,14 @@ func Run(ctx context.Context, opts *Options) error { RawRef: opts.RawRef, Reason: opts.Reason, Message: opts.Message, - Ban: opts.Ban, + Block: opts.Block, Yes: opts.Yes, Prompter: opts.Prompter, }, opts.Report); err != nil { return err } verb := "reported" - if opts.Ban { + if opts.Block { verb = "reported+blocked" } _, _ = fmt.Fprintf(opts.IOStreams.Out, "%s\t%s\n", verb, opts.RawRef) diff --git a/internal/telegram/contacts.go b/internal/telegram/contacts.go index e43b153..4920bfe 100644 --- a/internal/telegram/contacts.go +++ b/internal/telegram/contacts.go @@ -116,8 +116,8 @@ func UnblockContact(ctx context.Context, api *tg.Client, resolver *peer.Resolver } // ReportPeer reports one resolved peer to Telegram moderation via -// account.reportPeer with the given reason and optional comment. When q.Ban is -// set it also blocks the peer (contacts.block) after a successful report. +// account.reportPeer with the given reason and optional comment. When q.Block +// is set it also blocks the peer (contacts.block) after a successful report. func ReportPeer(ctx context.Context, api *tg.Client, resolver *peer.Resolver, q actioncontact.ReportQuery) error { resolved, err := resolver.Resolve(ctx, q.Ref) if err != nil { @@ -130,7 +130,7 @@ func ReportPeer(ctx context.Context, api *tg.Client, resolver *peer.Resolver, q }); err != nil { return err } - if q.Ban { + if q.Block { if _, err := api.ContactsBlock(ctx, &tg.ContactsBlockRequest{ID: resolved.InputPeer}); err != nil { return err }