Discord API examples & templates
Use these vals as a playground to view and fork Discord API examples and templates on Val Town. Run any example below or find templates that can be used as a pre-built solution.
stevekrouse
upgradeHTTPPreviewVals
Script
Auto-Upgrade for HTTP Preview This val is experimentally testing if we can use an LLM to determine if an old-style HTTP val
needs to be upgraded for the new HTTP runtime, currently in preview. You can read more about the breaking change and upgrade proccess here: https://blog.val.town/blog/http-preview/#breaking-changes In some light testing, it seems like ChatGPT 3.5 and 4o both are bad at this task,
so I'm pausing experimenting with this for now. Example output from 4o: [
{
"name": "harlequinChickadee",
"probabilityUpgradeNeeded": true,
"reason": "The current code structure has several functions and program logic outside the main handler, including word selection, game state management, and SVG generation. These parts would not re-run with the new runtime, potentially affecting functionality. They need to be moved inside the handler to ensure consistent behavior across requests."
},
{
"name": "redElephant",
"probabilityUpgradeNeeded": "100%",
"reason": "The initialization of `fs` and `vscode` objects should occur \n inside the handler in the new runtime in order to ensure that they are \n freshly created for each request. This is critical since the new runtime \n does not rerun code outside of the handler for each request.."
},
{
"name": "untitled_indigoNightingale",
"probabilityUpgradeNeeded": false,
"reason": "The code initializes and configures the Hono app outside of the handler, but it does not appear to have any stateful logic that would need to be re-calculated with each request. Each request will call the handler provided by Hono and should behave the same in the new runtime."
},
{
"name": "untitled_pinkRoundworm",
"probabilityUpgradeNeeded": true,
"reason": "The functions `addComment` and `getComments` as well as the initialization \nof the KEY variable perform actions that are intended to be run per request. These need to be moved \ninside the relevant HTTP handler to ensure the behavior remains consistent in the new runtime."
},
{
"name": "untitled_harlequinIguana",
"probabilityUpgradeNeeded": false,
"reason": "The provided code defines the handler directly without any side effects or additional code outside the handler. The behavior should remain the same in the new runtime."
},
{
"name": "untitled_moccasinHeron",
"probabilityUpgradeNeeded": false,
"reason": "The code outside the handler is just a constant string declaration, which does not change behavior between requests. The handler itself handles requests correctly and independently."
},
{
"name": "untitled_maroonSwallow",
"probabilityUpgradeNeeded": false,
"reason": "All the code, including the check for authentication,\n is inside the handler function. This means the behavior will stay \n the same with the new runtime."
},
{
"name": "wikiOG",
"probabilityUpgradeNeeded": true,
"reason": "The function `getWikipediaInfo` defined outside of the handler makes network requests and processes data for each request. In the new runtime, this function would only be executed once and cached. To ensure the same behavior in the new runtime, this function should be moved into the handler."
},
{
"name": "parsePostBodyExample",
"probabilityUpgradeNeeded": false,
"reason": "All the code is inside the handler, so the behavior will remain consistent in the new runtime."
},
{
"name": "discordEventReceiver",
"probabilityUpgradeNeeded": false,
"reason": "All the relevant code for handling requests and logging input is inside the handler.\n No code needs to be moved for the new runtime to function correctly."
}
] Feel free to fork this and try it yourself!
If you could get it working, it'd be a big help for us as we upgrade the thousands of HTTP vals. Future ideas: Better LLM (Claude 3.5) Better prompt More examples JSON mode having it reply with upgraded code send pull requests to users with public vals that probably need upgrading
0
postpostscript
blogSqliteUniverse
HTTP
sqliteUniverse: Make SQLite Queries Against Multiple Endpoints in Deno (Val Town) (Part 1) Prerequisite Knowledge Val Town-Hosted SQLite Val Town hosts SQLite as part of its standard library ( @std/sqlite ). This makes a fetch request against their closed-source API (using your API token) which returns results in a consistent format. This is great because you can host your own endpoints that work similarly, and reuse code that was only designed in mind for that original hosted interface The standard format (abridged to important fields): POST /execute {
"statement": {
"sql": "SELECT * FROM some_table",
"args": []
}
} Output: {
"rows": [[1, "first", 1709942400], [2, "second", 1709942401]],
"columns": ["id", "name", "lastModified"]
} POST /batch {
"statements": [
{
"sql": "INSERT INTO some_table VALUES (?, ?, ?)",
"args": [3, "third", 1709942402]
},
{
"sql": "SELECT * FROM some_table",
"args": []
}
]
} Output: [
{
"rows": [],
"columns": ["id", "name", "lastModified"]
},
{
"rows": [[1, "first", 1709942400], [2, "second", 1709942401], [3, "third", 1709942402]],
"columns": ["id", "name", "lastModified"]
},
] SQLite in Wasm There is a deno package (sqlite) which lets you (among other things) create SQLite databases in-memory using WebAssembly. I've created a Val which wraps this to enable it to be a drop-in replacement for @std/sqlite: @postpostscript/sqliteWasm Example import { createSqlite } from "https://esm.town/v/postpostscript/sqliteWasm";
import { Statement } from "https://esm.town/v/postpostscript/sqliteBuilder";
const sqlite = createSqlite();
console.log(sqlite.batch([
Statement`
CREATE TABLE test (
id TEXT PRIMARY KEY,
value TEXT
)
`,
Statement`
INSERT INTO test VALUES (
${"some-id"},
${"some-value"}
)
`,
Statement`
SELECT * FROM test
`,
])) Result: [
{
rows: [],
rowsAffected: 0,
columns: []
},
{
rows: [],
rowsAffected: 1,
columns: []
},
{
rows: [ [ "some-id", "some-value" ] ],
rowsAffected: 0,
columns: [ "id", "value" ]
}
] Dump Tool I have modified @nbbaier's great work at @postpostscript/sqliteDump to support dumping from any sqlite interface, whether the standard library's version, over HTTP, or through the above Wasm implementation Putting it All Together All of the above enables: Serving a subset of your private data publicly for others to query (Example: @postpostscript/sqlitePublic ) Backing up your database and querying against that backup (via @postpostscript/sqliteBackup's sqliteFromBlob and sqliteToBlob ) But we can do more..! What if we could query from multiple of these data sources.. at the same time! 😱 sqliteUniverse sqliteUniverse is an @std/sqlite compatible interface that determines where a table should route to based on different patterns Table Name Patterns The actual table name will always come after a "/", with the exception of tables without any endpoint, for example users . Everything before the last "/" is the endpoint name. Endpoint interfaces will be chosen in the following order: Exact match in options.interfaces.exact e.g. @std/sqlite/someTable would match options.interfaces.exact["@std/sqlite"] Each pattern in options.interfaces.patterns options.interfaces.fallback will be called An error is thrown if none of the above matches AND returns an sqlite interface. If there is a match but the handler returns nothing, it will continue down the list Default options.interfaces.patterns : patterns.https - /^https:\/\// ( https://example.com/somePath/tableName ): fetch from https://example.com/somePath/batch patterns.val - /^@/ ( @author/name/somePath/tableName ): fetch from the val's endpoint, https://author-name.web.val.run/somePath/batch Other Available Patterns: The following patterns are accessible through import { patterns } from "https://esm.town/v/postpostscript/sqliteUniverse" : patterns.blob - /^blob:\/\// ( blob://backup:sqlite:1709960402936 ) - import the database from private blob backup:sqlite:1709960402936 Overriding Default Options The sqliteUniverse export contains defaults insuring no private data will be leaked. If you want to reduce or extend these options, use the sqliteUniverseWithOptions export and pass a modified interfaces option in the first argument: Examples of how to set options.interfaces.exact , options.interfaces.patterns , and options.interfaces.fallback : import { sqliteUniverseWithOptions, patterns, defaultPatterns } from "https://esm.town/v/postpostscript/sqliteUniverse";
import { createSqlite } from "https://esm.town/v/postpostscript/sqliteWasm";
import { sqliteFromAPI } from "https://esm.town/v/postpostscript/sqliteFromAPI";
import { Statement } from "https://esm.town/v/postpostscript/sqliteBuilder";
const sqlite = sqliteUniverseWithOptions({
interfaces: {
exact: {
// `SELECT * FROM "some-endpoint/someTable"` will match
// `SELECT * FROM "some-endpoint/somePath/someTable"` will NOT match
"some-endpoint": ({ endpoint, tables }) => {
const sqlite = createSqlite()
sqlite.batch([
Statement`CREATE TABLE someTable (someField TEXT PRIMARY KEY)`,
Statement`INSERT INTO someTable VALUES (${"some-field"})`
])
return sqlite
},
},
patterns: [
...defaultPatterns,
[
// shorthand e.g. ~/sqlitePublic -> @postpostscript/sqlitePublic
/^~\/(\w+)/,
({ endpoint, tables, match }) => {
return sqliteFromAPI(`@postpostscript/${match[1]}`)
},
]
],
fallback({ endpoint, tables }) {
// if an endpoint is not found, this will be called
return sqliteFromAPI(`@postpostscript/sqlitePublic`)
},
},
})
console.log(await Statement`
SELECT *
FROM "some-endpoint/someTable"
JOIN "~/sqliteVals/vals"
JOIN authIdExampleComments_comment
LIMIT 1
`.execute({ sqlite })) Output: [
{
someField: "some-field",
id: "aeb70bbb-05fc-403b-8d6a-130c423ecb53",
name: "discordWelcomedMembers",
code: "// set at Sun Mar 10 2024 00:32:48 GMT+0000 (Coordinated Universal Time)\n" +
"export let discordWelcomedM"... 8289 more characters,
version: 234771,
privacy: "public",
public: 1,
run_start_at: "2024-03-10T00:32:48.978Z",
run_end_at: "2024-03-10T00:32:48.978Z",
created_at: "2024-03-10T00:32:48.978Z",
author_id: "a0bf3b31-15a5-4d5c-880e-4b1e22c9bc18",
author_username: "stevekrouse",
username: "postpostscript",
comment: "test",
date_added: 1709776325.857
}
] Part 2 Since Val Town currently has a character limit for val readmes, this will have to continue in Part 2 !
1
pomdtr
example_article
HTTP
Searching valtown via sql, jq, jo In a recent discussion, a useful command line pipeline was shared for querying a database and processing the results. The original command looked like this: echo "SELECT * FROM vals WHERE lower(name) LIKE '%feed%' and lower(name) like '%email%' LIMIT 100" | jq -R '{args: [.]} ' | xargs -0 -I {} curl -X POST "https://sqlite-execute.web.val.run" -H "Content-Type: application/json" -d {} | yq -P This command effectively queries a database for records matching certain criteria and processes the results. However, there are several ways this pipeline can be improved for efficiency and clarity. Recommendations for Improvement Elimination of xargs for stdin input in curl : Instead of using xargs to pass input from stdin, curl supports -d '@-' where @ means file and - means stdin. This simplifies the command. Use of --json flag in curl : Recent versions of curl support the --json flag, which automatically sets the correct HTTP headers for JSON content. This allows for a more straightforward command. Avoid explicit setting of HTTP method in curl : Explicitly setting the HTTP method (e.g., -X POST ) is considered bad practice when using data, form, and/or json flags. This is because it's unnecessary and can lead to unexpected side effects when more than one request is made behind the scenes. Use of jo for JSON payload creation: While jq can be used to create a JSON payload, it's more common and cleaner to use jo for this purpose. jo is specifically designed for creating JSON objects and arrays. Improved Command Examples Using the recommendations above, the command can be rewritten as follows: $ jo args="$(jo -a "SELECT * FROM vals WHERE lower(name) LIKE '%feed%' and lower(name) like '%email%' LIMIT 100")" \
| curl -s --json '@-' 'https://sqlite-execute.web.val.run' This command uses jo to create the JSON payload and then passes it to curl using the --json flag for processing. For keeping the SQL statement as input to the pipeline, the command can be further refined: $ echo "SELECT * FROM vals WHERE lower(name) LIKE '%feed%' and lower(name) like '%email%' LIMIT 100" \
| jo -a '@-' \
| jo args=':-' \
| curl -s --json '@-' 'https://sqlite-execute.web.val.run' In this version, @- means treat stdin as a string, and :- means treat stdin as JSON, allowing for dynamic input directly into the JSON payload. Additional Resources For those looking to deepen their understanding of curl and its capabilities, especially with JSON, it's highly recommended to read through Everything curl . This online book is full of useful tricks and insights that can significantly enhance one's command line data processing skills. References https://discord.com/channels/1020432421243592714/1221021689627017236
https://chatcraft.org/api/share/tarasglek/7B_nXLYazAyEryn4Z9Yz0
https://github.com/neverstew/valtown-search/
0
janpaul123
semanticSearchTurso
Script
Part of Val Town Semantic Search . Uses Turso to search embeddings of all vals, using the sqlite-vss extension. Call OpenAI to generate an embedding for the search query. Query the vss_vals_embeddings table in Turso using vss_search . The vss_vals_embeddings table has been generated by janpaul123/indexValsTurso . It is not run automatically. This table is incomplete due to a bug in Turso .
0
vlad
serverlessMatrixEchoBot
Express (deprecated)
A example Serverless Bot for Matrix chat. See https://vlad.roam.garden/How-to-create-a-serverless-Matrix-Chat-bot for a more detailed write-up on how to set one up! To test this bot: invite serverless-echo@matrix.org to your unencrypted room Send a message starting with !echo and the bot will repeat content after. Use https://matrix-serverless.netlify.app/ to configure Matrix to call the endpoint on newly received messages
1