Skip to content

Commit f7d27f3

Browse files
committed
quriiri init
1 parent 1e4db9a commit f7d27f3

File tree

3 files changed

+377
-1
lines changed

3 files changed

+377
-1
lines changed
Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
import quriiri from "../../quriiri.app.mjs";
2+
3+
export default {
4+
key: "quriiri-send-message",
5+
name: "Send Message",
6+
description: "Sends an SMS message using the Quriiri API. [See the documentation](https://docs.quriiri.fi/docs/quriiri/send-sms/operations/create-a)",
7+
version: "0.0.{{ts}}",
8+
type: "action",
9+
props: {
10+
quriiri: {
11+
type: "app",
12+
app: "quriiri",
13+
},
14+
sender: {
15+
propDefinition: [
16+
quriiri,
17+
"sender",
18+
],
19+
},
20+
destination: {
21+
propDefinition: [
22+
quriiri,
23+
"destination",
24+
],
25+
},
26+
text: {
27+
propDefinition: [
28+
quriiri,
29+
"text",
30+
],
31+
},
32+
senderType: {
33+
propDefinition: [
34+
quriiri,
35+
"senderType",
36+
],
37+
optional: true,
38+
},
39+
data: {
40+
propDefinition: [
41+
quriiri,
42+
"data",
43+
],
44+
optional: true,
45+
},
46+
udh: {
47+
propDefinition: [
48+
quriiri,
49+
"udh",
50+
],
51+
optional: true,
52+
},
53+
batchId: {
54+
propDefinition: [
55+
quriiri,
56+
"batchId",
57+
],
58+
optional: true,
59+
},
60+
billingRef: {
61+
propDefinition: [
62+
quriiri,
63+
"billingRef",
64+
],
65+
optional: true,
66+
},
67+
drUrl: {
68+
propDefinition: [
69+
quriiri,
70+
"drUrl",
71+
],
72+
optional: true,
73+
},
74+
drType: {
75+
propDefinition: [
76+
quriiri,
77+
"drType",
78+
],
79+
optional: true,
80+
},
81+
flash: {
82+
propDefinition: [
83+
quriiri,
84+
"flash",
85+
],
86+
optional: true,
87+
},
88+
validity: {
89+
propDefinition: [
90+
quriiri,
91+
"validity",
92+
],
93+
optional: true,
94+
},
95+
scheduleTime: {
96+
propDefinition: [
97+
quriiri,
98+
"scheduleTime",
99+
],
100+
optional: true,
101+
},
102+
},
103+
async run({ $ }) {
104+
const response = await this.quriiri.sendSms({
105+
sender: this.sender,
106+
destination: this.destination,
107+
text: this.text,
108+
senderType: this.senderType,
109+
data: this.data,
110+
udh: this.udh,
111+
batchId: this.batchId,
112+
billingRef: this.billingRef,
113+
drUrl: this.drUrl,
114+
drType: this.drType,
115+
flash: this.flash,
116+
validity: this.validity,
117+
scheduleTime: this.scheduleTime,
118+
});
119+
$.export("$summary", `Message sent successfully to ${this.destination}`);
120+
return response;
121+
},
122+
};

components/quriiri/quriiri.app.mjs

