From ebf9c5b4430eef892817206c2f9465b43a3d357c Mon Sep 17 00:00:00 2001 From: nikita42 <13642481+rekurt@users.noreply.github.com> Date: Wed, 8 Apr 2026 04:15:24 +0300 Subject: [PATCH] docs: improve repository SEO and discoverability - Add CI, GoDoc, Go Report Card, License, Go Version badges to both READMEs - Add Features section with keyword-rich descriptions (RU + EN) - Create doc.go for all service subpackages (messages, chats, polls, updates, self, users, files, ymerrors, middleware, client) to improve pkg.go.dev indexing - Add CONTRIBUTING.md (bilingual), CODE_OF_CONDUCT.md, SECURITY.md - Add GitHub Issue templates (bug report, feature request) and PR template - Set GitHub topics, improve repository description, add homepage URL --- .github/ISSUE_TEMPLATE/bug_report.md | 41 ++++++++++++ .github/ISSUE_TEMPLATE/config.yml | 5 ++ .github/ISSUE_TEMPLATE/feature_request.md | 29 +++++++++ .github/pull_request_template.md | 17 +++++ CODE_OF_CONDUCT.md | 39 +++++++++++ CONTRIBUTING.md | 79 +++++++++++++++++++++++ README.en.md | 17 +++++ README.md | 17 +++++ SECURITY.md | 29 +++++++++ client/doc.go | 16 +++++ client/ym/chats/doc.go | 14 ++++ client/ym/files/doc.go | 12 ++++ client/ym/messages/doc.go | 15 +++++ client/ym/polls/doc.go | 19 ++++++ client/ym/self/doc.go | 10 +++ client/ym/updates/doc.go | 18 ++++++ client/ym/users/doc.go | 11 ++++ client/ym/ymerrors/doc.go | 19 ++++++ middleware/doc.go | 20 ++++++ 19 files changed, 427 insertions(+) create mode 100644 .github/ISSUE_TEMPLATE/bug_report.md create mode 100644 .github/ISSUE_TEMPLATE/config.yml create mode 100644 .github/ISSUE_TEMPLATE/feature_request.md create mode 100644 .github/pull_request_template.md create mode 100644 CODE_OF_CONDUCT.md create mode 100644 CONTRIBUTING.md create mode 100644 SECURITY.md create mode 100644 client/doc.go create mode 100644 client/ym/chats/doc.go create mode 100644 client/ym/files/doc.go create mode 100644 client/ym/messages/doc.go create mode 100644 client/ym/polls/doc.go create mode 100644 client/ym/self/doc.go create mode 100644 client/ym/updates/doc.go create mode 100644 client/ym/users/doc.go create mode 100644 client/ym/ymerrors/doc.go create mode 100644 middleware/doc.go diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 0000000..7cf70bc --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,41 @@ +--- +name: Bug Report +about: Report a bug in ymsdk +title: "[Bug] " +labels: bug +assignees: '' +--- + +## Description + +A clear description of the bug. + +## Steps to Reproduce + +1. +2. +3. + +## Expected Behavior + +What you expected to happen. + +## Actual Behavior + +What actually happened. + +## Environment + +- Go version: +- ymsdk version: +- OS: + +## Code Sample + +```go +// Minimal code to reproduce the issue +``` + +## Additional Context + +Any other context, error messages, or stack traces. diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml new file mode 100644 index 0000000..cc5c7c4 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -0,0 +1,5 @@ +blank_issues_enabled: true +contact_links: + - name: Documentation + url: https://pkg.go.dev/github.com/rekurt/ymsdk + about: Check the Go package documentation diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md new file mode 100644 index 0000000..7bc8197 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -0,0 +1,29 @@ +--- +name: Feature Request +about: Suggest a new feature or improvement +title: "[Feature] " +labels: enhancement +assignees: '' +--- + +## Problem + +What problem does this feature solve? + +## Proposed Solution + +Describe the feature you'd like to see. + +## Alternatives Considered + +Any alternative approaches you've considered. + +## API Design (optional) + +```go +// How you imagine the API would look +``` + +## Additional Context + +Any other context or examples. diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md new file mode 100644 index 0000000..0b09aa3 --- /dev/null +++ b/.github/pull_request_template.md @@ -0,0 +1,17 @@ +## Summary + +Brief description of changes. + +## Changes + +- + +## Testing + +- [ ] `go test ./...` passes +- [ ] `golangci-lint run` passes +- [ ] New tests added for new functionality + +## Related Issues + +Closes # diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md new file mode 100644 index 0000000..6f86a31 --- /dev/null +++ b/CODE_OF_CONDUCT.md @@ -0,0 +1,39 @@ +# Contributor Covenant Code of Conduct + +## Our Pledge + +We as members, contributors, and leaders pledge to make participation in our +community a harassment-free experience for everyone, regardless of age, body +size, visible or invisible disability, ethnicity, sex characteristics, gender +identity and expression, level of experience, education, socio-economic status, +nationality, personal appearance, race, religion, or sexual identity +and orientation. + +## Our Standards + +Examples of behavior that contributes to a positive environment: + +* Using welcoming and inclusive language +* Being respectful of differing viewpoints and experiences +* Gracefully accepting constructive criticism +* Focusing on what is best for the community +* Showing empathy towards other community members + +Examples of unacceptable behavior: + +* The use of sexualized language or imagery and unwelcome sexual attention +* Trolling, insulting or derogatory comments, and personal or political attacks +* Public or private harassment +* Publishing others' private information without explicit permission +* Other conduct which could reasonably be considered inappropriate + +## Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be +reported by opening an issue or contacting the maintainers. + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant](https://www.contributor-covenant.org), +version 2.1, available at +https://www.contributor-covenant.org/version/2/1/code_of_conduct.html. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..9bda1ba --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,79 @@ +# Contributing to ymsdk + +[Русская версия](#как-внести-вклад-в-ymsdk) + +Thank you for your interest in contributing to ymsdk! This document provides guidelines for contributing. + +## Getting Started + +1. Fork and clone the repository +2. Install Go 1.25+ and [golangci-lint](https://golangci-lint.run/) +3. Run tests: `go test ./...` +4. Run linter: `golangci-lint run --config .golangci.yml` + +## Development Workflow + +1. Create a feature branch from `master` +2. Make your changes with tests +3. Ensure all tests pass and linter is clean +4. Submit a pull request + +## Code Standards + +- Follow existing code patterns and architecture +- All public APIs must have doc comments +- Table-driven tests are preferred +- Use `internal/testutil.FakeDoer` for HTTP mocking in tests +- Line length limit: 180 characters +- Import order: stdlib → external → `github.com/rekurt/` packages + +## Pull Request Guidelines + +- Keep PRs focused on a single change +- Include tests for new functionality +- Update documentation if adding public API +- Reference related issues in the PR description + +## Reporting Issues + +Use GitHub Issues with the provided templates for bug reports and feature requests. + +--- + +# Как внести вклад в ymsdk + +Спасибо за интерес к проекту! Ниже описаны правила для контрибьюторов. + +## Начало работы + +1. Форкните и клонируйте репозиторий +2. Установите Go 1.25+ и [golangci-lint](https://golangci-lint.run/) +3. Запустите тесты: `go test ./...` +4. Запустите линтер: `golangci-lint run --config .golangci.yml` + +## Рабочий процесс + +1. Создайте feature-ветку от `master` +2. Внесите изменения с тестами +3. Убедитесь, что тесты проходят и линтер чист +4. Отправьте pull request + +## Стандарты кода + +- Следуйте существующим паттернам и архитектуре +- Все публичные API должны иметь doc-комментарии +- Предпочтительны table-driven тесты +- Используйте `internal/testutil.FakeDoer` для мокирования HTTP в тестах +- Ограничение длины строки: 180 символов +- Порядок импортов: stdlib → external → `github.com/rekurt/` + +## Правила Pull Request + +- PR должен быть сфокусирован на одном изменении +- Включайте тесты для новой функциональности +- Обновляйте документацию при добавлении публичного API +- Ссылайтесь на связанные issues в описании PR + +## Сообщения об ошибках + +Используйте GitHub Issues с предоставленными шаблонами для баг-репортов и запросов функциональности. diff --git a/README.en.md b/README.en.md index d5ba0c1..d54717e 100644 --- a/README.en.md +++ b/README.en.md @@ -2,8 +2,25 @@ [Русская версия](README.md) +[![CI](https://github.com/rekurt/ymsdk/actions/workflows/ci.yml/badge.svg)](https://github.com/rekurt/ymsdk/actions/workflows/ci.yml) +[![Go Reference](https://pkg.go.dev/badge/github.com/rekurt/ymsdk.svg)](https://pkg.go.dev/github.com/rekurt/ymsdk) +[![Go Report Card](https://goreportcard.com/badge/github.com/rekurt/ymsdk)](https://goreportcard.com/report/github.com/rekurt/ymsdk) +[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE) +[![Go Version](https://img.shields.io/github/go-mod/go-version/rekurt/ymsdk)](go.mod) + Lightweight Go client for Yandex Messenger Bot API with typed models, built-in retry, and services for core API methods. Docs: https://pkg.go.dev/github.com/rekurt/ymsdk +## Features + +- **Type-safe models** — `ChatID`, `UserLogin`, `MessageID` and other distinct types prevent mix-ups at compile time +- **Automatic retry** — exponential backoff with configurable retry strategy +- **Rate limit handling** — automatic respect for API `Retry-After` headers +- **Service-oriented architecture** — separate packages for messages, chats, polls, updates, files, and users +- **Polling & Webhooks** — two update delivery modes +- **Debug logging** — structured logs via `zap` with HTTP request/response inspection +- **Minimal dependencies** — only `go.uber.org/zap` +- **Full API coverage** — all core Yandex Messenger Bot API methods + ## Installation ```bash diff --git a/README.md b/README.md index cda8efd..31712f8 100644 --- a/README.md +++ b/README.md @@ -2,8 +2,25 @@ [English](README.en.md) +[![CI](https://github.com/rekurt/ymsdk/actions/workflows/ci.yml/badge.svg)](https://github.com/rekurt/ymsdk/actions/workflows/ci.yml) +[![Go Reference](https://pkg.go.dev/badge/github.com/rekurt/ymsdk.svg)](https://pkg.go.dev/github.com/rekurt/ymsdk) +[![Go Report Card](https://goreportcard.com/badge/github.com/rekurt/ymsdk)](https://goreportcard.com/report/github.com/rekurt/ymsdk) +[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE) +[![Go Version](https://img.shields.io/github/go-mod/go-version/rekurt/ymsdk)](go.mod) + Легковесный Go-клиент для Yandex Messenger Bot API с типобезопасными моделями, встроенным retry и сервисами для всех основных методов API. Документация: https://pkg.go.dev/github.com/rekurt/ymsdk +## Возможности + +- **Типобезопасные модели** — `ChatID`, `UserLogin`, `MessageID` и другие типы предотвращают ошибки на этапе компиляции +- **Автоматический retry** — экспоненциальный backoff с настраиваемой стратегией повторных попыток +- **Rate limit** — автоматическое соблюдение `Retry-After` заголовков API +- **Сервис-ориентированная архитектура** — отдельные пакеты для сообщений, чатов, опросов, обновлений, файлов и пользователей +- **Polling и Webhooks** — два режима получения обновлений +- **Debug-логирование** — структурированные логи через `zap` с HTTP-инспекцией +- **Минимум зависимостей** — только `go.uber.org/zap` +- **Полное покрытие API** — все основные методы Yandex Messenger Bot API + ## Установка ```bash diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 0000000..d5968df --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,29 @@ +# Security Policy + +## Supported Versions + +| Version | Supported | +| ------- | ------------------ | +| latest | :white_check_mark: | + +## Reporting a Vulnerability + +If you discover a security vulnerability in ymsdk, please report it responsibly. + +**Do NOT open a public GitHub issue for security vulnerabilities.** + +Instead, please report vulnerabilities by opening a +[private security advisory](https://github.com/rekurt/ymsdk/security/advisories/new) +on GitHub. + +You should receive a response within 48 hours. We will work with you to +understand the issue and address it promptly. + +## Security Considerations + +This SDK handles API tokens for the Yandex Messenger Bot API. Please ensure: + +- Never commit API tokens to version control +- Use environment variables or secret management for token storage +- Keep the SDK updated to the latest version +- Review the `ymerrors` package for proper error handling of authentication failures diff --git a/client/doc.go b/client/doc.go new file mode 100644 index 0000000..c93a3c3 --- /dev/null +++ b/client/doc.go @@ -0,0 +1,16 @@ +// Package client provides the [YMClient] aggregator — a single entry point +// to all Yandex Messenger Bot API services. +// +// Create a client with [New] and access services through its fields: +// +// cs := client.New(ym.Config{Token: os.Getenv("YM_TOKEN")}) +// msg, _ := cs.Messages.SendToChat(ctx, chatID, "hello", nil) +// chat, _ := cs.Chats.Create(ctx, &chats.ChatCreateRequest{...}) +// updates, _ := cs.Updates.Get(ctx, 100, "") +// +// If you need a pre-configured core [ym.Client] (e.g. with custom HTTP +// transport), use [Wrap] instead: +// +// cl := ym.NewClientWithHTTP(cfg, customHTTP) +// cs := client.Wrap(cl) +package client diff --git a/client/ym/chats/doc.go b/client/ym/chats/doc.go new file mode 100644 index 0000000..732cfbe --- /dev/null +++ b/client/ym/chats/doc.go @@ -0,0 +1,14 @@ +// Package chats provides operations for creating and managing chats and +// channels in Yandex Messenger. +// +// The service supports creating group chats and channels, as well as +// updating chat membership (adding and removing members). +// +// Create the service via [NewService] with a configured [ym.Client]: +// +// svc := chats.NewService(ymClient) +// chat, err := svc.Create(ctx, &chats.ChatCreateRequest{ +// Name: "Team Chat", +// Members: []ym.ChatMember{{Login: "alice"}}, +// }) +package chats diff --git a/client/ym/files/doc.go b/client/ym/files/doc.go new file mode 100644 index 0000000..a86cd0e --- /dev/null +++ b/client/ym/files/doc.go @@ -0,0 +1,12 @@ +// Package files provides operations for uploading files to Yandex Messenger +// chats. +// +// Files can be sent to a chat by [ym.ChatID] or directly to a user by +// [ym.UserLogin]. The service handles multipart form encoding and +// automatic retry on transient failures. +// +// Create the service via [NewService] with a configured [ym.Client]: +// +// svc := files.NewService(ymClient) +// msg, err := svc.SendToChat(ctx, chatID, "report.pdf", fileReader) +package files diff --git a/client/ym/messages/doc.go b/client/ym/messages/doc.go new file mode 100644 index 0000000..b3a44b4 --- /dev/null +++ b/client/ym/messages/doc.go @@ -0,0 +1,15 @@ +// Package messages provides operations for sending, deleting, and managing +// messages in Yandex Messenger chats. +// +// The service supports plain-text messages, file and image attachments, +// image galleries, and message deletion. Messages can be sent to a chat +// by [ym.ChatID] or directly to a user by [ym.UserLogin]. +// +// Create the service via [NewService] with a configured [ym.Client]: +// +// svc := messages.NewService(ymClient) +// msg, err := svc.SendToChat(ctx, chatID, "Hello!", nil) +// +// File operations include uploading files and images, sending multi-image +// galleries, and downloading files by ID. +package messages diff --git a/client/ym/polls/doc.go b/client/ym/polls/doc.go new file mode 100644 index 0000000..8517f1c --- /dev/null +++ b/client/ym/polls/doc.go @@ -0,0 +1,19 @@ +// Package polls provides operations for creating and managing polls in +// Yandex Messenger chats. +// +// The service supports poll creation, retrieving poll results, and +// paginating through individual voter responses. +// +// Create the service via [NewService] with a configured [ym.Client]: +// +// svc := polls.NewService(ymClient) +// msg, err := svc.Create(ctx, &polls.CreatePollRequest{ +// ChatID: chatID, +// Question: "Lunch?", +// Answers: []string{"Pizza", "Sushi"}, +// }) +// +// Use [Service.GetResults] to fetch aggregated poll results and +// [Service.GetAllVoters] to collect all individual votes with automatic +// pagination. +package polls diff --git a/client/ym/self/doc.go b/client/ym/self/doc.go new file mode 100644 index 0000000..0712f27 --- /dev/null +++ b/client/ym/self/doc.go @@ -0,0 +1,10 @@ +// Package self provides operations for managing the bot's own settings in +// Yandex Messenger, such as configuring webhook URLs. +// +// Create the service via [NewService] with a configured [ym.Client]: +// +// svc := self.NewService(ymClient) +// bot, err := svc.Update(ctx, &self.SelfUpdateRequest{ +// WebhookURL: "https://example.com/webhook", +// }) +package self diff --git a/client/ym/updates/doc.go b/client/ym/updates/doc.go new file mode 100644 index 0000000..ed82eb5 --- /dev/null +++ b/client/ym/updates/doc.go @@ -0,0 +1,18 @@ +// Package updates provides mechanisms for receiving real-time updates from +// the Yandex Messenger Bot API. +// +// Two update modes are supported: +// +// - Long polling via [Service.PollLoop], which continuously fetches new +// updates and invokes a user-supplied callback. +// - Webhook handling via the companion webhook example, where the API +// pushes updates to a user-provided HTTP endpoint. +// +// Create the service via [NewService] with a configured [ym.Client]: +// +// svc := updates.NewService(ymClient) +// err := svc.PollLoop(ctx, updates.PollParams{Limit: 100}, func(ctx context.Context, u ym.Update) error { +// fmt.Println("got update:", u.UpdateID) +// return nil +// }) +package updates diff --git a/client/ym/users/doc.go b/client/ym/users/doc.go new file mode 100644 index 0000000..e696914 --- /dev/null +++ b/client/ym/users/doc.go @@ -0,0 +1,11 @@ +// Package users provides operations for retrieving user information from +// Yandex Messenger. +// +// Currently the service supports looking up a user's deep-link by login, +// which can be used to initiate direct conversations. +// +// Create the service via [NewService] with a configured [ym.Client]: +// +// svc := users.NewService(ymClient) +// link, err := svc.GetUserLink(ctx, "alice") +package users diff --git a/client/ym/ymerrors/doc.go b/client/ym/ymerrors/doc.go new file mode 100644 index 0000000..07a81d9 --- /dev/null +++ b/client/ym/ymerrors/doc.go @@ -0,0 +1,19 @@ +// Package ymerrors defines error types and sentinel errors for the Yandex +// Messenger Bot API SDK. +// +// The primary type is [APIError], which carries structured information about +// API failures including HTTP status, error kind, description, and an +// optional [APIError.RetryAfter] duration for rate-limited responses. +// +// Sentinel errors allow quick classification with [errors.Is]: +// +// if errors.Is(err, ymerrors.ErrRateLimited) { +// // back off and retry +// } +// +// Available sentinels: [ErrRateLimited], [ErrInvalidToken], +// [ErrUnauthorized], [ErrNetwork]. +// +// The package also provides [RetryStrategy] and [RateLimitHandling] +// configuration types used by the HTTP client's automatic retry logic. +package ymerrors diff --git a/middleware/doc.go b/middleware/doc.go new file mode 100644 index 0000000..c0cb4bb --- /dev/null +++ b/middleware/doc.go @@ -0,0 +1,20 @@ +// Package middleware provides structured logging and HTTP debugging utilities +// for the Yandex Messenger Bot API SDK. +// +// The package includes three components: +// +// - [ErrorLogger] — captures and logs API errors using [go.uber.org/zap], +// with structured fields for error kind, HTTP status, and retry-after. +// - [DebugLogger] — configurable debug logger with three verbosity levels +// ([LogLevelError], [LogLevelInfo], [LogLevelDebug]) for development +// and troubleshooting. +// - [HTTPLogger] — wraps an [net/http.Client] to log raw HTTP request +// and response bodies at debug level. +// +// Example setup with full HTTP inspection: +// +// logger, _ := zap.NewDevelopment() +// debugLog := middleware.NewDebugLogger(logger, middleware.LogLevelDebug) +// httpClient := middleware.NewHTTPLogger(http.DefaultClient, debugLog) +// ymClient := ym.NewClientWithHTTP(cfg, httpClient) +package middleware