amocrm

package module
v0.0.0-...-1d3e8ac Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 16, 2023 License: MIT Imports: 14 Imported by: 0

README

Go Package for amoCRM API

Go Package for amoCRM API

GoDoc Reference Code Coverage Build Status License

This package provides a Golang client for amoCRM API.

Disclaimer

This code is in no way affiliated with, authorized, maintained, sponsored or endorsed by amoCRM or any of its affiliates or subsidiaries. This is an independent and unofficial API client. Use at your own risk.

Installation

go get -u github.com/alexeykhan/amocrm

Quick Start

Step №1: Redirect user to the authorization page.

User grants access to their account and is redirected back with referer and code GET-parameters attached.

package main

import (
    "fmt"

    "github.com/alexeykhan/amocrm"
)

func main() {
    amoCRM := amocrm.New("clientID", "clientSecret", "redirectURL")
    
    state := amocrm.RandomState()  // store this state as a session identifier
    mode := amocrm.PostMessageMode // options: PostMessageMode, PopupMode
    
    authURL, err := amoCRM.AuthorizeURL(state, mode)
    if err != nil {
        fmt.Println("failed to get auth url:", err)
        return
    }
    
    fmt.Println("Redirect user to this URL:")
    fmt.Println(authURL)
}

Step №2: Exchange authorization code for token.

Use received referer and code parameters as account domain and authorization code respectively to make a handshake with amoCRM and Get a fresh set of access_token, refresh_token and token meta data.

package main

import (
    "fmt"

    "github.com/alexeykhan/amocrm"
)

func main() {
    amoCRM := amocrm.New("clientID", "clientSecret", "redirectURL")
    
    if err := amoCRM.SetDomain("example.amocrm.ru"); err != nil {
        fmt.Println("set domain:", err)
        return
    }
    
    token, err := amoCRM.TokenByCode("authorizationCode")
    if err != nil {
        fmt.Println("get token by code:", err)
        return
    }
    
    fmt.Println("access_token:", token.AccessToken())
    fmt.Println("refresh_token:", token.RefreshToken())
    fmt.Println("token_type:", token.TokenType())
    fmt.Println("expires_at:", token.ExpiresAt().Unix())
}

Step №3: Make your first API request.

Set amoCRM accounts domain and token to authorize your requests.

package main

import (
    "fmt"
    "time"

    "github.com/alexeykhan/amocrm"
)

func main() {
    amoCRM := amocrm.New("clientID", "clientSecret", "redirectURL")
    
    if err := amoCRM.SetDomain("example.amocrm.ru"); err != nil {
        fmt.Println("set domain:", err)
        return
    }
    
    token := amocrm.NewToken("accessToken", "refreshToken", "tokenType", time.Now())
    if err := amoCRM.SetToken(token); err != nil {
        fmt.Println("set token:", err)
        return
    }
    
    cfg := amocrm.AccountsConfig{
        Relations: []string{
            amocrm.WithUUID, 
            amocrm.WithVersion, 
            amocrm.WithAmojoID,
            amocrm.WithTaskTypes,
            amocrm.WithUserGroups,
            amocrm.WithAmojoRights,
            amocrm.WithDatetimeSettings,
        }, 
    }

    account, err := amoCRM.Accounts().Current(cfg)
    if err != nil {
        fmt.Println("fetch current accounts:", err)
        return
    }
    
    fmt.Println("current accounts:", account)
}

Development Status: In Progress

This package is under development so any methods, constants or types may be changed in newer versions without backward compatibility with previous ones. Use it at your own risk and feel free to fork it anytime.


Released under the MIT License.

Documentation

Overview

Example (GetAuthURL)
package main

import (
	"fmt"
	"time"

	"github.com/sintanial/amocrm"
)

var env = struct {
	clientID     string
	clientSecret string
	redirectURL  string
}{
	clientID:     "CLIENT_ID",
	clientSecret: "CLIENT_SECRET",
	redirectURL:  "REDIRECT_URI",
}

func main() {
	// Initialize amoCRM API Client.
	amoCRM := amocrm.New(env.clientID, env.clientSecret, env.redirectURL)

	// Save this random state as a session identifier to verify
	// user identity when they are redirected back with code.
	// Set required mode parameter: "post_message" or "popup".
	state := amocrm.RandomState()
	mode := amocrm.PostMessageMode

	// Redirect user to authorization URL.
	authURL, err := amoCRM.AuthorizeURL(state, mode)
	if err != nil {
		fmt.Println("Failed to Get auth url:", err)
		return
	}

	fmt.Println("Redirect user to this URL:")
	fmt.Println(authURL)
}
Output:

