proca 1.1.5 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +35 -35
- package/package.json +1 -1
- package/src/commands/action/list.mjs +3 -3
- package/src/commands/contact/list.mjs +204 -0
- package/src/commands/supporter/count.mjs +0 -96
package/README.md
CHANGED
|
@@ -18,7 +18,7 @@ $ npm install -g proca
|
|
|
18
18
|
$ proca COMMAND
|
|
19
19
|
running command...
|
|
20
20
|
$ proca (--version)
|
|
21
|
-
proca/1.
|
|
21
|
+
proca/1.2.0 linux-x64 node-v20.12.2
|
|
22
22
|
$ proca --help [COMMAND]
|
|
23
23
|
USAGE
|
|
24
24
|
$ proca COMMAND
|
|
@@ -58,6 +58,7 @@ USAGE
|
|
|
58
58
|
* [`proca config setup [ENVIRONMENT]`](#proca-config-setup-environment)
|
|
59
59
|
* [`proca config token`](#proca-config-token)
|
|
60
60
|
* [`proca config user`](#proca-config-user)
|
|
61
|
+
* [`proca contact list [TITLE]`](#proca-contact-list-title)
|
|
61
62
|
* [`proca help [COMMAND]`](#proca-help-command)
|
|
62
63
|
* [`proca org add`](#proca-org-add)
|
|
63
64
|
* [`proca org crm`](#proca-org-crm)
|
|
@@ -74,7 +75,6 @@ USAGE
|
|
|
74
75
|
* [`proca plugins uninstall [PLUGIN]`](#proca-plugins-uninstall-plugin)
|
|
75
76
|
* [`proca plugins unlink [PLUGIN]`](#proca-plugins-unlink-plugin)
|
|
76
77
|
* [`proca plugins update`](#proca-plugins-update)
|
|
77
|
-
* [`proca supporter count`](#proca-supporter-count)
|
|
78
78
|
* [`proca user get`](#proca-user-get)
|
|
79
79
|
* [`proca user leave`](#proca-user-leave)
|
|
80
80
|
* [`proca user list`](#proca-user-list)
|
|
@@ -448,6 +448,39 @@ EXAMPLES
|
|
|
448
448
|
$ proca config user
|
|
449
449
|
```
|
|
450
450
|
|
|
451
|
+
## `proca contact list [TITLE]`
|
|
452
|
+
|
|
453
|
+
```
|
|
454
|
+
USAGE
|
|
455
|
+
$ proca contact list [TITLE] -o <organisation name> [--json | --human | --csv] [-c
|
|
456
|
+
<campaign title>] [--limit <value>] [--today | --after 2025-04-09] [--optin] [--testing] [--doi] [--utm |
|
|
457
|
+
--simplify] [--comment | ]
|
|
458
|
+
|
|
459
|
+
ARGUMENTS
|
|
460
|
+
TITLE name of the campaign, % for wildchar
|
|
461
|
+
|
|
462
|
+
FLAGS
|
|
463
|
+
-c, --campaign=<campaign title> name of the campaign, % for wildchar
|
|
464
|
+
-o, --org=<organisation name> (required) campaigns of the organisation (coordinator or partner)
|
|
465
|
+
--after=2025-04-09 only actions after a date
|
|
466
|
+
--[no-]comment display the comment
|
|
467
|
+
--doi only export the double optin actions
|
|
468
|
+
--limit=<value> max number of actions
|
|
469
|
+
--optin only export the optin actions
|
|
470
|
+
--testing also export the test actions
|
|
471
|
+
--today only actions today
|
|
472
|
+
--[no-]utm display the utm tracking parameters
|
|
473
|
+
|
|
474
|
+
OUTPUT FLAGS
|
|
475
|
+
--csv Format output as csv
|
|
476
|
+
--human Format output to be read on screen by a human [default]
|
|
477
|
+
--json Format output as json
|
|
478
|
+
--[no-]simplify flatten and filter to output only the most important attributes, mostly relevant for json
|
|
479
|
+
|
|
480
|
+
EXAMPLES
|
|
481
|
+
$ proca contact list %pizza%
|
|
482
|
+
```
|
|
483
|
+
|
|
451
484
|
## `proca help [COMMAND]`
|
|
452
485
|
|
|
453
486
|
Display help for proca.
|
|
@@ -882,39 +915,6 @@ DESCRIPTION
|
|
|
882
915
|
|
|
883
916
|
_See code: [@oclif/plugin-plugins](https://github.com/oclif/plugin-plugins/blob/v5.4.25/src/commands/plugins/update.ts)_
|
|
884
917
|
|
|
885
|
-
## `proca supporter count`
|
|
886
|
-
|
|
887
|
-
counter of supporters
|
|
888
|
-
|
|
889
|
-
```
|
|
890
|
-
USAGE
|
|
891
|
-
$ proca supporter count [ID_NAME_DXID] [--json | --human | --csv] [--simplify] [-i <value>
|
|
892
|
-
| -n <the_short_name> | -x <value>] [--org] [--area] [--number --without <value>]
|
|
893
|
-
|
|
894
|
-
FLAGS
|
|
895
|
-
-i, --id=<value>
|
|
896
|
-
-n, --name=<the_short_name> name
|
|
897
|
-
-x, --dxid=<value> dxid
|
|
898
|
-
--area segment by area
|
|
899
|
-
--number just return the number to add to the partner's counter
|
|
900
|
-
--org segment by partner
|
|
901
|
-
--without=<value> total to add to the partner's counter
|
|
902
|
-
|
|
903
|
-
OUTPUT FLAGS
|
|
904
|
-
--csv Format output as csv
|
|
905
|
-
--human Format output to be read on screen by a human [default]
|
|
906
|
-
--json Format output as json
|
|
907
|
-
--[no-]simplify flatten and filter to output only the most important attributes, mostly relevant for json
|
|
908
|
-
|
|
909
|
-
DESCRIPTION
|
|
910
|
-
counter of supporters
|
|
911
|
-
|
|
912
|
-
EXAMPLES
|
|
913
|
-
$ proca supporter count --id <id of the campaign>
|
|
914
|
-
|
|
915
|
-
$ proca supporter count --name <name of the campaign>
|
|
916
|
-
```
|
|
917
|
-
|
|
918
918
|
## `proca user get`
|
|
919
919
|
|
|
920
920
|
fetch the information about a user
|
package/package.json
CHANGED
|
@@ -8,7 +8,7 @@ import {
|
|
|
8
8
|
} from "#src/queries/campaign.mjs";
|
|
9
9
|
import { gql, query } from "#src/urql.mjs";
|
|
10
10
|
|
|
11
|
-
export default class
|
|
11
|
+
export default class List extends Command {
|
|
12
12
|
actionTypes = new Set();
|
|
13
13
|
|
|
14
14
|
static args = {
|
|
@@ -85,7 +85,7 @@ export default class CampaignList extends Command {
|
|
|
85
85
|
$orgName: String!
|
|
86
86
|
$start: Int
|
|
87
87
|
) {
|
|
88
|
-
|
|
88
|
+
actions (
|
|
89
89
|
after: $after
|
|
90
90
|
campaignId: $campaignId
|
|
91
91
|
campaignName: $campaignName
|
|
@@ -142,7 +142,7 @@ export default class CampaignList extends Command {
|
|
|
142
142
|
orgName: flags.org,
|
|
143
143
|
start: flags.start,
|
|
144
144
|
});
|
|
145
|
-
return result.
|
|
145
|
+
return result.actions.map((d) => {
|
|
146
146
|
d.customFields = JSON.parse(d.customFields);
|
|
147
147
|
if (!d.contact.publicKey) {
|
|
148
148
|
const ref = d.contactRef;
|
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
import { Args, Flags } from "@oclif/core";
|
|
2
|
+
import { error, stdout, ux } from "@oclif/core/ux";
|
|
3
|
+
import Command from "#src/procaCommand.mjs";
|
|
4
|
+
import {
|
|
5
|
+
FragmentOrg,
|
|
6
|
+
FragmentStats,
|
|
7
|
+
FragmentSummary,
|
|
8
|
+
} from "#src/queries/campaign.mjs";
|
|
9
|
+
import { gql, query } from "#src/urql.mjs";
|
|
10
|
+
|
|
11
|
+
export default class List extends Command {
|
|
12
|
+
actionTypes = new Set();
|
|
13
|
+
|
|
14
|
+
static args = {
|
|
15
|
+
title: Args.string({ description: "name of the campaign, % for wildchar" }),
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
static examples = ["<%= config.bin %> <%= command.id %> %pizza%"];
|
|
19
|
+
|
|
20
|
+
static flags = {
|
|
21
|
+
// flag with no value (-f, --force)
|
|
22
|
+
...super.globalFlags,
|
|
23
|
+
org: Flags.string({
|
|
24
|
+
char: "o",
|
|
25
|
+
description: "campaigns of the organisation (coordinator or partner)",
|
|
26
|
+
required: true,
|
|
27
|
+
// exactlyOne: ["org", "title"],
|
|
28
|
+
helpValue: "<organisation name>",
|
|
29
|
+
}),
|
|
30
|
+
campaign: Flags.string({
|
|
31
|
+
char: "c",
|
|
32
|
+
description: "name of the campaign, % for wildchar",
|
|
33
|
+
helpValue: "<campaign title>",
|
|
34
|
+
}),
|
|
35
|
+
limit: Flags.string({
|
|
36
|
+
description: "max number of actions",
|
|
37
|
+
parse: (input) => Number.parseInt(input, 10),
|
|
38
|
+
}),
|
|
39
|
+
after: Flags.string({
|
|
40
|
+
description: "only actions after a date",
|
|
41
|
+
helpValue: "2025-04-09",
|
|
42
|
+
parse: (input) => new Date(input).toISOString(),
|
|
43
|
+
}),
|
|
44
|
+
today: Flags.boolean({
|
|
45
|
+
description: "only actions today",
|
|
46
|
+
exclusive: ["after"],
|
|
47
|
+
parse: (input) => `${new Date().toISOString().split("T")[0]}T00:00:00Z`,
|
|
48
|
+
}),
|
|
49
|
+
optin: Flags.boolean({
|
|
50
|
+
description: "only export the optin actions",
|
|
51
|
+
default: false,
|
|
52
|
+
}),
|
|
53
|
+
testing: Flags.boolean({
|
|
54
|
+
description: "also export the test actions",
|
|
55
|
+
default: false,
|
|
56
|
+
}),
|
|
57
|
+
doi: Flags.boolean({
|
|
58
|
+
description: "only export the double optin actions",
|
|
59
|
+
default: false,
|
|
60
|
+
}),
|
|
61
|
+
utm: Flags.boolean({
|
|
62
|
+
description: "display the utm tracking parameters",
|
|
63
|
+
default: true,
|
|
64
|
+
allowNo: true,
|
|
65
|
+
exclusive: ["simplify"],
|
|
66
|
+
}),
|
|
67
|
+
comment: Flags.boolean({
|
|
68
|
+
description: "display the comment",
|
|
69
|
+
default: true,
|
|
70
|
+
allowNo: true,
|
|
71
|
+
exclusive: ["simplify"],
|
|
72
|
+
}),
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
fetch = async (flags) => {
|
|
76
|
+
const Document = gql`
|
|
77
|
+
query (
|
|
78
|
+
$after: DateTime
|
|
79
|
+
$campaignId: Int
|
|
80
|
+
$campaignName: String
|
|
81
|
+
$includeTesting: Boolean
|
|
82
|
+
$limit: Int
|
|
83
|
+
$onlyDoubleOptIn: Boolean
|
|
84
|
+
$onlyOptIn: Boolean
|
|
85
|
+
$orgName: String!
|
|
86
|
+
$start: Int
|
|
87
|
+
) {
|
|
88
|
+
contacts(
|
|
89
|
+
after: $after
|
|
90
|
+
campaignId: $campaignId
|
|
91
|
+
campaignName: $campaignName
|
|
92
|
+
includeTesting: $includeTesting
|
|
93
|
+
limit: $limit
|
|
94
|
+
onlyDoubleOptIn: $onlyDoubleOptIn
|
|
95
|
+
onlyOptIn: $onlyOptIn
|
|
96
|
+
orgName: $orgName
|
|
97
|
+
start: $start
|
|
98
|
+
) {
|
|
99
|
+
actionId
|
|
100
|
+
actionPage {
|
|
101
|
+
locale
|
|
102
|
+
name
|
|
103
|
+
}
|
|
104
|
+
actionType
|
|
105
|
+
campaign {
|
|
106
|
+
name
|
|
107
|
+
}
|
|
108
|
+
contact {
|
|
109
|
+
contactRef
|
|
110
|
+
payload
|
|
111
|
+
nonce
|
|
112
|
+
publicKey {
|
|
113
|
+
public
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
createdAt
|
|
117
|
+
customFields
|
|
118
|
+
privacy {
|
|
119
|
+
emailStatus
|
|
120
|
+
emailStatusChanged
|
|
121
|
+
givenAt
|
|
122
|
+
optIn
|
|
123
|
+
withConsent
|
|
124
|
+
}
|
|
125
|
+
tracking {
|
|
126
|
+
campaign
|
|
127
|
+
content
|
|
128
|
+
medium
|
|
129
|
+
source
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
`;
|
|
134
|
+
const result = await query(Document, {
|
|
135
|
+
after: flags.after,
|
|
136
|
+
// "campaignId": 42,
|
|
137
|
+
campaignName: flags.campaign,
|
|
138
|
+
includeTesting: flags.testing,
|
|
139
|
+
limit: flags.limit,
|
|
140
|
+
onlyDoubleOptIn: flags.doi,
|
|
141
|
+
onlyOptIn: flags.optin,
|
|
142
|
+
orgName: flags.org,
|
|
143
|
+
start: flags.start,
|
|
144
|
+
});
|
|
145
|
+
return result.contacts.map((d) => {
|
|
146
|
+
d.customFields = JSON.parse(d.customFields);
|
|
147
|
+
if (!d.contact.publicKey) {
|
|
148
|
+
const ref = d.contactRef;
|
|
149
|
+
d.contact = JSON.parse(d.contact.payload);
|
|
150
|
+
d.contact.contactRef = ref;
|
|
151
|
+
} else {
|
|
152
|
+
this.error(
|
|
153
|
+
`encrypted contact we need the private key for ${d.contact.publicKey.public}`,
|
|
154
|
+
);
|
|
155
|
+
}
|
|
156
|
+
return d;
|
|
157
|
+
});
|
|
158
|
+
// return result.exportActions;
|
|
159
|
+
};
|
|
160
|
+
|
|
161
|
+
simplify = (d) => {
|
|
162
|
+
const result = {
|
|
163
|
+
id: d.actionId,
|
|
164
|
+
firstname: d.contact.firstName,
|
|
165
|
+
country: d.contact.country,
|
|
166
|
+
email: d.contact.email,
|
|
167
|
+
type: d.actionType,
|
|
168
|
+
date: d.createdAt,
|
|
169
|
+
campaign: d.campaign.name,
|
|
170
|
+
widget_id: d.actionPage.id,
|
|
171
|
+
widget: d.actionPage.name,
|
|
172
|
+
// customFields
|
|
173
|
+
};
|
|
174
|
+
if (this.flags.comment && d.customFields?.comment)
|
|
175
|
+
result.comment = d.customFields.comment;
|
|
176
|
+
if (d.customFields?.emailProvider)
|
|
177
|
+
result.provider = d.customFields.emailProvider;
|
|
178
|
+
if (this.flags.utm && d.tracking) {
|
|
179
|
+
result.utm_medium =
|
|
180
|
+
d.tracking.medium === "unknown" ? undefined : d.tracking.medium;
|
|
181
|
+
result.utm_source =
|
|
182
|
+
d.tracking.source === "unknown" ? undefined : d.tracking.source;
|
|
183
|
+
result.utm_campaign =
|
|
184
|
+
d.tracking.campaign === "unknown" ? undefined : d.tracking.campaign;
|
|
185
|
+
if (d.tracking.content)
|
|
186
|
+
result.utm_content =
|
|
187
|
+
d.tracking.content === "unknown" ? undefined : d.tracking.content;
|
|
188
|
+
}
|
|
189
|
+
return result;
|
|
190
|
+
};
|
|
191
|
+
|
|
192
|
+
_table = (r) => {
|
|
193
|
+
super.table(r, null, (table) => table.sort(["id|des"]).toString());
|
|
194
|
+
};
|
|
195
|
+
|
|
196
|
+
async run() {
|
|
197
|
+
const { args, flags } = await this.parse();
|
|
198
|
+
if (flags.today) flags.after = flags.today;
|
|
199
|
+
let data = [];
|
|
200
|
+
|
|
201
|
+
data = await this.fetch(flags);
|
|
202
|
+
return this.output(data);
|
|
203
|
+
}
|
|
204
|
+
}
|
|
@@ -1,96 +0,0 @@
|
|
|
1
|
-
import { Args, Flags } from "@oclif/core";
|
|
2
|
-
import Command from "#src/procaCommand.mjs";
|
|
3
|
-
import { gql, query } from "#src/urql.mjs";
|
|
4
|
-
|
|
5
|
-
export default class CounterGet extends Command {
|
|
6
|
-
static description = "counter of supporters";
|
|
7
|
-
|
|
8
|
-
static examples = [
|
|
9
|
-
"<%= config.bin %> <%= command.id %> --id <id of the campaign>",
|
|
10
|
-
"<%= config.bin %> <%= command.id %> --name <name of the campaign>",
|
|
11
|
-
];
|
|
12
|
-
|
|
13
|
-
static args = this.multiid();
|
|
14
|
-
static flags = {
|
|
15
|
-
// flag with no value (-f, --force)
|
|
16
|
-
...this.flagify({ multiid: true }),
|
|
17
|
-
org: Flags.boolean({
|
|
18
|
-
description: "segment by partner",
|
|
19
|
-
default: false,
|
|
20
|
-
}),
|
|
21
|
-
area: Flags.boolean({
|
|
22
|
-
description: "segment by area",
|
|
23
|
-
default: false,
|
|
24
|
-
}),
|
|
25
|
-
without: Flags.string({
|
|
26
|
-
description: "total to add to the partner's counter",
|
|
27
|
-
}),
|
|
28
|
-
number: Flags.boolean({
|
|
29
|
-
description: "just return the number to add to the partner's counter",
|
|
30
|
-
dependsOn: ["without"],
|
|
31
|
-
}),
|
|
32
|
-
};
|
|
33
|
-
|
|
34
|
-
fetchExcluding = async (params) => {
|
|
35
|
-
const GetCounterDocument = gql`
|
|
36
|
-
query GetCounter($name: String, $id: Int, $without: String!) {
|
|
37
|
-
campaign(name: $name, id: $id) {
|
|
38
|
-
stats {
|
|
39
|
-
supporterCount
|
|
40
|
-
supporterCountByOthers (orgName: $without)
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
}`;
|
|
44
|
-
|
|
45
|
-
const result = await query(GetCounterDocument, params);
|
|
46
|
-
return result.campaign.stats;
|
|
47
|
-
};
|
|
48
|
-
|
|
49
|
-
fetch = async (params) => {
|
|
50
|
-
const GetCounterDocument = gql`
|
|
51
|
-
query GetCounter($name: String, $id: Int, $org: Boolean = false, $area: Boolean = false) {
|
|
52
|
-
campaign(name: $name, id: $id) {
|
|
53
|
-
stats {
|
|
54
|
-
supporterCount
|
|
55
|
-
supporterCountByOrg @include(if: $org) { org { name } count }
|
|
56
|
-
supporterCountByArea @include(if: $area) { area count }
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
}`;
|
|
60
|
-
|
|
61
|
-
const result = await query(GetCounterDocument, params);
|
|
62
|
-
return result.campaign.stats;
|
|
63
|
-
};
|
|
64
|
-
|
|
65
|
-
simplify = (d) => {
|
|
66
|
-
const result = { total: d.supporterCount };
|
|
67
|
-
d.supporterCountByOrg
|
|
68
|
-
?.sort((a, b) => b.count - a.count)
|
|
69
|
-
.forEach((org) => {
|
|
70
|
-
result[org.org.name] = org.count;
|
|
71
|
-
});
|
|
72
|
-
d.supporterCountByArea
|
|
73
|
-
?.sort((a, b) => b.count - a.count)
|
|
74
|
-
.forEach((area) => {
|
|
75
|
-
result[area.area] = area.count;
|
|
76
|
-
});
|
|
77
|
-
if (d.supporterCountByOthers) {
|
|
78
|
-
result[`without ${this.flags.without}`] = d.supporterCountByOthers;
|
|
79
|
-
}
|
|
80
|
-
return result;
|
|
81
|
-
};
|
|
82
|
-
table = (r) => {
|
|
83
|
-
super.table(r, null, null);
|
|
84
|
-
};
|
|
85
|
-
|
|
86
|
-
async run() {
|
|
87
|
-
const { args, flags } = await this.parse();
|
|
88
|
-
if (flags.without) {
|
|
89
|
-
const data = await this.fetchExcluding(flags);
|
|
90
|
-
if (flags.number) return console.log(data.supporterCountByOthers);
|
|
91
|
-
return this.output(data);
|
|
92
|
-
}
|
|
93
|
-
const data = await this.fetch(flags);
|
|
94
|
-
return this.output(data);
|
|
95
|
-
}
|
|
96
|
-
}
|