1 | # Event Handlers
|
2 |
|
3 | Event handlers are triggered by events that create or update entities
|
4 | in the Atomist Cortex that meet certain criteria.
|
5 |
|
6 | ## Setting Up a Subscription
|
7 |
|
8 | First, define a query representing the data you want to match on. You
|
9 | typically begin by exploring Cortex data using a GraphQL
|
10 | client. GraphiQL is a great choice.
|
11 |
|
12 | You will get assistance for writing your queries, and see the shape of
|
13 | the resulting data.
|
14 |
|
15 | ![GraphiQL browser](images/graphiql.png)
|
16 |
|
17 | Once you're happy with your query, add it beginning with
|
18 | `subscription` to the `/graphql` directory of your project.
|
19 |
|
20 | Based on your query it is possible to generate TypeScript types that
|
21 | you can use in your handler code. In order to allow type generation
|
22 | you need to set up your project in the following way:
|
23 |
|
24 | ```
|
25 | $ npm install --save-dev graphql-code-generator
|
26 | ```
|
27 |
|
28 | And add the following to the `scripts` section of your `package.json`:
|
29 |
|
30 | ```javascript
|
31 | "gql:gen": "ql-gen --file node_modules/@atomist/automation-client/graph/schema.cortex.json --template typescript -m --out ./src/typings/ './graphql/**/*.graphql'"
|
32 | ```
|
33 |
|
34 | Next, generate TypeScript types for your query returns and variables:
|
35 |
|
36 | ```
|
37 | $ npm run gql:gen
|
38 | ```
|
39 |
|
40 | You can rerun this command at any time, if you add or change queries.
|
41 |
|
42 | Now import the generated types in your event handlers.
|
43 |
|
44 | A subscription is set up by referencing the appropriate GraphQL file as follows, using the `EventHandler` decorator:
|
45 |
|
46 | ```typescript
|
47 | @EventHandler("Event handler that notifies upstream PR of failed downstream build",
|
48 | GraphQL.subscriptionFromFile("graphql/cascadeBuildCompleted"))
|
49 | @Tags("cascade", "build", "status")
|
50 | export class SetUpstreamStatusOnBuildCompletion implements HandleEvent<graphql.BuildCompleted.Subscription> {
|
51 |
|
52 | @Secret(Secrets.ORG_TOKEN)
|
53 | public githubToken: string;
|
54 |
|
55 | public handle(root: EventFired<graphql.BuildCompleted.Subscription>,
|
56 | ctx: HandlerContext): Promise<HandlerResult> {
|
57 | // ... implementation
|
58 | }
|
59 | ```
|
60 |
|
61 | An event handler may do further filtering on the argument passed in,
|
62 | if it needs to apply criteria that cannot be expressed in GraphQL.
|
63 |
|
64 | Otherwise, the implementation of an event handler is similar to a
|
65 | command handler. It also returns a promise. However, the concept of
|
66 | a response message does not apply, as an event handler is not invoked
|
67 | from a command issued in a Slack channel. Even handlers can send
|
68 | messages directed to specific channels and/or users.
|