Skip to content

Commit 9712039

Browse files
committed
Add internal notes support to Gorgias OAuth integration
- Add channel prop to create-ticket-message action with internal-note support - Add conditional logic to skip sender/receiver validation for internal notes - Create internal-note-created webhook source for monitoring internal note events - Add JSDoc documentation to all methods - Update package.json version
1 parent acc9e22 commit 9712039

File tree

4 files changed

+187
-47
lines changed

4 files changed

+187
-47
lines changed

components/gorgias_oauth/actions/create-ticket-message/create-ticket-message.mjs

Lines changed: 80 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ export default {
77
key: "gorgias_oauth-create-ticket-message",
88
name: "Create Ticket Message",
99
description: "Create a message for a ticket in the Gorgias system. [See the documentation](https://developers.gorgias.com/reference/create-ticket-message)",
10-
version: "0.0.2",
10+
version: "0.0.3",
1111
type: "action",
1212
props: {
1313
gorgiasOauth,
@@ -67,6 +67,15 @@ export default {
6767
label: "Message",
6868
description: "Message of the ticket. Accepts HTML",
6969
},
70+
channel: {
71+
propDefinition: [
72+
gorgiasOauth,
73+
"channel",
74+
],
75+
optional: false,
76+
default: "email",
77+
reloadProps: true,
78+
},
7079
via: {
7180
propDefinition: [
7281
gorgiasOauth,
@@ -101,13 +110,20 @@ export default {
101110
},
102111
},
103112
additionalProps(props) {
104-
props.toUser.hidden = this.fromAgent;
105-
props.fromCustomer.hidden = this.fromAgent;
106-
props.toCustomer.hidden = !this.fromAgent;
107-
props.fromUser.hidden = !this.fromAgent;
113+
const isInternalNote = this.channel === "internal-note";
114+
props.toUser.hidden = this.fromAgent || isInternalNote;
115+
props.fromCustomer.hidden = this.fromAgent || isInternalNote;
116+
props.toCustomer.hidden = !this.fromAgent || isInternalNote;
117+
props.fromUser.hidden = !this.fromAgent || isInternalNote;
108118
return {};
109119
},
110120
methods: {
121+
/**
122+
* Get attachment information from URL
123+
* @param {object} $ - Step object
124+
* @param {string} url - Attachment URL
125+
* @returns {object} Content type and size information
126+
*/
111127
async getAttachmentInfo($, url) {
112128
const { headers } = await axios($, {
113129
method: "HEAD",
@@ -119,6 +135,13 @@ export default {
119135
size: headers["content-length"],
120136
};
121137
},
138+
/**
139+
* Get email address for user or customer
140+
* @param {object} $ - Step object
141+
* @param {string} id - User or customer ID
142+
* @param {string} type - Type of email to get (from/to)
143+
* @returns {string} Email address
144+
*/
122145
async getEmail($, id, type = "from") {
123146
const {
124147
gorgiasOauth: {
@@ -147,6 +170,8 @@ export default {
147170
throw new ConfigurationError("Must enter both Attachment URL and Attachment File Name");
148171
}
149172

173+
const isInternalNote = this.channel === "internal-note";
174+
150175
let contentType, size;
151176
if (this.attachmentUrl) {
152177
({
@@ -162,55 +187,64 @@ export default {
162187
? this.toCustomer
163188
: this.toUser;
164189

165-
if (!fromId) {
166-
throw new ConfigurationError(`"${this.fromAgent
167-
? "From User"
168-
: "From Customer"}" is required when "From Agent" is set to \`${this.fromAgent}\``);
169-
}
170-
if (!toId) {
171-
throw new ConfigurationError(`"${this.fromAgent
172-
? "To Customer"
173-
: "To User"}" is required when "From Agent" is set to \`${this.fromAgent}\``);
190+
// For internal notes, we don't need from/to validation
191+
if (!isInternalNote) {
192+
if (!fromId) {
193+
throw new ConfigurationError(`"${this.fromAgent
194+
? "From User"
195+
: "From Customer"}" is required when "From Agent" is set to \`${this.fromAgent}\``);
196+
}
197+
if (!toId) {
198+
throw new ConfigurationError(`"${this.fromAgent
199+
? "To Customer"
200+
: "To User"}" is required when "From Agent" is set to \`${this.fromAgent}\``);
201+
}
174202
}
175203

176-
const response = await this.gorgiasOauth.createMessage({
177-
$,
178-
ticketId: this.ticketId,
179-
data: {
180-
channel: "email",
181-
source: {
182-
from: {
183-
address: await this.getEmail($, fromId, "from"),
184-
},
185-
to: [
186-
{
187-
address: await this.getEmail($, toId, "to"),
188-
},
189-
],
204+
const messageData = {
205+
channel: this.channel,
206+
body_html: this.message,
207+
via: this.via,
208+
subject: this.subject,
209+
from_agent: this.fromAgent,
210+
sent_datetime: this.sentDatetime,
211+
attachments: this.attachmentUrl && [
212+
{
213+
url: this.attachmentUrl,
214+
name: this.attachmentName,
215+
content_type: contentType,
216+
size,
190217
},
191-
body_html: this.message,
192-
via: this.via,
193-
subject: this.subject,
194-
from_agent: this.fromAgent,
195-
sent_datetime: this.sentDatetime,
196-
attachments: this.attachmentUrl && [
218+
],
219+
};
220+
221+
// Only add source, sender, and receiver for non-internal notes
222+
if (!isInternalNote) {
223+
messageData.source = {
224+
from: {
225+
address: await this.getEmail($, fromId, "from"),
226+
},
227+
to: [
197228
{
198-
url: this.attachmentUrl,
199-
name: this.attachmentName,
200-
content_type: contentType,
201-
size,
229+
address: await this.getEmail($, toId, "to"),
202230
},
203231
],
204-
sender: {
205-
id: fromId,
206-
},
207-
receiver: {
208-
id: toId,
209-
},
210-
},
232+
};
233+
messageData.sender = {
234+
id: fromId,
235+
};
236+
messageData.receiver = {
237+
id: toId,
238+
};
239+
}
240+
241+
const response = await this.gorgiasOauth.createMessage({
242+
$,
243+
ticketId: this.ticketId,
244+
data: messageData,
211245
});
212246

213-
$.export("$summary", `Succesfully created ticket message with ID: ${response.id}`);
247+
$.export("$summary", `Successfully created ${isInternalNote ? "internal note" : "ticket message"} with ID: ${response.id}`);
214248

215249
return response;
216250
},

components/gorgias_oauth/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@pipedream/gorgias_oauth",
3-
"version": "0.5.1",
3+
"version": "0.5.2",
44
"description": "Pipedream Gorgias OAuth Components",
55
"main": "gorgias_oauth.app.mjs",
66
"keywords": [
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
import constants from "../../common/constants.mjs";
2+
import base from "../common/base.mjs";
3+
import eventTypes from "../common/event-types.mjs";
4+
import sampleEmit from "./test-event.mjs";
5+
6+
export default {
7+
...base,
8+
key: "gorgias_oauth-internal-note-created",
9+
name: "New Internal Note",
10+
description: "Emit new event when an internal note is created on a ticket. [See the documentation](https://developers.gorgias.com/reference/the-event-object)",
11+
version: "0.0.1",
12+
type: "source",
13+
props: {
14+
...base.props,
15+
ticketId: {
16+
propDefinition: [
17+
base.props.gorgias_oauth,
18+
"ticketId",
19+
],
20+
optional: true,
21+
},
22+
sender: {
23+
type: "string",
24+
label: "Sender Email",
25+
description: "Email address of the sender",
26+
optional: true,
27+
},
28+
},
29+
hooks: {
30+
...base.hooks,
31+
},
32+
methods: {
33+
...base.methods,
34+
/**
35+
* Get the event type for internal notes
36+
* @returns {string} The event type
37+
*/
38+
getEventType() {
39+
return eventTypes.TICKET_MESSAGE_CREATED;
40+
},
41+
/**
42+
* Check if a message is relevant for this source
43+
* @param {object} message - The message object
44+
* @returns {boolean} Whether the message is relevant
45+
*/
46+
isRelevant(message) {
47+
return message.channel === "internal-note"
48+
&& (!this.ticketId || message.ticket_id === this.ticketId)
49+
&& (!this.sender || message.sender?.email === this.sender);
50+
},
51+
/**
52+
* Process and emit relevant events
53+
* @param {object} event - The incoming event
54+
*/
55+
async processEvent(event) {
56+
const { message } = event;
57+
if (this.isRelevant(message)) {
58+
this.emitEvent(message);
59+
}
60+
},
61+
},
62+
sampleEmit,
63+
};
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
export default {
2+
id: 123456789,
3+
created_datetime: "2024-01-15T10:30:00Z",
4+
updated_datetime: "2024-01-15T10:30:00Z",
5+
ticket_id: 98765,
6+
channel: "internal-note",
7+
via: "internal-note",
8+
source: {
9+
type: "internal-note",
10+
from: {
11+
address: "[email protected]",
12+
name: "Support Agent"
13+
},
14+
to: []
15+
},
16+
sender: {
17+
id: 456,
18+
19+
name: "Support Agent"
20+
},
21+
receiver: null,
22+
body_html: "<p>This is an internal note about the customer's issue.</p>",
23+
body_text: "This is an internal note about the customer's issue.",
24+
subject: "Internal Note",
25+
from_agent: true,
26+
sent_datetime: "2024-01-15T10:30:00Z",
27+
attachments: [],
28+
public: false,
29+
stripped_html: "<p>This is an internal note about the customer's issue.</p>",
30+
stripped_text: "This is an internal note about the customer's issue.",
31+
stripped_signature: "",
32+
message_id: "internal-note-123456789",
33+
actions: [],
34+
rule_id: null,
35+
external_id: null,
36+
tags: [],
37+
integration_id: null,
38+
last_sending_error: null,
39+
opened_datetime: null,
40+
clicked_datetime: null,
41+
failed_datetime: null,
42+
errors: []
43+
};

0 commit comments

Comments
 (0)