npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

ws-cloud-api

v0.7.0-alpha

Published

WhatsApp Cloud API for NodeJS

Downloads

322

Readme

Simple WhatsApp Cloud API library

A simple-to-use library for sending messages and templates to WhatsApp numbers and detecting message events via webhook using cloud API.

Features

Webhook

Functions to verify webhook token and handle message webhook notifications to get messages content of from:

  • Text message
  • Button reply
  • List reply
  • Voice audio
  • Flow reply

Send messages

You can send messages of the following types:

Messages

Templates

Media

Functions to handle WhatsApp media

Config

To use the library you have to add the next env variables to your env file.

Messaging

WS_CA_VERSION='19.0'
WS_PHONE_NUMBER_ID=
WS_TOKEN=

Webhook

WS_VERIFY_TOKEN=

Usage

Webhook

How to handle messages events

import { handleWebhook } from "ws-cloud-api/webhook";
import express from "express";

const app = express();
const port = 3000;

app.use(express.json());

app.post("/whatsapp-webhook", async (req, res) => {
  try {
    const event = handleWebhook(req.body);

    if (event?.type === "message") {
      console.log(`New message from ${event.from}: ${event.message}`);
    }

    if (event?.type === "voiceAudio") {
      console.log(`New voice message from ${event.from}: ${event.audio.id}`);
    }

    if (event?.type === "flowReply") {
      console.log(
        `New flow reply from ${event.from}:\n\n`,
        JSON.stringify(event.flow, null, 2)
      );
    }

    res.status(200);
  } catch (error) {
    console.error("Error:", error);
    res.status(500).send("Internal server error");
  }
});

app.listen(port, () => {
  console.log(`Server start`);
});

Messages

Send Text

import { sendText } from "ws-cloud-api/messaging";

sendText({
  to: process.env.PHONE_NUMBER_RECIPIENT,
  message: "This is a test message"
})
  .then((sentSuccess) => {
    if (sentSuccess) {
      console.log("Message sent");
    }
  })
  .catch(console.error);

sendText({
  to: process.env.PHONE_NUMBER_RECIPIENT,
  message: "https://www.youtube.com/watch?v=L9jpMYn8q0g&pp=ygUjeW91IHRvIHlvdSBhc2lhbiBrdW5nIGZ1IGdlbmVyYXRpb24%3D",
  previewUrl: true
})
  .then((sentSuccess) => {
    if (sentSuccess) {
      console.log("Message with preview sent");
    }
  })
  .catch(console.error);

Send Image

import { sendImage } from "ws-cloud-api/messaging";

sendImage({
  to: process.env.PHONE_NUMBER_RECIPIENT,
  link: "https://example.com/image.jpg",
})
  .then((sentSuccess) => {
    if (sentSuccess) {
      console.log("Image sent");
    }
  })
  .catch(console.error);

Send Video

import { sendVideo } from "ws-cloud-api/messaging";

sendVideo({
  to: process.env.PHONE_NUMBER_RECIPIENT,
  link: "https://example.com/video.mp4",
})
  .then((sentSuccess) => {
    if (sentSuccess) {
      console.log("Video sent");
    }
  })
  .catch(console.error);

Send Document

import { sendDocument } from "ws-cloud-api/messaging";

sendDocument({
  to: process.env.PHONE_NUMBER_RECIPIENT,
  link: "https://example.com/document.pdf",
  filename: "document.pdf",
  caption: "Test document message",
})
  .then((sentSuccess) => {
    if (sentSuccess) {
      console.log("Document sent");
    }
  })
  .catch(console.error);

Send Audio

import { sendAudio } from "ws-cloud-api/messaging";

sendAudio({
  to: process.env.PHONE_NUMBER_RECIPIENT,
  link: "https://example.com/audio.mp3",
})
  .then((sentSuccess) => {
    if (sentSuccess) {
      console.log("Audio sent");
    }
  })
  .catch(console.error);

Send File

Supported files:

  • Images:
    • image/jpeg
    • image/png
  • Documents:
    • text/plain
    • application/pdf
    • application/vnd.ms-powerpoint
    • application/msword
    • application/vnd.ms-excel
    • application/vnd.openxmlformats-officedocument.wordprocessingml.document
    • application/vnd.openxmlformats-officedocument.presentationml.presentation
    • application/vnd.openxmlformats-officedocument.spreadsheetml.sheet
  • Audio:
    • audio/aac
    • audio/mp4
    • audio/mpeg
    • audio/amr
    • audio/ogg
    • audio/opus
  • Video:
    • video/mp4
    • video/3gp
import { sendFile } from "ws-cloud-api/messaging";

