-
Notifications
You must be signed in to change notification settings - Fork 1
/
ping.js
140 lines (113 loc) · 4.28 KB
/
ping.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
import fetch from "node-fetch";
import crypto from "crypto";
import nearJsCrypto from "@near-js/crypto";
import nearJsKeystores from "@near-js/keystores";
import nearJsAccounts from "@near-js/accounts";
import nearJsWalletAccount from "@near-js/wallet-account";
import dotenv from "dotenv";
// Accept environment and webhook type as command-line arguments
const type = process.argv[2]; // 'agenda' or 'alerts'
const ENVIRONMENT = process.argv[3] || "dev"; // 'dev', 'production', or 'local'
// Validate the webhook type
if (!type || (type !== "agenda" && type !== "alerts")) {
console.error('Please specify the webhook type as "agenda" or "alerts".');
process.exit(1);
}
// Validate the environment
if (!["dev", "production", "local"].includes(ENVIRONMENT)) {
console.error(
"Invalid environment specified. Use 'dev', 'production', or 'local'.",
);
process.exit(1);
}
// Load the appropriate environment variables file
dotenv.config({
path: ENVIRONMENT === "production" ? ".prod.vars" : ".dev.vars",
});
// Destructure necessary modules
const { Near } = nearJsWalletAccount;
const { Account } = nearJsAccounts;
const { InMemoryKeyStore } = nearJsKeystores;
const { KeyPair } = nearJsCrypto;
// Load environment variables
const NETWORK = process.env.NETWORK;
const FACTORY_CONTRACT_ID = process.env.FACTORY_CONTRACT_ID;
const WORKER_NEAR_SK = process.env.WORKER_NEAR_SK.trim();
const AGENDA_MAC_SECRET_BASE64 = process.env.AGENDA_MAC_SECRET_BASE64.trim();
const ALERTS_MAC_SECRET_BASE64 = process.env.ALERTS_MAC_SECRET_BASE64.trim();
// Set the base URL depending on the environment
let BASE_URL;
if (ENVIRONMENT === "dev") {
BASE_URL = "https://airtable-worker-dev.keypom.workers.dev";
} else if (ENVIRONMENT === "production") {
BASE_URL = "https://airtable-worker-production.keypom.workers.dev";
} else if (ENVIRONMENT === "local") {
BASE_URL = "http://localhost:8787";
}
// Set the Airtable Worker URL
const AIRTABLE_WORKER_URL = `${BASE_URL}/webhook/`;
// Helper function to create HMAC signature
function createHMACSignature(body, macSecretBase64) {
const macSecretDecoded = Buffer.from(macSecretBase64, "base64");
return crypto
.createHmac("sha256", macSecretDecoded)
.update(body)
.digest("hex");
}
// Helper function to send request to the worker
async function sendWebhook(type, macSecretBase64) {
const url = `${AIRTABLE_WORKER_URL}${type}`;
const body = JSON.stringify({}); // Empty body
const hmacSignature = `hmac-sha256=${createHMACSignature(body, macSecretBase64)}`;
const response = await fetch(url, {
method: "POST",
headers: {
"Content-Type": "application/json",
"X-Airtable-Content-MAC": hmacSignature,
},
body: body,
});
const responseData = await response.json();
console.log(`Response from worker (${type}):`, responseData);
}
// Helper function to setup NEAR connection
async function setupNear() {
const keyStore = new InMemoryKeyStore();
const workerKey = KeyPair.fromString(WORKER_NEAR_SK);
await keyStore.setKey(NETWORK, FACTORY_CONTRACT_ID, workerKey);
const nearConfig = {
networkId: NETWORK,
keyStore: keyStore,
nodeUrl: `https://rpc.${NETWORK}.near.org`,
walletUrl: `https://wallet.${NETWORK}.near.org`,
helperUrl: `https://helper.${NETWORK}.near.org`,
explorerUrl: `https://explorer.${NETWORK}.near.org`,
};
const near = new Near(nearConfig);
return new Account(near.connection, FACTORY_CONTRACT_ID);
}
// Fetch the latest data (agenda or alerts) from NEAR
async function fetchUpdatedData(type) {
const account = await setupNear();
const factoryAccountId = FACTORY_CONTRACT_ID;
// Wait for a few seconds to allow the data to be updated
await new Promise((resolve) => setTimeout(resolve, 8000));
const methodName = type === "agenda" ? "get_agenda" : "get_alerts";
const data = await account.viewFunction({
contractId: factoryAccountId,
methodName: methodName,
});
console.log(`Updated ${type} from NEAR:`, data);
}
// Main function to run the script
async function main() {
const macSecretBase64 =
type === "agenda" ? AGENDA_MAC_SECRET_BASE64 : ALERTS_MAC_SECRET_BASE64;
// Send the webhook request
await sendWebhook(type, macSecretBase64);
// Fetch the updated data from NEAR
await fetchUpdatedData(type);
}
main().catch((error) => {
console.error("Error:", error);
});