Lines changed: 166 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,176 @@
1+
import { axios } from "@pipedream/platform";
2+
13
export default {
24
type: "app",
35
app: "quriiri",
4-
propDefinitions: {},
6+
version: "0.0.{{ts}}",
7+
propDefinitions: {
8+
// Required props
9+
sender: {
10+
type: "string",
11+
label: "Sender",
12+
description: "The phone number or sender ID sending the SMS",
13+
},
14+
destination: {
15+
type: "string",
16+
label: "Destination",
17+
description: "The recipient's phone number",
18+
},
19+
text: {
20+
type: "string",
21+
label: "Text",
22+
description: "The message content",
23+
},
24+
// Optional props
25+
senderType: {
26+
type: "string",
27+
label: "Sender Type",
28+
description: "The type of sender",
29+
optional: true,
30+
},
31+
data: {
32+
type: "string",
33+
label: "Data",
34+
description: "Additional data",
35+
optional: true,
36+
},
37+
udh: {
38+
type: "string",
39+
label: "UDH",
40+
description: "User Data Header",
41+
optional: true,
42+
},
43+
batchId: {
44+
type: "string",
45+
label: "Batch ID",
46+
description: "Batch identifier",
47+
optional: true,
48+
},
49+
billingRef: {
50+
type: "string",
51+
label: "Billing Reference",
52+
description: "Billing reference",
53+
optional: true,
54+
},
55+
drUrl: {
56+
type: "string",
57+
label: "Delivery Receipt URL",
58+
description: "URL to receive delivery receipts",
59+
optional: true,
60+
},
61+
drType: {
62+
type: "string",
63+
label: "Delivery Receipt Type",
64+
description: "Type of delivery receipt",
65+
optional: true,
66+
},
67+
flash: {
68+
type: "boolean",
69+
label: "Flash",
70+
description: "Send as flash SMS",
71+
optional: true,
72+
},
73+
validity: {
74+
type: "integer",
75+
label: "Validity",
76+
description: "Validity period of the message in minutes",
77+
optional: true,
78+
},
79+
scheduleTime: {
80+
type: "string",
81+
label: "Schedule Time",
82+
description: "Time to schedule the message (ISO 8601 format)",
83+
optional: true,
84+
},
85+
},
586
methods: {
687
// this.$auth contains connected account data
788
authKeys() {
889
console.log(Object.keys(this.$auth));
990
},
91+
_baseUrl() {
92+
return "https://api.quriiri.fi";
93+
},
94+
async _makeRequest(opts = {}) {
95+
const {
96+
$, method = "GET", path = "/", headers, ...otherOpts
97+
} = opts;
98+
return axios($, {
99+
...otherOpts,
100+
method,
101+
url: this._baseUrl() + path,
102+
headers: {
103+
...headers,
104+
Authorization: `Bearer ${this.$auth.api_key}`,
105+
},
106+
});
107+
},
108+
async sendSms(opts = {}) {
109+
const {
110+
sender,
111+
destination,
112+
text,
113+
senderType,
114+
data,
115+
udh,
116+
batchId,
117+
billingRef,
118+
drUrl,
119+
drType,
120+
flash,
121+
validity,
122+
scheduleTime,
123+
} = opts;
124+
125+
const payload = {
126+
sender: sender,
127+
destination: destination,
128+
text: text,
129+
};
130+
131+
if (senderType) payload.senderType = senderType;
132+
if (data) payload.data = data;
133+
if (udh) payload.udh = udh;
134+
if (batchId) payload.batchId = batchId;
135+
if (billingRef) payload.billingRef = billingRef;
136+
if (drUrl) payload.drUrl = drUrl;
137+
if (drType) payload.drType = drType;
138+
if (flash !== undefined) payload.flash = flash;
139+
if (validity !== undefined) payload.validity = validity;
140+
if (scheduleTime) payload.scheduleTime = scheduleTime;
141+
142+
return this._makeRequest({
143+
method: "POST",
144+
path: "/send-sms",
145+
data: payload,
146+
});
147+
},
148+
async listIncomingMessages(opts = {}) {
149+
return this._makeRequest({
150+
method: "GET",
151+
path: "/messages/incoming",
152+
params: opts,
153+
});
154+
},
155+
async paginate(fn, ...opts) {
156+
const results = [];
157+
let more = true;
158+
let page = 1;
159+
160+
while (more) {
161+
const response = await fn({
162+
...opts,
163+
page,
164+
});
165+
if (response.length === 0) {
166+
more = false;
167+
} else {
168+
results.push(...response);
169+
page += 1;
170+
}
171+
}
172+
173+
return results;
174+
},
10175
},
11176
};
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
import {
2+
axios, DEFAULT_POLLING_SOURCE_TIMER_INTERVAL,
3+
} from "@pipedream/platform";
4+
import quriiri from "../../quriiri.app.mjs";
5+
6+
export default {
7+
key: "quriiri-new-message",
8+
name: "New Quriiri Message",
9+
description: "Emit a new event when a message is received at a specific phone number. [See the documentation]()",
10+
version: "0.0.{{ts}}",
11+
type: "source",
12+
dedupe: "unique",
13+
props: {
14+
quriiri,
15+
db: "$.service.db",
16+
timer: {
17+
type: "$.interface.timer",
18+
default: {
19+
intervalSeconds: DEFAULT_POLLING_SOURCE_TIMER_INTERVAL,
20+
},
21+
},
22+
destinationPhoneNumber: {
23+
type: "string",
24+
label: "Destination Phone Number",
25+
description: "The specific phone number to monitor for incoming messages.",
26+
},
27+
},
28+
hooks: {
29+
async deploy() {
30+
const destinationPhoneNumber = this.destinationPhoneNumber;
31+
const messages = await this.quriiri.paginate(this.quriiri.listIncomingMessages);
32+
const filteredMessages = messages.filter(
33+
(msg) => msg.destination === destinationPhoneNumber,
34+
);
35+
const sortedMessages = filteredMessages.sort(
36+
(a, b) => new Date(b.timestamp) - new Date(a.timestamp),
37+
);
38+
const recentMessages = sortedMessages.slice(0, 50).reverse();
39+
for (const message of recentMessages) {
40+
this.$emit(message, {
41+
id: message.id || new Date(message.timestamp).getTime(),
42+
summary: `New message from ${message.sender}`,
43+
ts: new Date(message.timestamp).getTime(),
44+
});
45+
}
46+
const latestTimestamp = recentMessages.reduce(
47+
(max, msg) => (new Date(msg.timestamp).getTime() > max
48+
? new Date(msg.timestamp).getTime()
49+
: max),
50+
0,
51+
);
52+
await this.db.set("lastTimestamp", latestTimestamp);
53+
},
54+
async activate() {
55+
// Activation logic can be added here if necessary
56+
},
57+
async deactivate() {
58+
// Deactivation logic can be added here if necessary
59+
},
60+
},
61+
async run() {
62+
const destinationPhoneNumber = this.destinationPhoneNumber;
63+
const lastTimestamp = (await this.db.get("lastTimestamp")) || 0;
64+
const messages = await this.quriiri.listIncomingMessages({
65+
since: lastTimestamp,
66+
});
67+
const filteredMessages = messages.filter(
68+
(msg) => msg.destination === destinationPhoneNumber,
69+
);
70+
for (const message of filteredMessages) {
71+
this.$emit(message, {
72+
id: message.id || new Date(message.timestamp).getTime(),
73+
summary: `New message from ${message.sender}`,
74+
ts: message.timestamp
75+
? new Date(message.timestamp).getTime()
76+
: Date.now(),
77+
});
78+
}
79+
if (filteredMessages.length > 0) {
80+
const latestTimestamp = filteredMessages.reduce(
81+
(max, msg) => (new Date(msg.timestamp).getTime() > max
82+
? new Date(msg.timestamp).getTime()
83+
: max),
84+
lastTimestamp,
85+
);
86+
await this.db.set("lastTimestamp", latestTimestamp);
87+
}
88+
},
89+
};

0 commit comments

Comments
 (0)