
Apify Email Signature Generator
Try for free
No credit card required
Go to Store

Apify Email Signature Generator
apify/email-signature-generator
Try for free
No credit card required
Generates a standardized email signature for Apify team members, using provided details.
build/generateHTML.js
1"use strict";
2Object.defineProperty(exports, "__esModule", { value: true });
3const types_1 = require("./types");
4const sanitizeUrl = (url) => {
5 if (!/^https?:\/\//i.test(url)) {
6 return 'https://' + url;
7 }
8 return url;
9};
10const generateLinksSection = (input) => {
11 var _a;
12 const urls = [
13 { key: "Twitter", value: input.twitterUrl },
14 { key: "LinkedIn", value: input.linkedInUrl },
15 { key: "Github", value: input.githubUrl },
16 { key: "Book a meeting", value: input.hubspotUrl },
17 ...((_a = input.otherUrls) !== null && _a !== void 0 ? _a : []),
18 ];
19 const urlsHtml = urls
20 .filter((u) => u.value)
21 .map((u) => `<a href="${sanitizeUrl(u.value)}" style="color: #4990ff; text-decoration: none;">${u.key}</a>`)
22 .join(" | ");
23 return `<div style="line-height: 18px;">${urlsHtml}</div>`;
24};
25const typeToHtml = (input) => ({
26 [types_1.EmailSignatureType.Gmail]: `<div style="font-family: Verdana, sans-serif; font-size: 12px; font-weight: 400; color: #8d92af;">
27 <div style="font-weight: 600; line-height: 18px; color: #272c3d;">${input.fullName}</div>
28 <div style="line-height: 18px;">${input.position}</div>
29 <div style="display: flex; align-items: center;">
30 <a href="https://apify.com/">
31 <img src="https://apify.com/ext/logo-for-signatures.png"
32 alt="Apify" style="margin-top: 12px; width:115px; margin-bottom: 12px;">
33 </a>
34 </div>
35 ${input.phoneNumber
36 ? `<div style="line-height: 18px;">${input.phoneNumber}</div>`
37 : ""}
38 ${generateLinksSection(input)}
39 ${input.apifyUrl
40 ? `<a href="${sanitizeUrl(input.apifyUrl)}" style="color: #4990ff;
41 text-decoration: none;"><div style="line-height: 18px;">${input.apifyUrlLabel || 'Apify Profile'}</div></a>`
42 : ""}
43 <div style="line-height: 18px; margin-top: 12px;"><a href="https://apify.com" style="color: #4990ff;
44 text-decoration: none; font-weight: 600;">Apify.com</a>${input.shouldDisplayHiring
45 ? ` | <a href="https://apify.com/jobs" style="color: #4990ff;
46 text-decoration: none;">We're hiring</a>`
47 : ""}
48 </div>
49
50 ${input.shouldDisplayG2
51 ? `<div style="display: flex; align-items: center;">
52 <a href="https://www.g2.com/products/apify/reviews">
53 <img src="https://apify.com/ext/g2badge.svg"
54 alt="G2 badge" style="margin-top: 12px; width:90px; margin-bottom: 12px;">
55 </a>
56 </div>`
57 : ""}</div>`,
58 [types_1.EmailSignatureType.Outlook]: `<div style="font-family: Verdana, sans-serif; font-size: 12px; font-weight: 400; color: #8d92af;">
59 <div style="font-weight: 600; line-height: 18px; color: #272c3d;">${input.fullName}</div>
60 <div style="line-height: 18px;">${input.position}</div>
61 <br style="line-height: 12px;">
62 <a href="https://apify.com/"><img src="https://apify.com/ext/logo-for-signatures.png"
63 alt="Apify" style="width: 115px;"></a>
64 <br style="line-height: 12px;">
65 ${input.phoneNumber
66 ? `<div style="line-height: 18px;">${input.phoneNumber}</div>`
67 : ""}
68 ${generateLinksSection(input)}
69 ${input.apifyUrl
70 ? `<a href="${sanitizeUrl(input.apifyUrl)}" style="color: #4990ff;
71 text-decoration: none;"><div style="line-height: 18px;">${input.apifyUrlLabel || 'Apify Profile'}</div></a>`
72 : ""}
73 <br style="line-height: 12px;">
74 <div style="line-height: 18px;"><a href="https://apify.com" style="color: #4990ff;
75 text-decoration: none; font-weight: 600;">Apify.com</a>${input.shouldDisplayHiring
76 ? ` | <a href="https://apify.com/jobs" style="color: #4990ff;
77 text-decoration: none;">We're hiring</a>`
78 : ""}
79 </div>
80 <br style="line-height: 12px;">
81 ${input.shouldDisplayG2
82 ? `
83 <a href="https://www.g2.com/products/apify/reviews">
84 <img src="https://apify.com/ext/g2badge.svg"
85 alt="G2 badge" style="width:90px;">
86 </a>`
87 : ""}
88</div>`,
89});
90exports.default = (input, type) => {
91 const result = typeToHtml(input)[type];
92 return result;
93};
build/main.js
1"use strict";
2Object.defineProperty(exports, "__esModule", { value: true });
3const generateHTML_1 = require("./generateHTML");
4const Apify = require("apify");
5Apify.main(async () => {
6 const input = (await Apify.getInput());
7 await Apify.setValue("OUTPUT", generateHTML_1.default(input, input.type), { 'contentType': 'text/html; charset=utf-8' });
8 console.log('Done!');
9 console.log('Your email signature can be viewed in the Key-value store under the key "OUTPUT"');
10});
build/types.js
1"use strict";
2Object.defineProperty(exports, "__esModule", { value: true });
3exports.EmailSignatureType = void 0;
4var EmailSignatureType;
5(function (EmailSignatureType) {
6 EmailSignatureType["Gmail"] = "Gmail";
7 EmailSignatureType["Outlook"] = "Outlook";
8})(EmailSignatureType = exports.EmailSignatureType || (exports.EmailSignatureType = {}));
src/generateHTML.ts
1import { EmailSignatureInput, EmailSignatureType } from "./types";
2
3const sanitizeUrl = (url) => {
4 if (!/^https?:\/\//i.test(url)) {
5 return 'https://' + url;
6 }
7 return url;
8};
9
10const generateLinksSection = (input: EmailSignatureInput) => {
11 const urls = [
12 { key: "Twitter", value: input.twitterUrl },
13 { key: "LinkedIn", value: input.linkedInUrl },
14 { key: "GitHub", value: input.githubUrl },
15 { key: "Book a meeting", value: input.hubspotUrl },
16 ...(input.otherUrls ?? []),
17 ];
18 const urlsHtml = urls
19 .filter((u) => u.value)
20 .map(
21 (u) =>
22 `<a href="${sanitizeUrl(u.value)}" style="color: #4990ff; text-decoration: none;">${u.key}</a>`
23 )
24 .join(" | ");
25 return `<div style="line-height: 18px;">${urlsHtml}</div>`;
26};
27
28const typeToHtml = (input: EmailSignatureInput) => ({
29 [EmailSignatureType.Gmail]: `<div style="font-family: Verdana, sans-serif; font-size: 12px; font-weight: 400; color: #8d92af;">
30 <div style="font-weight: 600; line-height: 18px; color: #272c3d;">${input.fullName
31 }</div>
32 <div style="line-height: 18px;">${input.position}</div>
33 <div style="display: flex; align-items: center;">
34 <a href="https://apify.com/">
35 <img src="https://apify.com/ext/logo-for-signatures.png"
36 alt="Apify" style="margin-top: 12px; width:115px; margin-bottom: 12px;">
37 </a>
38 </div>
39 ${input.phoneNumber
40 ? `<div style="line-height: 18px;">${input.phoneNumber}</div>`
41 : ""
42 }
43 ${generateLinksSection(input)}
44 ${input.apifyUrl
45 ? `<a href="${sanitizeUrl(input.apifyUrl)}" style="color: #4990ff;
46 text-decoration: none;"><div style="line-height: 18px;">${input.apifyUrlLabel || 'Apify Profile'}</div></a>`
47 : ""
48 }
49 <div style="line-height: 18px; margin-top: 12px;"><a href="https://apify.com" style="color: #4990ff;
50 text-decoration: none; font-weight: 600;">Apify.com</a>${input.shouldDisplayHiring
51 ? ` | <a href="https://apify.com/jobs" style="color: #4990ff;
52 text-decoration: none;">We're hiring</a>`
53 : ""
54 }
55 </div>
56
57 ${input.shouldDisplayG2
58 ? `<div style="display: flex; align-items: center;">
59 <a href="https://www.g2.com/products/apify/reviews">
60 <img src="https://apify.com/ext/g2badge.svg"
61 alt="G2 badge" style="margin-top: 12px; width:90px; margin-bottom: 12px;">
62 </a>
63 </div>`
64 : ""
65 }</div>`,
66 [EmailSignatureType.Outlook]: `<div style="font-family: Verdana, sans-serif; font-size: 12px; font-weight: 400; color: #8d92af;">
67 <div style="font-weight: 600; line-height: 18px; color: #272c3d;">${input.fullName
68 }</div>
69 <div style="line-height: 18px;">${input.position}</div>
70 <br style="line-height: 12px;">
71 <a href="https://apify.com/"><img src="https://apify.com/ext/logo-for-signatures.png"
72 alt="Apify" style="width: 115px;"></a>
73 <br style="line-height: 12px;">
74 ${input.phoneNumber
75 ? `<div style="line-height: 18px;">${input.phoneNumber}</div>`
76 : ""
77 }
78 ${generateLinksSection(input)}
79 ${input.apifyUrl
80 ? `<a href="${sanitizeUrl(input.apifyUrl)}" style="color: #4990ff;
81 text-decoration: none;"><div style="line-height: 18px;">${input.apifyUrlLabel || 'Apify Profile'}</div></a>`
82 : ""
83 }
84 <br style="line-height: 12px;">
85 <div style="line-height: 18px;"><a href="https://apify.com" style="color: #4990ff;
86 text-decoration: none; font-weight: 600;">Apify.com</a>${input.shouldDisplayHiring
87 ? ` | <a href="https://apify.com/jobs" style="color: #4990ff;
88 text-decoration: none;">We're hiring</a>`
89 : ""
90 }
91 </div>
92 <br style="line-height: 12px;">
93 ${input.shouldDisplayG2
94 ? `
95 <a href="https://www.g2.com/products/apify/reviews">
96 <img src="https://apify.com/ext/g2badge.svg"
97 alt="G2 badge" style="width:90px;">
98 </a>`
99 : ""
100 }
101</div>`,
102});
103
104export default (input: EmailSignatureInput, type: EmailSignatureType) => {
105 const result = typeToHtml(input)[type];
106 return result;
107};
src/main.ts
1import generateHTML from './generateHTML';
2import { EmailSignatureInput } from './types';
3const Apify = require('apify');
4
5Apify.main(async () => {
6 const input: EmailSignatureInput = (await Apify.getInput()) as any;
7 await Apify.setValue('OUTPUT', generateHTML(input, input.type), {'contentType': 'text/html; charset=utf-8'});
8 console.log('Done!');
9 console.log('Your email signature can be viewed in the Key-value store under the key "OUTPUT"');
10});
src/types.ts
1interface UrlWithLabel {
2 key: string;
3 value: string;
4}
5
6export interface EmailSignatureInput {
7 fullName: string;
8 position: string;
9 phoneNumber?: string;
10 twitterUrl?: string;
11 linkedInUrl?: string;
12 githubUrl?: string;
13 hubspotUrl?: string;
14 otherUrls?: UrlWithLabel[];
15 apifyUrlLabel?: string;
16 apifyUrl?: string;
17 shouldDisplayHiring?: boolean;
18 shouldDisplayG2?: boolean;
19 type: EmailSignatureType;
20}
21
22export enum EmailSignatureType {
23 Gmail = 'Gmail',
24 Outlook = 'Outlook',
25}
.editorconfig
1root = true
2
3[*]
4indent_style = space
5indent_size = 4
6charset = utf-8
7trim_trailing_whitespace = true
8insert_final_newline = true
9end_of_line = lf
.eslintrc
1{
2 "extends": "@apify"
3}
.gitignore
1# This file tells Git which files shouldn't be added to source control
2
3.idea
4node_modules
5
6apify_storage
Dockerfile
1# First, specify the base Docker image. You can read more about
2# the available images at https://sdk.apify.com/docs/guides/docker-images
3# You can also use any other image from Docker Hub.
4FROM apify/actor-node:15
5
6# Second, copy just package.json and package-lock.json since it should be
7# the only file that affects "npm install" in the next step, to speed up the build
8COPY package*.json ./
9
10# Install NPM packages, skip optional and development dependencies to
11# keep the image small. Avoid logging too much and print the dependency
12# tree for debugging
13RUN npm --quiet set progress=false \
14 && npm install --only=prod --no-optional \
15 && echo "Installed NPM packages:" \
16 && (npm list || true) \
17 && echo "Node.js version:" \
18 && node --version \
19 && echo "NPM version:" \
20 && npm --version
21
22# Next, copy the remaining files and directories with the source code.
23# Since we do this after NPM install, quick build will be really fast
24# for most source file changes.
25COPY . ./
26
27# Optionally, specify how to launch the source code of your actor.
28# By default, Apify's base Docker images define the CMD instruction
29# that runs the Node.js source code using the command specified
30# in the "scripts.start" section of the package.json file.
31# In short, the instruction looks something like this:
32#
33# CMD npm start
INPUT_SCHEMA.json
1{
2 "title": "Email signature generator actor input schema",
3 "description": "Enter your details for the Apify email signature. Only enter the values that you want to have in your signature.",
4 "type": "object",
5 "schemaVersion": 1,
6 "properties": {
7 "fullName": {
8 "title": "Full Name",
9 "type": "string",
10 "description": "The full name displayed in the signature.",
11 "editor": "textfield"
12 },
13 "position": {
14 "title": "Position",
15 "type": "string",
16 "description": "Your position in Apify.",
17 "editor": "textfield"
18 },
19 "phoneNumber": {
20 "title": "Phone Number",
21 "type": "string",
22 "description": "Your phone number.",
23 "editor": "textfield"
24 },
25 "twitterUrl": {
26 "title": "Twitter URL",
27 "type": "string",
28 "description": "The URL of your Twitter.",
29 "editor": "textfield"
30 },
31 "linkedInUrl": {
32 "title": "LinkedIn URL",
33 "type": "string",
34 "description": "The URL of your LinkedIn.",
35 "editor": "textfield"
36 },
37 "githubUrl": {
38 "title": "GitHub URL",
39 "type": "string",
40 "description": "The URL of your GitHub.",
41 "editor": "textfield"
42 },
43 "hubspotUrl": {
44 "title": "Hubspot URL",
45 "type": "string",
46 "description": "The URL for Hubspot meetings.",
47 "editor": "textfield"
48 },
49 "otherUrls": {
50 "title": "Other URLs",
51 "type": "array",
52 "description": "Other URLs. The first value is the label (e.g. \"Facebook\"), the second one is the URL (e.g. \"https://facebook.com\")",
53 "editor": "keyValue",
54 "uniqueItems": false,
55 "placeholderKey": "Displayed label (e.g. \"Facebook\")",
56 "placeholderValue": "URL (e.g. \"https://facebook.com\")"
57 },
58 "apifyUrl": {
59 "title": "Apify Profile URL",
60 "type": "string",
61 "description": "The URL of your Apify profile.",
62 "editor": "textfield"
63 },
64 "apifyUrlLabel": {
65 "title": "Apify Profile URL Label",
66 "type": "string",
67 "description": "Optional label for your Apify profile URL. The default is \"Apify Profile\"",
68 "editor": "textfield"
69 },
70 "shouldDisplayHiring": {
71 "title": "Should Display Hiring Information",
72 "type": "boolean",
73 "description": "Determines whether the hiring link gets displayed.",
74 "editor": "checkbox"
75 },
76 "shouldDisplayG2": {
77 "title": "Should Display G2 banner",
78 "type": "boolean",
79 "description": "Determines whether the G2 banner gets displayed.",
80 "editor": "checkbox"
81 },
82 "type": {
83 "title": "Signature type",
84 "type": "string",
85 "description": "The signature type.",
86 "default": "Gmail",
87 "editor": "select",
88 "enum": ["Gmail", "Outlook"]
89 }
90 },
91 "required": ["fullName", "position", "shouldDisplayHiring", "type"]
92}
apify.json
1{
2 "name": "email-signature-generator",
3 "version": "0.0",
4 "buildTag": "latest",
5 "env": null,
6 "template": "project_empty"
7}
package.json
1{
2 "name": "email-signature-generator",
3 "version": "0.0.1",
4 "description": "This actor generates email signatures for Apify.",
5 "dependencies": {
6 "@types/node": "^14.17.4",
7 "apify": "^1.0.1",
8 "typescript": "^4.3.5"
9 },
10 "devDependencies": {
11 "@apify/eslint-config": "^0.1.3",
12 "eslint": "^7.0.0"
13 },
14 "scripts": {
15 "start": "npm run build && node build/main.js",
16 "lint": "./node_modules/.bin/eslint ./src --ext .js,.jsx",
17 "lint:fix": "./node_modules/.bin/eslint ./src --ext .js,.jsx --fix",
18 "test": "echo \"Error: oops, the actor has no tests yet, sad!\" && exit 1",
19 "build": "tsc -p tsconfig.json"
20 },
21 "main": "build/main.js",
22 "author": "Jiri Moravcik",
23 "license": "ISC"
24}
test.html
1<html><body>
2 <div style="font-family: Verdana, sans-serif; font-size: 12px; font-weight: 400; color: #8d92af;">
3 <div style="font-weight: 600; line-height: 18px; color: #272c3d;">Jiri Moravcik</div>
4 <div style="line-height: 18px;">Platform Engineer</div>
5 <div style="display: flex; align-items: center;">
6 <a href="https://apify.com/">
7 <img src="https://apify.com/ext/apify-logo-120px.png"
8 alt="Apify" style="margin-top: 12px; width:115px; margin-bottom: 12px;">
9 </a>
10 </div>
11
12 <div style="line-height: 18px;"><a href="https://linkedin.com/krystofjezek" style="color: #4990ff;
13 text-decoration: none;">LinkedIn</a> | <a href="https://github.com/krystofjezek" style="color: #4990ff;
14 text-decoration: none;">Github</a> | <a href="https://meetings.hubspot.com/shash-tandon" style="color: #4990ff;
15 text-decoration: none;">Book a meeting</a>
16 </div>
17
18 <div style="line-height: 18px; margin-top: 12px;"><a href="https://apify.com" style="color: #4990ff;
19 text-decoration: none; font-weight: 600;">Apify.com</a>
20 </div>
21</body></html>
tsconfig.json
1{
2 "compilerOptions": {
3 "target": "es2019",
4 "module": "commonjs",
5 "moduleResolution": "node",
6 "strict": true,
7 "noImplicitAny": false,
8 "strictNullChecks": false,
9 "lib": [
10 "DOM",
11 "DOM.Iterable",
12 "ES2015",
13 "ES2016",
14 "ES2018",
15 "ES2019.Object",
16 "ES2018.AsyncIterable",
17 "ES2020.String",
18 "ES2019.Array"
19 ],
20 "rootDir": "src/",
21 "outDir": "build/"
22 },
23 "include": [
24 "src/"
25 ]
26}
Developer
Maintained by Apify
Actor Metrics
4 monthly users
-
24 bookmarks
>99% runs succeeded
Created in Aug 2021
Modified 15 days ago
Categories