social_data_api_projectproxy-api.ts23 matches
1/**
2* SocialData API Proxy for Cloudflare Workers
3* Acts as a backend for the X Search UI, handling API key management,
4* and request forwarding to SocialData API.
5*
6* This proxy runs on Cloudflare Workers and connects to:
7* - Supabase for authentication and user management
8* - Cloudflare D1 for tweet storage
9* - SocialData API for Twitter/X data
10*/
1141try {
42// Supabaseの公開鍵を使ってJWTを検証するのが理想ですが、
43// 簡易的な実装としてSupabase APIを利用して検証します
44const supabaseUrl = env.SUPABASE_URL;
45const supabaseKey = env.SUPABASE_SERVICE_KEY;
50}
5152// Supabase Auth APIを利用してユーザー情報を取得
53const response = await fetch(`${supabaseUrl}/auth/v1/user`, {
54headers: {
55"Authorization": `Bearer ${token}`,
56"apikey": supabaseKey,
57},
58});
69headers: {
70"Authorization": `Bearer ${supabaseKey}`,
71"apikey": supabaseKey,
72},
73});
104105/**
106* Forward request to SocialData API
107* @param {string} query - Search query
108* @param {string} type - Search type (Latest or Top)
113async function forwardToSocialData(query, type, cursor, env) {
114try {
115const apiKey = env.SOCIAL_DATA_API_KEY;
116if (!apiKey) {
117throw new Error("SOCIAL_DATA_API_KEY environment variable not set");
118}
119120const apiUrl = new URL("https://api.socialdata.tools/twitter/search");
121apiUrl.searchParams.set("query", query);
122apiUrl.searchParams.set("type", type || "Latest");
123if (cursor) {
124apiUrl.searchParams.set("cursor", cursor);
125}
126127const response = await fetch(apiUrl.toString(), {
128headers: {
129"Authorization": `Bearer ${apiKey}`,
130"Accept": "application/json",
131},
136try {
137const errorData = await response.json();
138errorText = errorData.message || `API Error: ${response.statusText}`;
139} catch {
140errorText = `API Error: ${response.statusText}`;
141}
142throw new Error(errorText);
167"Content-Type": "application/json",
168"Authorization": `Bearer ${supabaseKey}`,
169"apikey": supabaseKey,
170"Prefer": "return=minimal",
171},
344ctx.waitUntil(incrementSearchCount(authResult.userId, env));
345346// Forward request to SocialData API
347const data = await forwardToSocialData(query, type, cursor, env);
348450JSON.stringify({
451status: "ok",
452message: "SocialData API Proxy is running",
453environment: "Cloudflare Workers",
454}),
ipv4-counterindex.ts2 matches
15await initDatabase();
1617// API endpoint to get visit data
18app.get("/api/visits", async (c) => {
19const visits = await getAllVisits();
20const totalVisits = await getTotalVisits();
226227// Add engagement filters
228// Always use min_ (greater than or equal to) for API filters
229if (likesCount) {
230finalQuery += ` min_faves:${likesCount}`;
236237// Note: Replies count, bookmark count, and views count might not be directly filterable
238// in the Twitter/X API. These may need to be filtered client-side after fetching.
239240return finalQuery.trim();
272maxTweets: parseInt(maxTweets),
273filters: {
274// These filters will be applied client-side if the API doesn't support them directly
275// Always use "greater than or equal to" filtering
276repliesCount: repliesCount
380// Helper to check if a tweet meets the client-side filter criteria
381const meetsCriteria = (tweet) => {
382// Apply any client-side filters here that the API doesn't support
383// Only perform "greater than or equal to" checks
384401}
402403// Apply like count filter if not handled by API
404if (likesCount && tweet.favorite_count !== undefined) {
405if (tweet.favorite_count < parseInt(likesCount)) return false;
406}
407408// Apply retweet count filter if not handled by API
409if (retweetsCount && tweet.retweet_count !== undefined) {
410if (tweet.retweet_count < parseInt(retweetsCount)) return false;
ipv4-counterindex.html1 match
125document.getElementById('refresh-btn').addEventListener('click', async () => {
126try {
127const response = await fetch('/api/visits');
128const data = await response.json();
129updateUI(data);
StarterPackFeedsneynar.ts2 matches
1const baseUrl = '/neynar-proxy?path='
2// const baseUrl = "https://api.neynar.com/v2/farcaster/";
34export async function fetchNeynarGet(path: string) {
8'Content-Type': 'application/json',
9'x-neynar-experimental': 'true',
10'x-api-key': 'NEYNAR_API_DOCS',
11},
12})
StarterPackFeedsApp.tsx3 matches
60<div className="">✷ Farcaster mini app manifest + webhook + embed metadata</div>
61<div className="">✷ Farcaster notifications (storing tokens, sending recurring notifications, ...)</div>
62<div className="">✷ Neynar API integration for Farcaster data</div>
63<div className="">✷ Hosted on Val Town (instant deployments on save)</div>
64<div className="">
7475// function Database() {
76// const queryFn = () => fetch('/api/counter/get').then((r) => r.json())
77// const { data, refetch } = useQuery({ queryKey: ['counter'], queryFn })
78// return (
80// {/* <h2 className="font-semibold">Database Example</h2> */}
81// <div className="">Counter value: {data}</div>
82// <Button variant="outline" onClick={() => fetch('/api/counter/increment').then(refetch)}>
83// Increment
84// </Button>
StarterPackFeedsneynar.ts4 matches
1const NEYNAR_API_KEY = Deno.env.get("NEYNAR_API_KEY") || "NEYNAR_API_DOCS";
2const headers = {
3"Content-Type": "application/json",
4"x-api-key": NEYNAR_API_KEY,
5};
67export const fetchGet = async (path: string) => {
8return await fetch("https://api.neynar.com/v2/farcaster/" + path, {
9method: "GET",
10headers: headers,
1314export const fetchPost = async (path: string, body: any) => {
15return await fetch("https://api.neynar.com/v2/farcaster/" + path, {
16method: "POST",
17headers: headers,
reelMitrajsREADME.md2 matches
2const prompt = `Generate a short 15-second Instagram reel script and 5 viral hashtags for the topic: "${topic}". Make the script engaging and desi style.`;
34const res = await fetch("https://api.openai.com/v1/chat/completions", {
5method: "POST",
6headers: {
7"Authorization": `Bearer ${Deno.env.get("OPENAI_API_KEY")}`,
8"Content-Type": "application/json",
9},
untitled-509README.md2 matches
2const prompt = `Generate a short 15-second Instagram reel script and 5 viral hashtags for the topic: "${topic}". Make the script engaging and desi style.`;
34const res = await fetch("https://api.openai.com/v1/chat/completions", {
5method: "POST",
6headers: {
7"Authorization": `Bearer ${Deno.env.get("OPENAI_API_KEY")}`,
8"Content-Type": "application/json",
9},
resume-parserresumeSchemas.ts46 matches
1import {z} from 'npm:@hono/zod-openapi'
2import {ZodObject, ZodType, ZodTypeAny} from "npm:zod"
33132// Create new object schema with additionalProperties: false and all fields required
33return z.object(newShape).openapi({
34// Preserve description and example if they exist
35...(schema._def.openapi ? {
36description: schema._def.openapi.description,
37example: schema._def.openapi.example
38} : {}),
39// Always add additionalProperties: false
44// Process array items, removing all array constraints
45// This removes: minItems, maxItems, uniqueItems validation
46return z.array(processSchema(schema._def.type)).openapi({
47// Preserve description and example if they exist
48...(schema._def.openapi ? {
49description: schema._def.openapi.description,
50example: schema._def.openapi.example
51} : {})
52})
54else if (schema instanceof z.ZodString) {
55// Remove ALL string validations (min, max, regex, email, url, etc.)
56return z.string().openapi({
57// Preserve description and example if they exist
58...(schema._def.openapi ? {
59description: schema._def.openapi.description,
60example: schema._def.openapi.example
61} : {})
62})
64else if (schema instanceof z.ZodNumber) {
65// Remove ALL number validations (min, max, multipleOf, int, etc.)
66return z.number().openapi({
67// Preserve description and example if they exist
68...(schema._def.openapi ? {
69description: schema._def.openapi.description,
70example: schema._def.openapi.example
71} : {})
72})
74else if (schema instanceof z.ZodBoolean) {
75// Preserve boolean as is
76return z.boolean().openapi({
77// Preserve description and example if they exist
78...(schema._def.openapi ? {
79description: schema._def.openapi.description,
80example: schema._def.openapi.example
81} : {})
82})
93// Preserve enums and literals but without additional constraints
94// Convert them to strings for maximum compatibility
95return z.string().openapi({
96// Preserve description and example if they exist
97...(schema._def.openapi ? {
98description: schema._def.openapi.description,
99example: schema._def.openapi.example
100} : {})
101})
119z.object({
120value: valueSchema,
121confidence: z.number().min(0).max(1).openapi({
122description: 'Confidence score between 0 and 1',
123example: 0.95
124}),
125standardization: z.string().nullable().openapi({
126description: 'Notes about any standardization applied',
127example: 'Standardized from "JS" to "JavaScript"'
135durationInMonths: ConfidenceFieldSchema(z.number().nullable()),
136current: ConfidenceFieldSchema(z.boolean())
137}).openapi('DateRange')
138139// Request schema
140export const ResumeParserRequestSchema = z.object({
141resumeText: z.string().min(1).openapi({
142description: 'The raw text of the resume to parse',
143example: 'John Doe\nSoftware Engineer\n...'
144}),
145options: z.object({
146confidenceThreshold: z.number().min(0).max(1).optional().openapi({
147description: 'Minimum confidence score threshold (0-1)',
148example: 0.5
149}),
150standardizationEnabled: z.boolean().optional().openapi({
151description: 'Whether to standardize terminology',
152example: true
153}),
154extractSummary: z.boolean().optional().openapi({
155description: 'Whether to extract and analyze the resume summary',
156example: true
157}),
158sectionPriorities: z.array(z.string()).optional().openapi({
159description: 'Sections to prioritize in extraction',
160example: ['skills', 'workExperience']
161}),
162extractLanguages: z.boolean().optional().openapi({
163description: 'Whether to extract language proficiencies',
164example: true
165})
166}).optional().openapi({
167description: 'Parser configuration options'
168})
169}).openapi('ResumeParserRequest')
170171// Personal info schema
179website: ConfidenceFieldSchema(z.string().nullable()),
180summary: ConfidenceFieldSchema(z.string().nullable())
181}).openapi('PersonalInfo')
182183// Skill schema
187proficiency: ConfidenceFieldSchema(z.string().nullable()),
188yearsOfExperience: ConfidenceFieldSchema(z.number().nullable())
189}).openapi('Skill')
190191// Work experience schema
198technologies: ConfidenceFieldSchema(z.array(z.string())),
199achievements: ConfidenceFieldSchema(z.array(z.string()))
200}).openapi('WorkExperience')
201202// Education schema
209coursework: ConfidenceFieldSchema(z.array(z.string()).nullable()),
210achievements: ConfidenceFieldSchema(z.array(z.string()).nullable())
211}).openapi('Education')
212213// Project schema
219dates: ConfidenceFieldSchema(DateRangeSchema.nullable()),
220role: ConfidenceFieldSchema(z.string().nullable())
221}).openapi('Project')
222223// Certification schema
228expiryDate: ConfidenceFieldSchema(z.string().nullable()),
229id: ConfidenceFieldSchema(z.string().nullable())
230}).openapi('Certification')
231232// Language schema
234name: ConfidenceFieldSchema(z.string()),
235proficiency: ConfidenceFieldSchema(z.string().nullable())
236}).openapi('Language')
237238// Parsed resume schema
248missingFields: z.array(z.string()),
249detectedSections: z.array(z.string())
250}).openapi('ParsedResume')
251252// Response schema
259details: z.unknown().optional()
260}).optional()
261}).openapi('ParseResumeResponse')
262263// Error response schema
269details: z.unknown().optional()
270})
271}).openapi('ErrorResponse')
272//Simplified ConfidenceFieldSchema
273export const SimplifiedConfidenceFieldSchema = <T extends z.ZodTypeAny>(valueSchema: T) =>