const image = new Blob([fs.readFileSync(path.join(__dirname, "/image.jpg"))], {
  type: "image/jpeg",
});

return await sendFile({
  to: phoneNumberToTest,
  file: image,
})
  .then((sentSuccess) => {
    if (sentSuccess) {
      console.log("Audio sent");
    }
  })
  .catch(console.error);

Send Text with CTA Button

import { sendTextWithCTAButton } from "ws-cloud-api/messaging";

sendTextWithCTAButton({
  to: process.env.PHONE_NUMBER_RECIPIENT,
  message: {
    text: "This is a test message",
    buttonText: "CTA button",
    url: "https://www.google.com",
  },
})
  .then((sentSuccess) => {
    if (sentSuccess) {
      console.log("Message with CTA button sent");
    }
  })
  .catch(console.error);

Send Text with Buttons

import { sendTextWithButtons } from "ws-cloud-api/messaging";

sendTextWithButtons({
  to: process.env.PHONE_NUMBER_RECIPIENT,
  message: {
    text: "This is a test message",
    buttons: [
      {
        title: "Button 1",
        id: "1",
      },
      {
        title: "Button 2",
        id: "2",
      },
    ],
  },
})
  .then((sentSuccess) => {
    if (sentSuccess) {
      console.log("Message with buttons sent");
    }
  })
  .catch(console.error);

Send Text with Unique Section List

import { sendInteractiveListMessage } from "ws-cloud-api/messaging";

sendInteractiveListMessage({
  to: process.env.PHONE_NUMBER_RECIPIENT,
  list: {
    text: "Test list",
    buttonText: "List button",
    list: [
      {
        title: "Element 1",
        description: "Description 1",
      },
      {
        title: "Element 2",
        description: "Description 2",
      },
    ],
  },
})
  .then((sentSuccess) => {
    if (sentSuccess) {
      console.log("Message with unique section list sent");
    }
  })
  .catch(console.error);

Send Text with a List of Multiple Sections

import { sendInteractiveSectionListMessage } from "ws-cloud-api/messaging";

sendInteractiveSectionListMessage({
  to: phoneNumberToTest,
  list: {
    text: "Test section list",
    buttonText: "Section list button",
    sections: [
      {
        sectionTitle: "Section 1",
        list: [
          {
            title: "Element 1",
            description: "Description 1",
          },
          {
            title: "Element 2",
            description: "Description 2",
          },
        ],
      },
      {
        sectionTitle: "Section 2",
        list: [
          {
            title: "Element 3",
            description: "Description 3",
          },
          {
            title: "Element 4",
            description: "Description 4",
          },
        ],
      },
    ],
  },
})
  .then((sentSuccess) => {
    if (sentSuccess) {
      console.log("Message with multiple sections list sent");
    }
  })
  .catch(console.error);

Send Text with WhatsApp Flow

import { sendFlowMessage } from "ws-cloud-api/messaging";

sendFlowMessage({
  to: phoneNumberToTest,
  flow: {
    id: process.env.FLOW_MESSAGE_ID ?? "",
    text: "Test flow",
    token: "token",
    ctaText: "View flow",
    defaultScreen: process.env.FLOW_MESSAGE_DEFAULT_SCREEN ?? "",
  },
  draft: true,
})
  .then((sentSuccess) => {
    if (sentSuccess) {
      console.log("Message with WhatsApp flow sent");
    }
  })
  .catch(console.error);

Templates

Send text template

To send a template, you have to create it first. You will need the name and the language code.

import { sendTextTemplate } from "ws-cloud-api/templates";

sendTextTemplate({
  to: process.env.PHONE_NUMBER_RECIPIENT,
  templateName: "hello_world",
  language: "en_US",
})
  .then((sentSuccess) => {
    if (sentSuccess) {
      console.log("Template sent");
    }
  })
  .catch(console.error);

Media

Upload Media

import { uploadMedia } from "ws-cloud-api/media";

const blob = new Blob([fs.readFileSync(path.join(__dirname, "/image.jpg"))], {
  type: "image/jpeg",
});

uploadMedia({ media: blob })
  .then((mediaId) => {
    if (mediaId) {
      console.log("console media id: " + mediaId);
    }
  })
  .catch(console.error);

Get Media Url

import { getMediaUrl } from "ws-cloud-api/media";

getMediaUrl({ mediaId: "mediaId" })
  .then((url) => {
    if (url) {
      console.log("console media url: " + url);
    }
  })
  .catch(console.error);

Get Medias as Blob

import { getMedia } from "ws-cloud-api/media";

getMedia({ mediaUrl: "mediaUrl" })
  .then((blob) => {
    if (blob) {
      console.log("console media blob: " + blob);
    }
  })
  .catch(console.error);