//native
import * as wmill from "windmill-client"
/**
* New Email
* Emits messages received in a folder (default `inbox`) since the last poll, oldest first. The first run sets the watermark to now and emits nothing. Polls because Microsoft Graph push needs a change-notification subscription renewed every few days against a public endpoint, which belongs in a Windmill native trigger; run this as a Scheduled Poll until then. Requires Mail.Read (covered by the default Mail.ReadWrite) (a shared mailbox needs Mail.Read.Shared, not a default).
*/
export async function main(
auth: RT.MsOutlook,
folder: string = "inbox",
mailbox: string | undefined
) {
// `seen` holds the ids already emitted for the watermark second, since
// receivedDateTime only has second precision and the filter is inclusive.
const state: { since: string; seen: string[] } | undefined =
await wmill.getState()
// First run: set the watermark to now and don't emit a backlog.
if (!state?.since) {
await wmill.setState({
since: new Date().toISOString().replace(/\.\d+Z$/, "Z"),
seen: [],
})
return []
}
const base = `https://graph.microsoft.com/v1.0/${
mailbox != null && mailbox !== ""
? `users/${encodeURIComponent(mailbox)}`
: "me"
}`
const first = new URL(
`${base}/mailFolders/${encodeURIComponent(folder)}/messages`
)
first.searchParams.append("$filter", `receivedDateTime ge ${state.since}`)
first.searchParams.append("$orderby", "receivedDateTime asc")
first.searchParams.append("$top", "100")
const messages: { id: string; receivedDateTime: string }[] = []
let next: string | undefined = first.toString()
while (next) {
const response = await fetch(next, {
headers: {
Authorization: `Bearer ${auth.token}`,
Accept: "application/json",
},
})
if (!response.ok) {
throw new Error(`${response.status} ${await response.text()}`)
}
const page = (await response.json()) as {
value: { id: string; receivedDateTime: string }[]
"@odata.nextLink"?: string
}
messages.push(...page.value)
next = page["@odata.nextLink"]
}
const fresh = messages.filter((m) => !state.seen.includes(m.id))
if (fresh.length > 0) {
const since = messages[messages.length - 1].receivedDateTime
await wmill.setState({
since,
seen: messages
.filter((m) => m.receivedDateTime === since)
.map((m) => m.id),
})
}
return fresh
}
Submitted by hugo989 2 hours ago
//native
import * as wmill from "windmill-client"
/**
* New Email
* Emits messages received in a folder (default `inbox`) since the last poll, oldest first. The first run sets the watermark to now and emits nothing. Polls because Microsoft Graph push needs a change-notification subscription renewed every few days against a public endpoint, which belongs in a Windmill native trigger; run this as a Scheduled Poll until then. Requires Mail.Read (covered by the default Mail.ReadWrite) (a shared mailbox needs Mail.Read.Shared, not a default).
*/
export async function main(
auth: RT.Outlook,
folder: string = "inbox",
mailbox: string | undefined
) {
// `seen` holds the ids already emitted for the watermark second, since
// receivedDateTime only has second precision and the filter is inclusive.
const state: { since: string; seen: string[] } | undefined =
await wmill.getState()
// First run: set the watermark to now and don't emit a backlog.
if (!state?.since) {
await wmill.setState({
since: new Date().toISOString().replace(/\.\d+Z$/, "Z"),
seen: [],
})
return []
}
const base = `https://graph.microsoft.com/v1.0/${
mailbox != null && mailbox !== ""
? `users/${encodeURIComponent(mailbox)}`
: "me"
}`
const first = new URL(
`${base}/mailFolders/${encodeURIComponent(folder)}/messages`
)
first.searchParams.append("$filter", `receivedDateTime ge ${state.since}`)
first.searchParams.append("$orderby", "receivedDateTime asc")
first.searchParams.append("$top", "100")
const messages: { id: string; receivedDateTime: string }[] = []
let next: string | undefined = first.toString()
while (next) {
const response = await fetch(next, {
headers: {
Authorization: `Bearer ${auth.token}`,
Accept: "application/json",
},
})
if (!response.ok) {
throw new Error(`${response.status} ${await response.text()}`)
}
const page = (await response.json()) as {
value: { id: string; receivedDateTime: string }[]
"@odata.nextLink"?: string
}
messages.push(...page.value)
next = page["@odata.nextLink"]
}
const fresh = messages.filter((m) => !state.seen.includes(m.id))
if (fresh.length > 0) {
const since = messages[messages.length - 1].receivedDateTime
await wmill.setState({
since,
seen: messages
.filter((m) => m.receivedDateTime === since)
.map((m) => m.id),
})
}
return fresh
}
Submitted by hugo989 11 hours ago
//native
import * as wmill from "windmill-client"
/**
* New Email
* Emits messages received in a folder (default `inbox`) since the last poll, oldest first. The first run sets the watermark to now and emits nothing. Polls because Microsoft Graph push needs a change-notification subscription renewed every few days against a public endpoint, which belongs in a Windmill native trigger; run this as a Scheduled Poll until then. Requires Mail.Read on the connection (Mail.Read.Shared for a shared mailbox).
*/
export async function main(
auth: RT.Outlook,
folder: string = "inbox",
mailbox: string | undefined
) {
// `seen` holds the ids already emitted for the watermark second, since
// receivedDateTime only has second precision and the filter is inclusive.
const state: { since: string; seen: string[] } | undefined =
await wmill.getState()
// First run: set the watermark to now and don't emit a backlog.
if (!state?.since) {
await wmill.setState({
since: new Date().toISOString().replace(/\.\d+Z$/, "Z"),
seen: [],
})
return []
}
const base = `https://graph.microsoft.com/v1.0/${
mailbox != null && mailbox !== ""
? `users/${encodeURIComponent(mailbox)}`
: "me"
}`
const first = new URL(
`${base}/mailFolders/${encodeURIComponent(folder)}/messages`
)
first.searchParams.append("$filter", `receivedDateTime ge ${state.since}`)
first.searchParams.append("$orderby", "receivedDateTime asc")
first.searchParams.append("$top", "100")
const messages: { id: string; receivedDateTime: string }[] = []
let next: string | undefined = first.toString()
while (next) {
const response = await fetch(next, {
headers: {
Authorization: `Bearer ${auth.token}`,
Accept: "application/json",
},
})
if (!response.ok) {
throw new Error(`${response.status} ${await response.text()}`)
}
const page = (await response.json()) as {
value: { id: string; receivedDateTime: string }[]
"@odata.nextLink"?: string
}
messages.push(...page.value)
next = page["@odata.nextLink"]
}
const fresh = messages.filter((m) => !state.seen.includes(m.id))
if (fresh.length > 0) {
const since = messages[messages.length - 1].receivedDateTime
await wmill.setState({
since,
seen: messages
.filter((m) => m.receivedDateTime === since)
.map((m) => m.id),
})
}
return fresh
}
Submitted by hugo989 11 hours ago