Example (GetCurrentAccount)
package main

import (
	"fmt"
	"time"

	"github.com/sintanial/amocrm"
)

var (
	env = struct {
		clientID     string
		clientSecret string
		redirectURL  string
	}{
		clientID:     "CLIENT_ID",
		clientSecret: "CLIENT_SECRET",
		redirectURL:  "REDIRECT_URI",
	}

	storage = struct {
		domain       string
		accessToken  string
		refreshToken string
		tokenType    string
		expiresAt    time.Time
	}{
		domain:       "example.amocrm.ru",
		accessToken:  "access_token",
		refreshToken: "refresh_token",
		tokenType:    "bearer",
		expiresAt:    time.Now(),
	}
)

func main() {
	// Initialize amoCRM API Client.
	amoCRM := amocrm.New(env.clientID, env.clientSecret, env.redirectURL)

	// Retrieve domain from storage.
	if err := amoCRM.SetDomain(storage.domain); err != nil {
		fmt.Println("set domain:", err)
		return
	}

	// Retrieve token from storage.
	token := amocrm.NewToken(storage.accessToken, storage.refreshToken, storage.tokenType, storage.expiresAt)
	if err := amoCRM.SetToken(token); err != nil {
		fmt.Println("set token:", err)
		return
	}

	// Set up accounts request config.
	cfg := amocrm.AccountsConfig{
		Relations: []string{
			amocrm.WithUUID,
			amocrm.WithVersion,
			amocrm.WithAmojoID,
			amocrm.WithTaskTypes,
			amocrm.WithUserGroups,
			amocrm.WithAmojoRights,
			amocrm.WithDatetimeSettings,
		},
	}

	// Fetch current accounts with AccountsRepository.
	account, err := amoCRM.Accounts().Current(cfg)
	if err != nil {
		fmt.Println("fetch current accounts:", err)
		return
	}

	fmt.Println("current accounts:", account)
}
Output:

Example (GetTokenByCode)
package main

import (
	"fmt"
	"time"

	"github.com/sintanial/amocrm"
)

var env = struct {
	clientID     string
	clientSecret string
	redirectURL  string
}{
	clientID:     "CLIENT_ID",
	clientSecret: "CLIENT_SECRET",
	redirectURL:  "REDIRECT_URI",
}

func main() {
	// Initialize amoCRM API Client.
	amoCRM := amocrm.New(env.clientID, env.clientSecret, env.redirectURL)

	// Use the accounts domain and authorization code that are
	// pushed to the redirect URL as "referer" and "code GET
	// parameters respectively. AccessTokenByCode will do the
	// handshake to retrieve tokens.
	domain := "example.amocrm.ru"
	authCode := "def502000ba3e1724cac79...92146f93b70fd4ca31"

	// Set amoCRM API accounts domain.
	if err := amoCRM.SetDomain(domain); err != nil {
		fmt.Println("set domain:", err)
		return
	}

	// Exchange authorization code for token.
	token, err := amoCRM.TokenByCode(authCode)
	if err != nil {
		fmt.Println("Get token by code:", err)
		return
	}

	// Store received token.
	fmt.Println("access_token:", token.AccessToken())
	fmt.Println("refresh_token:", token.RefreshToken())
	fmt.Println("token_type:", token.TokenType())
	fmt.Println("expires_at:", token.ExpiresAt().Unix())
}
Output:

Index

Examples

Constants

View Source
const (
	PostMessageMode = "post_message"
	PopupMode       = "popup"
)

PostMessageMode and PopupMode are the only options for amoCRM OAuth2.0 "mode" request parameter.

View Source
const (
	WithUUID             = "uuid"
	WithVersion          = "version"
	WithAmojoID          = "amojo_id"
	WithTaskTypes        = "task_types"
	WithUserGroups       = "users_groups"
	WithAmojoRights      = "amojo_rights"
	WithDatetimeSettings = "datetime_settings"
)

Account relations.

Variables

View Source
var ErrNoRecord = errors.New("record not found")

Functions

func RandomState

func RandomState() string

RandomState generates a new random state.

Types

type Account

