pbnkp
pbnkp13mo ago

question.. web push notifications having trouble with modules

Hi. I’m new to Deno. Overall I’ve been happy with is performance and how lightweight and secure it is. The place I’m having trouble is building a successful server with modules. For example, most of the imports I need to use aren’t available anymore. Here’s an example of the code I can’t get modules to import with: import { Application, Router } from 'https://deno.land/x/oak/mod.ts'; import { oakCors } from "https://deno.land/x/cors/mod.ts"; import { json } from "https://deno.land/std/http/server.ts"; import { Application, Router, send } from "https://deno.land/x/oak/mod.ts"; import * as path from "https://deno.land/std/path/mod.ts"; import { webpush } from "https://cdn.skypack.dev/web-push"; import { TextDecoder } from "https://deno.land/std/encoding/utf8.ts"; import { crypto } from "https://deno.land/std/node/crypto.ts"; import { renderFileToString } from "https://deno.land/x/dejs/mod.ts"; import { v4 as uuidv4 } from "https://deno.land/std/uuid/mod.ts"; import { Client } from "https://deno.land/x/mysql/mod.ts"; const app = new Application(); const router = new Router(); const port = 3000; // Database const client = new Client(); await client.connect({ hostname: "localhost", port: 3600, db: "mysql", tls: false, }); const db = client.database("subscriptions"); const subscriptionCollection = db.collection("subscription"); // Middlewares app.use(oakCors()); app.use(json()); // Static files app.use(async (ctx) => { await ctx.send({ root: ${Deno.cwd()}/views, index: "index.html", }); }); // Service Worker Notifications // Generate your own vapid keys by running: // deno run --allow-write --allow-read https://deno.land/x/web_push/cli.ts const publicVapidKey = "<<Public Key>>"; const privateVapidKey = "<<Private Key>>"; webpush.setVapidDetails( "mailto:mail@someEmail.com", publicVapidKey, privateVapidKey );
4 Replies
pbnkp
pbnkpOP13mo ago
Here’s the remaining part: // Subscribe router.post("/subscribe", async (ctx) => { try { const body = await ctx.request.body(); const subscription = body.value; const hashValue = crypto.subtle.digest("SHA-256", new TextEncoder().encode(JSON.stringify(subscription))); const hash = Array.from(new Uint8Array(hashValue)).map(byte => byte.toString(16).padStart(2, '0')).join(''); const checkSubscription = await subscriptionCollection.findOne({ hash: hash, }); let theMessage = JSON.stringify({ title: "You have already subscribed", body: "Although we appreciate you trying to again", }); if (!checkSubscription) { const newSubscription = { hash: hash, subscriptionEl: subscription, }; await subscriptionCollection.insertOne(newSubscription); theMessage = JSON.stringify({ title: "Thank you for Subscribing!", body: "Some body message here", }); } ctx.response.status = 201; ctx.response.body = {}; await webpush.sendNotification(subscription, theMessage, { vapidDetails: webpushVapidDetails }); } catch (e) { console.log(e); } }); router.get("/sendwebpushnotification", async (ctx) => { try { const allSubscriptions = await subscriptionCollection.find(); for (const item of allSubscriptions) { let theMessage = JSON.stringify({ title: "Some notification", body: "Some description", }); await webpush.sendNotification(item.subscriptionEl, theMessage, { vapidDetails: webpushVapidDetails }).catch( (error) => { console.error(error.stack); } ); } ctx.response.status = 200; ctx.response.body = { message: "notification sent" }; } catch (e) { console.log(e); } }); app.use(router.routes()); app.use(router.allowedMethods()); router.use("/", router.routes()); app.use(router.routes()); app.use(router.allowedMethods()); await app.listen({ port: 80 }); const mail = "random@mydomain"; const publicKey = "vapidpub"; const privateKey = "vapidpriv"; // (E) SEND TEST PUSH NOTIFICATION router.get("/", async (ctx) => { await send(ctx, "/testme.html", { root: Deno.cwd() }); }); router.post("/goodboy", async (ctx) => { ctx.response.status = 201; ctx.response.body = {}; try { await webpush.sendNotification(ctx.request.body, JSON.stringify({ title: "😊", body: "👍🏼", icon: "i-ico.png", image: "i-banner.png" }), { vapidDetails: webpushVapidDetails }); } catch (err) { console.log(err); } }); // (F) START! app.listen(port, () => console.log(🙏🏽 is live on port ${port}));
raunioroo
raunioroo13mo ago
There's a couple of problems. - you are importing oak Application and Router twice * To avoid issues with changing modules you should use explicit versions in import urls. You can keep using old deno.land/std modules as long as you specify a version * I don't think you need to use skypack anymore, use deno's built-in node compat layer instead by importing with "npm:web-push" * Not sure why textdecoder from std is needed since it's a built in api that's usable without importing anything * Same for crypto
sr_martines
sr_martines13mo ago
npm:web-push have a problem with crypto lib. I can't use it on my project, instead I create another service on Vercel with standard node app to only send notifications with web-push lib. See this comment: https://github.com/denoland/deno/issues/20851#issuecomment-1765501127
GitHub
☂️ Node/npm compatibility issue for Q4 2023 · Issue #20851 · denola...
This is an umbrella issue for Node.js/npm compatibility work that we will undertake in Q4 2023. We made a lot of progress in Q2 with polyfills for node:http, node:https and node:http2 getting more ...
pbnkp
pbnkpOP13mo ago
Thank you I’m going to try that. I’m still learning Deno and coming from php it’s been a bit of a curve but one that I’m loving and happy to be moving to. I’m working on each area of a production level system so we are 100% Deno and increase performance. Dam that was a long 18 + hours trying to make my code function. Just when I was so close to finishing it there were just so many failures and the web push library from NPM I converted to Deno wouldn’t work without the crypto module.