diff --git a/front/mailing/20240308-weekly-update.ts b/front/mailing/20240308-weekly-update.ts new file mode 100644 index 000000000000..84eec3243c76 --- /dev/null +++ b/front/mailing/20240308-weekly-update.ts @@ -0,0 +1,159 @@ +import sgMail from "@sendgrid/mail"; + +import { front_sequelize } from "@app/lib/databases"; + +const { SENDGRID_API_KEY = "", LIVE = false } = process.env; +sgMail.setApiKey(SENDGRID_API_KEY); + +export const sendAPIUserEmail = async ({ + user_email, + workspace_id, +}: { + user_email: string; + workspace_id: string; +}) => { + const msg = { + to: user_email, + from: "team@dust.tt", + subject: "[Dust] Product Update 1", + html: `

Hi!

+

+ Dust makes work work better with custom AI assistants. +

+

+ The past month has been packed with powerful new features and upgrades. +

+ +

+ ⛵️ Mistral Large Now Available
+ • You can now access Mistral Large via the new @mistral-large global assistant (you can also use it to build custom assistants).
+ • Mistral Large, is the latest and most advanced language model from Mistral.
+ 🔗 https://mistral.ai/news/mistral-large/ +

+ +

+ 🧠 New Cutting-Edge Models from Anthropic
+ • Claude 3 Opus is now powering the @claude-3 global assistant, delivering a major performance boost over Claude 2.1.
+ • Opus is Anthropic's most intelligent model, with best-in-market performance and a very lage context window (200k tokens).
+ • All custom assistants using Claude 2.1 have been automatically upgraded to Claude 3 Opus.
+ 🔗 https://www.anthropic.com/news/claude-3-family +

+ +

+ 📊 Introducing Table Queries
+ • Create custom assistants to perform quantitative queries on Notion databases, Google Sheets, and CSV.
+ • Ask questions like "Show me top customers by revenue" and get back instant insights.
+ • Enable everyone to make data-informed decisions without needing SQL or analytics expertise.
+ 🔗 https://blog.dust.tt/dusts-for-quantitative-analysis-with-llms/ +

+ +

+ 📘 Confluence Connection
+ • Connect your Confluence instance to Dust to sync global spaces and pages.
+ • Simply add Confluence as a data source and let your assistants tap into that collective wisdom.
+

+ +

+ 💬 Intercom Connection
+ • Connect Intercom to sync Help Center articles and customer conversations to Dust.
+ • Choose which Teams to sync conversations from and control access to customer data.
+

+ +

+ 🔒 Okta Single Sign-On
+ • Enterprise customers can ask to enable Okta SSO for an even more seamless and secure authentication experience. Simplify user management by leveraging your existing Okta setup.
+

+ +

+ 🤖 Summon Assistants in Slack
+ • Interact with any Dust assistant right from Slack using the @dust ~assistantname or @dust +assistantname syntax. Bring the power of Dust to the tools you use every day.
+

+ +

+ 📘 Quick Start Guide
+ • We've added a handy walkthrough on first login to explain Dust fundamentals and help new users get oriented. Be sure to check it out!
+

+ +

+ 🏗️ Dust Builders Sessions #1
+ • Tune in on March 14th for our first Dust Sessions for Builders webinar! Folks from Alan, Pennylane, and Payfit will be demoing their innovative support and sales assistants.
+ • Admin and Builders, save your spot now! Send an email to pauline@dust.tt. +

+ +

+ ➕ And more...
+ • Refreshed assistant details page and builder UX.
+ • Experimental instruction suggestions and website crawling settings.
+ • New blog posts: How Eléonore improved the efficiency of Pennylane’s Care team thanks to Dust and Why Dust.
+

+ +

+ Happy building, +

+

+ The Dust Team +

+

+ PS: Simply reply to this email with any questions (or if you wish to unsubscribe from these updates). We're here to help! +

+`, + }; + + await sgMail.send(msg); + + console.log("EMAIL SENT", user_email); +}; + +async function main() { + const [rows] = await front_sequelize.query( + ` +SELECT "u".email user_email, "w"."sId" workspace_id +FROM "users" "u" +JOIN "memberships" "m" ON "u"."id" = "m"."userId" +JOIN "workspaces" "w" ON "m"."workspaceId" = "w"."id" +JOIN "subscriptions" "s" ON "w"."id" = "s"."workspaceId" +WHERE "s"."status" = 'active' +AND "m"."role" != 'revoked'; + ` + ); + + console.log({ count: rows.length }); + + // split rows in chunks of 16 + const chunks: { user_email: string; workspace_id: string }[][] = []; + let chunk: { user_email: string; workspace_id: string }[] = []; + for (let i = 0; i < rows.length; i++) { + chunk.push(rows[i] as { user_email: string; workspace_id: string }); + if (chunk.length === 16) { + chunks.push(chunk); + chunk = []; + } + } + if (chunk.length > 0) { + chunks.push(chunk); + } + + //const chunks: { user_email: string }[][] = [[{ user_email: "team@dust.tt" }]]; + + for (let i = 0; i < chunks.length; i++) { + const chunk = chunks[i]; + console.log("SENDING CHUNK", i, chunk.length); + await Promise.all( + chunk.map((row) => { + console.log("PREPARING EMAIL", row.user_email, row.workspace_id); + if (LIVE && LIVE === "true") { + return sendAPIUserEmail(row); + } else { + return Promise.resolve(); + } + }) + ); + } + + process.exit(0); +} + +void main().then(() => { + console.log("DONE"); + process.exit(0); +});