type Account struct {
	ID                      int    `json:"id"`
	Name                    string `json:"name"`
	Subdomain               string `json:"subdomain"`
	CreatedAt               int    `json:"created_at"`
	CreatedBy               int    `json:"created_by"`
	UpdatedAt               int    `json:"updated_at"`
	UpdatedBy               int    `json:"updated_by"`
	CurrentUserID           int    `json:"current_user_id"`
	Country                 string `json:"country"`
	Currency                string `json:"currency"`
	CustomersMode           string `json:"customers_mode"`
	IsUnsortedOn            bool   `json:"is_unsorted_on"`
	MobileFeatureVersion    int    `json:"mobile_feature_version"`
	IsLossReasonEnabled     bool   `json:"is_loss_reason_enabled"`
	IsHelpbotEnabled        bool   `json:"is_helpbot_enabled"`
	IsTechnicalAccount      bool   `json:"is_technical_account"`
	ContactNameDisplayOrder int    `json:"contact_name_display_order"`
	AmojoID                 string `json:"amojo_id"`
	UUID                    string `json:"uuid"`
	Version                 int    `json:"version"`
	Links                   struct {
		Self struct {
			Href string `json:"href"`
		} `json:"self"`
	} `json:"_links"`
	Embedded struct {
		AmojoRights struct {
			CanDirect       bool `json:"can_direct"`
			CanCreateGroups bool `json:"can_create_groups"`
		} `json:"amojo_rights"`
		UsersGroups []struct {
			ID   int         `json:"id"`
			Name string      `json:"name"`
			UUID interface{} `json:"uuid"`
		} `json:"users_groups"`
		TaskTypes []struct {
			ID     int         `json:"id"`
			Name   string      `json:"name"`
			Color  interface{} `json:"color"`
			IconID interface{} `json:"icon_id"`
			Code   string      `json:"code"`
		} `json:"task_types"`
		DatetimeSettings struct {
			DatePattern      string `json:"date_pattern"`
			ShortDatePattern string `json:"short_date_pattern"`
			ShortTimePattern string `json:"short_time_pattern"`
			DateFormat       string `json:"date_format"`
			TimeFormat       string `json:"time_format"`
			Timezone         string `json:"timezone"`
			TimezoneOffset   string `json:"timezone_offset"`
		} `json:"datetime_settings"`
	} `json:"_embedded"`
}

Account represents amoCRM Account entity json DTO.

type Accounts

type Accounts interface {
	Current(cfg AccountsConfig) (*Account, error)
}

Accounts describes methods available for Accounts entity.

type AccountsConfig

type AccountsConfig struct {
	Relations []string
}

Use AccountsConfig to set account parameters.

type Call

type Call struct {
	Direction         string `json:"direction"`                     // Направление звонка. inbound – входящий, outbound – исходящий. Обязательный параметр
	Uniq              string `json:"uniq,omitempty"`                // Уникальный идентификатор звонка. Необязательный параметр
	Duration          int    `json:"duration"`                      // Длительность звонка в секундах. Обязательный параметр
	Source            string `json:"source"`                        // Источник звонка. Обязательный параметр
	Link              string `json:"link,omitempty"`                // Ссылка на запись звонка. Необязательный параметр
	Phone             string `json:"phone"`                         // Номер телефона, по которому будет произведен поиск. Обязательный параметр
	CallResult        string `json:"call_result,omitempty"`         // Результат звонка. Необязательный параметр
	CallStatus        int    `json:"call_status,omitempty"`         // Статус звонка. Доступные варианты: 1 – оставил сообщение, 2 – перезвонить позже, 3 – нет на месте, 4 – разговор состоялся, 5 – неверный номер, 6 – Не дозвонился, 7 – номер занят. Необязательный параметр
	ResponsibleUserID int    `json:"responsible_user_id,omitempty"` // ID пользователя, ответственного за звонок
	CreatedBy         int    `json:"created_by,omitempty"`          // ID пользователя, создавший звонок
	UpdatedBy         int    `json:"updated_by,omitempty"`          // ID пользователя, изменивший звонок
	CreatedAt         int    `json:"created_at,omitempty"`          // Дата создания звонка, передается в Unix Timestamp
	UpdatedAt         int    `json:"updated_at,omitempty"`          // Дата изменения звонка, передается в Unix Timestamp
	RequestID         string `json:"request_id,omitempty"`          // Поле, которое вернется вам в ответе без изменений и не будет сохранено. Необязательный параметр
}

type Calls

type Calls interface {
	Create(calls []Call) ([]Contact, []Error, error)
}

Calls describes methods available for Calls entity

type Client

