Skip to content

Commit 5c21c81

Browse files
authored
Merge pull request #3 from stvoidit/dev310
Dev310
2 parents 2917db2 + b20a0ea commit 5c21c81

File tree

9 files changed

+609
-692
lines changed

9 files changed

+609
-692
lines changed

MegaplanAPI.go

Lines changed: 0 additions & 151 deletions
This file was deleted.

README.md

Lines changed: 151 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -1,82 +1,151 @@
1-
# megaplan
2-
3-
Обертка над oauth2 в стандартной бибилотеке.
4-
5-
Авторефреш токена, сохранение в указанный файл и т.п.
6-
7-
Возвращает обычный "http. Response" для дальнейшей обработки чем угодно. Прямой доступ к "*http. Client" для кастомизации.
8-
9-
import (
10-
"io"
11-
"github.com/stvoidit/megaplan/v3"
12-
"os"
13-
)
14-
15-
func main() {
16-
api := megaplang.NewClien( `mymegaplan.ru` )
17-
if err := api.CheckCredential("megaplan-token.json"); err != nil {
18-
if err := api.GetNewToken( `username@email.ru` , `password` , `megaplan-token.json` ); err != nil {
19-
panic(err)
20-
}
21-
}
22-
resp, err := api.Get("https://mymegaplan.ru/api/v3/deal/7520")
23-
if err != nil {
24-
panic(err)
25-
}
26-
defer resp.Body.Close()
27-
io.Copy(os.Stdout, resp.Body)
28-
}
29-
30-
### Инициализация
31-
32-
#### Вариант 1
33-
34-
Если имеется файл токена, либо вы можете передать как env аргументы и создать новый экземпляр *oauth2. Token
35-
36-
t, _ := megaplan.LoadTokenFromFile( `megaplan-token.json` )
37-
api, err := megaplan.NewClien( `mymegaplan.ru` , `username@email.ru` , `password` , t)
38-
if err != nil {
39-
panic(err)
40-
}
41-
defer func() {
42-
if t, err := api.Token(); err == nil && t != nil {
43-
megaplan.SaveToken(t, `megaplan-token.json` )
44-
}
45-
}()
46-
47-
#### Вариант 2
48-
49-
Если данных токена еще нет. Будет автоматически создан новый токен.
50-
51-
api, err := megaplan.NewClien( `mymegaplan.ru` , `username@email.ru` , `password` , nil)
52-
if err != nil {
53-
panic(err)
54-
}
55-
defer func() {
56-
if t, err := api.Token(); err == nil && t != nil {
57-
megaplan.SaveToken(t, `megaplan-token.json` )
58-
}
59-
}()
60-
61-
### Загрузка файлов
62-
63-
Всегада возвращает сущность в виде, который нужен для отправки в дальнейшем POST запросе.
64-
65-
...
66-
67-
r1, err := os.Open( `...\test\myfile1.xlsx` )
68-
if err != nil {
69-
panic(err)
70-
}
71-
r2, err := os.Open( `...\test\myfile2.jpg` )
72-
if err != nil {
73-
panic(err)
74-
}
75-
defer r1.Close()
76-
defer r2.Close()
77-
attchs, err := api.UploadFiles(
78-
megaplan.UploadFile{Filename: `myfile1.xlsx` , R: r1},
79-
megaplan.UploadFile{Filename: `myfile2.jpg` , R: r2})
80-
if err != nil {
81-
panic(err)
82-
}
1+
# Пример использования
2+
3+
Иниализация клиента + опция включения заголовка "Accept-Encoding":"gzip", ответ будет возвращаться сжатым:
4+
5+
import (
6+
"github.com/stvoidit/megaplan/v3"
7+
)
8+
const (
9+
domain = `https://yourdomain.ru`
10+
token = `token`
11+
)
12+
func main() {
13+
client := megaplan.NewClient(domain, token, megaplan.OptionEnableAcceptEncodingGzip(true))
14+
}
15+
16+
## Пример создания задачами
17+
https://demo.megaplan.ru/api/v3/docs#entityTask
18+
Для удобства составления json для тела запроса есть функция __megaplan.BuildQueryParams__. Её единственное название - собрать параметры в правильном формате.
19+
Некоторые сущности требуют специального формата (например [Дата и Время](https://demo.megaplan.ru/api/v3/docs#entityDateTime), [Интервал](https://demo.megaplan.ru/api/v3/docs#entityDateInterval), [Дата](https://demo.megaplan.ru/api/v3/docs#entityDateOnly), [~~Сдвиг дат~~](https://demo.megaplan.ru/api/v3/docs#entityShiftDate)), то функция __megaplan.BuildQueryParams__ корректно сформирует структуру этих сущностей.
20+
21+
func CreateTask(c *megaplan.ClientV3) {
22+
const endpoint = "/api/v3/task"
23+
var qp = megaplan.BuildQueryParams(
24+
megaplan.SetRawField("contentType", "Task"),
25+
megaplan.SetRawField("isUrgent", false),
26+
megaplan.SetRawField("isTemplate", false),
27+
megaplan.SetRawField("name", "library test"),
28+
megaplan.SetRawField("subject", "subject library test"),
29+
megaplan.SetRawField("statement", "statement library test"),
30+
megaplan.SetEntityField("owner", "Employee", 1000129),
31+
megaplan.SetEntityField("responsible", "Employee", 1000129),
32+
megaplan.SetEntityField("deadline", "DateOnly", time.Now().Add(time.Hour*72)),
33+
megaplan.SetEntityField("plannedWork", "DateInterval", time.Hour*13),
34+
)
35+
r, err := qp.ToReader()
36+
if err != nil {
37+
panic(err)
38+
}
39+
rc, err := c.DoRequestAPI(http.MethodPost, endpoint, nil, r)
40+
if err != nil {
41+
panic(err)
42+
}
43+
defer rc.Close()
44+
os.Stdout.ReadFrom(rc)
45+
}
46+
47+
## Пример запроса с параметрами URL
48+
Так как параметры запроса на api "Мегаплан" передаются в нетипичном формате ("*?json=?"), то необходимо их экранировать через url.QueryEscape.
49+
Для удобства составления этих параметров можно так же использовать тип __megaplan.QueryParams__.
50+
51+
func testGetWithFilters(c *megaplan.ClientV3) {
52+
const endpoint = "/api/v3/task"
53+
var requestedFiled = [...]string{
54+
"id",
55+
"name",
56+
"status",
57+
"deadline",
58+
"actualWork",
59+
"responsible",
60+
"timeCreated",
61+
}
62+
// параметры верхнего уровня
63+
var searchParams = megaplan.BuildQueryParams(
64+
megaplan.SetRawField("limit", 50),
65+
megaplan.SetRawField("onlyRequestedFields", true),
66+
megaplan.SetRawField("fields", requestedFiled),
67+
)
68+
69+
// пример составления параметров без megaplan.BuildQueryParams (т.к. есть большая вложенность параметров)
70+
// megaplan.QueryParams - это просто алиас к типа megaplan.QueryParams, но с доп. методами,
71+
// поэтому для корректного составления json в параметрах URL необходимо передавать в DoRequestAPI именно megaplan.QueryParams
72+
now := time.Now()
73+
from := time.Date(now.Year(), time.January, 1, 0, 0, 0, 0, time.Local)
74+
var filterParams = map[string]interface{}{
75+
"contentType": "TaskFilter",
76+
"id": nil,
77+
"config": megaplan.QueryParams{
78+
"contentType": "FilterConfig",
79+
"termGroup": megaplan.QueryParams{
80+
"contentType": "FilterTermGroup",
81+
"join": "and",
82+
"terms": [...]megaplan.QueryParams{
83+
{
84+
"contentType": "FilterTermEnum",
85+
"field": "status",
86+
"comparison": "equals",
87+
"value": [...]string{"filter_any"},
88+
},
89+
{
90+
"comparison": "equals",
91+
"field": "responsible",
92+
"contentType": "FilterTermRef",
93+
"value": [...]megaplan.QueryParams{
94+
{"id": 1000129, "contentType": "Employee"},
95+
},
96+
},
97+
{
98+
"comparison": "equals",
99+
"field": "statusChangeTime",
100+
"contentType": "FilterTermDate",
101+
"value": megaplan.QueryParams{
102+
"contentType": "IntervalDates",
103+
"from": megaplan.CreateEnity("DateOnly", from),
104+
"to": megaplan.QueryParams{
105+
"contentType": "DateOnly",
106+
"year": now.Year(),
107+
"month": int(now.Month()) - 1,
108+
"day": now.Day(),
109+
},
110+
},
111+
},
112+
},
113+
},
114+
},
115+
}
116+
searchParams["filter"] = filterParams
117+
118+
{
119+
// вариант отправки через DoRequestAPI, внутри формируется корректный http.Request, если http.Response был сжат, то будет разархивирован
120+
rc, err := c.DoRequestAPI(http.MethodGet, endpoint, searchParams, nil)
121+
if err != nil {
122+
panic(err)
123+
}
124+
defer rc.Close()
125+
os.Stdout.ReadFrom(rc)
126+
}
127+
{
128+
// пример с использование Do, внучную собирается http.Request (добавляются необходимые заголовки, http.Response никак не обрабатывается перед возвратом)
129+
c.SetOptions(megaplan.OptionEnableAcceptEncodingGzip(false))
130+
request, err := http.NewRequest(http.MethodGet, domain, nil)
131+
if err != nil {
132+
panic(err)
133+
}
134+
request.URL.Path = endpoint
135+
request.URL.RawQuery = searchParams.QueryEscape() // параметры будут правильно экранированы
136+
response, err := c.Do(request)
137+
if err != nil {
138+
panic(err)
139+
}
140+
defer response.Body.Close()
141+
os.Stdout.ReadFrom(response.Body)
142+
}
143+
}
144+
145+
## __!__ Про типы и сущности "мегаплана" __!__
146+
147+
Многие реализации библиотек для API "Мегаплана" пытаются строго типизировать и описать полностью сущности, которыми оперирует "Мегаплан".
148+
Однако это подход влечет за собой обязанность этих библиотек поддерживать согласованность с версиями "Мегаплана", а так же каким-то образом поддерживать кастомные варианты полей.
149+
Данная библиотека является просто оберткой для использования API v3 и включает минимальное кол-во вспомогательных функций для составления запросов и парсинга ответов.
150+
151+
В силу специфики строения сущностей "Мегаплана" некоторые типы могут некорретно собираться функцией __megaplan.BuildQueryParams__, поэтому выше даны примере, как можно "дособрать" необходимые объекты.

0 commit comments

Comments
 (0)