forked from motodriver/demo
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathREADME.html
636 lines (600 loc) · 99.4 KB
/
README.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
<!doctype html>
<html>
<head>
<meta charset='UTF-8'><meta name='viewport' content='width=device-width initial-scale=1'>
<title>README</title><link href='https://fonts.googleapis.com/css?family=Open+Sans:400italic,700italic,700,400&subset=latin,latin-ext' rel='stylesheet' type='text/css' /><style type='text/css'>html {overflow-x: initial !important;}:root { --bg-color: #ffffff; --text-color: #333333; --select-text-bg-color: #B5D6FC; --select-text-font-color: auto; }
html { font-size: 14px; background-color: var(--bg-color); color: var(--text-color); font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; -webkit-font-smoothing: antialiased; }
body { margin: 0px; padding: 0px; height: auto; bottom: 0px; top: 0px; left: 0px; right: 0px; font-size: 1rem; line-height: 1.42857143; overflow-x: hidden; background-image: inherit; background-size: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: inherit; background-position: inherit inherit; background-repeat: inherit inherit; }
a.url { word-break: break-all; }
a:active, a:hover { outline: 0px; }
.in-text-selection, ::selection { text-shadow: none; background: var(--select-text-bg-color); color: var(--select-text-font-color); }
#write { margin: 0px auto; height: auto; width: inherit; word-break: normal; word-wrap: break-word; position: relative; padding-bottom: 70px; white-space: pre-wrap; overflow-x: visible; }
.first-line-indent #write p .md-line { text-indent: 0px; }
.first-line-indent #write li, .first-line-indent #write p, .first-line-indent #write p .md-line:first-child { text-indent: 2em; }
.for-image #write { padding-left: 8px; padding-right: 8px; }
body.typora-export { padding-left: 30px; padding-right: 30px; }
@media screen and (max-width: 500px) {
body.typora-export { padding-left: 0px; padding-right: 0px; }
.CodeMirror-sizer { margin-left: 0px !important; }
.CodeMirror-gutters { display: none !important; }
}
#write > blockquote:first-child, #write > div:first-child, #write > figure:first-child, #write > ol:first-child, #write > p:first-child, #write > pre:first-child, #write > ul:first-child { margin-top: 30px; }
#write li > figure:first-child { margin-top: -20px; }
#write ol, #write ul { position: relative; }
img { max-width: 100%; vertical-align: middle; }
button, input, select, textarea { color: inherit; font-family: inherit; font-size: inherit; font-style: inherit; font-variant-caps: inherit; font-weight: inherit; font-stretch: inherit; line-height: inherit; }
input[type="checkbox"], input[type="radio"] { line-height: normal; padding: 0px; }
*, ::after, ::before { box-sizing: border-box; }
#write h1, #write h2, #write h3, #write h4, #write h5, #write h6, #write p, #write pre { width: inherit; }
#write h1, #write h2, #write h3, #write h4, #write h5, #write h6, #write p { position: relative; }
h1, h2, h3, h4, h5, h6 { break-after: avoid-page; break-inside: avoid; orphans: 2; }
p { orphans: 4; }
h1 { font-size: 2rem; }
h2 { font-size: 1.8rem; }
h3 { font-size: 1.6rem; }
h4 { font-size: 1.4rem; }
h5 { font-size: 1.2rem; }
h6 { font-size: 1rem; }
h1, h2, h3, h4, h5, h6 { margin-top: 1rem; margin-bottom: 1rem; }
p { -webkit-margin-before: 1rem; -webkit-margin-after: 1rem; -webkit-margin-start: 0px; -webkit-margin-end: 0px; }
.mathjax-block { margin-top: 0px; margin-bottom: 0px; -webkit-margin-before: 0px; -webkit-margin-after: 0px; }
.hidden { display: none; }
.md-blockmeta { color: rgb(204, 204, 204); font-weight: 700; font-style: italic; }
a { cursor: pointer; }
sup.md-footnote { padding: 2px 4px; background-color: rgba(238, 238, 238, 0.701961); color: rgb(85, 85, 85); border-top-left-radius: 4px; border-top-right-radius: 4px; border-bottom-right-radius: 4px; border-bottom-left-radius: 4px; cursor: pointer; }
sup.md-footnote a, sup.md-footnote a:hover { color: inherit; text-transform: inherit; text-decoration: inherit; }
#write input[type="checkbox"] { cursor: pointer; width: inherit; height: inherit; }
figure { overflow-x: auto; margin: 1.2em 0px; max-width: calc(100% + 16px); padding: 0px; }
figure > table { margin: 0px !important; }
tr { break-inside: avoid; break-after: auto; }
thead { display: table-header-group; }
table { border-collapse: collapse; border-spacing: 0px; width: 100%; overflow: auto; break-inside: auto; text-align: left; }
table.md-table td { min-width: 80px; }
.CodeMirror-gutters { border-right-width: 0px; background-color: inherit; }
.CodeMirror { text-align: left; }
.CodeMirror-placeholder { opacity: 0.3; }
.CodeMirror pre { padding: 0px 4px; }
.CodeMirror-lines { padding: 0px; }
div.hr:focus { cursor: none; }
pre { white-space: pre-wrap; }
pre.contain-cm { white-space: normal; }
.CodeMirror-gutters { margin-right: 4px; }
.md-fences { font-size: 0.9rem; display: block; break-inside: avoid; text-align: left; overflow: visible; white-space: pre; background-image: inherit; background-size: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: inherit; position: relative !important; background-position: inherit inherit; background-repeat: inherit inherit; }
.md-diagram-panel { width: 100%; margin-top: 10px; text-align: center; padding-top: 0px; padding-bottom: 8px; overflow-x: auto; }
.md-fences.mock-cm { white-space: pre-wrap; }
.show-fences-line-number .md-fences { padding-left: 0px; }
.show-fences-line-number .md-fences.mock-cm { padding-left: 40px; }
.CodeMirror-line { break-inside: avoid; }
.footnotes { opacity: 0.8; font-size: 0.9rem; margin-top: 1em; margin-bottom: 1em; }
.footnotes + .footnotes { margin-top: 0px; }
.md-reset { margin: 0px; padding: 0px; border: 0px; outline: 0px; vertical-align: top; text-decoration: none; text-shadow: none; float: none; position: static; width: auto; height: auto; white-space: nowrap; cursor: inherit; line-height: normal; font-weight: 400; text-align: left; box-sizing: content-box; direction: ltr; background-position: 0px 0px; background-repeat: initial initial; }
li div { padding-top: 0px; }
blockquote { margin: 1rem 0px; }
li .mathjax-block, li p { margin: 0.5rem 0px; }
li { margin: 0px; position: relative; }
blockquote > :last-child { margin-bottom: 0px; }
blockquote > :first-child, li > :first-child { margin-top: 0px; }
.footnotes-area { color: rgb(136, 136, 136); margin-top: 0.714rem; padding-bottom: 0.143rem; white-space: normal; }
.footnote-line { white-space: pre-wrap; }
@media print {
body, html { border: 1px solid transparent; height: 99%; break-after: avoid-page; break-before: avoid-page; }
#write { margin-top: 0px; border-color: transparent !important; }
.typora-export * { -webkit-print-color-adjust: exact; }
html.blink-to-pdf { font-size: 13px; }
.typora-export #write { padding-left: 1cm; padding-right: 1cm; padding-bottom: 0px; break-after: avoid-page; }
.typora-export #write::after { height: 0px; }
@page { margin: 20mm 0px; }
}
.footnote-line { margin-top: 0.714em; font-size: 0.7em; }
a img, img a { cursor: pointer; }
pre.md-meta-block { font-size: 0.8rem; min-height: 0.8rem; white-space: pre-wrap; background-color: rgb(204, 204, 204); display: block; overflow-x: hidden; background-position: initial initial; background-repeat: initial initial; }
p > img:only-child { display: block; margin: auto; }
.md-line > .md-image:only-child, p > .md-image:only-child { display: inline-block; width: 100%; text-align: center; }
#write .MathJax_Display { margin: 0.8em 0px 0px; }
.mathjax-block { white-space: pre; overflow: hidden; width: 100%; }
p + .mathjax-block { margin-top: -1.143rem; }
.mathjax-block:not(:empty)::after { display: none; }
[contenteditable="true"]:active, [contenteditable="true"]:focus { outline: 0px; box-shadow: none; }
.md-task-list-item { position: relative; list-style-type: none; }
.task-list-item.md-task-list-item { padding-left: 0px; }
.md-task-list-item > input { position: absolute; top: 0px; left: 0px; margin-left: -1.2em; margin-top: calc(1em - 10px); }
.math { font-size: 1rem; }
.md-toc { min-height: 3.58rem; position: relative; font-size: 0.9rem; border-top-left-radius: 10px; border-top-right-radius: 10px; border-bottom-right-radius: 10px; border-bottom-left-radius: 10px; }
.md-toc-content { position: relative; margin-left: 0px; }
.md-toc-content::after, .md-toc::after { display: none; }
.md-toc-item { display: block; color: rgb(65, 131, 196); }
.md-toc-item a { text-decoration: none; }
.md-toc-inner:hover { }
.md-toc-inner { display: inline-block; cursor: pointer; }
.md-toc-h1 .md-toc-inner { margin-left: 0px; font-weight: 700; }
.md-toc-h2 .md-toc-inner { margin-left: 2em; }
.md-toc-h3 .md-toc-inner { margin-left: 4em; }
.md-toc-h4 .md-toc-inner { margin-left: 6em; }
.md-toc-h5 .md-toc-inner { margin-left: 8em; }
.md-toc-h6 .md-toc-inner { margin-left: 10em; }
@media screen and (max-width: 48em) {
.md-toc-h3 .md-toc-inner { margin-left: 3.5em; }
.md-toc-h4 .md-toc-inner { margin-left: 5em; }
.md-toc-h5 .md-toc-inner { margin-left: 6.5em; }
.md-toc-h6 .md-toc-inner { margin-left: 8em; }
}
a.md-toc-inner { font-size: inherit; font-style: inherit; font-weight: inherit; line-height: inherit; }
.footnote-line a:not(.reversefootnote) { color: inherit; }
.md-attr { display: none; }
.md-fn-count::after { content: "."; }
code, pre, tt { font-family: var(--monospace); }
.md-comment { color: rgb(162, 127, 3); opacity: 0.8; font-family: var(--monospace); }
code { text-align: left; }
a.md-print-anchor { border: none !important; display: inline-block !important; position: absolute !important; width: 1px !important; right: 0px !important; outline: 0px !important; text-shadow: initial !important; background-position: 0px 0px !important; background-repeat: initial initial !important; }
.md-inline-math .MathJax_SVG .noError { display: none !important; }
.mathjax-block .MathJax_SVG_Display { text-align: center; margin: 1em 0px; position: relative; text-indent: 0px; max-width: none; max-height: none; min-height: 0px; min-width: 100%; width: auto; display: block !important; }
.MathJax_SVG_Display, .md-inline-math .MathJax_SVG_Display { width: auto; margin: inherit; display: inline-block !important; }
.MathJax_SVG .MJX-monospace { font-family: monospace; }
.MathJax_SVG .MJX-sans-serif { font-family: sans-serif; }
.MathJax_SVG { display: inline; font-style: normal; font-weight: 400; line-height: normal; zoom: 90%; text-indent: 0px; text-align: left; text-transform: none; letter-spacing: normal; word-spacing: normal; word-wrap: normal; white-space: nowrap; float: none; direction: ltr; max-width: none; max-height: none; min-width: 0px; min-height: 0px; border: 0px; padding: 0px; margin: 0px; }
.MathJax_SVG * { transition: none; }
.os-windows.monocolor-emoji .md-emoji { font-family: "Segoe UI Symbol", sans-serif; }
.md-diagram-panel > svg { max-width: 100%; }
[lang="flow"] svg, [lang="mermaid"] svg { max-width: 100%; }
[lang="mermaid"] .node text { font-size: 1rem; }
table tr th { border-bottom-width: 0px; }
.CodeMirror { height: auto; }
.CodeMirror.cm-s-inner { background-image: inherit; background-size: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: inherit; background-position: inherit inherit; background-repeat: inherit inherit; }
.CodeMirror-scroll { overflow-y: hidden; overflow-x: auto; z-index: 3; }
.CodeMirror-lines { padding: 4px 0px; }
.CodeMirror-gutter-filler, .CodeMirror-scrollbar-filler { background-color: rgb(255, 255, 255); }
.CodeMirror-gutters { border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); background-image: inherit; background-size: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: inherit; white-space: nowrap; background-position: inherit inherit; background-repeat: inherit inherit; }
.CodeMirror-linenumber { padding: 0px 3px 0px 5px; text-align: right; color: rgb(153, 153, 153); }
.cm-s-inner .cm-keyword { color: rgb(119, 0, 136); }
.cm-s-inner .cm-atom, .cm-s-inner.cm-atom { color: rgb(34, 17, 153); }
.cm-s-inner .cm-number { color: rgb(17, 102, 68); }
.cm-s-inner .cm-def { color: rgb(0, 0, 255); }
.cm-s-inner .cm-variable { color: rgb(0, 0, 0); }
.cm-s-inner .cm-variable-2 { color: rgb(0, 85, 170); }
.cm-s-inner .cm-variable-3 { color: rgb(0, 136, 85); }
.cm-s-inner .cm-string { color: rgb(170, 17, 17); }
.cm-s-inner .cm-property { color: rgb(0, 0, 0); }
.cm-s-inner .cm-operator { color: rgb(152, 26, 26); }
.cm-s-inner .cm-comment, .cm-s-inner.cm-comment { color: rgb(170, 85, 0); }
.cm-s-inner .cm-string-2 { color: rgb(255, 85, 0); }
.cm-s-inner .cm-meta { color: rgb(85, 85, 85); }
.cm-s-inner .cm-qualifier { color: rgb(85, 85, 85); }
.cm-s-inner .cm-builtin { color: rgb(51, 0, 170); }
.cm-s-inner .cm-bracket { color: rgb(153, 153, 119); }
.cm-s-inner .cm-tag { color: rgb(17, 119, 0); }
.cm-s-inner .cm-attribute { color: rgb(0, 0, 204); }
.cm-s-inner .cm-header, .cm-s-inner.cm-header { color: rgb(0, 0, 255); }
.cm-s-inner .cm-quote, .cm-s-inner.cm-quote { color: rgb(0, 153, 0); }
.cm-s-inner .cm-hr, .cm-s-inner.cm-hr { color: rgb(153, 153, 153); }
.cm-s-inner .cm-link, .cm-s-inner.cm-link { color: rgb(0, 0, 204); }
.cm-negative { color: rgb(221, 68, 68); }
.cm-positive { color: rgb(34, 153, 34); }
.cm-header, .cm-strong { font-weight: 700; }
.cm-del { text-decoration: line-through; }
.cm-em { font-style: italic; }
.cm-link { text-decoration: underline; }
.cm-error { color: red; }
.cm-invalidchar { color: red; }
.cm-constant { color: rgb(38, 139, 210); }
.cm-defined { color: rgb(181, 137, 0); }
div.CodeMirror span.CodeMirror-matchingbracket { color: rgb(0, 255, 0); }
div.CodeMirror span.CodeMirror-nonmatchingbracket { color: rgb(255, 34, 34); }
.cm-s-inner .CodeMirror-activeline-background { background-image: inherit; background-size: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: inherit; background-position: inherit inherit; background-repeat: inherit inherit; }
.CodeMirror { position: relative; overflow: hidden; }
.CodeMirror-scroll { margin-bottom: -30px; padding-bottom: 30px; height: 100%; outline: 0px; position: relative; box-sizing: content-box; background-image: inherit; background-size: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: inherit; background-position: inherit inherit; background-repeat: inherit inherit; }
.CodeMirror-sizer { position: relative; }
.CodeMirror-gutter-filler, .CodeMirror-hscrollbar, .CodeMirror-scrollbar-filler, .CodeMirror-vscrollbar { position: absolute; z-index: 6; display: none; }
.CodeMirror-vscrollbar { right: 0px; top: 0px; overflow: hidden; }
.CodeMirror-hscrollbar { bottom: 0px; left: 0px; overflow-y: hidden; overflow-x: scroll; }
.CodeMirror-scrollbar-filler { right: 0px; bottom: 0px; }
.CodeMirror-gutter-filler { left: 0px; bottom: 0px; }
.CodeMirror-gutters { position: absolute; left: 0px; top: 0px; padding-bottom: 30px; z-index: 3; }
.CodeMirror-gutter { white-space: normal; height: 100%; box-sizing: content-box; padding-bottom: 30px; margin-bottom: -32px; display: inline-block; }
.CodeMirror-gutter-wrapper { position: absolute; z-index: 4; border: none !important; background-position: 0px 0px !important; background-repeat: initial initial !important; }
.CodeMirror-gutter-background { position: absolute; top: 0px; bottom: 0px; z-index: 4; }
.CodeMirror-gutter-elt { position: absolute; cursor: default; z-index: 4; }
.CodeMirror-lines { cursor: text; }
.CodeMirror pre { border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; border-width: 0px; font-family: inherit; font-size: inherit; margin: 0px; white-space: pre; word-wrap: normal; color: inherit; z-index: 2; position: relative; overflow: visible; background-position: 0px 0px; background-repeat: initial initial; }
.CodeMirror-wrap pre { word-wrap: break-word; white-space: pre-wrap; word-break: normal; }
.CodeMirror-code pre { border-right-width: 30px; border-right-style: solid; border-right-color: transparent; width: fit-content; }
.CodeMirror-wrap .CodeMirror-code pre { border-right-style: none; width: auto; }
.CodeMirror-linebackground { position: absolute; left: 0px; right: 0px; top: 0px; bottom: 0px; z-index: 0; }
.CodeMirror-linewidget { position: relative; z-index: 2; overflow: auto; }
.CodeMirror-wrap .CodeMirror-scroll { overflow-x: hidden; }
.CodeMirror-measure { position: absolute; width: 100%; height: 0px; overflow: hidden; visibility: hidden; }
.CodeMirror-measure pre { position: static; }
.CodeMirror div.CodeMirror-cursor { position: absolute; visibility: hidden; border-right-style: none; width: 0px; }
.CodeMirror div.CodeMirror-cursor { visibility: hidden; }
.CodeMirror-focused div.CodeMirror-cursor { visibility: inherit; }
.cm-searching { background-color: rgba(255, 255, 0, 0.4); background-position: initial initial; background-repeat: initial initial; }
@media print {
.CodeMirror div.CodeMirror-cursor { visibility: hidden; }
}
.CodeMirror-lint-markers { width: 16px; }
.CodeMirror-lint-tooltip { background-color: infobackground; border: 1px solid rgb(0, 0, 0); border-top-left-radius: 4px; border-top-right-radius: 4px; border-bottom-right-radius: 4px; border-bottom-left-radius: 4px; color: infotext; font-family: var(--monospace); overflow: hidden; padding: 2px 5px; position: fixed; white-space: pre-wrap; z-index: 10000; max-width: 600px; opacity: 0; transition: opacity 0.4s; font-size: 0.8em; }
.CodeMirror-lint-mark-error, .CodeMirror-lint-mark-warning { background-position: left bottom; background-repeat: repeat no-repeat; }
.CodeMirror-lint-mark-error { background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAQAAAADCAYAAAC09K7GAAAAAXNSR0IArs4c6QAAAAZiS0dEAP8A/wD/oL2nkwAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB9sJDw4cOCW1/KIAAAAZdEVYdENvbW1lbnQAQ3JlYXRlZCB3aXRoIEdJTVBXgQ4XAAAAHElEQVQI12NggIL/DAz/GdA5/xkY/qPKMDAwAADLZwf5rvm+LQAAAABJRU5ErkJggg==); }
.CodeMirror-lint-marker-error, .CodeMirror-lint-marker-warning { cursor: pointer; display: inline-block; height: 16px; width: 16px; vertical-align: middle; position: relative; background-position: center center; background-repeat: no-repeat no-repeat; }
.CodeMirror-lint-message-error, .CodeMirror-lint-message-warning { padding-left: 18px; background-position: left top; background-repeat: no-repeat no-repeat; }
.CodeMirror-lint-marker-error, .CodeMirror-lint-message-error { background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAAHlBMVEW7AAC7AACxAAC7AAC7AAAAAAC4AAC5AAD///+7AAAUdclpAAAABnRSTlMXnORSiwCK0ZKSAAAATUlEQVR42mWPOQ7AQAgDuQLx/z8csYRmPRIFIwRGnosRrpamvkKi0FTIiMASR3hhKW+hAN6/tIWhu9PDWiTGNEkTtIOucA5Oyr9ckPgAWm0GPBog6v4AAAAASUVORK5CYII=); }
.CodeMirror-lint-marker-warning, .CodeMirror-lint-message-warning { background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAANlBMVEX/uwDvrwD/uwD/uwD/uwD/uwD/uwD/uwD/uwD6twD/uwAAAADurwD2tQD7uAD+ugAAAAD/uwDhmeTRAAAADHRSTlMJ8mN1EYcbmiixgACm7WbuAAAAVklEQVR42n3PUQqAIBBFUU1LLc3u/jdbOJoW1P08DA9Gba8+YWJ6gNJoNYIBzAA2chBth5kLmG9YUoG0NHAUwFXwO9LuBQL1giCQb8gC9Oro2vp5rncCIY8L8uEx5ZkAAAAASUVORK5CYII=); }
.CodeMirror-lint-marker-multiple { background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAcAAAAHCAMAAADzjKfhAAAACVBMVEUAAAAAAAC/v7914kyHAAAAAXRSTlMAQObYZgAAACNJREFUeNo1ioEJAAAIwmz/H90iFFSGJgFMe3gaLZ0od+9/AQZ0ADosbYraAAAAAElFTkSuQmCC); width: 100%; height: 100%; background-position: right bottom; background-repeat: no-repeat no-repeat; }
:root {
--side-bar-bg-color: #fafafa;
--control-text-color: #777;
}
@include-when-export url(https://fonts.googleapis.com/css?family=Open+Sans:400italic,700italic,700,400&subset=latin,latin-ext);
@font-face {
font-family: 'Open Sans';
font-style: normal;
font-weight: normal;
src: local('Open Sans Regular'),url('file:///Users/lee/Library/Application%20Support/abnerworks.Typora/themes/github/400.woff') format('woff')
}
@font-face {
font-family: 'Open Sans';
font-style: italic;
font-weight: normal;
src: local('Open Sans Italic'),url('file:///Users/lee/Library/Application%20Support/abnerworks.Typora/themes/github/400i.woff') format('woff')
}
@font-face {
font-family: 'Open Sans';
font-style: normal;
font-weight: bold;
src: local('Open Sans Bold'),url('file:///Users/lee/Library/Application%20Support/abnerworks.Typora/themes/github/700.woff') format('woff')
}
@font-face {
font-family: 'Open Sans';
font-style: italic;
font-weight: bold;
src: local('Open Sans Bold Italic'),url('file:///Users/lee/Library/Application%20Support/abnerworks.Typora/themes/github/700i.woff') format('woff')
}
html {
font-size: 16px;
}
body {
font-family: "Open Sans","Clear Sans","Helvetica Neue",Helvetica,Arial,sans-serif;
color: rgb(51, 51, 51);
line-height: 1.6;
}
#write{
max-width: 860px;
margin: 0 auto;
padding: 20px 30px 40px 30px;
padding-top: 20px;
padding-bottom: 100px;
}
#write > ul:first-child,
#write > ol:first-child{
margin-top: 30px;
}
body > *:first-child {
margin-top: 0 !important;
}
body > *:last-child {
margin-bottom: 0 !important;
}
a {
color: #4183C4;
}
h1,
h2,
h3,
h4,
h5,
h6 {
position: relative;
margin-top: 1rem;
margin-bottom: 1rem;
font-weight: bold;
line-height: 1.4;
cursor: text;
}
h1:hover a.anchor,
h2:hover a.anchor,
h3:hover a.anchor,
h4:hover a.anchor,
h5:hover a.anchor,
h6:hover a.anchor {
/*background: url("file:///Users/lee/Library/Application%20Support/images/modules/styleguide/para.png") no-repeat 10px center;*/
text-decoration: none;
}
h1 tt,
h1 code {
font-size: inherit;
}
h2 tt,
h2 code {
font-size: inherit;
}
h3 tt,
h3 code {
font-size: inherit;
}
h4 tt,
h4 code {
font-size: inherit;
}
h5 tt,
h5 code {
font-size: inherit;
}
h6 tt,
h6 code {
font-size: inherit;
}
h1 {
padding-bottom: .3em;
font-size: 2.25em;
line-height: 1.2;
border-bottom: 1px solid #eee;
}
h2 {
padding-bottom: .3em;
font-size: 1.75em;
line-height: 1.225;
border-bottom: 1px solid #eee;
}
h3 {
font-size: 1.5em;
line-height: 1.43;
}
h4 {
font-size: 1.25em;
}
h5 {
font-size: 1em;
}
h6 {
font-size: 1em;
color: #777;
}
p,
blockquote,
ul,
ol,
dl,
table{
margin: 0.8em 0;
}
li>ol,
li>ul {
margin: 0 0;
}
hr {
height: 2px;
padding: 0;
margin: 16px 0;
background-color: #e7e7e7;
border: 0 none;
overflow: hidden;
box-sizing: content-box;
}
body > h2:first-child {
margin-top: 0;
padding-top: 0;
}
body > h1:first-child {
margin-top: 0;
padding-top: 0;
}
body > h1:first-child + h2 {
margin-top: 0;
padding-top: 0;
}
body > h3:first-child,
body > h4:first-child,
body > h5:first-child,
body > h6:first-child {
margin-top: 0;
padding-top: 0;
}
a:first-child h1,
a:first-child h2,
a:first-child h3,
a:first-child h4,
a:first-child h5,
a:first-child h6 {
margin-top: 0;
padding-top: 0;
}
h1 p,
h2 p,
h3 p,
h4 p,
h5 p,
h6 p {
margin-top: 0;
}
li p.first {
display: inline-block;
}
ul,
ol {
padding-left: 30px;
}
ul:first-child,
ol:first-child {
margin-top: 0;
}
ul:last-child,
ol:last-child {
margin-bottom: 0;
}
blockquote {
border-left: 4px solid #dfe2e5;
padding: 0 15px;
color: #777777;
}
blockquote blockquote {
padding-right: 0;
}
table {
padding: 0;
word-break: initial;
}
table tr {
border-top: 1px solid #dfe2e5;
margin: 0;
padding: 0;
}
table tr:nth-child(2n),
thead {
background-color: #f8f8f8;
}
table tr th {
font-weight: bold;
border: 1px solid #dfe2e5;
border-bottom: 0;
text-align: left;
margin: 0;
padding: 6px 13px;
}
table tr td {
border: 1px solid #dfe2e5;
text-align: left;
margin: 0;
padding: 6px 13px;
}
table tr th:first-child,
table tr td:first-child {
margin-top: 0;
}
table tr th:last-child,
table tr td:last-child {
margin-bottom: 0;
}
.CodeMirror-gutters {
border-right: 1px solid #ddd;
}
.md-fences,
code,
tt {
border: 1px solid #dfe2e5;
background-color: #f8f8f8;
border-radius: 3px;
padding: 0;
font-family: Consolas, "Liberation Mono", Courier, monospace;
padding: 2px 4px 0px 4px;
font-size: 0.9em;
}
.md-fences {
margin-bottom: 15px;
margin-top: 15px;
padding: 0.2em 1em;
padding-top: 8px;
padding-bottom: 6px;
}
.md-task-list-item > input {
margin-left: -1.3em;
}
@media screen and (min-width: 914px) {
/*body {
width: 854px;
margin: 0 auto;
}*/
}
@media print {
html {
font-size: 13px;
}
table,
pre {
page-break-inside: avoid;
}
pre {
word-wrap: break-word;
}
}
.md-fences {
background-color: #f8f8f8;
}
#write pre.md-meta-block {
padding: 1rem;
font-size: 85%;
line-height: 1.45;
background-color: #f7f7f7;
border: 0;
border-radius: 3px;
color: #777777;
margin-top: 0 !important;
}
.mathjax-block>.code-tooltip {
bottom: .375rem;
}
#write>h3.md-focus:before{
left: -1.5625rem;
top: .375rem;
}
#write>h4.md-focus:before{
left: -1.5625rem;
top: .285714286rem;
}
#write>h5.md-focus:before{
left: -1.5625rem;
top: .285714286rem;
}
#write>h6.md-focus:before{
left: -1.5625rem;
top: .285714286rem;
}
.md-image>.md-meta {
/*border: 1px solid #ddd;*/
border-radius: 3px;
font-family: Consolas, "Liberation Mono", Courier, monospace;
padding: 2px 0px 0px 4px;
font-size: 0.9em;
color: inherit;
}
.md-tag{
color: inherit;
}
.md-toc {
margin-top:20px;
padding-bottom:20px;
}
.sidebar-tabs {
border-bottom: none;
}
#typora-quick-open {
border: 1px solid #ddd;
background-color: #f8f8f8;
}
#typora-quick-open-item {
background-color: #FAFAFA;
border-color: #FEFEFE #e5e5e5 #e5e5e5 #eee;
border-style: solid;
border-width: 1px;
}
#md-notification:before {
top: 10px;
}
/** focus mode */
.on-focus-mode blockquote {
border-left-color: rgba(85, 85, 85, 0.12);
}
header, .context-menu, .megamenu-content, footer{
font-family: "Segoe UI", "Arial", sans-serif;
}
.file-node-content:hover .file-node-icon,
.file-node-content:hover .file-node-open-state{
visibility: visible;
}
.mac-seamless-mode #typora-sidebar {
background-color: #fafafa;
background-color: var(--side-bar-bg-color);
}
.md-lang {
color: #b4654d;
}
.html-for-mac .context-menu {
--item-hover-bg-color: #E6F0FE;
}
.typora-export p, .typora-export .footnote-line {white-space: normal;}
</style>
</head>
<body class='typora-export' >
<div id='write' class = 'is-mac'><h1><a name='header-n0' class='md-header-anchor '></a>Facebook广告投放自动化需求1.0(流川枫)</h1><h2><a name='header-n2' class='md-header-anchor '></a>目录</h2><ul><li><p><a href='#facebook%E5%B9%BF%E5%91%8A%E6%8A%95%E6%94%BE%E8%87%AA%E5%8A%A8%E5%8C%96%E9%9C%80%E6%B1%8210%E6%B5%81%E5%B7%9D%E6%9E%AB'>Facebook广告投放自动化需求1.0(流川枫)</a></p><ul><li><p><a href='#header-n2'>目录</a></p></li><li><p><a href='#header-n235'>项目概述</a></p><ul><li><p><a href='#header-n236'>需求背景</a></p><ul><li><a href='#header-n241'>项目目标</a></li></ul></li><li><p><a href='#header-n261'>规划和进度</a></p><ul><li><a href='#header-n262'>系统规划</a></li><li><a href='#header-n286'>进度</a></li></ul></li></ul></li><li><p><a href='#header-n318'>功能需求</a></p><ul><li><p><a href='#header-n319'>创建</a></p><ul><li><p><a href='#%E6%89%B9%E9%87%8F%E5%88%9B%E5%BB%BA%E4%B8%80%E6%9C%9F%E5%8A%9F%E8%83%BD'>批量创建(一期功能)</a></p><ul><li><p><a href='#header-n321'>功能背景</a></p></li><li><p><a href='#header-n340'>流程图</a></p></li><li><p><a href='#header-n343'>原型图</a></p></li><li><p><a href='#header-n348'>前端需求</a></p></li><li><p><a href='#header-n355'>后端需求</a></p></li><li><p><a href='#header-n403'>基本信息</a></p><ul><li><a href='#%E9%80%89%E6%8B%A9%E5%B9%BF%E5%91%8A%E8%B4%A6%E6%88%B7%E5%BA%94%E7%94%A8'>选择广告账户、应用</a></li><li><a href='#header-n415'>创建名称</a></li></ul></li><li><p><a href='#header-n422'>投放信息</a></p><ul><li><a href='#header-n453'>新建模板</a></li><li><a href='#header-n486'>模板结构</a></li><li><a href='#header-n493'>字段对应关系</a></li><li><a href='#header-n527'>名称组成规则</a></li><li><a href='#header-n604'>审核规则</a></li><li><a href='#header-n638'>国家代码转换规则</a></li></ul></li><li><p><a href='#header-n643'>素材选择</a></p><ul><li><a href='#header-n648'>选择方式</a></li><li><a href='#header-n663'>关联素材</a></li><li><a href='#header-n686'>广告创建规则</a></li></ul></li><li><p><a href='#%E5%B9%BF%E5%91%8A%E8%B4%A6%E6%88%B7%E5%BA%94%E7%94%A8%E5%88%97%E8%A1%A8'>广告账户、应用列表</a></p></li><li><p><a href='#header-n735'>前后端交互</a></p><ul><li><a href='#%E6%B5%81%E7%A8%8B%E5%9B%BE-1'>流程图</a></li><li><a href='#header-n739'>json结构</a></li><li><a href='#header-n744'>json字段表</a></li><li><a href='#%E4%B8%8A%E4%BC%A0%E6%89%80%E9%9C%80%E6%8E%A5%E5%8F%A3%E5%8F%82%E8%80%83%E6%96%87%E6%A1%A3'>上传所需接口、参考文档</a></li><li><a href='#header-n871'>创建所需字段处理方法</a></li></ul></li></ul></li><li><p><a href='#%E7%B4%A0%E6%9D%90%E5%BA%93%E4%B8%80%E6%9C%9F%E5%8A%9F%E8%83%BD'>素材库(一期功能)</a></p><ul><li><p><a href='#%E9%9C%80%E6%B1%82%E8%83%8C%E6%99%AF-1'>需求背景</a></p><ul><li><a href='#%E6%B5%81%E7%A8%8B%E5%9B%BE-2'>流程图</a></li><li><a href='#%E5%8E%9F%E5%9E%8B%E5%9B%BE-1'>原型图</a></li></ul></li><li><p><a href='#%E7%B4%A0%E6%9D%90%E4%B8%8A%E4%BC%A0%E4%BD%BF%E7%94%A8'>素材上传&使用</a></p><ul><li><a href='#header-n1094'>素材使用</a></li><li><a href='#header-n1105'>素材库管理</a></li></ul></li></ul></li></ul></li><li><p><a href='#header-n1124'>投放</a></p><ul><li><p><a href='#header-n1125'>数据查看</a></p><ul><li><a href='#%E5%8A%9F%E8%83%BD%E8%83%8C%E6%99%AF-1'>功能背景</a></li><li><a href='#header-n1134'>查看数据</a></li><li><a href='#%E6%95%B0%E6%8D%AE%E7%AD%9B%E9%80%89%E6%8E%92%E5%BA%8F'>数据筛选、排序</a></li><li><a href='#%E5%8E%9F%E5%9E%8B%E5%9B%BE-2'>原型图</a></li></ul></li><li><p><a href='#header-n1165'>投放规则</a></p><ul><li><a href='#%E6%B5%81%E7%A8%8B%E5%9B%BE-3'>流程图</a></li></ul></li></ul></li></ul></li><li><p><a href='#header-n1178'>非功能需求</a></p><ul><li><a href='#header-n1179'>账号管理</a></li></ul></li><li><p><a href='#header-n1186'>附录</a></p><ul><li><p><a href='#header-n1187'>Token手动获得方式</a></p></li><li><p><a href='#header-n1190'>生成长期Token</a></p></li><li><p><a href='#header-n1209'>Business Manager平台</a></p><ul><li><p><a href='#header-n1218'>查看自有帐户</a></p></li><li><p><a href='#header-n1225'>查看商务管理平台拥有的应用</a></p></li><li><p><a href='#header-n1231'>认领应用</a></p></li><li><p><a href='#header-n1234'>生成token</a></p></li><li><p><a href='#header-n1239'>项目</a></p><ul><li><a href='#header-n1255'>项目的广告帐户</a></li><li><a href='#header-n1265'>项目的应用</a></li></ul></li><li><p><a href='#header-n1277'>给用户分配广告账户</a></p><ul><li><a href='#header-n1280'>管理用户和身份</a></li><li><a href='#header-n1300'>邀请用户</a></li><li><a href='#header-n1313'>添加用户到帐户</a></li></ul></li></ul></li></ul></li></ul></li></ul><p> </p><h2><a name='header-n235' class='md-header-anchor '></a>项目概述</h2><h3><a name='header-n236' class='md-header-anchor '></a>需求背景</h3><p>在日常的投放中发现并Facebook的人确认过后,确定在FB投放的每个广告和素材都能拿到一定的基础展示,所以想用自动化的手段来增加素材、广告的数量,目的是增加投放展示。</p><p>Facebook 营销API中提供了很多接口可以解决目前投放中遇到的问题(如批量创建、数据管理等)、提高投放的效率(自动投放),所以需要一个后台系统来调用API。</p><h4><a name='header-n241' class='md-header-anchor '></a>项目目标</h4><p>成本可控的情况下,通过自动化提高广告投放的数量,获得更多的展示</p><h4><a name='header-n244' class='md-header-anchor '></a>相关数据</h4><p><img src='./img/广告数量与展示的关系.png' alt='广告数量与展示的关系' referrerPolicy='no-referrer' /></p><p>取值范围:6月1日-8月1日的白牌投放数据</p><p>样本量:8个广告账号,3898个广告</p><p>impression:当天所有广告所拿到的展示量之和</p><p>广告数量:当天处于激活状态的广告数量</p><ul><li><strong>结论:广告数量和展示量有强关联</strong> </li></ul><p> </p><h3><a name='header-n261' class='md-header-anchor '></a>规划和进度</h3><h4><a name='header-n262' class='md-header-anchor '></a>系统规划</h4><p><img src='./img/整体逻辑1.jpg' alt='整体逻辑1' referrerPolicy='no-referrer' /></p><p><img src='./img/整体逻辑2.jpg' alt='整体逻辑2' referrerPolicy='no-referrer' /></p><ul><li>投放自动化流程</li></ul><ol start='' ><li>多渠道素材采集</li><li>批量创建广告</li><li>根据情况、算法实时调整出价</li><li>数据管理、查看投放效果</li></ol><p> </p><h4><a name='header-n1426' class='md-header-anchor '></a>系统逻辑</h4><p><img src='/Users/lee/Downloads/投放自动化逻辑 (6).png' alt='投放自动化逻辑 (6)' referrerPolicy='no-referrer' /></p><p> </p><h4><a name='header-n286' class='md-header-anchor '></a>进度</h4><ul><li><strong>第一期:(8月初上线)</strong></li></ul><p>新主题盲测批量创建</p><blockquote><p>目前进度:开发中</p></blockquote><ul><li><strong>第二期:(8月中旬)</strong></li></ul><p>新主题自动化投放,应用rule,接入商业LTV数据,数据查看</p><blockquote><p>目前进度:正在整理规则,商业LTV数据接口需求已提</p></blockquote><ul><li><strong>第二期:(8月底)</strong></li></ul><p>接入CM design接口、图片拼接</p><p>素材生产自动化,扩大素材数量级</p><blockquote><p>目前进度:—</p></blockquote><p> </p><h2><a name='header-n318' class='md-header-anchor '></a>功能需求</h2><h3><a name='header-n319' class='md-header-anchor '></a>创建</h3><h4><a name='header-n320' class='md-header-anchor '></a>批量创建(一期功能)</h4><h5><a name='header-n321' class='md-header-anchor '></a>功能背景</h5><p>1.提高投放效率</p><p>因为Launcher是以主题为单位来进行投放的,每周都会有新主题进行投放。而在一个新主题的投放工作里,最为繁琐重复的就是创建广告功能。所以需要批量上传工具来提升运营投放效率。</p><p>2.跑通自动化投放流程</p><p>投放自动化需求中,最基本的需求就是利用API进行广告的创建,后期会有各种不同场景的自动创建广告需求,所以首先需要验证的就是创建功能。</p><p> </p><ul><li>解决思路</li></ul><p>在Ad这一级,通过选择素材的数量直接决定广告的数量,减去Ad这一级之后,需要提供信息就只有Campaign和Adset层级。而投放信息通过将部分字段写死,另外一部分字段通过模板复用,从而减少了投放信息的维护。</p><p> </p><h5><a name='header-n340' class='md-header-anchor '></a>流程图</h5><p><img src='./img/整体流程.png' alt='整体流程' referrerPolicy='no-referrer' /></p><h5><a name='header-n343' class='md-header-anchor '></a>原型图</h5><p><a href='https://motodriver.github.io/demo/%E5%8E%9F%E5%9E%8B%E5%9B%BE/index.html'>原型图链接</a></p><p> </p><h5><a name='header-n348' class='md-header-anchor '></a>前端需求</h5><p>1.批量创建功能界面</p><p>2.素材库</p><p> </p><h5><a name='header-n355' class='md-header-anchor '></a>后端需求</h5><p>1.创建广告接口</p><p>后端接收到来自前端的json请求后解析,将信息分为四类(Campaign,Adset,Ad,Adcreative),并且按照顺序上传创建广告。</p><blockquote><p>预留点</p><ul><li>能接收创建各层级(Campaign到Adcreative层级)的单独创建请求的接口。</li><li>能向已有的Campaign中创建广告组、广告(如果前端返回了Campaign id这个字段,就在对应的Campaign中创建。</li></ul></blockquote><p> </p><p>2.素材库的建立;前端上传完素材后,需要将素材上传到Facebook服务器,并将返回的素材id和文件一一对应。</p><p> </p><p>3.拉取广告账户、应用列表的接口</p><blockquote><p>预留点</p><ul><li>BM平台的Admin权限下来之后,广告账户和应用的拉取,将实时通过Facebook API来完成</li><li>这个功能放在最后做,这两周之内我会尽量申请到权限</li></ul></blockquote><p> </p><p>4.测试广告账户、应用是否有关联的接口</p><blockquote><p>预留点</p><ul><li>关联关系可能会在之后的拉取数据功能中用到,所以需要找个地方存起来。</li></ul></blockquote><p>5.投放信息模板拉取</p><p> </p><h5><a name='header-n403' class='md-header-anchor '></a>基本信息</h5><p>维护上传所需的基本信息。</p><p> </p><h6><a name='header-n408' class='md-header-anchor '></a>选择广告账户、应用</h6><p>选择本次创建要使用的广告账户,以及关联的应用。</p><p>账号、应用列表从后端拉取。</p><p> </p><h6><a name='header-n415' class='md-header-anchor '></a>创建名称</h6><p>由运营创建时手动输入,作为正式上传名称的一部分字符串,后面选择投放信息应用模板时在前端合成正式名称。</p><p>合成规则在【名称组成规则】中详叙。</p><p> </p><h5><a name='header-n422' class='md-header-anchor '></a>投放信息</h5><p>投放信息以模板形式上传,运营在在前端填写完模板后,储存在后端,每个用户的模板是独立储存的。</p><p>每次批量创建都可以选择之前填写的模板,需要前端提供一个编辑、删除模板的入口,新增模板的入口在选择模板的边上。</p><blockquote><p><strong>为什么要使用模板上传</strong></p><p>每次新主题创建广告所需要的信息(不包括素材),其实是有很大的重复的,按照能复用的频率来看,能分成三种信息</p><figure><table><thead><tr><th>类型</th><th>信息</th><th>处理方式</th></tr></thead><tbody><tr><td>一定要上传的</td><td>基本信息(应用名、账号Id)</td><td>每次上传填写或选用</td></tr><tr><td>大概率能复用</td><td>名称,出价,国家等字段</td><td>使用模板方式来复用</td></tr><tr><td>一定能复用的</td><td>竞价方式等</td><td>写死在后端</td></tr></tbody></table></figure><p>使用模板后,大部分时间只需要维护一定要上传的这部分信息,这样就提高了创建的效率。</p></blockquote><p> </p><h6><a name='header-n453' class='md-header-anchor '></a>新建模板</h6><ul><li>模板名称</li></ul><p>手动输入模板名称</p><ul><li>新建广告系列</li></ul><p>手动输入广告系列名称</p><ul><li>新建所属的广告组</li></ul><p>输入创建广告组所需的字段,有两种信息输入方式</p><p>1.手动输入信息,点击'新增广告组'则增加空白行。</p><p>2.通过Excel粘贴批量输入,分隔符为\t</p><p>注意:不输入任何广告组也可以提交进入下一步。</p><ul><li>显示信息</li></ul><p>显示已创建的广告系列名称和对应的广告组数量,每一行边上有删除按钮</p><p><br/></p><h6><a name='header-n486' class='md-header-anchor '></a>模板结构</h6><p>新建模板后,以如下结构的json储存在前端。</p><p><img src='./img/模板结构.png' alt='模板结构' referrerPolicy='no-referrer' /></p><p> </p><h6><a name='header-n493' class='md-header-anchor '></a>字段对应关系</h6><p>模板中的字段需要转换后放在给后端的json中,转换关系如下:</p><figure><table><thead><tr><th>模板中字段名称</th><th>对应给后端的字段</th><th>处理方法</th></tr></thead><tbody><tr><td>广告系列名称</td><td>Campaign:name</td><td>模板中的名称只是作为合成上传名称的部分字符串,和其他名称一起组成上传的名称</td></tr><tr><td>广告组名称</td><td>AdSet:name</td><td>模板中的名称只是作为合成上传名称的部分字符串,和其他名称一起组成上传的名称</td></tr><tr><td>国家</td><td>AdSet:targeting:countries</td><td>单选的国家按照附1【国家-国家代码对应关系】转换后上传即可,单选'全球'则;多选的国家需要用英文逗号拆分后转换为国家代码加入 country_groups中</td></tr><tr><td>出价</td><td>AdSet:bid_amount</td><td>传入即可</td></tr><tr><td>单日预算</td><td>AdSet:daily_budget</td><td>需要将数值转换后传入,例:10转换为1000</td></tr><tr><td>加速状态</td><td>AdSet:pacing_type</td><td>加速:<code>no_pacing</code> 匀速:<code>standard</code></td></tr></tbody></table></figure><p> </p><h6><a name='header-n527' class='md-header-anchor '></a>名称组成规则</h6><p>正式用API上传的名称,是由运营填写/选择的字段拼接而成的,拼接规则如下。</p><figure><table><thead><tr><th>名称</th><th>组成规则</th><th>对应字段</th></tr></thead><tbody><tr><td>广告系列名称</td><td>关联应用名称+创建名称+模板中的广告系列名称</td><td>Campaign:name</td></tr><tr><td>广告组名称</td><td>关联应用名称+创建名称+模板中的广告系列名称+模板中广告组名称</td><td>AdSet.Field:name</td></tr><tr><td>广告名称</td><td>关联应用名称+创建名称+模板中的广告系列名称+模板中广告组名称+关联素材文件编号</td><td>Ad:name</td></tr></tbody></table></figure><blockquote><p>广告系列、广告组名称创建示例</p></blockquote><ul><li>关联应用名称为:3D cute cat</li><li>创建名称为:盲测</li><li>模板中的广告系列名为:一类国家</li><li>模板中的广告组名为:美国</li></ul><p>则正式上传的广告系列名称为 <strong>3D cute cat 盲测 一类国家</strong></p><p>广告组名称为<strong>3D cute cat 盲测 一类国家 美国</strong></p><hr /><p><strong>广告名称=广告组名称+视频编号+封面图编号</strong>(选择视频+封面图情况)</p><p><strong>广告名称=广告组名称+图片编号</strong>(选择图片情况)</p><p><strong>广告名称=广告组名称+视频编号</strong>(选择视频情况)</p><blockquote><p>广告名称创建示例</p></blockquote><ul><li>广告组名称为<strong>3D cute cat 盲测 一类国家 美国</strong></li><li>关联的素材为:</li></ul><blockquote><p>标题:3D cute cat
文案1:<strong></strong>
视频:视频1、视频2</p><p>封面图:封面图1、封面图2</p></blockquote><p>则这个广告组下产生的4个广告(更详细的广告创建规则参考【广告创建规则】,这里只解释名称创建规则)分别名为:</p><blockquote><ul><li>3D cute cat 盲测 一类国家 美国 V1 C1</li><li>3D cute cat 盲测 一类国家 美国 V1 C2</li><li>3D cute cat 盲测 一类国家 美国 V1 C1</li><li>3D cute cat 盲测 一类国家 美国 V2 C2</li></ul></blockquote><p> </p><h6><a name='header-n604' class='md-header-anchor '></a>审核规则</h6><p>模板中的信息需要审核后再储存,审核规则如下。</p><figure><table><thead><tr><th>模板中字段名称</th><th>对应投放信息字段</th><th>审核规则</th></tr></thead><tbody><tr><td>广告系列名称</td><td>Campaign.name</td><td>不用审核</td></tr><tr><td>广告组名称</td><td>AdSet.Field.name</td><td>不用审核</td></tr><tr><td>国家</td><td>AdSet.Field.targeting:countries</td><td>检查中文国家名称是否在【国家-国家代码对应关系】中,多选国家需要拆开后检查</td></tr><tr><td>出价</td><td>AdSet.bid_amount</td><td>出价<=2</td></tr><tr><td>单日预算</td><td>AdSet.Field.daily_budget</td><td>单日预算>0</td></tr><tr><td>加速状态</td><td>AdSet.Field.pacing_type</td><td>只能为:''匀速'' 或 ''加速''</td></tr></tbody></table></figure><p> </p><h6><a name='header-n638' class='md-header-anchor '></a>国家代码转换规则</h6><p>在需求文档-附录-国家代码转换规则里,需求文档同目录里有csv版本。</p><p> </p><h5><a name='header-n643' class='md-header-anchor '></a>素材选择</h5><p>通过选择素材的数量,直接在选定的广告组下创建对应数量的广告。</p><p> </p><h6><a name='header-n648' class='md-header-anchor '></a>选择方式</h6><ul><li>通过广告系列选择</li></ul><p>选择一个广告系列则是选中了其所属的所有广告组,下拉列表框,可以多选,可以全选。</p><ul><li>通过广告组选择</li></ul><p>广告组选择,下拉列表框,可以多选,可以全选。</p><p> </p><h6><a name='header-n663' class='md-header-anchor '></a>关联素材</h6><p>标题、文案需要每次关联时输入,都只支持单个,不支持一次关联多个标题、文案。</p><p>有三种素材关联方式:</p><p>这三种方式互斥,只能单选,不能多选。</p><p>被选择的图片、视频、封面图需要从后端拉取,图片、封面图需要拉取缩略图和文件名;视频最好可以拉取首帧和文件名,实现难度大的话拉取文件名即可。</p><ul><li>选择图片</li><li>选择视频</li><li>选择视频+封面图</li></ul><p>关联完成后,将对应的素材编号(不是文件名,是素材对应的Facebook素材编号!)传入json中。</p><p> </p><h6><a name='header-n686' class='md-header-anchor '></a>广告创建规则</h6><ul><li>选择图片</li></ul><p>可单选可多选,选择几张图片则在选定的广告组创建几个广告。</p><p><strong>创建数量 = 图片数量</strong></p><ul><li>选择视频</li></ul><p>可单选可多选,选择几张视频则在选定的广告组创建几个广告。</p><p><strong>创建数量 = 视频数量</strong></p><ul><li>选择视频+封面图</li></ul><p>视频、封面图都是必选,选择后创建视频、封面图排列组合的广告。</p><p><strong>创建数量 = 视频数量*封面图数量</strong></p><blockquote><p>例:</p><p>选择了视频1、视频2</p><p>封面图1、封面图2</p><p>则在对应的广告组下创建:</p><p>视频1-封面图1</p><p>视频1-封面图2</p><p>视频2-封面图1</p><p>视频2-封面图2</p></blockquote><p> </p><h5><a name='header-n730' class='md-header-anchor '></a>广告账户、应用列表</h5><p>列表通过Business Manger API拉取,具体方法可以参考<a href=''>参考文档</a>或需求文档附录中【Business Manager】一节。</p><p> </p><h5><a name='header-n735' class='md-header-anchor '></a>前后端交互</h5><h6><a name='header-n736' class='md-header-anchor '></a>流程图</h6><p><img src='./img/后端流程图.png' alt='后端流程图' referrerPolicy='no-referrer' /></p><h6><a name='header-n739' class='md-header-anchor '></a>json结构</h6><p>json结构需要前后端协商制定。</p><p> </p><h6><a name='header-n744' class='md-header-anchor '></a>json字段表</h6><figure><table><thead><tr><th>字段名称(key)</th><th>字段值(value)</th><th>字段类型</th></tr></thead><tbody><tr><td>AD_ACCOUNT_ID</td><td>账号编号</td><td>string</td></tr><tr><td>APP_ID</td><td>应用编号</td><td>int</td></tr><tr><td>Campaign_info</td><td>Campaign信息构成的字典</td><td>dict</td></tr><tr><td>生成的Campaign名称</td><td>对应Campaign信息构成的字典</td><td>dict</td></tr><tr><td>Adset_info</td><td>Adset信息构成的字典</td><td>dict</td></tr><tr><td>生成的Adset名称</td><td>对应Adset信息构成的字典</td><td>dict</td></tr><tr><td>AdSet_bid_amount</td><td>对应广告组的出价</td><td>float</td></tr><tr><td>AdSet_daily_budget</td><td>对应广告组的单日预算</td><td>int</td></tr><tr><td>AdSet_pacing_type</td><td>对应广告组的加速状态</td><td>string</td></tr><tr><td>AdSet_targeting:country</td><td>对应广告组的目标国家(单选国家情况)</td><td>string</td></tr><tr><td>AdSet_targeting:countries</td><td>对应广告组的目标国家(多选国家情况)</td><td>list</td></tr><tr><td>AdSet_targeting:rule</td><td>自定义受众:除了安装关联应用的受众</td><td>string</td></tr><tr><td>Ad_info</td><td>Ad信息构成的字典</td><td>dict</td></tr><tr><td>生成的Ad名称</td><td>对应Ad信息构成的字典</td><td>dict</td></tr><tr><td>Ad_title</td><td>运营填写的标题(会有多语言)</td><td>string</td></tr><tr><td>Ad_text</td><td>运营填写的文案(会有多语言)</td><td>string</td></tr><tr><td>Ad_image_id</td><td>Facebook素材库中的图片编号</td><td>string</td></tr><tr><td>Ad_video_id</td><td>Facebook素材库中的视频编号</td><td>string</td></tr><tr><td>Ad_cover_id</td><td>Facebook素材库中的封面图编号</td><td>string</td></tr><tr><td>Ad_app_link</td><td>关联应用的Google play链接</td><td>string</td></tr></tbody></table></figure><p> </p><h6><a name='header-n832' class='md-header-anchor '></a>上传所需接口、参考文档</h6><figure><table><thead><tr><th>层级</th><th>说明</th><th>上传说明</th><th>库</th><th>接口</th><th>参考文档地址</th></tr></thead><tbody><tr><td>Campaign</td><td>广告系列</td><td>创建后,返回Campaign ID</td><td>facebookads.adobjects.adaccount.AdAccount</td><td>create_campaign</td><td><a href='https://developers.facebook.com/docs/marketing-api/reference/ad-campaign-group'>Campaign</a></td></tr><tr><td>Adset</td><td>广告组</td><td>使用返回的Campaign ID创建Adset</td><td>facebookads.adobjects.adset.AdSet</td><td>adset.update</td><td><a href='https://developers.facebook.com/docs/marketing-api/reference/ad-campaign'>Ad set</a></td></tr><tr><td>Ad</td><td>广告</td><td>使用返回的Ad set ID和广告创意创建Adset</td><td>facebookads.adobjects.adaccount.AdAccount</td><td>create_ad</td><td><a href='https://developers.facebook.com/docs/marketing-api/reference/adgroup'>Ad</a></td></tr><tr><td>Adcreative</td><td>广告创意(素材)</td><td>会从后端收到素材id,使用素材id创建广告创意</td><td>facebookads.adobjects.adaccount.AdAccount</td><td>create_ad_creative</td><td><a href='https://developers.facebook.com/docs/marketing-api/reference/ad-creative'>Ad creative</a></td></tr></tbody></table></figure><p> </p><h6><a name='header-n871' class='md-header-anchor '></a>创建所需字段处理方法</h6><p>创建所需字段,包括了一部分写死的字段的处理方法。</p><figure><table><thead><tr><th>创建层级</th><th>所需字段</th><th>含义</th><th>字段来源</th><th>参考文档</th></tr></thead><tbody><tr><td>广告系列(Campaign)</td><td>Campaign.name</td><td>广告系列名称</td><td>前端</td><td> </td></tr><tr><td> </td><td>Campaign.objective</td><td>营销目标</td><td>默认为: APP_INSTALLS</td><td> </td></tr><tr><td> </td><td>Campaign.status</td><td>广告系列状态</td><td>批量上传时为Pause,所有上传完成后Active</td><td> </td></tr><tr><td>广告组(Adset)</td><td>AdSet.Field.name</td><td>广告组名称</td><td>前端</td><td> </td></tr><tr><td> </td><td>AdSet.Field.campaign_id</td><td>广告系列编号</td><td>自动连线,创建Campaign时获取</td><td> </td></tr><tr><td> </td><td>AdSet.Field.daily_budget</td><td>单日预算</td><td>前端</td><td> </td></tr><tr><td> </td><td>AdSet.Field.billing_event</td><td>计费方式</td><td>默认为:impression</td><td> </td></tr><tr><td> </td><td>AdSet.Field.optimization_goal</td><td>优化目标</td><td>默认为:APP_INSTALLS</td><td> </td></tr><tr><td> </td><td>AdSet.Field.bid_amount</td><td>出价</td><td>前端</td><td> </td></tr><tr><td> </td><td>AdSet.Field.start_time</td><td>开始时间</td><td>自动取上传当天的日期</td><td> </td></tr><tr><td> </td><td>AdSet.Field</td><td>结束时间</td><td>默认为:长期</td><td> </td></tr><tr><td> </td><td>AdSet.Field.pacing_type</td><td>加速状态</td><td>前端</td><td> </td></tr><tr><td> </td><td>AdSet.Field.targeting:rule</td><td>目标受众中的自定义受众</td><td>默认为:除了安装关联应用的受众</td><td><a href='https://developers.facebook.com/docs/marketing-api/audiences-api/mobile-apps'>创建自定义受众参考文档</a></td></tr><tr><td> </td><td>AdSet.Field.targeting:genders</td><td>目标受众中的性别</td><td>默认为:不限</td><td> </td></tr><tr><td> </td><td>AdSet.Field.targeting:countries</td><td>目标受众中的国家</td><td>前端(需要区分单选和多选的情况)</td><td> </td></tr><tr><td> </td><td>AdSet.Field.targeting:age_min</td><td>目标受众中的年龄(最小年龄)</td><td>默认为:18</td><td> </td></tr><tr><td> </td><td>AdSet.Field.targeting:age_max</td><td>目标受众中的年龄(最大年龄)</td><td>默认为:65</td><td> </td></tr><tr><td>广告(Ad)</td><td>Ad.name</td><td>广告名称</td><td>前端</td><td> </td></tr><tr><td> </td><td>adset_id</td><td>广告组编号</td><td>自动连线,创建广告组时获取</td><td> </td></tr><tr><td> </td><td>creative-id</td><td>广告创意</td><td>自动连线,创建广告创意时获取</td><td> </td></tr><tr><td>广告创意(Adcreative)</td><td>creative</td><td>广告创意</td><td>前端</td><td> </td></tr><tr><td> </td><td>AdCreativeLinkData.Field.link</td><td>素材 - app link</td><td>前端</td><td> </td></tr><tr><td> </td><td>AdCreativeLinkData.Field.caption</td><td>素材 - 图片标题</td><td>前端(这个字段是不是标题需要确认一下)</td><td> </td></tr><tr><td> </td><td>AdCreativeLinkData.Field.message</td><td>素材 - 图片文案</td><td>前端</td><td> </td></tr><tr><td> </td><td>AdCreativeLinkData.Field.image_hash</td><td>素材 - 图片</td><td>前端</td><td> </td></tr><tr><td> </td><td>AdCreativeVideoData.Field.video_id</td><td>素材 - 视频</td><td>前端</td><td> </td></tr><tr><td> </td><td>AdCreativeVideoData.Field.image_url</td><td>素材 - 封面图</td><td>前端</td><td> </td></tr><tr><td> </td><td>AdCreativeVideoData.Field.description</td><td>素材 - 视频文案</td><td>前端</td><td> </td></tr><tr><td> </td><td>call_to_action:type</td><td>素材 - 行动号召</td><td>默认为:INSTALL_MOBILE_APP</td><td> </td></tr><tr><td> </td><td>call_to_action:value:link</td><td>素材 - 行动号召</td><td>默认为:app link</td><td> </td></tr><tr><td> </td><td>call_to_action:value:link_title</td><td>素材 - 视频标题</td><td> </td><td> </td></tr><tr><td>素材</td><td> </td><td>素材id</td><td>前端</td><td> </td></tr></tbody></table></figure><p> </p><h4><a name='header-n1075' class='md-header-anchor '></a>素材库(一期功能)</h4><h5><a name='header-n1076' class='md-header-anchor '></a>需求背景</h5><p>1.批量创建功能需要提前上传素材到Facebook服务器,减少单次创建的信息量。</p><p>2.不同应用之中会有素材需要复用的情况,需要将上传过的素材储存起来。</p><p>3.后期的自动化需求通过其他接口产生素材,需要一个素材库将创建功能和素材接口连接起来。</p><p> </p><h6><a name='header-n1085' class='md-header-anchor '></a>流程图</h6><p><img src='./img/素材库逻辑.png' alt='素材库逻辑' referrerPolicy='no-referrer' /></p><h6><a name='header-n1088' class='md-header-anchor '></a>原型图</h6><p><a href='https://motodriver.github.io/demo/%E5%8E%9F%E5%9E%8B%E5%9B%BE/%E7%B4%A0%E6%9D%90%E4%B8%8A%E4%BC%A0.html'>素材上传原型图</a></p><p> </p><h5><a name='header-n1093' class='md-header-anchor '></a>素材上传&使用</h5><h6><a name='header-n1094' class='md-header-anchor '></a>素材使用</h6><p>当选择定好关联方式时,调出素材库选择界面,只需要展示对应的类型。(关联方式选择图片时,默认拉取当前选择应用的图片,同时界面上也有选择其他应用的选项,但是不能选择其他的类型)</p><p>当选择素材时,展示文件缩略图和文件名,按照时间倒序排列(新上传的在前)。</p><p>当运营选定素材后,后端不用给前端文件,只要给前端文件对应的素材id。</p><p>前端将素材id写进创建信息json中,传回后端。</p><p> </p><h6><a name='header-n1105' class='md-header-anchor '></a>素材库管理</h6><p>素材库第一期只有上传的入口,没有删查减的入口。</p><p><img src='./img/素材库结构.png' alt='素材库结构' referrerPolicy='no-referrer' /></p><ul><li>第一级</li></ul><p>以应用名来区分的文件夹</p><ul><li>第二级</li></ul><p>以类型区分的文件夹,类型有Video\Photo\Cover三种</p><p> </p><h3><a name='header-n1124' class='md-header-anchor '></a>投放</h3><h4><a name='header-n1125' class='md-header-anchor '></a>数据查看</h4><h5><a name='header-n1126' class='md-header-anchor '></a>功能背景</h5><ol start='' ><li>因为Facebook政策限制,一个账号下的投放应用是有限的,所以创建了很多账号。同一个应用,可能投放的数据分布在各个账号中,查看数据的时候十分不方便,需要有一个统一的数据查看平台。</li><li>基于之后的投放自动化的需求,需要将数据拉取下来之后根据算法计算评分,然后根据评分做出出价、预算等变动。所以需要一个数据查看平台。</li></ol><h5><a name='header-n1134' class='md-header-anchor '></a>查看数据</h5><ul><li>选择应用</li><li>选择查看时间段</li><li>选择查看维度(广告系列、广告组、广告)</li><li>查看细分数据(国家、版位等)</li></ul><p>选择完成后选择点击应用按钮,则从服务器调取相应的数据。</p><h5><a name='header-n1150' class='md-header-anchor '></a>数据筛选、排序</h5><ul><li><p>数据筛选</p><p>可以对每一个数值列进行区间筛选(规定展示的最小值和最大值区间)</p></li><li><p>数据排序</p><p>单击列名可以对该列进行排序</p></li></ul><h5><a name='header-n1162' class='md-header-anchor '></a>原型图</h5><p> </p><h4><a name='header-n1165' class='md-header-anchor '></a>投放规则</h4><p>广告规则是在广告规则库中创建和存储的独立对象,至少包含一个 <code>name</code>、一个 <code>evaluation_spec</code> 和一个 <code>execution_spec</code>。规则的基本架构如下所示:</p><pre spellcheck="false" class="md-fences md-end-block contain-cm modeLoaded" lang=""><div class="CodeMirror cm-s-inner CodeMirror-wrap"><div style="overflow: hidden; position: relative; width: 3px; height: 0px; top: 4px; left: 4px;"><textarea autocorrect="off" autocapitalize="off" spellcheck="false" tabindex="0" style="position: absolute; bottom: -1em; padding: 0px; width: 1000px; height: 1em; outline: none;"></textarea></div><div class="CodeMirror-scrollbar-filler" cm-not-content="true"></div><div class="CodeMirror-gutter-filler" cm-not-content="true"></div><div class="CodeMirror-scroll" tabindex="-1"><div class="CodeMirror-sizer" style="margin-left: 0px; margin-bottom: 0px; border-right-width: 0px; padding-right: 0px; padding-bottom: 0px;"><div style="position: relative; top: 0px;"><div class="CodeMirror-lines" role="presentation"><div role="presentation" style="position: relative; outline: none;"><div class="CodeMirror-measure"></div><div class="CodeMirror-measure"></div><div style="position: relative; z-index: 1;"></div><div class="CodeMirror-code" role="presentation" style=""><div class="CodeMirror-activeline" style="position: relative;"><div class="CodeMirror-activeline-background CodeMirror-linebackground"></div><div class="CodeMirror-gutter-background CodeMirror-activeline-gutter" style="left: 0px; width: 0px;"></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;">curl \</span></pre></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;">-F 'name=Rule 1' \</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;">-F 'evaluation_spec={</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> ...</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> }' \</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;">-F 'execution_spec={</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> ...</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> }' \</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;">-F "access_token=<ACCESS_TOKEN>" \</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;">https://graph.facebook.com/<VERSION>/<AD_ACCOUNT_ID>/adrules_library</span></pre></div></div></div></div></div><div style="position: absolute; height: 0px; width: 1px; border-bottom-width: 0px; border-bottom-style: solid; border-bottom-color: transparent; top: 228px;"></div><div class="CodeMirror-gutters" style="display: none; height: 228px;"></div></div></div></pre><p>Facebook 会在成效分析指标或对象元数据字段出现变化时评估实时触发规则,根据设置的时间间隔评估定期触发规则。</p><p> </p><h2><a name='header-n1174' class='md-header-anchor '></a>判断逻辑</h2><p><strong>判断impression --> 判断install --> 判断CPI --> 判断CTR -->判断CVR</strong></p><p> </p><h2><a name='header-n1449' class='md-header-anchor '></a>流程图</h2><p><img src='/Users/lee/Downloads/Untitled Diagram (3).png' alt='Untitled Diagram (3)' referrerPolicy='no-referrer' /></p><p> </p><h2><a name='header-n1178' class='md-header-anchor '></a>非功能需求</h2><h3><a name='header-n1179' class='md-header-anchor '></a>账号管理</h3><p>创建所需的账号、应用、token都通过Business Manager API来拉取。</p><p>后期会加上账号权限管理这一块,这一期实现拉取功能即可。</p><p> </p><h2><a name='header-n1186' class='md-header-anchor '></a>附录</h2><h3><a name='header-n1187' class='md-header-anchor '></a>Token手动获得方式</h3><p><img src='./img/long_live_token_generate.png' alt='long_live_token_generate' referrerPolicy='no-referrer' /></p><h3><a name='header-n1190' class='md-header-anchor '></a>生成长期Token</h3><ol start='' ><li>Short-lived access token obtained via login dialog.</li><li>Start with a short-lived token generated on a client and ship it back to your server.</li><li>Use the user token, your app ID and app secret to make the following call from your server to Facebook's servers:</li></ol><pre spellcheck="false" class="md-fences md-end-block contain-cm modeLoaded" lang=""><div class="CodeMirror cm-s-inner CodeMirror-wrap"><div style="overflow: hidden; position: relative; width: 3px; height: 0px; top: 4px; left: 4px;"><textarea autocorrect="off" autocapitalize="off" spellcheck="false" tabindex="0" style="position: absolute; bottom: -1em; padding: 0px; width: 1000px; height: 1em; outline: none;"></textarea></div><div class="CodeMirror-scrollbar-filler" cm-not-content="true"></div><div class="CodeMirror-gutter-filler" cm-not-content="true"></div><div class="CodeMirror-scroll" tabindex="-1"><div class="CodeMirror-sizer" style="margin-left: 0px; margin-bottom: 0px; border-right-width: 0px; padding-right: 0px; padding-bottom: 0px;"><div style="position: relative; top: 0px;"><div class="CodeMirror-lines" role="presentation"><div role="presentation" style="position: relative; outline: none;"><div class="CodeMirror-measure"></div><div class="CodeMirror-measure"></div><div style="position: relative; z-index: 1;"></div><div class="CodeMirror-code" role="presentation" style=""><div class="CodeMirror-activeline" style="position: relative;"><div class="CodeMirror-activeline-background CodeMirror-linebackground"></div><div class="CodeMirror-gutter-background CodeMirror-activeline-gutter" style="left: 0px; width: 0px;"></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;">GET /oauth/access_token? </span></pre></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> grant_type=fb_exchange_token& </span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> client_id={app-id}&</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> client_secret={app-secret}&</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> fb_exchange_token={short-lived-token} </span></pre></div></div></div></div></div><div style="position: absolute; height: 0px; width: 1px; border-bottom-width: 0px; border-bottom-style: solid; border-bottom-color: transparent; top: 118px;"></div><div class="CodeMirror-gutters" style="display: none; height: 118px;"></div></div></div></pre><p><a href='https://developers.facebook.com/docs/facebook-login/access-tokens/'>参考文档</a></p><p>自动获取token请参考【Business Manager平台】这一节的内容。</p><p> </p><h3><a name='header-n1209' class='md-header-anchor '></a>Business Manager平台</h3><p><img src='./img/bm_token.png' alt='bm_token' referrerPolicy='no-referrer' /></p><p>Business Manager平台的功能是管理资产,资产包括广告账户、应用等,可以通过Business manager API来拉取应用、账号列表,以及对于的token。</p><p>目前我们有的是BM平台admin和System user级别的token,admin token用于权限分配,system user token用于实际api调用。出于安全原因不写在这,需要的话找我要。</p><p><a href='https://developers.facebook.com/docs/marketing-api/businessmanager/assets'>BM平台管理参考文档</a></p><h4><a name='header-n1218' class='md-header-anchor '></a>查看自有帐户</h4><p>您可以通过 <code>GET</code> 调用查看商务管理平台可访问的所有广告帐户:</p><pre spellcheck="false" class="md-fences md-end-block contain-cm modeLoaded" lang=""><div class="CodeMirror cm-s-inner CodeMirror-wrap"><div style="overflow: hidden; position: relative; width: 3px; height: 0px; top: 4px; left: 4px;"><textarea autocorrect="off" autocapitalize="off" spellcheck="false" tabindex="0" style="position: absolute; bottom: -1em; padding: 0px; width: 1000px; height: 1em; outline: none;"></textarea></div><div class="CodeMirror-scrollbar-filler" cm-not-content="true"></div><div class="CodeMirror-gutter-filler" cm-not-content="true"></div><div class="CodeMirror-scroll" tabindex="-1"><div class="CodeMirror-sizer" style="margin-left: 0px; margin-bottom: 0px; border-right-width: 0px; padding-right: 0px; padding-bottom: 0px;"><div style="position: relative; top: 0px;"><div class="CodeMirror-lines" role="presentation"><div role="presentation" style="position: relative; outline: none;"><div class="CodeMirror-measure"></div><div class="CodeMirror-measure"></div><div style="position: relative; z-index: 1;"></div><div class="CodeMirror-code" role="presentation"><div class="CodeMirror-activeline" style="position: relative;"><div class="CodeMirror-activeline-background CodeMirror-linebackground"></div><div class="CodeMirror-gutter-background CodeMirror-activeline-gutter" style="left: 0px; width: 0px;"></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;">curl -G \</span></pre></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;">-d "access_token=<ACCESS_TOKEN>" \</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;">"https://graph.facebook.com/<API_VERSION>/<BUSINESS_ID>/owned_ad_accounts"</span></pre></div></div></div></div></div><div style="position: absolute; height: 0px; width: 1px; border-bottom-width: 0px; border-bottom-style: solid; border-bottom-color: transparent; top: 74px;"></div><div class="CodeMirror-gutters" style="display: none; height: 74px;"></div></div></div></pre><p>这会返回商务管理平台拥有的所有广告帐户。有些字段会特别指明平台与广告帐户之间的关系。</p><h4><a name='header-n1225' class='md-header-anchor '></a>查看商务管理平台拥有的应用</h4><p>如要查看商务管理平台拥有的所有应用程序:</p><pre spellcheck="false" class="md-fences md-end-block contain-cm modeLoaded" lang=""><div class="CodeMirror cm-s-inner CodeMirror-wrap"><div style="overflow: hidden; position: relative; width: 3px; height: 0px; top: 4px; left: 4px;"><textarea autocorrect="off" autocapitalize="off" spellcheck="false" tabindex="0" style="position: absolute; bottom: -1em; padding: 0px; width: 1000px; height: 1em; outline: none;"></textarea></div><div class="CodeMirror-scrollbar-filler" cm-not-content="true"></div><div class="CodeMirror-gutter-filler" cm-not-content="true"></div><div class="CodeMirror-scroll" tabindex="-1"><div class="CodeMirror-sizer" style="margin-left: 0px; margin-bottom: 0px; border-right-width: 0px; padding-right: 0px; padding-bottom: 0px;"><div style="position: relative; top: 0px;"><div class="CodeMirror-lines" role="presentation"><div role="presentation" style="position: relative; outline: none;"><div class="CodeMirror-measure"></div><div class="CodeMirror-measure"></div><div style="position: relative; z-index: 1;"></div><div class="CodeMirror-code" role="presentation"><div class="CodeMirror-activeline" style="position: relative;"><div class="CodeMirror-activeline-background CodeMirror-linebackground"></div><div class="CodeMirror-gutter-background CodeMirror-activeline-gutter" style="left: 0px; width: 0px;"></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;">curl -G \</span></pre></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;">-d "access_token=<ACCESS_TOKEN>" \</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;">"https://graph.facebook.com/<API_VERSION>/<BUSINESS_ID>/owned_apps"</span></pre></div></div></div></div></div><div style="position: absolute; height: 0px; width: 1px; border-bottom-width: 0px; border-bottom-style: solid; border-bottom-color: transparent; top: 74px;"></div><div class="CodeMirror-gutters" style="display: none; height: 74px;"></div></div></div></pre><p>这会返回一列与商务管理平台关联的应用。</p><h4><a name='header-n1231' class='md-header-anchor '></a>认领应用</h4><p>Facebook文档中,有提到认领应用的功能,但是没有具体的命令,正在跟FB的人交流中。没有认领应用的命令的话,会通过手动添加完成,现在白牌所需的应用已经都关联到了白牌项目下。</p><h4><a name='header-n1234' class='md-header-anchor '></a>生成token</h4><p><a href='https://developers.facebook.com/docs/marketing-api/businessmanager/systemuser/?translation#generate-token'>通过user权限获取app token</a></p><p> </p><h4><a name='header-n1239' class='md-header-anchor '></a>项目</h4><p>按照逻辑分组来组织商务管理平台的资产,例如广告帐户、主页、应用。项目更便于您浏览商务管理平台的层级。您可以用项目管理多个经销商和客户拥有的资产。每个资产只能有一个标签。</p><p>如要创建商务管理平台项目,您必须在 <code>POST</code> 请求中指定 <code>name</code>。</p><pre spellcheck="false" class="md-fences md-end-block contain-cm modeLoaded" lang=""><div class="CodeMirror cm-s-inner CodeMirror-wrap"><div style="overflow: hidden; position: relative; width: 3px; height: 0px; top: 4px; left: 4px;"><textarea autocorrect="off" autocapitalize="off" spellcheck="false" tabindex="0" style="position: absolute; bottom: -1em; padding: 0px; width: 1000px; height: 1em; outline: none;"></textarea></div><div class="CodeMirror-scrollbar-filler" cm-not-content="true"></div><div class="CodeMirror-gutter-filler" cm-not-content="true"></div><div class="CodeMirror-scroll" tabindex="-1"><div class="CodeMirror-sizer" style="margin-left: 0px; margin-bottom: 0px; border-right-width: 0px; padding-right: 0px; padding-bottom: 0px;"><div style="position: relative; top: 0px;"><div class="CodeMirror-lines" role="presentation"><div role="presentation" style="position: relative; outline: none;"><div class="CodeMirror-measure"></div><div class="CodeMirror-measure"></div><div style="position: relative; z-index: 1;"></div><div class="CodeMirror-code" role="presentation"><div class="CodeMirror-activeline" style="position: relative;"><div class="CodeMirror-activeline-background CodeMirror-linebackground"></div><div class="CodeMirror-gutter-background CodeMirror-activeline-gutter" style="left: 0px; width: 0px;"></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;">curl \</span></pre></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;">-F "name=Test label" \</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;">-F "access_token=<ACCESS_TOKEN>" \</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;">"https://graph.facebook.com/<API_VERSION>/<BUSINESS_ID>/businessprojects"</span></pre></div></div></div></div></div><div style="position: absolute; height: 0px; width: 1px; border-bottom-width: 0px; border-bottom-style: solid; border-bottom-color: transparent; top: 96px;"></div><div class="CodeMirror-gutters" style="display: none; height: 96px;"></div></div></div></pre><p>您可以通过 <code>GET</code> 请求查看商务管理平台帐户下的所有标签:</p><pre spellcheck="false" class="md-fences md-end-block contain-cm modeLoaded" lang=""><div class="CodeMirror cm-s-inner CodeMirror-wrap"><div style="overflow: hidden; position: relative; width: 3px; height: 0px; top: 4px; left: 4px;"><textarea autocorrect="off" autocapitalize="off" spellcheck="false" tabindex="0" style="position: absolute; bottom: -1em; padding: 0px; width: 1000px; height: 1em; outline: none;"></textarea></div><div class="CodeMirror-scrollbar-filler" cm-not-content="true"></div><div class="CodeMirror-gutter-filler" cm-not-content="true"></div><div class="CodeMirror-scroll" tabindex="-1"><div class="CodeMirror-sizer" style="margin-left: 0px; margin-bottom: 0px; border-right-width: 0px; padding-right: 0px; padding-bottom: 0px;"><div style="position: relative; top: 0px;"><div class="CodeMirror-lines" role="presentation"><div role="presentation" style="position: relative; outline: none;"><div class="CodeMirror-measure"></div><div class="CodeMirror-measure"></div><div style="position: relative; z-index: 1;"></div><div class="CodeMirror-code" role="presentation"><div class="CodeMirror-activeline" style="position: relative;"><div class="CodeMirror-activeline-background CodeMirror-linebackground"></div><div class="CodeMirror-gutter-background CodeMirror-activeline-gutter" style="left: 0px; width: 0px;"></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;">curl -G \</span></pre></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;">-d "access_token=<ACCESS_TOKEN>" \</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;">"https://graph.facebook.com/<API_VERSION>/<BUSINESS_ID>/businessprojects"</span></pre></div></div></div></div></div><div style="position: absolute; height: 0px; width: 1px; border-bottom-width: 0px; border-bottom-style: solid; border-bottom-color: transparent; top: 74px;"></div><div class="CodeMirror-gutters" style="display: none; height: 74px;"></div></div></div></pre><p> 查看商务管理平台中的项目</p><p>您可通过发出此 GET 调用查看项目的详情:</p><pre spellcheck="false" class="md-fences md-end-block contain-cm modeLoaded" lang=""><div class="CodeMirror cm-s-inner CodeMirror-wrap"><div style="overflow: hidden; position: relative; width: 3px; height: 0px; top: 4px; left: 4px;"><textarea autocorrect="off" autocapitalize="off" spellcheck="false" tabindex="0" style="position: absolute; bottom: -1em; padding: 0px; width: 1000px; height: 1em; outline: none;"></textarea></div><div class="CodeMirror-scrollbar-filler" cm-not-content="true"></div><div class="CodeMirror-gutter-filler" cm-not-content="true"></div><div class="CodeMirror-scroll" tabindex="-1"><div class="CodeMirror-sizer" style="margin-left: 0px; margin-bottom: 0px; border-right-width: 0px; padding-right: 0px; padding-bottom: 0px;"><div style="position: relative; top: 0px;"><div class="CodeMirror-lines" role="presentation"><div role="presentation" style="position: relative; outline: none;"><div class="CodeMirror-measure"></div><div class="CodeMirror-measure"></div><div style="position: relative; z-index: 1;"></div><div class="CodeMirror-code" role="presentation"><div class="CodeMirror-activeline" style="position: relative;"><div class="CodeMirror-activeline-background CodeMirror-linebackground"></div><div class="CodeMirror-gutter-background CodeMirror-activeline-gutter" style="left: 0px; width: 0px;"></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;">curl -G \</span></pre></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;">-d "access_token=<ACCESS_TOKEN>" \</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;">"https://graph.facebook.com/<API_VERSION>/<PROJECT_ID>"</span></pre></div></div></div></div></div><div style="position: absolute; height: 0px; width: 1px; border-bottom-width: 0px; border-bottom-style: solid; border-bottom-color: transparent; top: 74px;"></div><div class="CodeMirror-gutters" style="display: none; height: 74px;"></div></div></div></pre><p> </p><h5><a name='header-n1255' class='md-header-anchor '></a>项目的广告帐户</h5><p>您可发出以下 POST 调用为项目添加广告帐户:</p><pre spellcheck="false" class="md-fences md-end-block contain-cm modeLoaded" lang=""><div class="CodeMirror cm-s-inner CodeMirror-wrap"><div style="overflow: hidden; position: relative; width: 3px; height: 0px; top: 4px; left: 4px;"><textarea autocorrect="off" autocapitalize="off" spellcheck="false" tabindex="0" style="position: absolute; bottom: -1em; padding: 0px; width: 1000px; height: 1em; outline: none;"></textarea></div><div class="CodeMirror-scrollbar-filler" cm-not-content="true"></div><div class="CodeMirror-gutter-filler" cm-not-content="true"></div><div class="CodeMirror-scroll" tabindex="-1"><div class="CodeMirror-sizer" style="margin-left: 0px; margin-bottom: 0px; border-right-width: 0px; padding-right: 0px; padding-bottom: 0px;"><div style="position: relative; top: 0px;"><div class="CodeMirror-lines" role="presentation"><div role="presentation" style="position: relative; outline: none;"><div class="CodeMirror-measure"></div><div class="CodeMirror-measure"></div><div style="position: relative; z-index: 1;"></div><div class="CodeMirror-code" role="presentation"><div class="CodeMirror-activeline" style="position: relative;"><div class="CodeMirror-activeline-background CodeMirror-linebackground"></div><div class="CodeMirror-gutter-background CodeMirror-activeline-gutter" style="left: 0px; width: 0px;"></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;">curl \</span></pre></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;">-F "adaccount_id=act_<ADACCOUNT_ID>" \</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;">-F "access_token=<ACCESS_TOKEN>" \</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;">"https://graph.facebook.com/<API_VERSION>/<PROJECT_ID>/adaccounts"</span></pre></div></div></div></div></div><div style="position: absolute; height: 0px; width: 1px; border-bottom-width: 0px; border-bottom-style: solid; border-bottom-color: transparent; top: 96px;"></div><div class="CodeMirror-gutters" style="display: none; height: 96px;"></div></div></div></pre><p>您可发出以下 GET 调用查看某个项目下的所有广告帐户:</p><pre spellcheck="false" class="md-fences md-end-block contain-cm modeLoaded" lang=""><div class="CodeMirror cm-s-inner CodeMirror-wrap"><div style="overflow: hidden; position: relative; width: 3px; height: 0px; top: 4px; left: 4px;"><textarea autocorrect="off" autocapitalize="off" spellcheck="false" tabindex="0" style="position: absolute; bottom: -1em; padding: 0px; width: 1000px; height: 1em; outline: none;"></textarea></div><div class="CodeMirror-scrollbar-filler" cm-not-content="true"></div><div class="CodeMirror-gutter-filler" cm-not-content="true"></div><div class="CodeMirror-scroll" tabindex="-1"><div class="CodeMirror-sizer" style="margin-left: 0px; margin-bottom: 0px; border-right-width: 0px; padding-right: 0px; padding-bottom: 0px;"><div style="position: relative; top: 0px;"><div class="CodeMirror-lines" role="presentation"><div role="presentation" style="position: relative; outline: none;"><div class="CodeMirror-measure"></div><div class="CodeMirror-measure"></div><div style="position: relative; z-index: 1;"></div><div class="CodeMirror-code" role="presentation"><div class="CodeMirror-activeline" style="position: relative;"><div class="CodeMirror-activeline-background CodeMirror-linebackground"></div><div class="CodeMirror-gutter-background CodeMirror-activeline-gutter" style="left: 0px; width: 0px;"></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;">curl -G \</span></pre></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;">-d "access_token=<ACCESS_TOKEN>" \</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;">"https://graph.facebook.com/<API_VERSION>/<PROJECT_ID>/adaccounts"</span></pre></div></div></div></div></div><div style="position: absolute; height: 0px; width: 1px; border-bottom-width: 0px; border-bottom-style: solid; border-bottom-color: transparent; top: 74px;"></div><div class="CodeMirror-gutters" style="display: none; height: 74px;"></div></div></div></pre><p>您可发出以下 DELETE 调用从项目移除广告帐户:</p><pre spellcheck="false" class="md-fences md-end-block contain-cm modeLoaded" lang=""><div class="CodeMirror cm-s-inner CodeMirror-wrap"><div style="overflow: hidden; position: relative; width: 3px; height: 0px; top: 4px; left: 4px;"><textarea autocorrect="off" autocapitalize="off" spellcheck="false" tabindex="0" style="position: absolute; bottom: -1em; padding: 0px; width: 1000px; height: 1em; outline: none;"></textarea></div><div class="CodeMirror-scrollbar-filler" cm-not-content="true"></div><div class="CodeMirror-gutter-filler" cm-not-content="true"></div><div class="CodeMirror-scroll" tabindex="-1"><div class="CodeMirror-sizer" style="margin-left: 0px; margin-bottom: 0px; border-right-width: 0px; padding-right: 0px; padding-bottom: 0px;"><div style="position: relative; top: 0px;"><div class="CodeMirror-lines" role="presentation"><div role="presentation" style="position: relative; outline: none;"><div class="CodeMirror-measure"></div><div class="CodeMirror-measure"></div><div style="position: relative; z-index: 1;"></div><div class="CodeMirror-code" role="presentation"><div class="CodeMirror-activeline" style="position: relative;"><div class="CodeMirror-activeline-background CodeMirror-linebackground"></div><div class="CodeMirror-gutter-background CodeMirror-activeline-gutter" style="left: 0px; width: 0px;"></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;">curl -X DELETE \</span></pre></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;">-F "adaccount_id=act_<AD_ACCOUNT_ID>" \</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;">-F "access_token=<ACCESS_TOKEN>" \</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;">"https://graph.facebook.com/<API_VERSION>/<PROJECT_ID>/adaccounts"</span></pre></div></div></div></div></div><div style="position: absolute; height: 0px; width: 1px; border-bottom-width: 0px; border-bottom-style: solid; border-bottom-color: transparent; top: 96px;"></div><div class="CodeMirror-gutters" style="display: none; height: 96px;"></div></div></div></pre><h5><a name='header-n1265' class='md-header-anchor '></a>项目的应用</h5><p>您可发出以下 POST 调用为项目添加应用:</p><pre spellcheck="false" class="md-fences md-end-block contain-cm modeLoaded" lang=""><div class="CodeMirror cm-s-inner CodeMirror-wrap"><div style="overflow: hidden; position: relative; width: 3px; height: 0px; top: 4px; left: 4px;"><textarea autocorrect="off" autocapitalize="off" spellcheck="false" tabindex="0" style="position: absolute; bottom: -1em; padding: 0px; width: 1000px; height: 1em; outline: none;"></textarea></div><div class="CodeMirror-scrollbar-filler" cm-not-content="true"></div><div class="CodeMirror-gutter-filler" cm-not-content="true"></div><div class="CodeMirror-scroll" tabindex="-1"><div class="CodeMirror-sizer" style="margin-left: 0px; margin-bottom: 0px; border-right-width: 0px; padding-right: 0px; padding-bottom: 0px;"><div style="position: relative; top: 0px;"><div class="CodeMirror-lines" role="presentation"><div role="presentation" style="position: relative; outline: none;"><div class="CodeMirror-measure"></div><div class="CodeMirror-measure"></div><div style="position: relative; z-index: 1;"></div><div class="CodeMirror-code" role="presentation"><div class="CodeMirror-activeline" style="position: relative;"><div class="CodeMirror-activeline-background CodeMirror-linebackground"></div><div class="CodeMirror-gutter-background CodeMirror-activeline-gutter" style="left: 0px; width: 0px;"></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;">curl \</span></pre></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;">-F "app_id=<PAGE_ID>" \</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;">-F "access_token=<ACCESS_TOKEN>" \</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;">"https://graph.facebook.com/<API_VERSION>/<PROJECT_ID>/apps"</span></pre></div></div></div></div></div><div style="position: absolute; height: 0px; width: 1px; border-bottom-width: 0px; border-bottom-style: solid; border-bottom-color: transparent; top: 96px;"></div><div class="CodeMirror-gutters" style="display: none; height: 96px;"></div></div></div></pre><p>您可发出以下 GET 调用来查看某个项目下的所有应用:</p><pre spellcheck="false" class="md-fences md-end-block contain-cm modeLoaded" lang=""><div class="CodeMirror cm-s-inner CodeMirror-wrap"><div style="overflow: hidden; position: relative; width: 3px; height: 0px; top: 4px; left: 4px;"><textarea autocorrect="off" autocapitalize="off" spellcheck="false" tabindex="0" style="position: absolute; bottom: -1em; padding: 0px; width: 1000px; height: 1em; outline: none;"></textarea></div><div class="CodeMirror-scrollbar-filler" cm-not-content="true"></div><div class="CodeMirror-gutter-filler" cm-not-content="true"></div><div class="CodeMirror-scroll" tabindex="-1"><div class="CodeMirror-sizer" style="margin-left: 0px; margin-bottom: 0px; border-right-width: 0px; padding-right: 0px; padding-bottom: 0px;"><div style="position: relative; top: 0px;"><div class="CodeMirror-lines" role="presentation"><div role="presentation" style="position: relative; outline: none;"><div class="CodeMirror-measure"></div><div class="CodeMirror-measure"></div><div style="position: relative; z-index: 1;"></div><div class="CodeMirror-code" role="presentation"><div class="CodeMirror-activeline" style="position: relative;"><div class="CodeMirror-activeline-background CodeMirror-linebackground"></div><div class="CodeMirror-gutter-background CodeMirror-activeline-gutter" style="left: 0px; width: 0px;"></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;">curl -G \</span></pre></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;">-d "access_token=<ACCESS_TOKEN>" \</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;">"https://graph.facebook.com/<API_VERSION>/<PROJECT_ID>/apps"</span></pre></div></div></div></div></div><div style="position: absolute; height: 0px; width: 1px; border-bottom-width: 0px; border-bottom-style: solid; border-bottom-color: transparent; top: 74px;"></div><div class="CodeMirror-gutters" style="display: none; height: 74px;"></div></div></div></pre><p>您可发出以下 DELETE 调用从项目中移除应用:</p><pre spellcheck="false" class="md-fences md-end-block contain-cm modeLoaded" lang=""><div class="CodeMirror cm-s-inner CodeMirror-wrap"><div style="overflow: hidden; position: relative; width: 3px; height: 0px; top: 4px; left: 4px;"><textarea autocorrect="off" autocapitalize="off" spellcheck="false" tabindex="0" style="position: absolute; bottom: -1em; padding: 0px; width: 1000px; height: 1em; outline: none;"></textarea></div><div class="CodeMirror-scrollbar-filler" cm-not-content="true"></div><div class="CodeMirror-gutter-filler" cm-not-content="true"></div><div class="CodeMirror-scroll" tabindex="-1"><div class="CodeMirror-sizer" style="margin-left: 0px; margin-bottom: 0px; border-right-width: 0px; padding-right: 0px; padding-bottom: 0px;"><div style="position: relative; top: 0px;"><div class="CodeMirror-lines" role="presentation"><div role="presentation" style="position: relative; outline: none;"><div class="CodeMirror-measure"></div><div class="CodeMirror-measure"></div><div style="position: relative; z-index: 1;"></div><div class="CodeMirror-code" role="presentation"><div class="CodeMirror-activeline" style="position: relative;"><div class="CodeMirror-activeline-background CodeMirror-linebackground"></div><div class="CodeMirror-gutter-background CodeMirror-activeline-gutter" style="left: 0px; width: 0px;"></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;">curl -X DELETE \</span></pre></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;">-F "app_id=<PAGE_ID>" \</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;">-F "access_token=<ACCESS_TOKEN>" \</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;">"https://graph.facebook.com/<API_VERSION>/<PROJECT_ID>/apps"</span></pre></div></div></div></div></div><div style="position: absolute; height: 0px; width: 1px; border-bottom-width: 0px; border-bottom-style: solid; border-bottom-color: transparent; top: 96px;"></div><div class="CodeMirror-gutters" style="display: none; height: 96px;"></div></div></div></pre><p> </p><h4><a name='header-n1277' class='md-header-anchor '></a>给用户分配广告账户</h4><p>之后的功能中可能会加入对于账号权限管理的部分,先将参考文档贴在这。</p><h5><a name='header-n1280' class='md-header-anchor '></a>管理用户和身份</h5><p>商务管理平台中有两种类型的身份:</p><figure><table><thead><tr><th>名称</th><th>API 常量</th><th>说明</th></tr></thead><tbody><tr><td>管理员</td><td><code>ADMIN</code></td><td>可以管理商务管理平台的各个方面,包括修改或删除帐户、为工作人员列表添加或移除用户。对商务管理平台关联的全部资产拥有 <code>READ</code> 和 <code>WRITE</code> 访问权限。</td></tr><tr><td>工作人员</td><td><code>EMPLOYEE</code></td><td>可以查看商务管理平台设置中的所有信息,且可由商务管理平台管理员分配身份。不能进行任何更改,只能将自己担任管理员的主页或广告帐户添加到商务管理平台中。对商务管理平台关联的全部资产拥有 <code>READ</code> 访问权限。</td></tr></tbody></table></figure><p> 如要了解有关身份的更多信息,请参阅<a href='https://www.facebook.com/business/help/1953352334878186'>在商务管理平台中设置目录身份</a>。</p><p> </p><h5><a name='header-n1300' class='md-header-anchor '></a>邀请用户</h5><p>如需将同事添加到商务管理平台,您必须邀请他们。发出邀请时,请提供他们能使用的有效邮箱。<strong>发送在商务管理平台添加工作人员的请求有数量限制。当您达到此限制时,将收到错误代码 17,但在 24 小时后应能再次发送请求。</strong></p><p>如要邀请用户担任工作人员,请发送以下 <code>POST</code> 请求:</p><pre spellcheck="false" class="md-fences md-end-block contain-cm modeLoaded" lang=""><div class="CodeMirror cm-s-inner CodeMirror-wrap"><div style="overflow: hidden; position: relative; width: 3px; height: 0px; top: 4px; left: 4px;"><textarea autocorrect="off" autocapitalize="off" spellcheck="false" tabindex="0" style="position: absolute; bottom: -1em; padding: 0px; width: 1000px; height: 1em; outline: none;"></textarea></div><div class="CodeMirror-scrollbar-filler" cm-not-content="true"></div><div class="CodeMirror-gutter-filler" cm-not-content="true"></div><div class="CodeMirror-scroll" tabindex="-1"><div class="CodeMirror-sizer" style="margin-left: 0px; margin-bottom: 0px; border-right-width: 0px; padding-right: 0px; padding-bottom: 0px;"><div style="position: relative; top: 0px;"><div class="CodeMirror-lines" role="presentation"><div role="presentation" style="position: relative; outline: none;"><div class="CodeMirror-measure"></div><div class="CodeMirror-measure"></div><div style="position: relative; z-index: 1;"></div><div class="CodeMirror-code" role="presentation" style=""><div class="CodeMirror-activeline" style="position: relative;"><div class="CodeMirror-activeline-background CodeMirror-linebackground"></div><div class="CodeMirror-gutter-background CodeMirror-activeline-gutter" style="left: 0px; width: 0px;"></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;">curl \</span></pre></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;">-F "[email protected]" \</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;">-F "role=EMPLOYEE" \</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;">-F "access_token=<ACCESS_TOKEN>" \</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;">"https://graph.facebook.com/<API_VERSION>/<BUSINESS_ID>/business_users"</span></pre></div></div></div></div></div><div style="position: absolute; height: 0px; width: 1px; border-bottom-width: 0px; border-bottom-style: solid; border-bottom-color: transparent; top: 118px;"></div><div class="CodeMirror-gutters" style="display: none; height: 118px;"></div></div></div></pre><p>Facebook 会向您指定的工作邮箱发送一封邀请邮件。被邀请人必须查收邮件,并按照注册流程操作。他们完成操作后,您便可在用户列表中看到他们。</p><p>注意:如果邮件接收不到的话,在 <code>POST</code> 请求返回的结果中有邀请链接;</p><p> </p><h5><a name='header-n1313' class='md-header-anchor '></a>添加用户到帐户</h5><p>在您的商务管理平台具有广告帐户后,您现在可以分配平台上的其他用户身份,如下所示:</p><figure><table><thead><tr><th>名称</th><th>API 常量</th><th>说明</th></tr></thead><tbody><tr><td>仅报告</td><td><code>REPORTS_ONLY</code></td><td>可以查看广告表现</td></tr><tr><td>一般用户</td><td><code>GENERAL_USER</code></td><td>可以查看和编辑广告,并使用与广告帐户相关联的资金源设置广告,但不能设置帐户级别</td></tr><tr><td>管理员</td><td><code>ADMIN</code></td><td>可以管理广告系列、报告、账单和帐户权限的各个方面</td></tr></tbody></table></figure><p>您需要:</p><ul><li><code>adaccount_id</code>:广告帐户编号(格式为 <code>act_123</code>)</li><li><code>user_id</code>:要添加的用户编号</li><li>要分配的身份</li></ul><p>如要添加新用户作为管理员,请发出以下 <code>POST</code> 调用:</p><pre spellcheck="false" class="md-fences md-end-block contain-cm modeLoaded" lang=""><div class="CodeMirror cm-s-inner CodeMirror-wrap"><div style="overflow: hidden; position: relative; width: 3px; height: 0px; top: 4px; left: 4px;"><textarea autocorrect="off" autocapitalize="off" spellcheck="false" tabindex="0" style="position: absolute; bottom: -1em; padding: 0px; width: 1000px; height: 1em; outline: none;"></textarea></div><div class="CodeMirror-scrollbar-filler" cm-not-content="true"></div><div class="CodeMirror-gutter-filler" cm-not-content="true"></div><div class="CodeMirror-scroll" tabindex="-1"><div class="CodeMirror-sizer" style="margin-left: 0px; margin-bottom: 0px; border-right-width: 0px; padding-right: 0px; padding-bottom: 0px;"><div style="position: relative; top: 0px;"><div class="CodeMirror-lines" role="presentation"><div role="presentation" style="position: relative; outline: none;"><div class="CodeMirror-measure"></div><div class="CodeMirror-measure"></div><div style="position: relative; z-index: 1;"></div><div class="CodeMirror-code" role="presentation" style=""><div class="CodeMirror-activeline" style="position: relative;"><div class="CodeMirror-activeline-background CodeMirror-linebackground"></div><div class="CodeMirror-gutter-background CodeMirror-activeline-gutter" style="left: 0px; width: 0px;"></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;">curl \</span></pre></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;">-F "user=BUSINESS_SCOPED_USER_ID" \</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;">-F "role=ADMIN" \</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;">-F "access_token=ACCESS_TOKEN" \</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;">"https://graph.facebook.com/VERSION/act_AD_ACCOUNT_ID/assigned_users"</span></pre></div></div></div></div></div><div style="position: absolute; height: 0px; width: 1px; border-bottom-width: 0px; border-bottom-style: solid; border-bottom-color: transparent; top: 118px;"></div><div class="CodeMirror-gutters" style="display: none; height: 118px;"></div></div></div></pre><p> </p></div>
</body>
</html>