type Client interface {
	AuthorizeURL(state, mode string) (*url.URL, error)
	TokenByCode(code string) (Token, error)
	LoadTokenOrAuthorize(code string) error
	LoadTokenAndAuthorize() error
	NewTokenAndAuthorize(authCode string) error
	SetToken(token Token) error
	SetAPIHost(apiHost string)
	SetDomain(domain string) error
	Accounts() Accounts
	Leads() Leads
	Pipelines() Pipelines
	Contacts() Contacts
	Calls() Calls
	EventsV2() EventsV2
}

Provider is a wrapper for authorization and making requests.

func New

func New(clientID, clientSecret, redirectURL string) Client

New allocates and returns a new amoCRM API Client.

func NewWithStorage

func NewWithStorage(tokenStorage TokenStorage, clientID, clientSecret, redirectURL string) Client

type Contact

type Contact struct {
	Id                 int               `json:"id,omitempty"`
	Name               string            `json:"name,omitempty"`                 //Название контакта
	FirstName          string            `json:"first_name,omitempty"`           //Имя контакта
	LastName           string            `json:"last_name,omitempty"`            //Фамилия контакта
	ResponsibleUserId  int               `json:"responsible_user_id,omitempty"`  //ID пользователя, ответственного за контакт
	CreatedBy          int               `json:"created_by,omitempty"`           //ID пользователя, создавший контакт
	UpdatedBy          int               `json:"updated_by,omitempty"`           //ID пользователя, изменивший контакт
	CreatedAt          int               `json:"created_at,omitempty"`           //Дата создания контакта, передается в Unix Timestamp
	UpdatedAt          int               `json:"updated_at,omitempty"`           //Дата изменения контакта, передается в Unix Timestamp
	CustomFieldsValues []FieldValues     `json:"custom_fields_values,omitempty"` //Массив, содержащий информацию по дополнительным полям, заданным для данной сделки. Поле не является обязательным. Примеры заполнения полей
	Embedded           *ContactsEmbedded `json:"_embedded,omitempty"`            //Данные вложенных сущностей, при создании и редактировании можно передать только теги. Поле не является обязательным
}

type Contacts

type Contacts interface {
	Contacts(values url.Values) ([]Contact, error)
	Create(contacts []Contact) ([]Contact, error)
	GetOne(contactId int, with ...string) (Contact, error)
}

Contacts describes methods available for Contacts entity.

type ContactsEmbedded

type ContactsEmbedded struct {
	Tags []FieldValues `json:"tags,omitempty"`
}

type Error

type Error struct {
	Detail    string `json:"detail"`
	RequestID string `json:"request_id"`
	Status    int    `json:"status"`
	Title     string `json:"title"`
}

type Event

type Event struct {
	Type        string `json:"type"`         // Тип уведомления – phone_call
	PhoneNumber string `json:"phone_number"` // Номер телефона на который поступает звонок. Можно передавать в любом формате
	Users       []int  `json:"users"`        // Пользователи для которых будет отправлено уведомление. Если не передавать этот параметр, то уведомление будет отправлено для всех пользователей
}

type EventEmbeddedItem

type EventEmbeddedItem struct {
	ElementID   int    `json:"element_id"`
	ElementType int    `json:"element_type"`
	UID         string `json:"uid"`
	PhoneNumber string `json:"phone_number"`
}

type EventsV2

type EventsV2 interface {
	Add(events []Event) ([]EventEmbeddedItem, error)
}

Events describes methods available for Events entity

type FieldValues

type FieldValues map[string]interface{}

type GrantType

type GrantType struct {
	// contains filtered or unexported fields
}

type JSONFileTokenStorage

type JSONFileTokenStorage struct {
	File string
}

func (JSONFileTokenStorage) GetToken

func (self JSONFileTokenStorage) GetToken() (Token, error)

func (JSONFileTokenStorage) SetToken

func (self JSONFileTokenStorage) SetToken(token Token) error

type JSONToken

type JSONToken struct {
	AccessToken  string    `json:"access_token"`
	RefreshToken string    `json:"refresh_token"`
	TokenType    string    `json:"token_type"`
	ExpiresAt    time.Time `json:"expires_at"`
}

type Lead

type Lead struct {
	Id                 int           `json:"id,omitempty"`
	Name               string        `json:"name,omitempty"`                 //Название сделки. Поле не является обязательным
	Price              int           `json:"price,omitempty"`                //Бюджет сделки. Поле не является обязательным
	StatusId           int           `json:"status_id,omitempty"`            //ID статуса, в который добавляется сделка. Поле не является обязательным, по-умолчанию – первый этап главной воронки
	PipelineId         int           `json:"pipeline_id,omitempty"`          //ID воронки, в которую добавляется сделка. Поле не является обязательным
	CreatedBy          int           `json:"created_by,omitempty"`           //ID пользователя, создающий сделку. При передаче значения 0, сделка будет считаться созданной роботом. Поле не является обязательным
	UpdatedBy          int           `json:"updated_by,omitempty"`           //ID пользователя, изменяющий сделку. При передаче значения 0, сделка будет считаться измененной роботом. Поле не является обязательным
	ClosedAt           int           `json:"closed_at,omitempty"`            //Дата закрытия сделки, передается в Unix Timestamp. Поле не является обязательным
	CreatedAt          int           `json:"created_at,omitempty"`           //Дата создания сделки, передается в Unix Timestamp. Поле не является обязательным
	UpdatedAt          int           `json:"updated_at,omitempty"`           //Дата изменения сделки, передается в Unix Timestamp. Поле не является обязательным
	LossReasonId       int           `json:"loss_reason_id,omitempty"`       //ID причины отказа. Поле не является обязательным
	ResponsibleUserId  int           `json:"responsible_user_id,omitempty"`  //ID пользователя, ответственного за сделку. Поле не является обязательным
	CustomFieldsValues []FieldValues `json:"custom_fields_values,omitempty"` //Массив, содержащий информацию по дополнительным полям, заданным для данной сделки. Поле не является обязательным. Примеры заполнения полей
	Embedded           *LeadEmbedded `json:"_embedded,omitempty"`            //Данные вложенных сущностей, при создании и редактировании можно передать только теги. Поле не является обязательным
}

func (*Lead) GetCustomField

func (lead *Lead) GetCustomField(fieldName string) (string, bool)

type LeadContactEmbedded

type LeadContactEmbedded struct {
	Id     int  `json:"id,omitempty"`
	IsMain bool `json:"is_main,omitempty"`
}

type LeadEmbedded

type LeadEmbedded struct {
	Tags      []FieldValues         `json:"tags,omitempty"`
	Contacts  []LeadContactEmbedded `json:"contacts,omitempty"`
	Companies []FieldValues         `json:"companies,omitempty"`
}

type Leads

type Leads interface {
	Create(leads []Lead) ([]Lead, error)
	Update(leads []Lead) ([]Lead, error)
	List(page int) ([]Lead, error)
	GetOne(leadId int, with string) (Lead, error)
}

Leads describes methods available for Leads entity.

type Pipeline

type Pipeline struct {
	Id           int               `json:"id,omitempty"`
	Name         string            `json:"name,omitempty"`
	Sort         int               `json:"price,omitempty"`
	IsMain       bool              `json:"is_main,omitempty"`        //Defines whether the pipeline is main for the account
	IsUnsortedOn bool              `json:"is_unsorted_on,omitempty"` //Defines whether Incoming Leads are enabled
	IsArchive    bool              `json:"is_archive,omitempty"`     //Defines whether Incoming Leads are enabled
	AccountId    int               `json:"account_id,omitempty"`
	Embedded     *PipelineEmbedded `json:"_embedded,omitempty"` //Данные вложенных сущностей
}

type PipelineEmbedded

type PipelineEmbedded struct {
	Statuses []PipelineStatus `json:"statuses,omitempty"`
}

type PipelineStatus

type PipelineStatus struct {
	Id         int    `json:"id,omitempty"`
	Name       string `json:"name,omitempty"`
	Sort       int    `json:"sort,omitempty"`
	IsEditable bool   `json:"is_editable,omitempty"`
	PipelineId int    `json:"pipeline_id,omitempty"`
	Color      string `json:"color,omitempty"`
	Type       int    `json:"type,omitempty"`
	AccountId  int    `json:"account_id,omitempty"`
}

type Pipelines

type Pipelines interface {
	List() ([]Pipeline, error)
}

Pipelines describes methods available for Pipelines entity.

type Token

type Token interface {
	AccessToken() string
	RefreshToken() string
	ExpiresAt() time.Time
	TokenType() string
	Expired() bool
}

GetToken stores a set of GetToken, RefreshToken and meta data.

func NewToken

func NewToken(accessToken, refreshToken, tokenType string, expiresAt time.Time) Token

NewToken allocates and returns a new TokenSource.

type TokenStorage

type TokenStorage interface {
	SetToken(Token) error
	GetToken() (Token, error)
}

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL